Browse Source

qcacmn: Handle scan failure and vdev start caused by NOL violation

This commit includes the following changes:
Send usenol pdev param to FW.
Set and get dfs_disable_radar_marking flag.
Handle scan failure due to NOL violation.

Change-Id: I814f6381145f98eccf465af730734238c60d8896
CRs-Fixed: 2328894
Priyadarshnee S 6 years ago
parent
commit
d3173ca81c

+ 49 - 1
umac/dfs/core/src/dfs.h

@@ -364,6 +364,28 @@
 #define HOST_DFS_STATUS_WAIT_TIMER_MS 200
 #endif
 
+/*
+ * USENOL_DISABLE_NOL_HOST_AND_FW : Do not add radar hit channel to NOL
+ * in host and FW. Enable CSA on the same channel.
+ */
+#define USENOL_DISABLE_NOL_HOST_AND_FW 0
+/*
+ * USENOL_ENABLE_NOL_HOST_AND_FW : Add the radar hit channel to NOL in
+ * host and FW (in case of FO). NOL timer cannot be configured by the user
+ * as FW does not allow manipulating NOL timeout. If noltimeout is configured,
+ * (say 1 min) FW will not be intimated about the configuration and hence NOL
+ * timer may elapse at different instances in host (after 1 min) and FW (after
+ * default 30 min) which could lead to DFS Violation if host tries to come up
+ * on the channel after host NOL timeout (of 1 min) as the FW would still
+ * have the channel in NOL list.
+ */
+#define USENOL_ENABLE_NOL_HOST_AND_FW 1
+/*
+ * USENOL_ENABLE_NOL_HOST_DISABLE_NOL_FW : Add the radar hit channel to NOL
+ * in host. NOL timer can be configured by user. NOL in FW (for FO) is disabled.
+ */
+#define USENOL_ENABLE_NOL_HOST_DISABLE_NOL_FW 2
+
 /**
  * struct dfs_pulseparams - DFS pulse param structure.
  * @p_time:        Time for start of pulse in usecs.
@@ -979,6 +1001,7 @@ struct dfs_event_log {
  * @dfs_bw_reduced:                  DFS bandwidth reduced channel bit.
  * @dfs_freq_offset:                 Frequency offset where radar was found.
  * @dfs_cac_aborted:                 DFS cac is aborted.
+ * @dfs_disable_radar_marking:       To mark or unmark NOL chan as radar hit.
  */
 struct wlan_dfs {
 	uint32_t       dfs_debug_mask;
@@ -1071,7 +1094,9 @@ struct wlan_dfs {
 	os_timer_t     dfs_precac_timer;
 	int            dfs_precac_timeout_override;
 	uint8_t        dfs_num_precac_freqs;
-
+#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
+	uint8_t        dfs_disable_radar_marking;
+#endif
 	TAILQ_HEAD(, dfs_precac_entry) dfs_precac_required_list;
 	TAILQ_HEAD(, dfs_precac_entry) dfs_precac_done_list;
 	TAILQ_HEAD(, dfs_precac_entry) dfs_precac_nol_list;
@@ -2472,4 +2497,27 @@ void dfs_task_testtimer_detach(struct wlan_dfs *dfs);
  * @dfs: Pointer to wlan_dfs structure.
  */
 void dfs_timer_detach(struct wlan_dfs *dfs);
+
+/**
+ * dfs_is_disable_radar_marking_set() - Check if radar marking is set on
+ * NOL chan.
+ * @dfs: Pointer to wlan_dfs structure.
+ */
+#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
+int dfs_is_disable_radar_marking_set(struct wlan_dfs *dfs,
+				     bool *disable_radar_marking);
+#else
+static inline int dfs_is_disable_radar_marking_set(struct wlan_dfs *dfs,
+						   bool *disable_radar_marking)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+/**
+ * dfs_get_disable_radar_marking() - Get the value of disable radar marking.
+ * @dfs: Pointer to wlan_dfs structure.
+ */
+#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
+bool dfs_get_disable_radar_marking(struct wlan_dfs *dfs);
+#endif
 #endif  /* _DFS_H_ */

+ 64 - 1
umac/dfs/core/src/misc/dfs.c

@@ -33,6 +33,9 @@
 #include "../dfs_etsi_precac.h"
 #include "../dfs_partial_offload_radar.h"
 
+/* Disable NOL in FW. */
+#define DISABLE_NOL_FW 0
+
 #ifndef WLAN_DFS_STATIC_MEM_ALLOC
 /*
  * dfs_alloc_wlan_dfs() - allocate wlan_dfs buffer
@@ -274,6 +277,35 @@ void dfs_destroy_object(struct wlan_dfs *dfs)
 }
 #endif
 
+/* dfs_set_disable_radar_marking()- Set the flag to mark/unmark a radar flag
+ * on NOL channel.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @disable_radar_marking: Flag to enable/disable marking channel as radar.
+ */
+#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
+static void dfs_set_disable_radar_marking(struct wlan_dfs *dfs,
+					  bool disable_radar_marking)
+{
+	dfs->dfs_disable_radar_marking = disable_radar_marking;
+}
+#else
+static inline void dfs_set_disable_radar_marking(struct wlan_dfs *dfs,
+						 bool disable_radar_marking)
+{
+}
+#endif
+
+#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
+bool dfs_get_disable_radar_marking(struct wlan_dfs *dfs)
+{
+	return dfs->dfs_disable_radar_marking;
+}
+#else
+static inline bool dfs_get_disable_radar_marking(struct wlan_dfs *dfs)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
 int dfs_control(struct wlan_dfs *dfs,
 		u_int id,
 		void *indata,
@@ -290,6 +322,7 @@ int dfs_control(struct wlan_dfs *dfs,
 	uint32_t *data = NULL;
 	int i;
 	struct dfs_emulate_bang_radar_test_cmd dfs_unit_test;
+	int usenol_pdev_param;
 
 	qdf_mem_zero(&dfs_unit_test, sizeof(dfs_unit_test));
 
@@ -574,6 +607,36 @@ int dfs_control(struct wlan_dfs *dfs,
 			break;
 		}
 		dfs->dfs_use_nol = *(uint32_t *)indata;
+		usenol_pdev_param = dfs->dfs_use_nol;
+		if (dfs->dfs_is_offload_enabled) {
+			if (dfs->dfs_use_nol ==
+				USENOL_ENABLE_NOL_HOST_DISABLE_NOL_FW)
+				usenol_pdev_param = DISABLE_NOL_FW;
+			tgt_dfs_send_usenol_pdev_param(dfs->dfs_pdev_obj,
+						       usenol_pdev_param);
+		}
+		break;
+	case DFS_SET_DISABLE_RADAR_MARKING:
+		if (dfs->dfs_is_offload_enabled &&
+		    (utils_get_dfsdomain(dfs->dfs_pdev_obj) ==
+			 DFS_FCC_DOMAIN)) {
+			if (insize < sizeof(uint32_t) || !indata) {
+				error = -EINVAL;
+				break;
+			}
+			dfs_set_disable_radar_marking(dfs, *(uint8_t *)indata);
+		}
+		break;
+	case DFS_GET_DISABLE_RADAR_MARKING:
+		if (!outdata || !outsize || *outsize < sizeof(uint8_t)) {
+			error = -EINVAL;
+			break;
+		}
+		if (dfs->dfs_is_offload_enabled) {
+			*outsize = sizeof(uint8_t);
+			*((uint8_t *)outdata) =
+				dfs_get_disable_radar_marking(dfs);
+		}
 		break;
 	case DFS_GET_NOL:
 		if (!outdata || !outsize ||
@@ -605,12 +668,12 @@ int dfs_control(struct wlan_dfs *dfs,
 		dfs_print_nolhistory(dfs);
 		break;
 	case DFS_BANGRADAR:
+		dfs->dfs_bangradar = 1;
 		if (dfs->dfs_is_offload_enabled) {
 			error = dfs_fill_emulate_bang_radar_test(dfs,
 					SEG_ID_PRIMARY,
 					&dfs_unit_test);
 		} else {
-			dfs->dfs_bangradar = 1;
 			error = dfs_start_host_based_bangradar(dfs);
 		}
 		break;

+ 3 - 1
umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h

@@ -52,13 +52,15 @@
 #define DFS_SHOW_PRECAC_LISTS    24
 #define DFS_RESET_PRECAC_LISTS   25
 #define DFS_BANGRADAR_ENH        26
+#define DFS_SET_DISABLE_RADAR_MARKING 27
+#define DFS_GET_DISABLE_RADAR_MARKING 28
 
 /*
  * Spectral IOCTLs use DFS_LAST_IOCTL as the base.
  * This must always be the last IOCTL in DFS and have
  * the highest value.
  */
-#define DFS_LAST_IOCTL 27
+#define DFS_LAST_IOCTL 29
 
 #ifndef DFS_CHAN_MAX
 #define DFS_CHAN_MAX 1023

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

@@ -267,4 +267,18 @@ bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev,
 	return true;
 }
 #endif
+
+/**
+ * dfs_mlme_handle_dfs_scan_violation() - Handle scan start failure
+ * due to DFS violation (presence of NOL channel in scan channel list).
+ * @pdev: Pointer to pdev object.
+ */
+#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
+void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev);
+#else
+static inline
+void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev)
+{
+}
+#endif
 #endif /* _WLAN_DFS_MLME_API_H_ */

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

@@ -402,4 +402,22 @@ QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev)
  * Return: true if the pdev supports 5GHz, else false.
  */
 bool tgt_dfs_is_pdev_5ghz(struct wlan_objmgr_pdev *pdev);
+/**
+ * tgt_dfs_send_usenol_pdev_param() - Send usenol pdev param to FW.
+ * @pdev: Pointer to pdev object.
+ * @usenol: Value of usenol
+ *
+ * Return: QDF_STATUS
+ */
+#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
+QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev,
+					  bool usenol);
+#else
+static inline
+QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev,
+					  bool usenol)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
 #endif /* _WLAN_DFS_TGT_API_H_ */

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

@@ -59,6 +59,8 @@
  * @mlme_check_allowed_prim_chanlist:  Check whether the given channel is
  *                                     present in the primary allowed channel
  *                                     list or not.
+ * @mlme_update_scan_channel_list:     Update the scan channel list sent to FW.
+ * @mlme_bringdown_vaps:               Bringdown vaps if no chans is present.
  */
 struct dfs_to_mlme {
 	QDF_STATUS (*pdev_component_obj_attach)(struct wlan_objmgr_pdev *pdev,
@@ -141,6 +143,10 @@ struct dfs_to_mlme {
 			(struct wlan_objmgr_pdev *pdev, int no_chans_avail);
 	bool (*mlme_check_allowed_prim_chanlist)
 			(struct wlan_objmgr_pdev *pdev, uint32_t chan_num);
+	QDF_STATUS (*mlme_update_scan_channel_list)
+			(struct wlan_objmgr_pdev *pdev);
+	QDF_STATUS (*mlme_bringdown_vaps)
+			(struct wlan_objmgr_pdev *pdev);
 };
 
 extern struct dfs_to_mlme global_dfs_to_mlme;

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

@@ -571,4 +571,22 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
  */
 bool utils_dfs_check_for_cac_start(struct wlan_objmgr_pdev *pdev,
 				   bool *continue_current_cac);
+
+/**
+ * utils_dfs_get_disable_radar_marking - Retrieve the value of disable radar
+ * marking.
+ * @pdev: Pointer to DFS pdev object.
+ * @dis_radar_marking: pointer to retrieve the value of disable_radar_marking.
+ */
+#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
+QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev,
+					       bool *disable_radar_marking);
+#else
+static inline
+QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev,
+					       bool *disable_radar_marking)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
 #endif /* _WLAN_DFS_UTILS_API_H_ */

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

@@ -34,6 +34,8 @@
 #include "a_types.h"
 #include "wlan_serialization_api.h"
 #include <qdf_trace.h>
+#include "wlan_scan_ucfg_api.h"
+#include "wlan_dfs_mlme_api.h"
 
 struct dfs_to_mlme global_dfs_to_mlme;
 
@@ -102,6 +104,10 @@ void register_dfs_callbacks(void)
 		mlme_dfs_restart_vaps_with_non_dfs_chan;
 	tmp_dfs_to_mlme->mlme_check_allowed_prim_chanlist =
 		mlme_dfs_check_allowed_prim_chanlist;
+	tmp_dfs_to_mlme->mlme_update_scan_channel_list =
+		mlme_dfs_update_scan_channel_list;
+	tmp_dfs_to_mlme->mlme_bringdown_vaps =
+		mlme_dfs_bringdown_vaps;
 
 	/*
 	 * Register precac auto channel switch feature related callbacks

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

@@ -26,6 +26,7 @@
 #include "wlan_objmgr_pdev_obj.h"
 #include "../../core/src/dfs.h"
 #include "scheduler_api.h"
+#include <wlan_reg_ucfg_api.h>
 #ifdef QCA_MCL_DFS_SUPPORT
 #include "wni_api.h"
 #endif
@@ -322,4 +323,18 @@ bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev,
 	return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev,
 								   chan_num);
 }
+
+#endif
+
+#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
+void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev)
+{
+	bool dfs_enable = 0;
+
+	/*Disable all DFS channels in master channel list and ic channel list */
+	ucfg_reg_enable_dfs_channels(pdev, dfs_enable);
+
+	/* send the updated channel list to FW */
+	global_dfs_to_mlme.mlme_update_scan_channel_list(pdev);
+}
 #endif

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

@@ -584,3 +584,29 @@ QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev)
 
 qdf_export_symbol(tgt_dfs_reset_spoof_test);
 #endif
+
+#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
+QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev,
+					  bool usenol)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc) {
+		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
+	if (dfs_tx_ops && dfs_tx_ops->dfs_send_usenol_pdev_param)
+		return dfs_tx_ops->dfs_send_usenol_pdev_param(pdev, usenol);
+
+	dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
+		"dfs_tx_ops=%pK", dfs_tx_ops);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+qdf_export_symbol(tgt_dfs_send_usenol_pdev_param);
+#endif

+ 23 - 0
umac/dfs/dispatcher/src/wlan_dfs_utils_api.c

@@ -979,3 +979,26 @@ int dfs_get_num_chans(void)
 {
 	return NUM_CHANNELS;
 }
+
+#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
+QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev,
+					       bool *disable_radar_marking)
+{
+	struct wlan_dfs *dfs;
+
+	if (!tgt_dfs_is_pdev_5ghz(pdev))
+		return QDF_STATUS_SUCCESS;
+
+	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is null");
+		return  QDF_STATUS_E_FAILURE;
+	}
+
+	*disable_radar_marking = dfs_get_disable_radar_marking(dfs);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(utils_dfs_get_disable_radar_marking);
+#endif