[WCNCR00173453] wifi: sync wcncr00172128ecn

[Description]
Fix WinStart and WinEnd are obsolete and unsync with AP's SN
after resuming.

Change-Id: Ia2b41dc923fbc098397e2221e214efa5bf792935
Signed-off-by: Jiehang Zheng <jiehang.zheng@mediatek.com>
CR-Id: WCNCR00173453
Feature: wifi
Reviewed-on: http://gerrit.mediatek.inc:8080/1450037
CheckPatch: Check Patch <srv_checkpatch@mediatek.com>
Reviewed-by: Shengxi xu <shengxi.xu@mediatek.com>
Tested-by: Shengxi xu <shengxi.xu@mediatek.com>
diff --git a/common/wlan_lib.c b/common/wlan_lib.c
index 002aa0a..94b0572 100644
--- a/common/wlan_lib.c
+++ b/common/wlan_lib.c
@@ -9665,6 +9665,8 @@
 	UINT_8 ucKeyIdx = 0;
 	UINT_8 ucRpyOffload = 0;
 #endif
+	P_STA_RECORD_T prStaRec;
+	P_RX_BA_ENTRY_T prRxBaEntry;
 
 	if (prGlueInfo->prAdapter->u4IsKeepFullPwrBitmap)
 		wlanKeepFullPwr(prGlueInfo->prAdapter, FALSE);
@@ -9751,6 +9753,24 @@
 			nicUpdateBss(prGlueInfo->prAdapter, idx);
 		}
 	}
+
+	/* After resuming, WinStart will unsync with AP's SN.
+	  * Set fgFirstSnToWinStart for all valid BA entry before suspend.
+	 */
+	for (idx = 0; idx < CFG_STA_REC_NUM; idx++) {
+		prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, idx);
+		if (!prStaRec)
+			continue;
+
+		for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) {
+			prRxBaEntry = prStaRec->aprRxReorderParamRefTbl[i];
+			if (!prRxBaEntry || !(prRxBaEntry->fgIsValid))
+				continue;
+
+			prRxBaEntry->fgFirstSnToWinStart = TRUE;
+		}
+	}
+
 }
 
 /*----------------------------------------------------------------------------*/
diff --git a/include/nic/que_mgt.h b/include/nic/que_mgt.h
index 8967dd1..7209b3b 100644
--- a/include/nic/que_mgt.h
+++ b/include/nic/que_mgt.h
@@ -348,6 +348,7 @@
 	UINT_8 u8LastAmsduSubIdx;
 	BOOL fgIsAmsduDuplicated;
 #endif
+	BOOLEAN fgFirstSnToWinStart;
 } RX_BA_ENTRY_T, *P_RX_BA_ENTRY_T;
 
 typedef UINT_32(*PFN_DEQUEUE_FUNCTION) (IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_32
diff --git a/nic/que_mgt.c b/nic/que_mgt.c
index ab643fe..219a630 100644
--- a/nic/que_mgt.c
+++ b/nic/que_mgt.c
@@ -283,6 +283,7 @@
 		prQM->arRxBaTable[u4Idx].fgAmsduNeedLastFrame = FALSE;
 		prQM->arRxBaTable[u4Idx].fgIsAmsduDuplicated = FALSE;
 #endif
+		prQM->arRxBaTable[u4Idx].fgFirstSnToWinStart = FALSE;
 		cnmTimerInitTimer(prAdapter,
 				  &(prQM->arRxBaTable[u4Idx].rReorderBubbleTimer),
 				  (PFN_MGMT_TIMEOUT_FUNC) qmHandleReorderBubbleTimeout,
@@ -2678,6 +2679,25 @@
 #endif
 
 	RX_DIRECT_REORDER_LOCK(prAdapter, 0);
+
+	/* After resuming, WinStart and WinEnd are obsolete and unsync
+	 * with AP's SN. So assign the SN of first packet to WinStart
+	 * as "Fall Within" case.
+	 */
+	if (prReorderQueParm->fgFirstSnToWinStart) {
+		DBGLOG(QM, INFO,
+			"[%u] First resumed SN(%u) reset Window{%u,%u}\n",
+			prSwRfb->ucTid, prSwRfb->u2SSN,
+			prReorderQueParm->u2WinStart,
+			prReorderQueParm->u2WinEnd);
+
+		prReorderQueParm->u2WinStart = prSwRfb->u2SSN;
+		prReorderQueParm->u2WinEnd =
+			((prReorderQueParm->u2WinStart) +
+			(prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT;
+		prReorderQueParm->fgFirstSnToWinStart = FALSE;
+	}
+
 	/* Insert reorder packet */
 	qmInsertReorderPkt(prAdapter, prSwRfb, prReorderQueParm, prReturnedQue);
 	RX_DIRECT_REORDER_UNLOCK(prAdapter, 0);