qcacld-3.0: SAP DFS-3 Feature support in DFS layer

Introduce DFS-3 support changes in DFS layer.
Add support for per segment based queuing, processing
and pattern matching of the radar events in 80+80 channel
width mode,  when both segments are dfs.

Also, add support for parsing the new DFS-3 radar summary
report and extract the segment ID on which a phyerror is
seen.  Report the segment ID on which the radar has been
detected to the WMA layer to add only radar detected 80MHz
segment channels to be added to NOL in 80+80 MHz channel
width mode.

Change-Id: Ib9ed2122844cef5fde2b632accc8c798e86bf7a3
CRs-Fixed: 964262
diff --git a/core/sap/dfs/src/dfs.c b/core/sap/dfs/src/dfs.c
index 2d0a81a..22ba6f4 100644
--- a/core/sap/dfs/src/dfs.c
+++ b/core/sap/dfs/src/dfs.c
@@ -300,6 +300,28 @@
 		return 1;
 	}
 
+	/*
+	 * If the chip supports DFS-3 then allocate
+	 * memory for pulses for extension segment.
+	 */
+	if (ic->dfs_hw_bd_id !=  DFS_HWBD_QCA6174) {
+		dfs->pulses_ext_seg = (struct dfs_pulseline *)
+					os_malloc(NULL,
+						sizeof(struct dfs_pulseline),
+						GFP_ATOMIC);
+		if (dfs->pulses_ext_seg == NULL) {
+			OS_FREE(dfs->events);
+			dfs->events = NULL;
+			OS_FREE(dfs);
+			ic->ic_dfs = NULL;
+			CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
+			    "%s[%d]: pulse buffer allocation failed",
+			    __func__, __LINE__);
+			return 1;
+		}
+		dfs->pulses_ext_seg->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;
+	}
+
 	dfs->pulses->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;
 
 	/* Allocate memory for radar filters */
@@ -351,6 +373,10 @@
 	dfs->dfs_rinfo.dfs_bin5_chirp_ts = dfs->dfs_rinfo.ext_chan_busy_ts;
 	dfs->dfs_rinfo.dfs_last_bin5_dur = MAX_BIN5_DUR;
 	dfs->dfs_b5radars = NULL;
+	if (ic->dfs_hw_bd_id !=  DFS_HWBD_QCA6174) {
+		dfs->dfs_rinfo.dfs_last_bin5_dur_ext_seg = MAX_BIN5_DUR;
+		dfs->dfs_b5radars_ext_seg = NULL;
+	}
 
 	/*
 	 * If dfs_init_radar_filters() fails, we can abort here and
@@ -388,6 +414,11 @@
 		OS_FREE(dfs->pulses);
 		dfs->pulses = NULL;
 	}
+	if (dfs->pulses_ext_seg &&
+	    ic->dfs_hw_bd_id !=  DFS_HWBD_QCA6174) {
+		OS_FREE(dfs->pulses_ext_seg);
+		dfs->pulses_ext_seg = NULL;
+	}
 	if (dfs->events) {
 		OS_FREE(dfs->events);
 		dfs->events = NULL;
@@ -446,9 +477,12 @@
 	}
 #endif
 #endif
+
 	/* Return radar events to free q */
 	dfs_reset_radarq(dfs);
-	dfs_reset_alldelaylines(dfs);
+	dfs_reset_alldelaylines(dfs, DFS_80P80_SEG0);
+	if (ic->dfs_hw_bd_id !=  DFS_HWBD_QCA6174)
+		dfs_reset_alldelaylines(dfs, DFS_80P80_SEG1);
 
 	/* Free up pulse log */
 	if (dfs->pulses != NULL) {
@@ -456,6 +490,12 @@
 		dfs->pulses = NULL;
 	}
 
+	if (dfs->pulses_ext_seg != NULL &&
+	    ic->dfs_hw_bd_id !=  DFS_HWBD_QCA6174) {
+		OS_FREE(dfs->pulses_ext_seg);
+		dfs->pulses_ext_seg = NULL;
+	}
+
 	for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
 		if (dfs->dfs_radarf[n] != NULL) {
 			OS_FREE(dfs->dfs_radarf[n]);
@@ -481,6 +521,11 @@
 		OS_FREE(dfs->dfs_b5radars);
 		dfs->dfs_b5radars = NULL;
 	}
+	if (dfs->dfs_b5radars_ext_seg != NULL &&
+	    ic->dfs_hw_bd_id !=  DFS_HWBD_QCA6174) {
+		OS_FREE(dfs->dfs_b5radars_ext_seg);
+		dfs->dfs_b5radars_ext_seg = NULL;
+	}
 
 /*      Commenting out since all the ar functions are obsolete and
  *      the function definition has been removed as part of dfs_ar.c
@@ -582,7 +627,14 @@
 			if (is_ext_ch) {
 				ext_ch = ieee80211_get_extchan(ic);
 			}
-			dfs_reset_alldelaylines(dfs);
+			dfs_reset_alldelaylines(dfs, DFS_80P80_SEG0);
+			/*
+			 * Extension segment delaylines will be
+			 * enabled only when SAP operates in 80p80
+			 * and both the channels are DFS.
+			 */
+			if (chan->ic_80p80_both_dfs)
+				dfs_reset_alldelaylines(dfs, DFS_80P80_SEG1);
 
 			rs_pri = dfs_getchanstate(dfs, &index_pri, 0);
 			if (ext_ch) {
@@ -594,9 +646,17 @@
 
 				OS_MEMSET(&pe, '\0', sizeof(pe));
 
-				if (index_pri != dfs->dfs_curchan_radindex)
-					dfs_reset_alldelaylines(dfs);
-
+				if (index_pri != dfs->dfs_curchan_radindex) {
+					dfs_reset_alldelaylines(dfs,
+								DFS_80P80_SEG0);
+					/*
+					 * Reset only when ext segment is
+					 * present
+					 */
+					if (chan->ic_80p80_both_dfs)
+						dfs_reset_alldelaylines(dfs,
+								DFS_80P80_SEG1);
+				}
 				dfs->dfs_curchan_radindex = (int16_t) index_pri;
 				dfs->dfs_pri_multiplier_ini =
 					radar_info->dfs_pri_multiplier;