Browse Source

qcacmn: Fix Zero CAC DFS kernel panic

* Moved target type macros to global target_if header file.
* Fixed kernel panic: Channel details were written in  invalid
  memory location.

Change-Id: Ia9134b8dad651e53f57243c45eb93fb86ddd94c5
CRs-Fixed: 2104219
Shashikala Prabhu 7 years ago
parent
commit
4f8130e8c9

+ 37 - 0
target_if/core/inc/target_if.h

@@ -52,6 +52,11 @@
 #define GET_WMI_HDL_FROM_PSOC(psoc) \
 		(((struct target_psoc_info *)(psoc->tgt_if_handle))->wmi_handle)
 
+#define TARGET_TYPE_AR900B    9
+#define TARGET_TYPE_QCA9984   15 /* cascade */
+#define TARGET_TYPE_IPQ4019   16 /* dakota */
+#define TARGET_TYPE_QCA9888   17 /* besra */
+
 typedef struct wlan_objmgr_psoc *(*get_psoc_handle_callback)(
 			void *scn_handle);
 
@@ -159,5 +164,37 @@ QDF_STATUS target_if_register_legacy_service_ready_cb(
 	wmi_legacy_service_ready_callback service_ready_cb);
 
 void *target_if_get_wmi_handle(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_is_tgt_type_ar900b() - Check if the target type is AR900B
+ * @target_type: target type to be checked.
+ *
+ * Return: true if the target_type is AR900B, else false.
+ */
+bool target_is_tgt_type_ar900b(uint32_t target_type);
+
+/**
+ * target_is_tgt_type_ipq4019() - Check if the target type is IPQ4019
+ * @target_type: target type to be checked.
+ *
+ * Return: true if the target_type is IPQ4019, else false.
+ */
+bool target_is_tgt_type_ipq4019(uint32_t target_type);
+
+/**
+ * target_is_tgt_type_qca9984() - Check if the target type is QCA9984
+ * @target_type: target type to be checked.
+ *
+ * Return: true if the target_type is QCA9984, else false.
+ */
+bool target_is_tgt_type_qca9984(uint32_t target_type);
+
+/**
+ * target_is_tgt_type_qca9888() - Check if the target type is QCA9888
+ * @target_type: target type to be checked.
+ *
+ * Return: true if the target_type is QCA9888, else false.
+ */
+bool target_is_tgt_type_qca9888(uint32_t target_type);
 #endif
 

+ 47 - 0
target_if/core/src/target_if_main.c

@@ -205,6 +205,31 @@ static void target_if_sptrl_tx_ops_register(
 }
 #endif /* WLAN_CONV_SPECTRAL_ENABLE */
 
+static void target_if_target_tx_ops_register(
+		struct wlan_lmac_if_tx_ops *tx_ops)
+{
+	struct wlan_lmac_if_target_tx_ops *target_tx_ops;
+
+	if (!tx_ops) {
+		target_if_err("invalid tx_ops");
+		return;
+	}
+
+	target_tx_ops = &tx_ops->target_tx_ops;
+
+	target_tx_ops->tgt_is_tgt_type_ar900b =
+		target_is_tgt_type_ar900b;
+
+	target_tx_ops->tgt_is_tgt_type_ipq4019 =
+		target_is_tgt_type_ipq4019;
+
+	target_tx_ops->tgt_is_tgt_type_qca9984 =
+		target_is_tgt_type_qca9984;
+
+	target_tx_ops->tgt_is_tgt_type_qca9888 =
+		target_is_tgt_type_qca9888;
+}
+
 static
 QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
 {
@@ -230,6 +255,9 @@ QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
 	target_if_son_tx_ops_register(tx_ops);
 
 	target_if_tdls_tx_ops_register(tx_ops);
+
+	target_if_target_tx_ops_register(tx_ops);
+
 	/* Converged UMAC components to register their TX-ops here */
 	return QDF_STATUS_SUCCESS;
 }
@@ -303,3 +331,22 @@ void *target_if_get_wmi_handle(struct wlan_objmgr_psoc *psoc)
 
 }
 
+bool target_is_tgt_type_ar900b(uint32_t target_type)
+{
+	return target_type == TARGET_TYPE_AR900B;
+}
+
+bool target_is_tgt_type_ipq4019(uint32_t target_type)
+{
+	return target_type == TARGET_TYPE_IPQ4019;
+}
+
+bool target_is_tgt_type_qca9984(uint32_t target_type)
+{
+	return target_type == TARGET_TYPE_QCA9984;
+}
+
+bool target_is_tgt_type_qca9888(uint32_t target_type)
+{
+	return target_type == TARGET_TYPE_QCA9888;
+}

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

@@ -1683,7 +1683,7 @@ void dfs_stacac_stop(struct wlan_dfs *dfs);
  * @chan: Pointer to dfs channel structure.
  */
 void dfs_find_precac_secondary_vht80_chan(struct wlan_dfs *dfs,
-		struct dfs_ieee80211_channel **chan);
+		struct dfs_ieee80211_channel *chan);
 
 /**
  * dfs_phyerr_param_copy() - Function to copy src buf to dest buf.

+ 0 - 12
umac/dfs/core/src/dfs_zero_cac.h

@@ -34,10 +34,6 @@
 #include "dfs.h"
 
 #define VHT160_IEEE_FREQ_DIFF 16
-#define TARGET_TYPE_AR900B    9
-#define TARGET_TYPE_QCA9984   10
-#define TARGET_TYPE_IPQ4019   11
-#define TARGET_TYPE_QCA9888   12
 
 /**
  * struct dfs_precac_entry - PreCAC entry.
@@ -245,12 +241,4 @@ void dfs_mark_precac_dfs(struct wlan_dfs *dfs,
  * @dfs: Pointer to wlan_dfs structure.
  */
 bool dfs_is_precac_timer_running(struct wlan_dfs *dfs);
-
-/**
- * dfs_find_precac_secondary_vht80_chan() - Get a VHT80 channel with the
- *                                          precac primary center frequency.
- * @dfs: Pointer to wlan_dfs structure.
- */
-void dfs_find_precac_secondary_vht80_chan(struct wlan_dfs *dfs,
-		struct dfs_ieee80211_channel **chan);
 #endif /* _DFS_ZERO_CAC_H_ */

+ 30 - 22
umac/dfs/core/src/filtering/dfs_radar.c

@@ -241,30 +241,28 @@ struct dfs_pulse dfs_korea_radars[] = {
 	{3,   1, 3003, 3003, 1, 7,  2,  0,  1, 18,  0, 0, 1,  43},
 };
 
-#define TARGET_TYPE_AR900B    9
-#define TARGET_TYPE_QCA9984   10
-#define TARGET_TYPE_IPQ4019   11
-#define TARGET_TYPE_QCA9888   12
 #define RSSI_THERSH_AR900B    15
 
 /**
  * dfs_assign_fcc_pulse_table() - Assign FCC pulse table
  * @rinfo: Pointer to wlan_dfs_radar_tab_info structure.
  * @target_type: Target type.
+ * @tx_ops: target tx ops.
  */
 static inline void dfs_assign_fcc_pulse_table(
 		struct wlan_dfs_radar_tab_info *rinfo,
-		uint32_t target_type)
+		uint32_t target_type,
+		struct wlan_lmac_if_target_tx_ops *tx_ops)
 {
 	rinfo->dfs_radars = dfs_fcc_radars;
 	rinfo->numradars = QDF_ARRAY_SIZE(dfs_fcc_radars);
 
-	if (target_type == TARGET_TYPE_AR900B ||
-			target_type == TARGET_TYPE_IPQ4019) {
+	if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
+			tx_ops->tgt_is_tgt_type_ipq4019(target_type)) {
 		rinfo->b5pulses = dfs_fcc_bin5pulses_ar900b;
 		rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_ar900b);
-	} else if (target_type == TARGET_TYPE_QCA9984 ||
-			target_type == TARGET_TYPE_QCA9888) {
+	} else if (tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
+			tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
 		rinfo->b5pulses = dfs_fcc_bin5pulses_qca9984;
 		rinfo->numb5radars =
 			QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_qca9984);
@@ -276,6 +274,8 @@ static inline void dfs_assign_fcc_pulse_table(
 void ol_if_dfs_configure(struct wlan_dfs *dfs)
 {
 	struct wlan_dfs_radar_tab_info rinfo;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_lmac_if_target_tx_ops *tx_ops;
 	int i;
 	uint32_t target_type;
 	int dfsdomain = DFS_FCC_DOMAIN;
@@ -292,6 +292,13 @@ void ol_if_dfs_configure(struct wlan_dfs *dfs)
 	dfsdomain = lmac_get_dfsdomain(dfs->dfs_pdev_obj);
 	target_type = lmac_get_target_type(dfs->dfs_pdev_obj);
 
+	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
+	if (!psoc) {
+		DFS_PRINTK("%s: PSOC is NULL\n", __func__);
+		return;
+	}
+
+	tx_ops = &(psoc->soc_cb.tx_ops.target_tx_ops);
 	switch (dfsdomain) {
 	case DFS_FCC_DOMAIN:
 		DFS_PRINTK("%s: FCC domain\n", __func__);
@@ -310,7 +317,7 @@ void ol_if_dfs_configure(struct wlan_dfs *dfs)
 			rinfo.b5pulses = NULL;
 			rinfo.numb5radars = 0;
 		} else {
-			dfs_assign_fcc_pulse_table(&rinfo, target_type);
+			dfs_assign_fcc_pulse_table(&rinfo, target_type, tx_ops);
 		}
 
 		break;
@@ -346,13 +353,13 @@ void ol_if_dfs_configure(struct wlan_dfs *dfs)
 		rinfo.dfs_radars = dfs_mkk4_radars;
 		rinfo.numradars = QDF_ARRAY_SIZE(dfs_mkk4_radars);
 
-		if (target_type == TARGET_TYPE_AR900B ||
-				target_type == TARGET_TYPE_IPQ4019) {
+		if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
+				tx_ops->tgt_is_tgt_type_ipq4019(target_type)) {
 			rinfo.b5pulses = dfs_jpn_bin5pulses_ar900b;
 			rinfo.numb5radars = QDF_ARRAY_SIZE(
 					dfs_jpn_bin5pulses_ar900b);
-		} else if (target_type == TARGET_TYPE_QCA9984 ||
-				target_type == TARGET_TYPE_QCA9888) {
+		} else if (tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
+				tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
 			rinfo.b5pulses = dfs_jpn_bin5pulses_qca9984;
 			rinfo.numb5radars = QDF_ARRAY_SIZE
 				(dfs_jpn_bin5pulses_qca9984);
@@ -372,10 +379,10 @@ void ol_if_dfs_configure(struct wlan_dfs *dfs)
 		break;
 	}
 
-	if (target_type == TARGET_TYPE_AR900B ||
-			target_type == TARGET_TYPE_IPQ4019 ||
-			target_type == TARGET_TYPE_QCA9984 ||
-			target_type == TARGET_TYPE_QCA9888) {
+	if (tx_ops->tgt_is_tgt_type_ar900b(target_type) ||
+			tx_ops->tgt_is_tgt_type_ipq4019(target_type) ||
+			tx_ops->tgt_is_tgt_type_qca9984(target_type) ||
+			tx_ops->tgt_is_tgt_type_qca9888(target_type)) {
 		/* Beeliner WAR: lower RSSI threshold to improve detection of
 		 * certian radar types
 		 */
@@ -503,13 +510,14 @@ void dfs_radar_found_action(struct wlan_dfs *dfs)
 		if (dfs->is_radar_found_on_secondary_seg &&
 				dfs_is_precac_timer_running(dfs)) {
 			/* Get a VHT80 channel and mark it */
-			struct dfs_ieee80211_channel *ichan;
+			struct dfs_ieee80211_channel ichan;
 
 			dfs_find_precac_secondary_vht80_chan(dfs, &ichan);
+
 			dfs_mlme_channel_mark_radar(dfs->dfs_pdev_obj,
-					ichan->dfs_ch_freq,
-					ichan->dfs_ch_vhtop_ch_freq_seg2,
-					ichan->dfs_ch_flags);
+					ichan.dfs_ch_freq,
+					ichan.dfs_ch_vhtop_ch_freq_seg2,
+					ichan.dfs_ch_flags);
 		} else {
 			dfs_mlme_channel_mark_radar(dfs->dfs_pdev_obj,
 					dfs->dfs_curchan->dfs_ch_freq,

+ 21 - 9
umac/dfs/core/src/misc/dfs_zero_cac.c

@@ -371,7 +371,7 @@ bool dfs_is_precac_timer_running(struct wlan_dfs *dfs)
 
 #define VHT80_IEEE_FREQ_OFFSET 6
 void dfs_find_precac_secondary_vht80_chan(struct wlan_dfs *dfs,
-		struct dfs_ieee80211_channel **chan)
+		struct dfs_ieee80211_channel *chan)
 {
 	uint8_t first_primary_dfs_ch_ieee;
 
@@ -381,12 +381,12 @@ void dfs_find_precac_secondary_vht80_chan(struct wlan_dfs *dfs,
 	dfs_mlme_find_dot11_channel(dfs->dfs_pdev_obj,
 			first_primary_dfs_ch_ieee, 0,
 			IEEE80211_MODE_11AC_VHT80,
-			&((*chan)->dfs_ch_freq),
-			&((*chan)->dfs_ch_flags),
-			&((*chan)->dfs_ch_flagext),
-			&((*chan)->dfs_ch_ieee),
-			&((*chan)->dfs_ch_vhtop_ch_freq_seg1),
-			&((*chan)->dfs_ch_vhtop_ch_freq_seg2));
+			&(chan->dfs_ch_freq),
+			&(chan->dfs_ch_flags),
+			&(chan->dfs_ch_flagext),
+			&(chan->dfs_ch_ieee),
+			&(chan->dfs_ch_vhtop_ch_freq_seg1),
+			&(chan->dfs_ch_vhtop_ch_freq_seg2));
 }
 
 /**
@@ -781,6 +781,19 @@ void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs,
 		bool *dfs_set_cfreq2,
 		bool *set_agile)
 {
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_lmac_if_target_tx_ops *tx_ops;
+	uint32_t target_type;
+
+	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
+	if (!psoc) {
+		DFS_PRINTK("%s: PSOC is NULL\n", __func__);
+		return;
+	}
+
+	tx_ops = &(psoc->soc_cb.tx_ops.target_tx_ops);
+	target_type = lmac_get_target_type(dfs->dfs_pdev_obj);
+
 	if (chan_mode == IEEE80211_MODE_11AC_VHT80) {
 		/*
 		 * If
@@ -800,8 +813,7 @@ void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs,
 			dfs->dfs_precac_timer_running);
 
 		if (dfs->dfs_precac_enable &&
-				(lmac_get_target_type(dfs->dfs_pdev_obj) ==
-				 TARGET_TYPE_QCA9984) &&
+				tx_ops->tgt_is_tgt_type_qca9984(target_type) &&
 				(lmac_get_dfsdomain(dfs->dfs_pdev_obj) ==
 				 DFS_ETSI_DOMAIN)) {
 			/*

+ 16 - 0
umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h

@@ -507,6 +507,21 @@ struct wlan_lmac_if_dfs_tx_ops {
 			bool dfs_offload);
 };
 
+/**
+ * struct wlan_lmac_if_target_tx_ops - Function pointers to call target
+ *                                     functions from other modules.
+ * @tgt_is_tgt_type_ar900b:  To check AR900B target type.
+ * @tgt_is_tgt_type_ipq4019: To check IPQ4019 target type.
+ * @tgt_is_tgt_type_qca9984: To check QCA9984 target type.
+ * @tgt_is_tgt_type_qca9888: To check QCA9888 target type.
+ */
+struct wlan_lmac_if_target_tx_ops {
+	bool (*tgt_is_tgt_type_ar900b)(uint32_t);
+	bool (*tgt_is_tgt_type_ipq4019)(uint32_t);
+	bool (*tgt_is_tgt_type_qca9984)(uint32_t);
+	bool (*tgt_is_tgt_type_qca9888)(uint32_t);
+};
+
 /**
  * struct wlan_lmac_if_tx_ops - south bound tx function pointers
  * @mgmt_txrx_tx_ops: mgmt txrx tx ops
@@ -560,6 +575,7 @@ struct wlan_lmac_if_tx_ops {
 	struct wlan_lmac_if_tdls_tx_ops tdls_tx_ops;
 #endif
 	 struct wlan_lmac_if_mlme_tx_ops mops;
+	 struct wlan_lmac_if_target_tx_ops target_tx_ops;
 };
 
 /**