소스 검색

qcacmn: Use regdb component to set/get NOL-History channel list

In case of STADFS feature, when STA vap detects the RADAR, it marks the
channel as RADAR and adds the RADAR found channel to both NOL and
NOL-HISTORY list.
After nol expiry, STA vap does the CAC before connecting to the RootAP if
the RootAP channel is present in the STA  NOL-HISTORY.

Set nol_history_flag in regulatory component current channel list when STA
vap detects the RADAR.

Change-Id: I8d01f5830e6b4dd634b71c551ac347bc7d3d5c4c
CRs-Fixed: 2337921
Shashikala Prabhu 6 년 전
부모
커밋
62ce2260e9

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

@@ -1003,6 +1003,7 @@ struct dfs_event_log {
  * @dfs_spoof_test_done:             Indicates if the sppof test is done.
  * @dfs_status_timeout_override:     Used to change the timeout value of
  *                                   dfs_host_wait_timer.
+ * @dfs_is_stadfs_enabled:           Is STADFS enabled.
  * @dfs_min_sidx:                    Minimum sidx of the received radar pulses.
  * @dfs_max_sidx:                    Maximum sidx of the received radar pulses.
  * @dfs_seg_id:                      Segment ID of the radar hit channel.
@@ -1140,6 +1141,7 @@ struct wlan_dfs {
 	struct dfs_channel dfs_radar_found_chan;
 	int            dfs_status_timeout_override;
 #endif
+	bool           dfs_is_stadfs_enabled;
 	uint32_t       dfs_min_sidx;
 	uint32_t       dfs_max_sidx;
 	uint8_t        dfs_seg_id;

+ 48 - 35
umac/dfs/core/src/misc/dfs_nol.c

@@ -292,34 +292,35 @@ void dfs_print_nol(struct wlan_dfs *dfs)
 
 void dfs_print_nolhistory(struct wlan_dfs *dfs)
 {
-	struct dfs_channel *c, lc;
-	int i, j = 0;
-	int nchans = 0;
+	struct dfs_channel *chan_list;
+	int i, j;
+	int nchans;
 
 	if (!dfs) {
 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
 		return;
 	}
 
-	c = &lc;
+	nchans = dfs_get_num_chans();
 
-	dfs_mlme_get_dfs_ch_nchans(dfs->dfs_pdev_obj, &nchans);
-	for (i = 0; i < nchans; i++) {
-		dfs_mlme_get_dfs_ch_channels(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),
-				i);
-		if (WLAN_IS_CHAN_HISTORY_RADAR(c)) {
-			dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS,
-				"nolhistory:%d channel=%d MHz Flags=%llx",
-				j, c->dfs_ch_freq, c->dfs_ch_flags);
-			j++;
-		}
+	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;
 	}
+
+	for (i = 0, j = 0; i < nchans; i++, j++)
+		dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS,
+			 "nolhistory = %d channel = %d MHz",
+			 j, chan_list[i].dfs_ch_freq);
+
+	qdf_mem_free(chan_list);
 }
 
 void dfs_get_nol(struct wlan_dfs *dfs,
@@ -592,24 +593,36 @@ void dfs_getnol(struct wlan_dfs *dfs, void *dfs_nolinfo)
 
 void dfs_clear_nolhistory(struct wlan_dfs *dfs)
 {
-	/* We should have a dfs_clear_nolhistory API from Regdomain. */
-	struct dfs_channel *c, lc;
-	int i;
+	struct dfs_channel *chan_list;
 	int nchans = 0;
+	bool sta_opmode;
 
-	c = &lc;
-	dfs_mlme_get_dfs_ch_nchans(dfs->dfs_pdev_obj, &nchans);
-	for (i = 0; i < nchans; i++) {
-		dfs_mlme_get_dfs_ch_channels(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),
-				i);
-		WLAN_CHAN_CLR_HISTORY_RADAR(c);
+	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_ch(dfs->dfs_pdev_obj,
+					    (void *)chan_list, nchans,
+					    DFS_NOL_HISTORY_RESET);
+
+	qdf_mem_free(chan_list);
 }
 
 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)

+ 7 - 0
umac/dfs/core/src/misc/dfs_process_radar_found_ind.c

@@ -170,6 +170,13 @@ static QDF_STATUS dfs_radar_add_channel_list_to_nol(struct wlan_dfs *dfs,
 
 	utils_dfs_reg_update_nol_ch(dfs->dfs_pdev_obj,
 				    nollist, num_ch, DFS_NOL_SET);
+
+	if (dfs->dfs_is_stadfs_enabled)
+		if (dfs_mlme_is_opmode_sta(dfs->dfs_pdev_obj))
+			utils_dfs_reg_update_nol_history_ch(
+					dfs->dfs_pdev_obj, nollist, num_ch,
+					DFS_NOL_HISTORY_SET);
+
 	dfs_nol_update(dfs);
 	utils_dfs_save_nol(dfs->dfs_pdev_obj);
 

+ 8 - 0
umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h

@@ -281,4 +281,12 @@ void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev)
 {
 }
 #endif
+
+/**
+ * dfs_mlme_is_opmode_sta() - Check if pdev opmode is STA.
+ * @pdev: Pointer to DFS pdev object.
+ *
+ * Return: true if pdev opmode is STA, else false.
+ */
+bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev);
 #endif /* _WLAN_DFS_MLME_API_H_ */

+ 15 - 0
umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h

@@ -395,6 +395,21 @@ QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev)
 }
 #endif
 
+/**
+ * tgt_dfs_enable_stadfs() - Enable/Disable STADFS capability.
+ * @pdev: Pointer to DFS pdev object.
+ * @val: input value.
+ */
+void tgt_dfs_enable_stadfs(struct wlan_objmgr_pdev *pdev, bool val);
+
+/**
+ * tgt_dfs_is_stadfs_enabled() - Get STADFS capability
+ * @pdev: Pointer to DFS pdev object.
+ *
+ * Return: true if STADFS is enabled, else false.
+ */
+bool tgt_dfs_is_stadfs_enabled(struct wlan_objmgr_pdev *pdev);
+
 /**
  * tgt_dfs_is_pdev_5ghz() - Check if the input pdev is 5GHZ.
  * @pdev: Pointer to DFS pdev object.

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

@@ -52,6 +52,7 @@
  *                                     Channel Switch Announcement.
  * @mlme_nol_timeout_notification:     NOL timeout notification.
  * @mlme_clist_update:                 Updates the channel list.
+ * @mlme_is_opmode_sta:                Check if pdev opmode is STA.
  * @mlme_get_cac_timeout:              Gets the CAC timeout.
  * @mlme_rebuild_chan_list_with_non_dfs_channel: Rebuild channels with non-dfs
  *                                     channels.
@@ -132,6 +133,7 @@ struct dfs_to_mlme {
 	QDF_STATUS (*mlme_clist_update)(struct wlan_objmgr_pdev *pdev,
 			void *nollist,
 			int nentries);
+	bool (*mlme_is_opmode_sta)(struct wlan_objmgr_pdev *pdev);
 	QDF_STATUS (*mlme_get_cac_timeout)(struct wlan_objmgr_pdev *pdev,
 			uint16_t dfs_ch_freq,
 			uint8_t c_vhtop_ch_freq_seg2,

+ 31 - 0
umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h

@@ -34,6 +34,12 @@
 /* Remove channel from nol */
 #define DFS_NOL_RESET                0
 
+/* Mark nol-history flag for the channel */
+#define DFS_NOL_HISTORY_SET 1
+
+/* Clear nol-history flag from the channel */
+#define DFS_NOL_HISTORY_RESET 0
+
 /* Max nol channels */
 #define DFS_MAX_NOL_CHANNEL         80
 
@@ -560,6 +566,31 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 			     void *clist,
 			     uint32_t *num_chan);
 
+/**
+ * utils_dfs_get_nol_history_chan_list() - Get nol_history channels from regdb
+ * component.
+ * @pdev: Pointer to pdev structure.
+ * @clist: Pointer to channel list.
+ * @num_chan: number of channels.
+ */
+void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev,
+					 void *clist, uint32_t *num_chan);
+
+/**
+ * utils_dfs_reg_update_nol_history_ch() - set nol history channel
+ *
+ * @pdev: pdev ptr
+ * @ch_list: channel list to be returned
+ * @num_ch: number of channels
+ * @nol_history_ch: nol history flag
+ *
+ * Return: void
+ */
+void utils_dfs_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev,
+					 uint8_t *ch_list,
+					 uint8_t num_ch,
+					 bool nol_history_ch);
+
 /**
  * utils_dfs_check_for_cac_start() - Check for DFS CAC start conditions.
  * @pdev: pdev ptr

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

@@ -102,6 +102,8 @@ void register_dfs_callbacks(void)
 		mlme_dfs_rebuild_chan_list_with_non_dfs_channels;
 	tmp_dfs_to_mlme->mlme_restart_vaps_with_non_dfs_chan =
 		mlme_dfs_restart_vaps_with_non_dfs_chan;
+	tmp_dfs_to_mlme->mlme_is_opmode_sta =
+		mlme_dfs_is_opmode_sta;
 	tmp_dfs_to_mlme->mlme_check_allowed_prim_chanlist =
 		mlme_dfs_check_allowed_prim_chanlist;
 	tmp_dfs_to_mlme->mlme_update_scan_channel_list =

+ 8 - 0
umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c

@@ -338,3 +338,11 @@ void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev)
 	global_dfs_to_mlme.mlme_update_scan_channel_list(pdev);
 }
 #endif
+
+bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev)
+{
+	if (!global_dfs_to_mlme.mlme_is_opmode_sta)
+		return false;
+
+	return global_dfs_to_mlme.mlme_is_opmode_sta(pdev);
+}

+ 26 - 0
umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c

@@ -610,3 +610,29 @@ QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev,
 
 qdf_export_symbol(tgt_dfs_send_usenol_pdev_param);
 #endif
+
+void tgt_dfs_enable_stadfs(struct wlan_objmgr_pdev *pdev, bool val)
+{
+	struct wlan_dfs *dfs;
+
+	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
+		return;
+	}
+
+	dfs->dfs_is_stadfs_enabled = val;
+}
+
+bool tgt_dfs_is_stadfs_enabled(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_dfs *dfs;
+
+	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
+		return false;
+	}
+
+	return dfs->dfs_is_stadfs_enabled;
+}

+ 62 - 12
umac/dfs/dispatcher/src/wlan_dfs_utils_api.c

@@ -429,6 +429,43 @@ static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev,
 }
 
 #ifndef QCA_DFS_USE_POLICY_MANAGER
+void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev,
+					 void *clist, uint32_t *num_chan)
+{
+	int i, j = 0;
+	struct regulatory_channel *cur_chan_list;
+	struct wlan_dfs *dfs;
+	struct dfs_channel *chan_list = (struct dfs_channel *)clist;
+
+	*num_chan = 0;
+
+	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
+	if (!dfs)
+		return;
+
+	cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(*cur_chan_list));
+	if (!cur_chan_list)
+		return;
+
+	if (wlan_reg_get_current_chan_list(
+			pdev, cur_chan_list) != QDF_STATUS_SUCCESS) {
+		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
+			  "failed to get cur_chan list");
+		qdf_mem_free(cur_chan_list);
+		return;
+	}
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		if (cur_chan_list[i].nol_history) {
+			chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq;
+			j++;
+		}
+	}
+
+	*num_chan = j;
+	qdf_mem_free(cur_chan_list);
+}
+
 void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 			     void *clist, uint32_t *num_chan)
 {
@@ -467,6 +504,10 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 			if (state == CHANNEL_STATE_DFS)
 				chan_list[j].dfs_ch_flagext =
 					WLAN_CHAN_DFS;
+
+			if (cur_chan_list[i].nol_history)
+				chan_list[j].dfs_ch_flagext |=
+					WLAN_CHAN_HISTORY_RADAR;
 			j++;
 		}
 	}
@@ -477,19 +518,20 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 }
 
 /**
- * utils_dfs_get_channel_list() - Get channel list from regdb component based
+ * utils_dfs_get_channel_list() - Get channel list from regdb component, based
  * on current channel list.
  * @pdev: Pointer to pdev structure.
- * @chan_list: Pointer to regdb channel list.
+ * @chan: Pointer to channel list.
  * @num_chan: number of channels.
  *
  * Get regdb channel list based on dfs current channel.
- * ex: When  AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels
+ * Ex: When  AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels
  * so that the random channel function does not select either 2.4GHz or 4.9GHz
  * channel.
  */
 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
-	struct dfs_channel *chan_list, uint32_t *num_chan)
+				       struct dfs_channel *chan_list,
+				       uint32_t *num_chan)
 {
 	struct dfs_channel *tmp_chan_list = NULL;
 	struct wlan_dfs *dfs;
@@ -554,6 +596,12 @@ static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
 
 #else
 
+void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev,
+					 void *clist, uint32_t *num_chan)
+{
+	utils_dfs_get_chan_list(pdev, clist, num_chan);
+}
+
 void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 			     void *clist, uint32_t *num_chan)
 {
@@ -601,15 +649,9 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 	dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i);
 }
 
-/**
- * utils_dfs_get_channel_list() - Wrapper function to get channel list from
- * regdb component.
- * @pdev: Pointer to pdev structure.
- * @chan_list: Pointer to regdb channel list.
- * @num_chan: number of channels.
- */
 static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
-	struct dfs_channel *chan_list, uint32_t *num_chan)
+				       struct dfs_channel *chan_list,
+				       uint32_t *num_chan)
 {
 	utils_dfs_get_chan_list(pdev, (void *)chan_list, num_chan);
 }
@@ -886,6 +928,14 @@ void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev,
 }
 qdf_export_symbol(utils_dfs_reg_update_nol_ch);
 
+void utils_dfs_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev,
+					 uint8_t *ch_list,
+					 uint8_t num_ch,
+					 bool nol_history_ch)
+{
+	wlan_reg_update_nol_history_ch(pdev, ch_list, num_ch, nol_history_ch);
+}
+
 uint8_t utils_dfs_freq_to_chan(uint32_t freq)
 {
 	uint8_t chan;