Browse Source

qcacmn: Process DFS events from firmware

Add support to process DFS events from firmware.

Change-Id: I38bea404fdb50d80430c8b14a2a4f6a729d3557e
CRs-Fixed: 2017481
Arif Hussain 8 years ago
parent
commit
c64510ba8b

+ 27 - 0
init_deinit/dispatcher/src/dispatcher_init_deinit.c

@@ -462,6 +462,16 @@ static QDF_STATUS dispatcher_deinit_dfs(void)
 {
 	return dfs_deinit();
 }
+
+static QDF_STATUS dispatcher_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return wifi_dfs_psoc_enable(psoc);
+}
+
+static QDF_STATUS dispatcher_dfs_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #else
 static QDF_STATUS dispatcher_init_dfs(void)
 {
@@ -472,6 +482,16 @@ static QDF_STATUS dispatcher_deinit_dfs(void)
 {
 	return QDF_STATUS_SUCCESS;
 }
+
+static QDF_STATUS dispatcher_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS dispatcher_dfs_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif
 
 #ifdef WLAN_OFFCHAN_TXRX_ENABLE
@@ -701,8 +721,13 @@ QDF_STATUS dispatcher_psoc_enable(struct wlan_objmgr_psoc *psoc)
 	if (QDF_STATUS_SUCCESS != dispatcher_nan_psoc_enable(psoc))
 		goto nan_psoc_enable_fail;
 
+	if (QDF_STATUS_SUCCESS != dispatcher_dfs_psoc_enable(psoc))
+		goto wifi_dfs_psoc_enable_fail;
+
 	return QDF_STATUS_SUCCESS;
 
+wifi_dfs_psoc_enable_fail:
+	dispatcher_nan_psoc_disable(psoc);
 nan_psoc_enable_fail:
 	dispatcher_wifi_pos_disable(psoc);
 wifi_pos_psoc_enable_fail:
@@ -738,6 +763,8 @@ QDF_STATUS dispatcher_psoc_disable(struct wlan_objmgr_psoc *psoc)
 
 	QDF_BUG(QDF_STATUS_SUCCESS == ucfg_scan_psoc_disable(psoc));
 
+	QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_dfs_psoc_disable(psoc));
+
 	return QDF_STATUS_SUCCESS;
 }
 EXPORT_SYMBOL(dispatcher_psoc_disable);

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

@@ -171,7 +171,7 @@ static os_timer_func(dfs_cac_timeout)
 	}
 
 	/* Iterate over the nodes, processing the CAC completion event. */
-	dfs_mlme_proc_cac(dfs->dfs_pdev_obj);
+	dfs_mlme_proc_cac(dfs->dfs_pdev_obj, 0);
 
 	/* Send a CAC timeout, VAP up event to user space */
 	dfs_mlme_deliver_event_up_afrer_cac(dfs->dfs_pdev_obj);

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

@@ -63,4 +63,10 @@ QDF_STATUS wlan_dfs_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
 QDF_STATUS wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
 		void *arg);
 
+/**
+ * wifi_dfs_psoc_enable() - handles registering dfs event handlers.
+ * @psoc: psoc object.
+ */
+QDF_STATUS wifi_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc);
+
 #endif /* _WLAN_DFS_INIT_DEINIT_API_H_ */

+ 2 - 1
umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h

@@ -70,8 +70,9 @@ void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, uint8_t ieeeChan);
 /**
  * dfs_mlme_proc_cac() - Process the CAC completion event.
  * @pdev: Pointer to DFS pdev object.
+ * @vdev_id: vdev id.
  */
-void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev);
+void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id);
 
 /**
  * dfs_mlme_deliver_event_up_afrer_cac() - Send a CAC timeout, VAP up event to

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

@@ -26,6 +26,7 @@
 #define _WLAN_DFS_TGT_API_H_
 
 #include "wlan_dfs_ucfg_api.h"
+#include "wlan_dfs_utils_api.h"
 
 extern struct dfs_to_mlme global_dfs_to_mlme;
 
@@ -185,4 +186,39 @@ QDF_STATUS tgt_dfs_find_vht80_chan_for_precac(struct wlan_objmgr_pdev *pdev,
 		bool *dfs_set_cfreq2,
 		bool *set_agile);
 
+/**
+ * tgt_dfs_process_radar_ind() - Process radar found indication.
+ * @pdev: Pointer to DFS pdev object.
+ * @radar_found: radar found info.
+ *
+ * Process radar found indication.
+ *
+ * Return QDF_STATUS.
+ */
+QDF_STATUS tgt_dfs_process_radar_ind(struct wlan_objmgr_pdev *pdev,
+		struct radar_found_info *radar_found);
+
+/**
+ * tgt_dfs_cac_complete() - Process cac complete indication.
+ * @pdev: Pointer to DFS pdev object.
+ * @vdev_id: vdev id.
+ *
+ * Process cac complete indication from firmware.
+ *
+ * Return QDF_STATUS.
+ */
+QDF_STATUS tgt_dfs_cac_complete(struct wlan_objmgr_pdev *pdev,
+		uint32_t vdev_id);
+
+/**
+ * tgt_dfs_reg_ev_handler() - Register dfs events.
+ * @psoc: Pointer to psoc.
+ * @dfs_offload: phy err processing offloaded to firmware.
+ *
+ * Register dfs events.
+ *
+ * Return: QDF_STATUS.
+ */
+QDF_STATUS tgt_dfs_reg_ev_handler(struct wlan_objmgr_psoc *psoc,
+		bool dfs_offload);
 #endif /* _WLAN_DFS_TGT_API_H_ */

+ 41 - 16
umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c

@@ -22,12 +22,15 @@
  */
 
 #include "wlan_dfs_ucfg_api.h"
+#include "wlan_dfs_tgt_api.h"
+#include "wlan_dfs_utils_api.h"
 #ifndef QCA_MCL_DFS_SUPPORT
 #include "ieee80211_mlme_dfs_interface.h"
 #endif
 #include "wlan_objmgr_global_obj.h"
 #include "wlan_dfs_init_deinit_api.h"
 #include "../../core/src/dfs.h"
+#include "a_types.h"
 
 struct dfs_to_mlme global_dfs_to_mlme;
 
@@ -138,35 +141,43 @@ QDF_STATUS wlan_dfs_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
 		void *arg)
 {
 	struct wlan_dfs *dfs = NULL;
+	struct wlan_objmgr_psoc *psoc;
+	bool dfs_offload = false;
 
 	if (pdev == NULL) {
-		DFS_PRINTK("%s:PDEV is NULL\n", __func__);
+		DFS_PRINTK("%s: null pdev\n", __func__);
 		return QDF_STATUS_E_FAILURE;
 	}
 
 	if (dfs_create_object(&dfs) == 1) {
-		DFS_PRINTK("%s : Failed to create DFS object\n", __func__);
+		DFS_PRINTK("%s: failed to create object\n", __func__);
 		return QDF_STATUS_E_FAILURE;
 	}
 
 	global_dfs_to_mlme.pdev_component_obj_attach(pdev,
-			WLAN_UMAC_COMP_DFS,
-			(void *)dfs,
-			QDF_STATUS_SUCCESS);
+		WLAN_UMAC_COMP_DFS, (void *)dfs, QDF_STATUS_SUCCESS);
 	dfs->dfs_pdev_obj = pdev;
-
-	/* wlan_ar_ops are assigned to sc_wlan_ops in wlan_dev_attach.
-	 * This function is called during module init.
-	 * and wlan_dev_attach is called during wlan_attach.
-	 * If we call dfs_attach here, seen crash in wlan_net80211_attach_dfs.
-	 */
-	if (dfs_attach(dfs) == 1) {
-		DFS_PRINTK("%s : dfs_attch failed\n", __func__);
-		dfs_destroy_object(dfs);
+	wlan_pdev_obj_lock(pdev);
+	psoc = wlan_pdev_get_psoc(pdev);
+	wlan_pdev_obj_unlock(pdev);
+	if (!psoc) {
+		DFS_PRINTK("%s: null psoc\n", __func__);
 		return QDF_STATUS_E_FAILURE;
 	}
-
-	dfs_get_radars(dfs);
+	dfs_offload =
+		DFS_OFFLOAD_IS_ENABLED(psoc->service_param.service_bitmap);
+	DFS_PRINTK("%s: dfs_offload %d\n", __func__, dfs_offload);
+	dfs = wlan_pdev_get_dfs_obj(pdev);
+	if (!dfs_offload) {
+		if (dfs_attach(dfs) == 1) {
+			DFS_PRINTK("%s: dfs_attch failed\n", __func__);
+			dfs_destroy_object(dfs);
+			return QDF_STATUS_E_FAILURE;
+		}
+		dfs_get_radars(dfs);
+	}
+	dfs_init_nol(pdev);
+	dfs_print_nol(dfs);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -198,3 +209,17 @@ QDF_STATUS wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS wifi_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	bool dfs_offload =
+		DFS_OFFLOAD_IS_ENABLED(psoc->service_param.service_bitmap);
+
+	DFS_PRINTK("%s: dfs_offload %d\n", __func__, dfs_offload);
+
+	if (QDF_STATUS_SUCCESS != tgt_dfs_reg_ev_handler(psoc, dfs_offload)) {
+		DFS_PRINTK("%s: tgt_dfs_reg_ev_handler failed\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}

+ 56 - 1
umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c

@@ -22,6 +22,13 @@
  */
 
 #include "wlan_dfs_mlme_api.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "../../core/src/dfs.h"
+#include "scheduler_api.h"
+#ifdef QCA_MCL_DFS_SUPPORT
+#include "wni_api.h"
+#endif
 
 void dfs_mlme_channel_mark_radar(struct wlan_objmgr_pdev *pdev,
 		uint16_t freq,
@@ -41,6 +48,7 @@ void dfs_mlme_start_rcsa(struct wlan_objmgr_pdev *pdev)
 		global_dfs_to_mlme.dfs_start_rcsa(pdev);
 }
 
+#ifndef QCA_MCL_DFS_SUPPORT
 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev,
 		uint8_t ieee,
 		uint16_t freq,
@@ -54,6 +62,39 @@ void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev,
 				vhtop_ch_freq_seg2,
 				flags);
 }
+#else
+static void dfs_send_radar_ind(struct wlan_objmgr_pdev *pdev,
+		void *object,
+		void *arg)
+{
+	struct scheduler_msg sme_msg = {0};
+	uint8_t vdev_id = wlan_vdev_get_id((struct wlan_objmgr_vdev *)object);
+
+	sme_msg.type = eWNI_SME_DFS_RADAR_FOUND;
+	sme_msg.bodyptr = NULL;
+	sme_msg.bodyval = vdev_id;
+	scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
+	DFS_PRINTK("%s: eWNI_SME_DFS_RADAR_FOUND pdev%d posted\n",
+		   __func__, vdev_id);
+}
+
+void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev,
+		uint8_t ieee,
+		uint16_t freq,
+		uint8_t vhtop_ch_freq_seg2,
+		uint32_t flags)
+{
+	if (!pdev) {
+		DFS_PRINTK("%s: null pdev\n", __func__);
+		return;
+	}
+
+	wlan_objmgr_pdev_iterate_obj_list(pdev,
+				WLAN_VDEV_OP,
+				dfs_send_radar_ind,
+				NULL, 0, WLAN_DFS_ID);
+}
+#endif
 
 void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev,
 		uint8_t ieeeChan)
@@ -62,11 +103,25 @@ void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev,
 		global_dfs_to_mlme.mlme_start_csa(pdev, ieeeChan);
 }
 
-void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev)
+#ifndef QCA_MCL_DFS_SUPPORT
+void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
 {
 	if (global_dfs_to_mlme.mlme_proc_cac != NULL)
 		global_dfs_to_mlme.mlme_proc_cac(pdev);
 }
+#else
+void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
+{
+	struct scheduler_msg sme_msg = {0};
+
+	sme_msg.type = eWNI_SME_DFS_CAC_COMPLETE;
+	sme_msg.bodyptr = NULL;
+	sme_msg.bodyval = vdev_id;
+	scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
+	DFS_PRINTK("%s: eWNI_SME_DFS_CAC_COMPLETE vdev%d posted\n",
+		   __func__, vdev_id);
+}
+#endif
 
 void dfs_mlme_deliver_event_up_afrer_cac(struct wlan_objmgr_pdev *pdev)
 {

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

@@ -22,8 +22,18 @@
  * to outside of DFS component.
  */
 #include "wlan_dfs_tgt_api.h"
+#include "wlan_lmac_if_def.h"
+#include "wlan_lmac_if_api.h"
+#include "wlan_dfs_mlme_api.h"
 #include "../../core/src/dfs.h"
 #include "../../core/src/dfs_zero_cac.h"
+#include "../../core/src/dfs_process_radar_found_ind.h"
+
+static inline struct wlan_lmac_if_dfs_tx_ops *
+wlan_psoc_get_dfs_txops(struct wlan_objmgr_psoc *psoc)
+{
+	return &((psoc->soc_cb.tx_ops.dfs_tx_ops));
+}
 
 QDF_STATUS tgt_dfs_set_current_channel(struct wlan_objmgr_pdev *pdev,
 		uint16_t ic_freq,
@@ -224,3 +234,63 @@ QDF_STATUS tgt_dfs_find_vht80_chan_for_precac(struct wlan_objmgr_pdev *pdev,
 	return  QDF_STATUS_SUCCESS;
 }
 EXPORT_SYMBOL(tgt_dfs_find_vht80_chan_for_precac);
+
+QDF_STATUS tgt_dfs_process_radar_ind(struct wlan_objmgr_pdev *pdev,
+		struct radar_found_info *radar_found)
+{
+	struct wlan_dfs *dfs;
+
+	if (!pdev) {
+		DFS_PRINTK("%s: null pdev\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
+	if (!dfs || !dfs->dfs_curchan) {
+		DFS_PRINTK("%s: err, dfs=%p, dfs->dfs_curchan=%p\n",
+			   __func__, dfs, dfs->dfs_curchan);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dfs_process_radar_found_indication(dfs, radar_found);
+	dfs_mlme_mark_dfs(pdev, dfs->dfs_curchan->ic_ieee,
+		dfs->dfs_curchan->ic_freq,
+		dfs->dfs_curchan->ic_vhtop_ch_freq_seg2,
+		dfs->dfs_curchan->ic_flags);
+
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(tgt_dfs_process_radar_ind);
+
+QDF_STATUS tgt_dfs_cac_complete(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
+{
+	dfs_mlme_proc_cac(pdev, vdev_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(tgt_dfs_cac_complete);
+
+QDF_STATUS tgt_dfs_reg_ev_handler(struct wlan_objmgr_psoc *psoc,
+		bool dfs_offload)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
+	struct wlan_objmgr_pdev *pdev = NULL;
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_DFS_ID);
+	if (!pdev) {
+		DFS_PRINTK("%s: null pdev\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
+	if (dfs_tx_ops && dfs_tx_ops->dfs_reg_ev_handler)
+		status = dfs_tx_ops->dfs_reg_ev_handler(pdev, dfs_offload);
+	else
+		DFS_PRINTK("%s: err, dfs_tx_ops=%p\n", __func__, dfs_tx_ops);
+
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID);
+
+	return status;
+}
+EXPORT_SYMBOL(tgt_dfs_reg_ev_handler);