[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);