فهرست منبع

Merge "qca-wifi: Configure proper agile preCAC timeout value"

Linux Build Service Account 6 سال پیش
والد
کامیت
8b73b3c50d
1فایلهای تغییر یافته به همراه100 افزوده شده و 28 حذف شده
  1. 100 28
      umac/dfs/core/src/misc/dfs_zero_cac.c

+ 100 - 28
umac/dfs/core/src/misc/dfs_zero_cac.c

@@ -508,6 +508,7 @@ void dfs_prepare_agile_precac_chan(struct wlan_dfs *dfs)
 	uint8_t cur_dfs_idx = 0;
 	uint8_t vhtop_ch_freq_seg1, vhtop_ch_freq_seg2;
 	int i;
+	struct dfs_agile_cac_params adfs_param;
 
 	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
 	dfs_soc_obj = dfs->dfs_soc_obj;
@@ -551,10 +552,15 @@ void dfs_prepare_agile_precac_chan(struct wlan_dfs *dfs)
 	}
 
 	if (ch_freq) {
+		adfs_param.precac_chan = ch_freq;
+		adfs_param.precac_chwidth = dfs->dfs_precac_chwidth;
+		dfs_start_agile_precac_timer(temp_dfs,
+					     dfs->dfs_soc_obj->ocac_status,
+					     &adfs_param);
 		qdf_info("%s : %d ADFS channel set request sent for pdev: %pK ch_freq: %d",
 			 __func__, __LINE__, pdev, ch_freq);
 		if (dfs_tx_ops && dfs_tx_ops->dfs_agile_ch_cfg_cmd)
-			dfs_tx_ops->dfs_agile_ch_cfg_cmd(pdev, &ch_freq);
+			dfs_tx_ops->dfs_agile_ch_cfg_cmd(pdev, &adfs_param);
 		else
 			dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
 				"dfs_tx_ops=%pK", dfs_tx_ops);
@@ -930,6 +936,7 @@ void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev,
 			       uint32_t center_freq)
 {
 	struct wlan_dfs *dfs = NULL;
+	struct dfs_agile_cac_params adfs_param;
 
 	dfs = wlan_pdev_get_dfs_obj(pdev);
 
@@ -950,7 +957,11 @@ void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev,
 		 * TRIGGER agile precac timer with 0sec timeout
 		 * with ocac_status 0 for old pdev
 		 */
-		dfs_start_agile_precac_timer(dfs, center_freq, ocac_status);
+		adfs_param.precac_chan = center_freq;
+		adfs_param.precac_chwidth = dfs->dfs_precac_chwidth;
+		dfs_start_agile_precac_timer(dfs,
+					     ocac_status,
+					     &adfs_param);
 	} else {
 		dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, "Error Unknown");
 	}
@@ -1627,28 +1638,94 @@ void dfs_cancel_precac_timer(struct wlan_dfs *dfs)
 }
 
 #ifdef QCA_SUPPORT_AGILE_DFS
-#define DEFAULT_CAC_DURATION 62
-void dfs_start_agile_precac_timer(struct wlan_dfs *dfs, uint8_t precac_chan,
-				  uint8_t ocac_status)
+/* FIND_IF_OVERLAP_WITH_WEATHER_RANGE() - Find if the given channel range
+ * overlaps with the weather channel range.
+ * @first_ch: First subchannel of the channel range.
+ * @last_ch:  Last subchannel of the channel range.
+ *
+ * Algorithm:
+ * If the first channel of given range is left of last weather channel
+ * and if the last channel of given range is right of the first weather channel,
+ * return true, else false.
+ */
+#define FIND_IF_OVERLAP_WITH_WEATHER_RANGE(first_ch, last_ch) \
+((first_ch <= WEATHER_CHAN_START) && (WEATHER_CHAN_END <= last_ch))
+
+/* dfs_is_precac_on_weather_channel() - Given a channel number, find if
+ * it's a weather radar channel.
+ * @dfs: Pointer to WLAN_DFS structure.
+ * @chwidth: PreCAC channel width enum.
+ * @precac_chan: Channel for preCAC.
+ *
+ * Based on the precac_width, find the first and last subchannels of the given
+ * preCAC channel and check if this range overlaps with weather channel range.
+ *
+ * Return: True if weather channel, else false.
+ */
+static bool dfs_is_precac_on_weather_channel(struct wlan_dfs *dfs,
+					     enum phy_ch_width chwidth,
+					     uint8_t precac_chan)
+{
+	uint8_t first_subch, last_subch;
+
+	switch (chwidth) {
+	case CH_WIDTH_20MHZ:
+		first_subch = precac_chan;
+		last_subch = precac_chan;
+		break;
+	case CH_WIDTH_40MHZ:
+		first_subch = precac_chan - DFS_5GHZ_NEXT_CHAN_OFFSET;
+		last_subch = precac_chan + DFS_5GHZ_NEXT_CHAN_OFFSET;
+		break;
+	case CH_WIDTH_80MHZ:
+		first_subch = precac_chan - DFS_5GHZ_2ND_CHAN_OFFSET;
+		last_subch = precac_chan + DFS_5GHZ_2ND_CHAN_OFFSET;
+		break;
+	default:
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
+			"Precac channel width invalid!");
+		return false;
+	}
+	return FIND_IF_OVERLAP_WITH_WEATHER_RANGE(first_subch, last_subch);
+}
+
+void dfs_start_agile_precac_timer(struct wlan_dfs *dfs,
+				  uint8_t ocac_status,
+				  struct dfs_agile_cac_params *adfs_param)
 {
-	int agile_cac_timeout;
+	uint8_t precac_chan = adfs_param->precac_chan;
+	enum phy_ch_width chwidth = adfs_param->precac_chwidth;
+	uint32_t min_precac_timeout, max_precac_timeout;
 	struct dfs_soc_priv_obj *dfs_soc_obj;
 
 	dfs_soc_obj = dfs->dfs_soc_obj;
 	dfs_soc_obj->dfs_precac_timer_running = 1;
 
-	agile_cac_timeout = (dfs->dfs_precac_timeout_override != -1) ?
-				dfs->dfs_precac_timeout_override :
-				DEFAULT_CAC_DURATION;
 	if (ocac_status == OCAC_SUCCESS) {
 		dfs_soc_obj->ocac_status = OCAC_SUCCESS;
-		agile_cac_timeout = 0;
+		min_precac_timeout = 0;
+		max_precac_timeout = 0;
+	} else {
+		/* Find the minimum and maximum precac timeout. */
+		max_precac_timeout = MAX_PRECAC_DURATION;
+		if (dfs->dfs_precac_timeout_override != -1) {
+			min_precac_timeout =
+				dfs->dfs_precac_timeout_override * 1000;
+		} else if (dfs_is_precac_on_weather_channel(dfs,
+							    chwidth,
+							    precac_chan)) {
+			min_precac_timeout = MIN_WEATHER_PRECAC_DURATION;
+			max_precac_timeout = MAX_WEATHER_PRECAC_DURATION;
+		} else {
+			min_precac_timeout = MIN_PRECAC_DURATION;
+		}
 	}
 
 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
-		 "precactimeout = %d", (agile_cac_timeout) * 1000);
-	qdf_timer_mod(&dfs_soc_obj->dfs_precac_timer,
-		      (agile_cac_timeout) * 1000);
+		 "precactimeout = %d ms", (min_precac_timeout));
+	qdf_timer_mod(&dfs_soc_obj->dfs_precac_timer, min_precac_timeout);
+	adfs_param->min_precac_timeout = min_precac_timeout;
+	adfs_param->max_precac_timeout = max_precac_timeout;
 }
 #endif
 
@@ -2172,15 +2249,10 @@ void dfs_get_ieeechan_for_agilecac(struct wlan_dfs *dfs,
 						pri_ch_ieee,
 						sec_ch_ieee,
 						chwidth_val);
-	if (ieee_chan) {
+	if (ieee_chan)
 		dfs->dfs_agile_precac_freq = ieee_chan;
-		/* Start the pre_cac_timer */
-		dfs_start_agile_precac_timer(dfs,
-					     dfs->dfs_agile_precac_freq,
-					     dfs->dfs_soc_obj->ocac_status);
-	} else {
+	else
 		dfs->dfs_agile_precac_freq = 0;
-	}
 
 	*ch_ieee = dfs->dfs_agile_precac_freq;
 }
@@ -2374,16 +2446,12 @@ void dfs_set_precac_enable(struct wlan_dfs *dfs, uint32_t value)
 #ifdef QCA_SUPPORT_AGILE_DFS
 void dfs_agile_precac_start(struct wlan_dfs *dfs)
 {
-	uint8_t agile_freq = 0;
+	struct dfs_agile_cac_params adfs_param;
 	uint8_t ocac_status = 0;
 	struct dfs_soc_priv_obj *dfs_soc_obj;
 	uint8_t cur_dfs_idx;
 
 	dfs_soc_obj = dfs->dfs_soc_obj;
-	/*
-	 * Initiate first call to start preCAC here, for agile_freq as 0,
-	 * and ocac_status as 0
-	 */
 
 	qdf_info("%s : %d agile_precac_started: %d",
 		 __func__, __LINE__,
@@ -2400,12 +2468,16 @@ void dfs_agile_precac_start(struct wlan_dfs *dfs)
 		 dfs->dfs_soc_obj->dfs_priv[cur_dfs_idx].dfs);
 
 	if (!dfs->dfs_soc_obj->precac_state_started) {
+		/*
+		 * Initiate first call to start preCAC here, for channel as 0,
+		 * and ocac_status as 0
+		 */
+		adfs_param.precac_chan = 0;
+		adfs_param.precac_chwidth = CH_WIDTH_INVALID;
 		qdf_info("%s : %d Initiated agile precac",
 			 __func__, __LINE__);
 		dfs->dfs_soc_obj->precac_state_started = true;
-		dfs_start_agile_precac_timer(dfs,
-					     agile_freq,
-					     ocac_status);
+		dfs_start_agile_precac_timer(dfs, ocac_status, &adfs_param);
 	}
 }
 #endif