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