wlan: Skip PN replay check for TDLS packets

If any RX TDLS traffic coming to HOST during or after TDLS
tear down as TDLS sta id does not exist the traffic is mapped
to AP sta id. This will overwrite the current PN value for AP
sta id. As a result after TDLS tear down packets coming via AP
will be dropped due to replay check. To avoid this skip PN
replay check for TDLS packets when mapped to AP sta id.

Change-Id: Ibd24dde465832910fa8158d370c05c32ee8cd519
CRs-Fixed: 2182324
diff --git a/CORE/TL/src/wlan_qct_tl.c b/CORE/TL/src/wlan_qct_tl.c
index 372a6f7..b125cc1 100644
--- a/CORE/TL/src/wlan_qct_tl.c
+++ b/CORE/TL/src/wlan_qct_tl.c
@@ -6499,6 +6499,7 @@
       seq_no = (uint16_t)WDA_GET_RX_REORDER_CUR_PKT_SEQ_NO(pvBDHeader);
       pn_num = WDA_GET_RX_REPLAY_COUNT(pvBDHeader);
 
+      vosTempBuff->pn_replay_skip = 0;
       vosTempBuff->pn_num = pn_num;
 
       TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
@@ -6630,11 +6631,13 @@
               }
               else
               {
-                  TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
-                           "%s: staId %d doesn't exist, but mapped to AP staId %d", __func__,
-                           ucSTAId, ucAddr3STAId));
+                  VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                            "staId %d doesn't exist"
+                            " but mapped to AP staId %d PN:[0x%llX]",
+                            ucSTAId, ucAddr3STAId, pn_num);
                   ucSTAId = ucAddr3STAId;
                   pClientSTA = pTLCb->atlSTAClients[ucAddr3STAId];
+                  vosTempBuff->pn_replay_skip = 1;
               }
           }
       }
@@ -9778,10 +9781,10 @@
                                  (v_PVOID_t)STAMetaInfoPtr);
     }
 
-  /*------------------------------------------------------------------------
-    Check to see if re-ordering session is in place
-   ------------------------------------------------------------------------*/
-  if ( 0 != pClientSTA->atlBAReorderInfo[ucTid].ucExists )
+  /* Check to see if re-ordering session is in place.
+     Skip add to reorder list for TDLS packet on AP staid*/
+  if (0 != pClientSTA->atlBAReorderInfo[ucTid].ucExists  &&
+      !vosDataBuff->pn_replay_skip)
   {
     WLANTL_MSDUReorder( pTLCb, &vosDataBuff, aucBDHeader, ucSTAId, ucTid );
   }
@@ -9793,7 +9796,8 @@
 #endif
 )
 {
-  /* replay check code : check whether replay check is needed or not */
+  /* replay check code : check whether replay check is needed or not
+     Skip replay check for TDLS traffic with AP sta id */
   if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid)
   {
       /* replay check is needed for the station */
@@ -9849,6 +9853,7 @@
       else
       {
            v_BOOL_t status;
+           uint16_t seq_no = (uint16_t)WDA_GET_RX_REORDER_CUR_PKT_SEQ_NO(aucBDHeader);
 
            /* Getting 48-bit replay counter from the RX BD */
            ullcurrentReplayCounter = WDA_DS_GetReplayCounter(aucBDHeader);
@@ -9865,7 +9870,7 @@
            /* It is not AMSDU frame so perform 
               reaply check for each packet, as
               each packet contains valid replay counter*/
-           if (vosDataBuff != NULL) {
+           if (vosDataBuff != NULL && !vosDataBuff->pn_replay_skip) {
               if (vos_is_pkt_chain(vosDataBuff)) {
                  WLANTL_ReorderReplayCheck(pClientSTA, &vosDataBuff, ucTid);
               } else {
@@ -9874,10 +9879,13 @@
                  if(VOS_FALSE == status) {
                     /* Not a replay paket, update previous replay counter in TL CB */
                     pClientSTA->ullReplayCounter[ucTid] = ullcurrentReplayCounter;
+                    pClientSTA->last_seq_no[ucTid] = seq_no;
                  } else {
                     VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
-                    "WLAN TL: Non AMSDU Drop replay packet with PN: [0x%llX], prevPN: [0x%llx]",
-                    ullcurrentReplayCounter, ullpreviousReplayCounter);
+                    "Non AMSDU Drop replay with PN: [0x%llX], prevPN: [0x%llx]"
+                    " seq_no:%d last_seq_no:%d",
+                    ullcurrentReplayCounter, ullpreviousReplayCounter, seq_no,
+                    pClientSTA->last_seq_no[ucTid]);
 
                     pClientSTA->ulTotalReplayPacketsDetected++;
                     VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
diff --git a/CORE/TL/src/wlan_qct_tli.h b/CORE/TL/src/wlan_qct_tli.h
index 15204b5..868e745 100644
--- a/CORE/TL/src/wlan_qct_tli.h
+++ b/CORE/TL/src/wlan_qct_tli.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -703,6 +703,9 @@
  /* It contains 48-bit replay counter per TID*/
   v_U64_t       ullReplayCounter[WLANTL_MAX_TID];
 
+  /* Last seq number received on Tid */
+  v_U16_t      last_seq_no[WLANTL_MAX_TID];
+
  /* It contains no of replay packets found per STA.
     It is for debugging purpose only.*/
   v_U32_t       ulTotalReplayPacketsDetected;
diff --git a/CORE/VOSS/inc/i_vos_packet.h b/CORE/VOSS/inc/i_vos_packet.h
index 173d792..ad6b968 100644
--- a/CORE/VOSS/inc/i_vos_packet.h
+++ b/CORE/VOSS/inc/i_vos_packet.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013,2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013,2017-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -129,6 +129,8 @@
 
    v_U64_t pn_num;
 
+   v_U8_t pn_replay_skip;
+
    // magic number for verifying this is really a struct vos_pkt_t
    v_U32_t magic;
 };