[WCNCR00166482] misc: Fix get_csi content incomplete issue

[Description]
Fix get_csi content incomplete issue

The output of the CSI IQ data may be larger than the iwpriv buffer,
so separate the get CSI command into:
iwpriv wlan0 driver "get_csi 0" -> Get I data
iwpriv wlan0 driver "get_csi 1" -> Get Q data

Be noted that if one of above command executed, another should be
executed later, or the new CSI data from FW will be ignored.

Change-Id: Ie50df6d7edb2f21033ae36d42d3e4bab011d5610
Signed-off-by: Awk Jiang <awk.jiang@mediatek.com>
CR-Id: WCNCR00166482
Feature: misc
diff --git a/include/nic/adapter.h b/include/nic/adapter.h
index 5fe7f47..da9275d 100644
--- a/include/nic/adapter.h
+++ b/include/nic/adapter.h
@@ -934,6 +934,7 @@
 	INT_16 ac2IData[256];
 	INT_16 ac2QData[256];
 	UINT_8 ucDbdcIdx;
+	UINT_8 ucDataOutputted; /* bit 0: I data, bit 1: Q data. Set to 1 if it's ouputted */
 };
 
 /*
diff --git a/nic/nic_cmd_event.c b/nic/nic_cmd_event.c
index 1b1a213..613413d 100644
--- a/nic/nic_cmd_event.c
+++ b/nic/nic_cmd_event.c
@@ -3373,6 +3373,13 @@
 
 	DBGLOG(NIC, INFO, "nicEventCSIData\n");
 
+	if (prAdapter->rCsiData.ucDataOutputted != 0) {
+		DBGLOG(NIC, INFO,
+			"Previous %s data is not outputted. Ignore this new data!\n",
+			(prAdapter->rCsiData.ucDataOutputted & BIT(0)) ? "Q" : "I");
+		return;
+	}
+
 	prCsiData = (struct EVENT_CSI_DATA_T *) (prEvent->aucBuffer);
 	prAdapter->rCsiData.ucDbdcIdx = prCsiData->ucDbdcIdx;
 	prAdapter->rCsiData.ucBw = prCsiData->ucBw;
diff --git a/os/linux/gl_wext_priv.c b/os/linux/gl_wext_priv.c
index 628d793..f8d294c 100644
--- a/os/linux/gl_wext_priv.c
+++ b/os/linux/gl_wext_priv.c
@@ -9765,6 +9765,10 @@
 	P_ADAPTER_T prAdapter = NULL;
 	UINT_8 ucBw = 20;
 	UINT_16 i = 0;
+	INT_32 i4Argc = 0;
+	PCHAR apcArgv[WLAN_CFG_ARGV_MAX];
+	UINT_8 ucDataType = 0;
+	PINT_16 pri2Data = NULL;
 
 	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
 	prAdapter = prGlueInfo->prAdapter;
@@ -9775,6 +9779,15 @@
 	}
 
 	DBGLOG(REQ, LOUD, "command is %s\n", pcCommand);
+	wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
+	DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc);
+
+	if (i4Argc != 2 || kalkStrtou8(apcArgv[1], 0, &ucDataType) ||
+		ucDataType > 1) {
+		LOGBUF(pcCommand, i4TotalLen, i4BytesWritten,
+			"0 or 1 should be given as the parameter to output I or Q data!\n");
+		goto out;
+	}
 
 	if (prAdapter->rCsiData.u2DataCount == 0) {
 		LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "No CSI Data\n");
@@ -9795,28 +9808,31 @@
 		prAdapter->rCsiData.bIsCck);
 	LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "data count: %d\n",
 		prAdapter->rCsiData.u2DataCount);
-	LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "I data:\n");
+
+	if (ucDataType == 0) {
+		LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "I data:\n");
+		pri2Data = prAdapter->rCsiData.ac2IData;
+		prAdapter->rCsiData.ucDataOutputted |= BIT(0);
+	} else {
+		LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "Q data:\n");
+		pri2Data = prAdapter->rCsiData.ac2QData;
+		prAdapter->rCsiData.ucDataOutputted |= BIT(1);
+	}
 
 	for (i = 0; i < prAdapter->rCsiData.u2DataCount; i++) {
 		if ((i % 16) == 0)
 			LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\n");
 
-		LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "%d ",
-			prAdapter->rCsiData.ac2IData[i]);
+		LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "%d ", pri2Data[i]);
 	}
 
-	LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\n\nQ data:\n");
-
-	for (i = 0; i < prAdapter->rCsiData.u2DataCount; i++) {
-		if ((i % 16) == 0)
-			LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\n");
-
-		LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "%d ",
-			prAdapter->rCsiData.ac2QData[i]);
+	if (prAdapter->rCsiData.ucDataOutputted == 0x3) {
+		prAdapter->rCsiData.u2DataCount = 0;
+		 /* clean this indate I/Q data indicates that I & Q data are all outputted,
+		  * we can start to receive the new IQ data
+		  */
+		prAdapter->rCsiData.ucDataOutputted = 0;
 	}
-	LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\n");
-
-	prAdapter->rCsiData.u2DataCount = 0;
 
 out:
 	return i4BytesWritten;