Browse Source

qcacmn: Add DFS APIs for Rolling CAC feature

Feature Description:
FCC/JP domains do not support PreCAC. However, we can always start
beaconning in a channel if we have completed CAC in that channel for more
than or equal to the CAC period of that channel.
If an Agile engine is available and the next channel is known, we can
start CAC in the next channel using agile, while continuing the Tx/Rx
in the current channel. And when we want to start beaconning in the
next channel after a radar detection (or after/for a user request) we can
do so without any new CAC. This allows us to jump to the new channel
without having to disrupt any ongoing data traffic. This type of
continuous CAC in the next channel while operating in the current channel
is known as Rolling CAC.

Following changes are implemented:
I)Per DFS PDEV:
1) 'dfs_agile_rcac_freq' to store agile RCAC frequency.
2) 'dfs_agile_rcac_ucfg' to enable/disable RCAC feature.

II)Per DFS PSOC:
1) 'dfs_rcac_timer' is the only RCAC timer for the device/Psoc. This will
be shared by pdev level dfs objects.
2) 'dfs_rcac_timer_running' to indicate if RCAC is running or not.

III) New APIs:
1. A dispatcher API 'ucfg_dfs_set_rcac_enable' to set rcac config.
2. A dispatcher API 'ucfg_dfs_get_rcac_enable' to get rcac_config.
3. A dispatcher API 'ucfg_dfs_set_rcac_freq' to set user configured
rcac freq.
4. A dispatcher API 'ucfg_dfs_get_rcac_freq' to get the user configured
rcac freq.
5. Rolling CAC timer init/deinit APIs.

CRs-Fixed: 2659666
Change-Id: Iae002b2ab77964fca4faf237b0d0a4e2f2afe4c2
Priyadarshnee S 5 years ago
parent
commit
4dab98d3ce

+ 15 - 0
umac/dfs/core/src/dfs.h

@@ -1090,6 +1090,7 @@ struct dfs_mode_switch_defer_params {
  * @dfs_legacy_precac_ucfg:          User configuration for legacy preCAC in
  *                                   partial offload chipsets.
  * @dfs_agile_precac_ucfg:           User configuration for agile preCAC.
+ * @dfs_agile_rcac_ucfg:             User configuration for Rolling CAC.
  * @dfs_fw_adfs_support_non_160:     Target Agile DFS support for non-160 BWs.
  * @dfs_fw_adfs_support_160:         Target Agile DFS support for 160 BW.
  * @dfs_allow_hw_pulses:             Allow/Block HW pulses. When synthetic
@@ -1101,6 +1102,8 @@ struct dfs_mode_switch_defer_params {
  * @dfs_defer_params:                DFS deferred event parameters (allocated
  *                                   only for the duration of defer alone).
  * @dfs_agile_detector_id:           Agile detector ID for the DFS object.
+ * @dfs_agile_rcac_freq:             User programmed Rolling CAC frequency in
+ *                                   MHZ.
  */
 struct wlan_dfs {
 	uint32_t       dfs_debug_mask;
@@ -1259,6 +1262,9 @@ struct wlan_dfs {
 	bool           dfs_is_nol_ie_sent;
 	uint8_t        dfs_legacy_precac_ucfg:1,
 		       dfs_agile_precac_ucfg:1,
+#if defined(QCA_SUPPORT_ADFS_RCAC)
+		       dfs_agile_rcac_ucfg:1,
+#endif
 		       dfs_fw_adfs_support_non_160:1,
 		       dfs_fw_adfs_support_160:1;
 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR)
@@ -1266,6 +1272,9 @@ struct wlan_dfs {
 #endif
 	struct dfs_mode_switch_defer_params dfs_defer_params;
 	uint8_t        dfs_agile_detector_id;
+#if defined(QCA_SUPPORT_ADFS_RCAC)
+	uint16_t       dfs_agile_rcac_freq;
+#endif
 };
 
 #if defined(QCA_SUPPORT_AGILE_DFS) || defined(ATH_SUPPORT_ZERO_CAC_DFS)
@@ -1297,6 +1306,8 @@ struct wlan_dfs_priv {
  * @dfs_precac_timer_running: precac timer running flag
  * @ocac_status: Off channel CAC complete status
  * @dfs_nol_ctx: dfs NOL data for all radios.
+ * @dfs_rcac_timer: Agile RCAC (Rolling CAC) timer.
+ * @dfs_rcac_timer_running: RCAC (Rolling CAC) timer running flag.
  */
 struct dfs_soc_priv_obj {
 	struct wlan_objmgr_psoc *psoc;
@@ -1312,6 +1323,10 @@ struct dfs_soc_priv_obj {
 	bool ocac_status;
 #endif
 	struct dfsreq_nolinfo *dfs_psoc_nolinfo;
+#if defined(QCA_SUPPORT_ADFS_RCAC)
+	qdf_timer_t dfs_rcac_timer;
+	bool dfs_rcac_timer_running;
+#endif
 };
 
 /**

+ 113 - 0
umac/dfs/core/src/dfs_zero_cac.h

@@ -1143,4 +1143,117 @@ static inline bool dfs_is_precac_timer_running(struct wlan_dfs *dfs)
 
 #endif
 
+/**
+ * dfs_set_rcac_enable() - Set rcac enable flag.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @rcac_en: input value to configure rolling cac feature.
+ */
+#ifdef QCA_SUPPORT_ADFS_RCAC
+QDF_STATUS dfs_set_rcac_enable(struct wlan_dfs *dfs,
+			       bool rcac_en);
+#else
+static inline QDF_STATUS
+dfs_set_rcac_enable(struct wlan_dfs *dfs,
+		    bool rcac_en)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * dfs_get_rcac_enable() - Get rcac enable flag.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @rcac_en: Variable to hold the current rcac config.
+ */
+#ifdef QCA_SUPPORT_ADFS_RCAC
+QDF_STATUS dfs_get_rcac_enable(struct wlan_dfs *dfs,
+			       uint8_t *rcac_en);
+#else
+static inline QDF_STATUS
+dfs_get_rcac_enable(struct wlan_dfs *dfs,
+		    uint8_t *rcac_en)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * dfs_set_rcac_freq() - Set user configured rolling CAC frequency.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @rcac_freq: User preferred rolling cac frequency.
+ */
+#ifdef QCA_SUPPORT_ADFS_RCAC
+QDF_STATUS dfs_set_rcac_freq(struct wlan_dfs *dfs,
+			     qdf_freq_t rcac_freq);
+#else
+static inline QDF_STATUS
+dfs_set_rcac_freq(struct wlan_dfs *dfs,
+		  qdf_freq_t rcac_freq)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * dfs_get_rcac_freq() - Get user configured rolling CAC frequency.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @rcac_freq: Variable to store the user preferred rolling cac frequency.
+ */
+#ifdef QCA_SUPPORT_ADFS_RCAC
+QDF_STATUS dfs_get_rcac_freq(struct wlan_dfs *dfs,
+			     qdf_freq_t *rcac_freq);
+#else
+static inline QDF_STATUS
+dfs_get_rcac_freq(struct wlan_dfs *dfs,
+		  qdf_freq_t *rcac_freq)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * dfs_rcac_timer_init() - Initialize rolling cac timer.
+ * @dfs_soc_obj: Pointer to DFS SOC object structure.
+ */
+#ifdef QCA_SUPPORT_ADFS_RCAC
+void dfs_rcac_timer_init(struct dfs_soc_priv_obj *dfs_soc_obj);
+#else
+static inline void
+dfs_rcac_timer_init(struct dfs_soc_priv_obj *dfs_soc_obj)
+{
+}
+#endif
+
+/**
+ * dfs_rcac_timer_deinit() - Free rolling cac timer object.
+ * @dfs_soc_obj: Pointer to dfs_soc_priv_obj structure.
+ */
+#ifdef QCA_SUPPORT_ADFS_RCAC
+void dfs_rcac_timer_deinit(struct dfs_soc_priv_obj *dfs_soc_obj);
+#else
+static inline void
+dfs_rcac_timer_deinit(struct dfs_soc_priv_obj *dfs_soc_obj)
+{
+}
+#endif
+
+/**
+ * dfs_is_host_agile_rcac_config_enabled() - Check if agile rCAC is enabled.
+ * This considers the user config and DFS domain of the pdev to
+ * to decide if agile RCAC is supported or not.
+ * @dfs: Pointer to the wlan_dfs object.
+ *
+ * Return: True if agile DFS is enabled, else false.
+ *
+ */
+#ifdef QCA_SUPPORT_ADFS_RCAC
+bool dfs_is_host_agile_rcac_config_enabled(struct wlan_dfs *dfs);
+#else
+static inline bool
+dfs_is_host_agile_rcac_config_enabled(struct wlan_dfs *dfs)
+{
+	return false;
+}
+#endif
+
 #endif /* _DFS_ZERO_CAC_H_ */

+ 73 - 0
umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h

@@ -596,4 +596,77 @@ static inline QDF_STATUS ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc
 	return QDF_STATUS_SUCCESS;
 }
 #endif
+
+/**
+ * ucfg_dfs_set_rcac_enable() - Set rcac enable flag.
+ * @pdev: Pointer to DFS pdev object.
+ * @rcac_en: User input value to enable/disable rolling cac feature.
+ *
+ */
+#ifdef QCA_SUPPORT_ADFS_RCAC
+QDF_STATUS ucfg_dfs_set_rcac_enable(struct wlan_objmgr_pdev *pdev,
+				    bool rcac_en);
+#else
+static inline QDF_STATUS
+ucfg_dfs_set_rcac_enable(struct wlan_objmgr_pdev *pdev,
+			 bool rcac_en)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * ucfg_dfs_get_rcac_enable() - Get rcac enable flag.
+ * @pdev: Pointer to DFS pdev object.
+ * @rcac_en: Pointer to hold the "rcac" config.
+ *
+ */
+#ifdef QCA_SUPPORT_ADFS_RCAC
+QDF_STATUS ucfg_dfs_get_rcac_enable(struct wlan_objmgr_pdev *pdev,
+				    uint8_t *rcac_en);
+#else
+static inline QDF_STATUS
+ucfg_dfs_get_rcac_enable(struct wlan_objmgr_pdev *pdev,
+			 uint8_t *rcac_en)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * ucfg_dfs_set_rcac_freq() - Set rcac freq.
+ * @pdev: Pointer to DFS pdev object.
+ * @rcac_freq: User configured rcac freq in MHZ.
+ *
+ */
+#ifdef QCA_SUPPORT_ADFS_RCAC
+QDF_STATUS ucfg_dfs_set_rcac_freq(struct wlan_objmgr_pdev *pdev,
+				  qdf_freq_t rcac_freq);
+#else
+static inline QDF_STATUS
+ucfg_dfs_set_rcac_freq(struct wlan_objmgr_pdev *pdev,
+		       qdf_freq_t rcac_freq)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * ucfg_dfs_get_rcac_freq() - Get rcac freq.
+ * @pdev: Pointer to DFS pdev object.
+ * @rcac_freq: Pointer to store the user configured rcac freq in MHZ.
+ *
+ */
+#ifdef QCA_SUPPORT_ADFS_RCAC
+QDF_STATUS ucfg_dfs_get_rcac_freq(struct wlan_objmgr_pdev *pdev,
+				  qdf_freq_t *rcac_freq);
+#else
+static inline QDF_STATUS
+ucfg_dfs_get_rcac_freq(struct wlan_objmgr_pdev *pdev,
+		       qdf_freq_t *rcac_freq)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 #endif /* _WLAN_DFS_UCFG_API_H_ */

+ 4 - 0
umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c

@@ -195,6 +195,9 @@ static QDF_STATUS dfs_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc
 	/* Initialize precac timer here*/
 	dfs_zero_cac_timer_init(dfs_soc_obj);
 
+	/* Initialize Rolling CAC timer */
+	dfs_rcac_timer_init(dfs_soc_obj);
+
 	dfs_debug(NULL, WLAN_DEBUG_DFS1,
 		"DFS obj attach to psoc successfully");
 
@@ -222,6 +225,7 @@ static QDF_STATUS dfs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *pso
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	dfs_rcac_timer_deinit(dfs_soc_obj);
 	dfs_zero_cac_timer_detach(dfs_soc_obj);
 
 	status = wlan_objmgr_psoc_component_obj_detach(psoc,

+ 75 - 1
umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -448,3 +448,77 @@ QDF_STATUS ucfg_dfs_reinit_timers(struct wlan_objmgr_pdev *pdev)
 }
 
 qdf_export_symbol(ucfg_dfs_reinit_timers);
+
+#ifdef QCA_SUPPORT_ADFS_RCAC
+QDF_STATUS ucfg_dfs_set_rcac_enable(struct wlan_objmgr_pdev *pdev,
+				    bool rcac_en)
+{
+	struct wlan_dfs *dfs;
+
+	dfs = wlan_pdev_get_dfs_obj(pdev);
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dfs_set_rcac_enable(dfs, rcac_en);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(ucfg_dfs_set_rcac_enable);
+
+QDF_STATUS ucfg_dfs_get_rcac_enable(struct wlan_objmgr_pdev *pdev,
+				    uint8_t *rcac_en)
+{
+	struct wlan_dfs *dfs;
+
+	dfs = wlan_pdev_get_dfs_obj(pdev);
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dfs_get_rcac_enable(dfs, rcac_en);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(ucfg_dfs_get_rcac_enable);
+
+QDF_STATUS ucfg_dfs_set_rcac_freq(struct wlan_objmgr_pdev *pdev,
+				  qdf_freq_t rcac_freq)
+{
+	struct wlan_dfs *dfs;
+
+	dfs = wlan_pdev_get_dfs_obj(pdev);
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dfs_set_rcac_freq(dfs, rcac_freq);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(ucfg_dfs_set_rcac_freq);
+
+QDF_STATUS ucfg_dfs_get_rcac_freq(struct wlan_objmgr_pdev *pdev,
+				  qdf_freq_t *rcac_freq)
+{
+	struct wlan_dfs *dfs;
+
+	dfs = wlan_pdev_get_dfs_obj(pdev);
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dfs_get_rcac_freq(dfs, rcac_freq);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(ucfg_dfs_get_rcac_freq);
+#endif