Browse Source

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
Dustin Brown 6 years ago
parent
commit
8660dd30d8

+ 1 - 1
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,

+ 45 - 21
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

+ 39 - 10
core/hdd/src/wlan_hdd_sap_cond_chan_switch.c

@@ -23,13 +23,14 @@
  *
  */
 
-#include <wlan_hdd_includes.h>
+#include <cds_utils.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/etherdevice.h>
 #include <linux/if_ether.h>
-#include <cds_utils.h>
+#include "osif_sync.h"
 #include <qdf_str.h>
+#include <wlan_hdd_includes.h>
 #include <wlan_hdd_sap_cond_chan_switch.h>
 
 /**
@@ -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;