Эх сурвалжийг харах

qcacmn: DFS API support for Rolling CAC

An extension of preCAC feature is Rolling CAC. The distinct difference
between these features is that the FW runs the off channel CAC
timer for a "finite" time for preCAC and runs the timer for "infinite"
time on an off channel. Hence the infrastructure built for
preCAC feature is being modified to accommodate RCAC feature as well.
Following are the modifications done:

1. Add an enum to represent various off-channel CAC modes.
2. Remove the 'static' declaration of few APIS so as to re-use them.
3. Add 'dfs_rcac_ch_params' to DFS PDEV object to store the RCAC
channel params so as to use the channel params after radar detect.
4. Rename DFS APIs to match its functionality.

CRs-Fixed: 2670419
Change-Id: I0bf0d33955706941cffb4e9cf6fcebfb465a6c74
Priyadarshnee S 5 жил өмнө
parent
commit
4c6b5c6f69

+ 1 - 2
target_if/dfs/src/target_if_dfs_full_offload.c

@@ -33,7 +33,6 @@
 
 #if defined(QCA_SUPPORT_AGILE_DFS)
 #include <wlan_mlme_dispatcher.h>
-#define QUICK_OCAC_MODE 0
 #endif
 /**
  * target_if_dfs_cac_complete_event_handler() - CAC complete indication.
@@ -372,7 +371,7 @@ QDF_STATUS target_send_agile_ch_cfg_cmd(struct wlan_objmgr_pdev *pdev,
 
 	qdf_mem_set(&param, sizeof(param), 0);
 	param.vdev_id = wlan_vdev_get_id(vdev);
-	param.ocac_mode = QUICK_OCAC_MODE;
+	param.ocac_mode = adfs_param->ocac_mode;
 	param.min_duration_ms = adfs_param->min_precac_timeout;
 	param.max_duration_ms = adfs_param->max_precac_timeout;
 	param.chan_freq = adfs_param->precac_center_freq_1;

+ 32 - 4
umac/dfs/core/src/dfs.h

@@ -1102,8 +1102,10 @@ 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
+ * @dfs_agile_rcac_freq_ucfg:        User programmed Rolling CAC frequency in
  *                                   MHZ.
+ * @dfs_rcac_ch_params:              Channel params of the selected RCAC
+ *                                   channel.
  */
 struct wlan_dfs {
 	uint32_t       dfs_debug_mask;
@@ -1273,7 +1275,8 @@ struct wlan_dfs {
 	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;
+	uint16_t       dfs_agile_rcac_freq_ucfg;
+	struct ch_params dfs_rcac_ch_params;
 #endif
 };
 
@@ -1307,7 +1310,6 @@ struct wlan_dfs_priv {
  * @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.
  * @dfs_rcac_sm_hdl: DFS Rolling CAC state machine handle.
  * @dfs_rcac_curr_state: Current state of DFS rolling CAC state machine.
  * @dfs_rcac_sm_lock: DFS Rolling CAC state machine lock.
@@ -1328,7 +1330,6 @@ struct dfs_soc_priv_obj {
 	struct dfsreq_nolinfo *dfs_psoc_nolinfo;
 #if defined(QCA_SUPPORT_ADFS_RCAC)
 	qdf_timer_t dfs_rcac_timer;
-	bool dfs_rcac_timer_running;
 	wlan_sm *dfs_rcac_sm_hdl;
 	enum dfs_rcac_sm_state dfs_rcac_curr_state;
 	qdf_spinlock_t dfs_rcac_sm_lock;
@@ -2919,4 +2920,31 @@ static inline uint8_t dfs_get_agile_detector_id(struct wlan_dfs *dfs)
 	return INVALID_DETECTOR_ID;
 }
 #endif
+
+/**
+ * dfs_is_new_chan_subset_of_old_chan() - Find if new channel is subset of
+ *                                        old channel.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @new_chan: Pointer to new channel of dfs_channel structure.
+ * @old_chan: Pointer to old channel of dfs_channel structure.
+ *
+ * Return: True if new channel is subset of old channel, else false.
+ */
+bool dfs_is_new_chan_subset_of_old_chan(struct wlan_dfs *dfs,
+					struct dfs_channel *new_chan,
+					struct dfs_channel *old_chan);
+
+/**
+ * dfs_find_dfs_sub_channels_for_freq() - Given a dfs channel, find its
+ *                                        HT20 subset channels.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @chan: Pointer to dfs_channel structure.
+ * @subchan_arr: Pointer to subchannels array.
+ *
+ * Return: Number of sub channels.
+ */
+uint8_t dfs_find_dfs_sub_channels_for_freq(struct  wlan_dfs *dfs,
+					   struct dfs_channel *chan,
+					   uint16_t *subchan_arr);
+
 #endif  /* _DFS_H_ */

+ 40 - 20
umac/dfs/core/src/dfs_zero_cac.h

@@ -72,6 +72,8 @@
 #define MIN_WEATHER_PRECAC_DURATION          (60 * 60 * 1000) /* 1 hour */
 #define MAX_PRECAC_DURATION              (4 * 60 * 60 * 1000) /* 4 hours */
 #define MAX_WEATHER_PRECAC_DURATION     (24 * 60 * 60 * 1000) /* 24 hours */
+#define MIN_RCAC_DURATION                     (62 * 1000) /* 62 seconds */
+#define MAX_RCAC_DURATION                     0xffffffff
 
 #define PCAC_DFS_INDEX_ZERO               0
 #define PCAC_TIMER_NOT_RUNNING            0
@@ -594,7 +596,7 @@ void dfs_get_ieeechan_for_agilecac(struct wlan_dfs *dfs,
 #endif
 
 /**
- * dfs_get_ieeechan_for_agilecac_for_freq() - Find chan freq for agile CAC.
+ * dfs_set_agilecac_chan_for_freq() - Find chan freq for agile CAC.
  * @dfs:         Pointer to wlan_dfs structure.
  * @chan_freq:     Pointer to channel freq for agile set request.
  * @pri_chan_freq: Current primary IEEE channel freq.
@@ -604,10 +606,10 @@ void dfs_get_ieeechan_for_agilecac(struct wlan_dfs *dfs,
  * channels (indicated by pri_chan_freq, sec_chan_freq).
  */
 #ifdef CONFIG_CHAN_FREQ_API
-void dfs_get_ieeechan_for_agilecac_for_freq(struct wlan_dfs *dfs,
-					    uint16_t *chan_freq,
-					    uint16_t pri_chan_freq,
-					    uint16_t sec_chan_freq);
+void dfs_set_agilecac_chan_for_freq(struct wlan_dfs *dfs,
+				    uint16_t *chan_freq,
+				    uint16_t pri_chan_freq,
+				    uint16_t sec_chan_freq);
 #endif
 
 /**
@@ -670,10 +672,10 @@ static inline void dfs_get_ieeechan_for_agilecac(struct wlan_dfs *dfs,
 
 #ifdef CONFIG_CHAN_FREQ_API
 static inline void
-dfs_get_ieeechan_for_agilecac_for_freq(struct wlan_dfs *dfs,
-				       uint16_t *chan_freq,
-				       uint16_t pri_chan_freq,
-				       uint16_t sec_chan_freq)
+dfs_set_agilecac_chan_for_freq(struct wlan_dfs *dfs,
+			       uint16_t *chan_freq,
+			       uint16_t pri_chan_freq,
+			       uint16_t sec_chan_freq)
 {
 }
 #endif
@@ -946,18 +948,20 @@ void dfs_find_chwidth_and_center_chan(struct wlan_dfs *dfs,
 
 #ifdef CONFIG_CHAN_FREQ_API
 /**
- * dfs_find_chwidth_and_center_chan_for_freq() - Find the channel width enum and
- *                                      primary and secondary center channel
- *                                      value of the current channel.
+ * dfs_find_curchwidth_and_center_chan_for_freq() - Find the channel width
+ *                                                  enum, primary and secondary
+ *                                                  center channel value of
+ *                                                  the current channel.
  * @dfs:                  Pointer to wlan_dfs structure.
  * @chwidth:              Channel width enum of current channel.
  * @primary_chan_freq:    Primary IEEE channel freq.
  * @secondary_chan_freq:  Secondary IEEE channel freq (in HT80_80 mode).
  */
-void dfs_find_chwidth_and_center_chan_for_freq(struct wlan_dfs *dfs,
-					       enum phy_ch_width *chwidth,
-					       uint16_t *primary_chan_freq,
-					       uint16_t *secondary_chan_freq);
+void
+dfs_find_curchwidth_and_center_chan_for_freq(struct wlan_dfs *dfs,
+					     enum phy_ch_width *chwidth,
+					     uint16_t *primary_chan_freq,
+					     uint16_t *secondary_chan_freq);
 #endif
 
 /**
@@ -1051,10 +1055,10 @@ dfs_find_chwidth_and_center_chan(struct wlan_dfs *dfs,
 
 #ifdef CONFIG_CHAN_FREQ_API
 static inline void
-dfs_find_chwidth_and_center_chan_for_freq(struct wlan_dfs *dfs,
-					  enum phy_ch_width *chwidth,
-					  uint16_t *primary_chan_freq,
-					  uint16_t *secondary_chan_freq)
+dfs_find_curchwidth_and_center_chan_for_freq(struct wlan_dfs *dfs,
+					     enum phy_ch_width *chwidth,
+					     uint16_t *primary_chan_freq,
+					     uint16_t *secondary_chan_freq)
 {
 }
 #endif
@@ -1329,4 +1333,20 @@ QDF_STATUS dfs_rcac_sm_destroy(struct dfs_soc_priv_obj *dfs_soc_obj)
 }
 #endif /* QCA_SUPPORT_ADFS_RCAC */
 
+/**
+ * dfs_prepare_agile_rcac_channel() - Prepare agile RCAC channel.
+ * @dfs: Pointer to struct wlan_dfs.
+ * @is_rcac_chan_available: Flag to indicate if a valid RCAC channel is
+ *                          found.
+ */
+#ifdef QCA_SUPPORT_ADFS_RCAC
+void dfs_prepare_agile_rcac_channel(struct wlan_dfs *dfs,
+				    bool *is_rcac_chan_available);
+#else
+static inline void
+dfs_prepare_agile_rcac_channel(struct wlan_dfs *dfs,
+			       bool *is_rcac_chan_available)
+{
+}
+#endif
 #endif /* _DFS_ZERO_CAC_H_ */

+ 8 - 16
umac/dfs/core/src/misc/dfs_cac.c

@@ -125,7 +125,7 @@ static void dfs_clear_cac_started_chan(struct wlan_dfs *dfs)
 void dfs_process_cac_completion(struct wlan_dfs *dfs)
 {
 	enum phy_ch_width ch_width = CH_WIDTH_INVALID;
-	uint16_t primary_chan_freq = 0, secondary_chan_freq = 0;
+	uint16_t primary_chan_freq = 0, sec_chan_freq = 0;
 	struct dfs_channel *dfs_curchan;
 
 	dfs->dfs_cac_timer_running = 0;
@@ -167,13 +167,13 @@ void dfs_process_cac_completion(struct wlan_dfs *dfs)
 				      dfs->dfs_cac_valid_time * 1000);
 		}
 
-		dfs_find_chwidth_and_center_chan_for_freq(dfs,
-							  &ch_width,
-							  &primary_chan_freq,
-							  &secondary_chan_freq);
+		dfs_find_curchwidth_and_center_chan_for_freq(dfs,
+							     &ch_width,
+							     &primary_chan_freq,
+							     &sec_chan_freq);
 		/* Mark the current channel as preCAC done */
 		dfs_mark_precac_done_for_freq(dfs, primary_chan_freq,
-					      secondary_chan_freq, ch_width);
+					      sec_chan_freq, ch_width);
 	}
 
 	dfs_clear_cac_started_chan(dfs);
@@ -440,7 +440,7 @@ dfs_is_subset_channel_for_freq(uint16_t *old_subchans_freq,
 #endif
 
 #ifdef CONFIG_CHAN_FREQ_API
-static uint8_t
+uint8_t
 dfs_find_dfs_sub_channels_for_freq(struct wlan_dfs *dfs,
 				   struct dfs_channel *chan,
 				   uint16_t *subchan_arr)
@@ -472,16 +472,8 @@ dfs_find_dfs_sub_channels_for_freq(struct wlan_dfs *dfs,
 }
 #endif
 
-/* dfs_is_new_chan_subset_of_old_chan() - Find if new channel is subset of
- * old channel.
- * @dfs: Pointer to wlan_dfs structure.
- * @new_chan: Pointer to new channel of dfs_channel structure.
- * @old_chan: Pointer to old channel of dfs_channel structure.
- *
- * Return: True if new channel is subset of old channel, else false.
- */
 #ifdef CONFIG_CHAN_FREQ_API
-static bool
+bool
 dfs_is_new_chan_subset_of_old_chan(struct wlan_dfs *dfs,
 				   struct dfs_channel *new_chan,
 				   struct dfs_channel *old_chan)

+ 18 - 0
umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h

@@ -125,6 +125,22 @@ struct dfs_radar_found_params {
 	u_int32_t sidx_max;
 };
 
+/**
+ * enum adfs_ocac_mode - Various Off-Channel CAC modes.
+ * @QUICK_OCAC_MODE: Used for OCAC where the CAC timeout value is finite.
+ *                   This is also known as PreCAC.
+ * @EXTENSIVE_OCAC:  Extensive OCAC.
+ * @QUICK_RCAC_MODE: Used for RollingCAC where the timeout value is assumed to
+ *                   be infinite by the Firmware code, that is, the FW has to
+ *                   be on the agile channel until host stop/aborts the agile
+ *                   CAC.
+ */
+enum adfs_ocac_mode {
+	QUICK_OCAC_MODE = 0,
+	EXTENSIVE_OCAC_MODE,
+	QUICK_RCAC_MODE,
+};
+
 /**
  * struct dfs_agile_cac_params - Agile DFS-CAC parameters.
  * @precac_chan:           Agile preCAC channel.
@@ -137,6 +153,7 @@ struct dfs_radar_found_params {
  * @precac_chwidth:        Agile preCAC channel width.
  * @min_precac_timeout:    Minimum agile preCAC timeout.
  * @max_precac_timeout:    Maximum agile preCAC timeout.
+ * @ocac_mode:             Off-Channel CAC mode.
  */
 struct dfs_agile_cac_params {
 	uint8_t precac_chan;
@@ -145,5 +162,6 @@ struct dfs_agile_cac_params {
 	enum phy_ch_width precac_chwidth;
 	uint32_t min_precac_timeout;
 	uint32_t max_precac_timeout;
+	enum adfs_ocac_mode ocac_mode;
 };
 #endif