qcacmn: Add frequency APIS in DFS Core, TGT DFS and DFS Utils

To avoid "channel number" collision with the introduction of
6GHZ frequency band, add frequency-based APIs to DFS Core.
Also, do not remove the old IEEE channel-number-based APIs that are still
referenced.

The DFS APIs of Target-IF layer and DFS UTILS in DFS dispatcher layer are
included as a part of this change as they invoke DFS Core APIs and are
dependent.

CRs-Fixed: 2526372
Change-Id: I7a00ca5796e9c81527438c326c2d41de1147ffee
diff --git a/umac/dfs/core/src/misc/dfs_nol.c b/umac/dfs/core/src/misc/dfs_nol.c
index d71f551..b2a9831 100644
--- a/umac/dfs/core/src/misc/dfs_nol.c
+++ b/umac/dfs/core/src/misc/dfs_nol.c
@@ -55,6 +55,64 @@
  *
  * Clears the WLAN_CHAN_DFS_RADAR_FOUND flag for the NOL timeout channel.
  */
+/* Unused function */
+#ifdef CONFIG_CHAN_FREQ_API
+static os_timer_func(dfs_nol_timeout)
+{
+	struct dfs_channel *c = NULL, lc;
+	unsigned long oldest, now;
+	struct wlan_dfs *dfs = NULL;
+	int i;
+	int nchans = 0;
+
+	c = &lc;
+
+	OS_GET_TIMER_ARG(dfs, struct wlan_dfs *);
+	dfs_mlme_get_dfs_ch_nchans(dfs->dfs_pdev_obj, &nchans);
+
+	now = oldest = qdf_system_ticks();
+	for (i = 0; i < nchans; i++) {
+		dfs_mlme_get_dfs_channels_for_freq
+			(dfs->dfs_pdev_obj,
+			 &c->dfs_ch_freq,
+			 &c->dfs_ch_flags,
+			 &c->dfs_ch_flagext,
+			 &c->dfs_ch_ieee,
+			 &c->dfs_ch_vhtop_ch_freq_seg1,
+			 &c->dfs_ch_vhtop_ch_freq_seg2,
+			 &c->dfs_ch_mhz_freq_seg1,
+			 &c->dfs_ch_mhz_freq_seg2,
+			 i);
+		if (WLAN_IS_CHAN_RADAR(c)) {
+			if (qdf_system_time_after_eq(now,
+						     dfs->dfs_nol_event[i] +
+						     dfs_get_nol_timeout(dfs))) {
+				c->dfs_ch_flagext &= ~WLAN_CHAN_DFS_RADAR_FOUND;
+				if (c->dfs_ch_flags & WLAN_CHAN_DFS_RADAR) {
+					/*
+					 * NB: do this here so we get only one
+					 * msg instead of one for every channel
+					 * table entry.
+					 */
+					dfs_debug(dfs, WLAN_DEBUG_DFS,
+						  "radar on channel %u (%u MHz) cleared after timeout",
+						  c->dfs_ch_ieee,
+						  c->dfs_ch_freq);
+				}
+			} else if (dfs->dfs_nol_event[i] < oldest) {
+				oldest = dfs->dfs_nol_event[i];
+			}
+		}
+	}
+	if (oldest != now) {
+		/* Arrange to process next channel up for a status change. */
+		qdf_timer_mod(&dfs->dfs_nol_timer,
+			      dfs_get_nol_timeout(dfs) -
+			      qdf_system_ticks_to_msecs(qdf_system_ticks()));
+	}
+}
+#else
+#ifdef CONFIG_CHAN_NUM_API
 static os_timer_func(dfs_nol_timeout)
 {
 	struct dfs_channel *c = NULL, lc;
@@ -108,6 +166,8 @@
 				qdf_system_ticks_to_msecs(qdf_system_ticks()));
 	}
 }
+#endif
+#endif
 
 /**
  * dfs_nol_elem_free_work_cb -  Free NOL element
@@ -227,6 +287,40 @@
  *
  * When NOL times out, this function removes the channel from NOL list.
  */
+#ifdef CONFIG_CHAN_FREQ_API
+static os_timer_func(dfs_remove_from_nol)
+{
+	struct dfs_nolelem *nol_arg;
+	struct wlan_dfs *dfs;
+	uint16_t delfreq;
+	uint16_t delchwidth;
+	uint8_t chan;
+
+	OS_GET_TIMER_ARG(nol_arg, struct dfs_nolelem *);
+
+	dfs = nol_arg->nol_dfs;
+	delfreq = nol_arg->nol_freq;
+	delchwidth = nol_arg->nol_chwidth;
+
+	/* Delete the given NOL entry. */
+	DFS_NOL_DELETE_CHAN_LOCKED(dfs, delfreq, delchwidth);
+
+	/* Update the wireless stack with the new NOL. */
+	dfs_nol_update(dfs);
+
+	dfs_mlme_nol_timeout_notification(dfs->dfs_pdev_obj);
+	chan = utils_dfs_freq_to_chan(delfreq);
+	utils_dfs_deliver_event(dfs->dfs_pdev_obj, delfreq,
+				WLAN_EV_NOL_FINISHED);
+	dfs_debug(dfs, WLAN_DEBUG_DFS_NOL,
+		  "remove channel %d from nol", chan);
+	utils_dfs_unmark_precac_nol_for_freq(dfs->dfs_pdev_obj, delfreq);
+	utils_dfs_reg_update_nol_chan_for_freq(dfs->dfs_pdev_obj,
+					     &delfreq, 1, DFS_NOL_RESET);
+	utils_dfs_save_nol(dfs->dfs_pdev_obj);
+}
+#else
+#ifdef CONFIG_CHAN_NUM_API
 static os_timer_func(dfs_remove_from_nol)
 {
 	struct dfs_nolelem *nol_arg;
@@ -258,6 +352,8 @@
 				    &chan, 1, DFS_NOL_RESET);
 	utils_dfs_save_nol(dfs->dfs_pdev_obj);
 }
+#endif
+#endif
 
 void dfs_print_nol(struct wlan_dfs *dfs)
 {
@@ -344,6 +440,45 @@
 	}
 }
 
+#ifdef CONFIG_CHAN_FREQ_API
+void dfs_set_nol(struct wlan_dfs *dfs,
+		 struct dfsreq_nolelem *dfs_nol,
+		 int nchan)
+{
+#define TIME_IN_MS 1000
+	uint32_t nol_time_lft_ms;
+	struct dfs_channel chan;
+	int i;
+
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
+		return;
+	}
+
+	for (i = 0; i < nchan; i++) {
+		nol_time_lft_ms =
+			qdf_system_ticks_to_msecs(qdf_system_ticks() -
+				dfs_nol[i].nol_start_ticks);
+
+		if (nol_time_lft_ms < dfs_nol[i].nol_timeout_ms) {
+			chan.dfs_ch_freq = dfs_nol[i].nol_freq;
+			chan.dfs_ch_flags = 0;
+			chan.dfs_ch_flagext = 0;
+			nol_time_lft_ms =
+				(dfs_nol[i].nol_timeout_ms - nol_time_lft_ms);
+
+			DFS_NOL_ADD_CHAN_LOCKED(dfs, chan.dfs_ch_freq,
+						(nol_time_lft_ms / TIME_IN_MS));
+			utils_dfs_reg_update_nol_chan_for_freq(dfs->dfs_pdev_obj,
+							     &chan.dfs_ch_freq,
+							     1, DFS_NOL_SET);
+		}
+	}
+#undef TIME_IN_MS
+	dfs_nol_update(dfs);
+}
+#else
+#ifdef CONFIG_CHAN_NUM_API
 void dfs_set_nol(struct wlan_dfs *dfs,
 		struct dfsreq_nolelem *dfs_nol,
 		int nchan)
@@ -381,6 +516,8 @@
 #undef TIME_IN_MS
 	dfs_nol_update(dfs);
 }
+#endif
+#endif
 
 void dfs_nol_addchan(struct wlan_dfs *dfs,
 		uint16_t freq,
@@ -438,8 +575,9 @@
 	}
 
 	qdf_timer_init(NULL,
-			&elem->nol_timer, dfs_remove_from_nol,
-			elem, QDF_TIMER_TYPE_WAKE_APPS);
+		       &elem->nol_timer, dfs_remove_from_nol,
+		       elem, QDF_TIMER_TYPE_WAKE_APPS);
+
 	qdf_timer_mod(&elem->nol_timer, dfs_nol_timeout * TIME_IN_MS);
 
 	/* Update the NOL counter. */
@@ -586,6 +724,42 @@
 	DFS_GET_NOL_LOCKED(dfs, nolinfo->dfs_nol, &(nolinfo->dfs_ch_nchans));
 }
 
+#ifdef CONFIG_CHAN_FREQ_API
+void dfs_clear_nolhistory(struct wlan_dfs *dfs)
+{
+	struct dfs_channel *chan_list;
+	int nchans = 0;
+	bool sta_opmode;
+
+	if (!dfs->dfs_is_stadfs_enabled)
+		return;
+
+	sta_opmode = dfs_mlme_is_opmode_sta(dfs->dfs_pdev_obj);
+	if (!sta_opmode)
+		return;
+
+	nchans = dfs_get_num_chans();
+
+	chan_list = qdf_mem_malloc(nchans * sizeof(*chan_list));
+	if (!chan_list)
+		return;
+
+	utils_dfs_get_nol_history_chan_list(dfs->dfs_pdev_obj,
+					    (void *)chan_list, &nchans);
+	if (!nchans) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "zero chans");
+		qdf_mem_free(chan_list);
+		return;
+	}
+
+	utils_dfs_reg_update_nol_history_chan_for_freq(dfs->dfs_pdev_obj,
+						     (void *)chan_list, nchans,
+						     DFS_NOL_HISTORY_RESET);
+
+	qdf_mem_free(chan_list);
+}
+#else
+#ifdef CONFIG_CHAN_NUM_API
 void dfs_clear_nolhistory(struct wlan_dfs *dfs)
 {
 	struct dfs_channel *chan_list;
@@ -619,8 +793,42 @@
 
 	qdf_mem_free(chan_list);
 }
+#endif
+#endif
 
-#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) && \
+	defined(CONFIG_CHAN_FREQ_API)
+void dfs_remove_spoof_channel_from_nol(struct wlan_dfs *dfs)
+{
+	struct dfs_nolelem *nol;
+	uint16_t freq_list[NUM_CHANNELS_160MHZ];
+	int i, nchans = 0;
+
+	nchans = dfs_get_bonding_channels_for_freq(dfs,
+						   &dfs->dfs_radar_found_chan,
+						   SEG_ID_PRIMARY,
+						   DETECTOR_ID_0,
+						   freq_list);
+
+	WLAN_DFSNOL_LOCK(dfs);
+	for (i = 0; i < nchans && i < NUM_CHANNELS_160MHZ; i++) {
+		nol = dfs->dfs_nol;
+		while (nol) {
+			if (nol->nol_freq == freq_list[i]) {
+				OS_SET_TIMER(&nol->nol_timer, 0);
+				break;
+			}
+			nol = nol->nol_next;
+		}
+	}
+	WLAN_DFSNOL_UNLOCK(dfs);
+
+	utils_dfs_reg_update_nol_chan_for_freq(dfs->dfs_pdev_obj,
+					     freq_list, nchans, DFS_NOL_RESET);
+}
+#else
+#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) && \
+	defined(CONFIG_CHAN_NUM_API)
 void dfs_remove_spoof_channel_from_nol(struct wlan_dfs *dfs)
 {
 	struct dfs_nolelem *nol;
@@ -651,3 +859,4 @@
 				    channels, nchans, DFS_NOL_RESET);
 }
 #endif
+#endif