From 8660dd30d8a62baa6abebe215ce2de61573d8864 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Thu, 24 Jan 2019 11:09:12 -0800 Subject: [PATCH] qcacld-3.0: Integrate DSC (pre-cac) 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 pre-CAC vdev create and destroy. Change-Id: I8f597fca2ccd908e358475abf360feefeac7db4d CRs-Fixed: 2397319 --- core/hdd/src/wlan_hdd_cfg80211.h | 2 +- core/hdd/src/wlan_hdd_hostapd.c | 66 +++++++++++++------- core/hdd/src/wlan_hdd_sap_cond_chan_switch.c | 49 ++++++++++++--- 3 files changed, 85 insertions(+), 32 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index caea166daf08..c68827470c16 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -387,7 +387,7 @@ static inline int wlan_hdd_send_roam_auth_event(struct hdd_adapter *adapter, #endif int wlan_hdd_cfg80211_update_apies(struct hdd_adapter *adapter); -int wlan_hdd_request_pre_cac(uint8_t channel); +int wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, uint8_t channel); int wlan_hdd_sap_cfg_dfs_override(struct hdd_adapter *adapter); int wlan_hdd_enable_dfs_chan_scan(struct hdd_context *hdd_ctx, diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 2a18f5faa49d..0c74341a258a 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1042,25 +1042,18 @@ static int wlan_hdd_set_pre_cac_complete_status(struct hdd_adapter *ap_adapter, /** * __wlan_hdd_sap_pre_cac_failure() - Process the pre cac failure - * @data: AP adapter + * @adapter: AP adapter * * Deletes the pre cac adapter * * Return: None */ -static void __wlan_hdd_sap_pre_cac_failure(void *data) +static void __wlan_hdd_sap_pre_cac_failure(struct hdd_adapter *adapter) { - struct hdd_adapter *adapter; struct hdd_context *hdd_ctx; hdd_enter(); - adapter = (struct hdd_adapter *) data; - if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { - hdd_err("SAP Pre CAC adapter invalid"); - return; - } - hdd_ctx = WLAN_HDD_GET_CTX(adapter); if (wlan_hdd_validate_context(hdd_ctx)) { hdd_err("HDD context is null"); @@ -1070,6 +1063,8 @@ static void __wlan_hdd_sap_pre_cac_failure(void *data) wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); hdd_stop_adapter(hdd_ctx, adapter); hdd_close_adapter(hdd_ctx, adapter, false); + + hdd_exit(); } /** @@ -1082,45 +1077,51 @@ static void __wlan_hdd_sap_pre_cac_failure(void *data) */ void wlan_hdd_sap_pre_cac_failure(void *data) { + struct hdd_adapter *adapter = data; + struct osif_vdev_sync *vdev_sync; + int errno; + + errno = osif_vdev_sync_trans_start_wait(adapter->dev, &vdev_sync); + if (errno) + return; + + osif_vdev_sync_unregister(adapter->dev); + osif_vdev_sync_wait_for_ops(vdev_sync); + cds_ssr_protect(__func__); __wlan_hdd_sap_pre_cac_failure(data); cds_ssr_unprotect(__func__); + + osif_vdev_sync_trans_stop(vdev_sync); + osif_vdev_sync_destroy(vdev_sync); } /** - * wlan_hdd_sap_pre_cac_success() - Process the pre cac result - * @data: AP adapter + * __wlan_hdd_sap_pre_cac_success() - Process the pre cac result + * @adapter: AP adapter * * Deletes the pre cac adapter and moves the existing SAP to the pre cac * channel * * Return: None */ -static void wlan_hdd_sap_pre_cac_success(void *data) +static void __wlan_hdd_sap_pre_cac_success(struct hdd_adapter *adapter) { - struct hdd_adapter *adapter, *ap_adapter; + struct hdd_adapter *ap_adapter; int i; struct hdd_context *hdd_ctx; hdd_enter(); - adapter = (struct hdd_adapter *) data; - if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { - hdd_err("SAP Pre CAC adapter invalid"); - return; - } - hdd_ctx = WLAN_HDD_GET_CTX(adapter); if (!hdd_ctx) { hdd_err("HDD context is null"); return; } - cds_ssr_protect(__func__); wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); hdd_stop_adapter(hdd_ctx, adapter); hdd_close_adapter(hdd_ctx, adapter, false); - cds_ssr_unprotect(__func__); /* Prepare to switch AP from 2.4GHz channel to the pre CAC channel */ ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE); @@ -1141,6 +1142,29 @@ static void wlan_hdd_sap_pre_cac_success(void *data) hdd_err("failed to change channel"); wlan_hdd_set_pre_cac_complete_status(ap_adapter, false); } + + hdd_exit(); +} + +static void wlan_hdd_sap_pre_cac_success(void *data) +{ + struct hdd_adapter *adapter = data; + struct osif_vdev_sync *vdev_sync; + int errno; + + errno = osif_vdev_sync_trans_start_wait(adapter->dev, &vdev_sync); + if (errno) + return; + + osif_vdev_sync_unregister(adapter->dev); + osif_vdev_sync_wait_for_ops(vdev_sync); + + cds_ssr_protect(__func__); + __wlan_hdd_sap_pre_cac_success(adapter); + cds_ssr_unprotect(__func__); + + osif_vdev_sync_trans_stop(vdev_sync); + osif_vdev_sync_destroy(vdev_sync); } #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE diff --git a/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c b/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c index c0c257751374..4378627abac2 100644 --- a/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c +++ b/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c @@ -23,13 +23,14 @@ * */ -#include +#include #include #include #include #include -#include +#include "osif_sync.h" #include +#include #include /** @@ -150,18 +151,21 @@ static int wlan_hdd_validate_and_get_pre_cac_ch(struct hdd_context *hdd_ctx, } /** - * wlan_hdd_request_pre_cac() - Start pre CAC in the driver + * __wlan_hdd_request_pre_cac() - Start pre CAC in the driver + * @hdd_ctx: the HDD context to operate against * @channel: Channel option provided by userspace + * @out_adapter: out parameter for the newly created pre-cac adapter * * Sets the driver to the required hardware mode and start an adapter for * pre CAC which will mimic an AP. * * Return: Zero on success, non-zero value on error */ -int wlan_hdd_request_pre_cac(uint8_t channel) +static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, + uint8_t channel, + struct hdd_adapter **out_adapter) { uint8_t pre_cac_chan = 0, *mac_addr; - struct hdd_context *hdd_ctx; int ret; struct hdd_adapter *ap_adapter, *pre_cac_adapter; struct hdd_ap_ctx *hdd_ap_ctx; @@ -175,10 +179,6 @@ int wlan_hdd_request_pre_cac(uint8_t channel) mac_handle_t mac_handle; bool val; - hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); - if (wlan_hdd_validate_context(hdd_ctx) != 0) - return -EINVAL; - if (policy_mgr_get_connection_count(hdd_ctx->psoc) > 1) { hdd_err("pre cac not allowed in concurrency"); return -EINVAL; @@ -373,6 +373,8 @@ int wlan_hdd_request_pre_cac(uint8_t channel) ap_adapter->pre_cac_chan = pre_cac_chan; + *out_adapter = pre_cac_adapter; + return 0; stop_close_pre_cac_adapter: @@ -392,6 +394,33 @@ release_intf_addr_and_return_failure: return -EINVAL; } +int wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, uint8_t channel) +{ + struct hdd_adapter *adapter; + struct osif_vdev_sync *vdev_sync; + int errno; + + errno = osif_vdev_sync_create_with_trans(hdd_ctx->parent_dev, + &vdev_sync); + if (errno) + return errno; + + errno = __wlan_hdd_request_pre_cac(hdd_ctx, channel, &adapter); + if (errno) + goto destroy_sync; + + osif_vdev_sync_register(adapter->dev, vdev_sync); + osif_vdev_sync_trans_stop(vdev_sync); + + return 0; + +destroy_sync: + osif_vdev_sync_trans_stop(vdev_sync); + osif_vdev_sync_destroy(vdev_sync); + + return errno; +} + /** * __wlan_hdd_cfg80211_conditional_chan_switch() - Conditional channel switch * @wiphy: Pointer to wireless phy @@ -498,7 +527,7 @@ __wlan_hdd_cfg80211_conditional_chan_switch(struct wiphy *wiphy, * If channel is zero, any channel in the available outdoor regulatory * domain will be selected. */ - ret = wlan_hdd_request_pre_cac(chans[0]); + ret = wlan_hdd_request_pre_cac(hdd_ctx, chans[0]); if (ret) { hdd_err("pre cac request failed with reason:%d", ret); return ret;