Home | History | Annotate | Download | only in 4X
      1 /****************************************************************************
      2 **+-----------------------------------------------------------------------+**
      3 **|                                                                       |**
      4 **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved.      |**
      5 **| All rights reserved.                                                  |**
      6 **|                                                                       |**
      7 **| Redistribution and use in source and binary forms, with or without    |**
      8 **| modification, are permitted provided that the following conditions    |**
      9 **| are met:                                                              |**
     10 **|                                                                       |**
     11 **|  * Redistributions of source code must retain the above copyright     |**
     12 **|    notice, this list of conditions and the following disclaimer.      |**
     13 **|  * Redistributions in binary form must reproduce the above copyright  |**
     14 **|    notice, this list of conditions and the following disclaimer in    |**
     15 **|    the documentation and/or other materials provided with the         |**
     16 **|    distribution.                                                      |**
     17 **|  * Neither the name Texas Instruments nor the names of its            |**
     18 **|    contributors may be used to endorse or promote products derived    |**
     19 **|    from this software without specific prior written permission.      |**
     20 **|                                                                       |**
     21 **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |**
     22 **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |**
     23 **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
     24 **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |**
     25 **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
     26 **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |**
     27 **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
     28 **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
     29 **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |**
     30 **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
     31 **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |**
     32 **|                                                                       |**
     33 **+-----------------------------------------------------------------------+**
     34 ****************************************************************************/
     35 
     36 /***************************************************************************/
     37 /*																		   */
     38 /*		MODULE:	ackEmulUtil.c											   */
     39 /*   PURPOSE:	Ack emulation utility 	              					   */
     40 /*															    		   */
     41 /***************************************************************************/
     42 #include "osApi.h"
     43 #include "802_11Defs.h"
     44 #include "ackEmulDb.h"
     45 #include "report.h"
     46 #include "utils.h"
     47 #include "memMngrEx.h"
     48 #include "ackEmulDb.h"
     49 #include "ackEmulUtil.h"
     50 #include "whalCtrl_api.h"
     51 
     52 
     53 /* The minimum of segment size in byte to lock the segment size */
     54 #define MIN_LOCK_SEGMENT_SIZE 500
     55 
     56 typedef enum {
     57 	OTHER    =0,
     58       TCP_ACK_ONLY ,
     59       TCP_DATA    ,
     60 } packetInclude_T;
     61 
     62 
     63 
     64 #define TI_SNAP_HEADER_LEN 8
     65 #define TI_SNAP_AE_TYPE 0x02
     66 #define TI_SNAP_AE_LEN  3
     67 
     68 #define OFFSET_802_3_HDR	14
     69 
     70 #define K_FACTOR 14
     71 
     72 /* TI Snap Header */
     73 /*  -------------------------------------------
     74    | dsap | SSAP | Control |    OUI   |  Type  |
     75    | 0xAA | 0xAA |   0x00  | 0x080028 | 0x60D0 |
     76     -------------------------------------------  */
     77 
     78 static UINT8 tiSnapHeader[]={0xAA,0xAA,0x00,0x08,0x00,0x28,0x60,0xD0};
     79 
     80 static void wdrv_ackEmulationPktType(ackEmul_t*		ackEmul, UINT8 *pWlanSnapHeader ,UINT8 *pIpHeader , packetInclude_T *packetInclude, UINT16 *tcpDataSize);
     81 static void wdrv_ackEmulationDataStandbyState(ackEmul_t*		ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader);
     82 static void wdrv_ackEmulationAckStandbyState(ackEmul_t*		ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader);
     83 static void wdrv_ackEmulationAckCandidateActivState(ackEmul_t*		ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader,
     84 																	 UINT8 *addYTag, UINT8 *activeIndex,
     85 																	 UINT32 *segmentSize);
     86 static void wdrv_ackEmulationAckActivState(ackEmul_t*		ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader,UINT8 *dropAck);
     87 static void wdrv_ackEmulationAckTerminateState(ackEmul_t*		ackEmul, UINT8 sessionIndex);
     88 
     89 static void wdrv_ackEmulationAddYTag(ackEmul_t*		ackEmul, UINT8 *pDot11Header, UINT16 firstBdLength,
     90 												 UINT8 activeIndex, UINT32 segmentSize);
     91 
     92 static int wdrv_aeChackSnapWithYtag(ackEmul_t*		ackEmul, UINT8 *pSnapHeader, UINT8 *tiSnapLen,
     93 										  UINT8 *activeIndex, UINT16 *segmentSize);
     94 
     95 static void wdrv_aeGenerateAck(ackEmul_t*		ackEmul, UINT16 stationIndex, UINT8 activeIndex ,UINT32 ackNumber);
     96 
     97 
     98 static UINT16 wdrv_IpChecksumCalc(ackEmul_t*		ackEmul, UINT16 len_ip_header, UINT8 *buff);
     99 static UINT16 wdrv_TcpChecksumCalc(ackEmul_t*		ackEmul, UINT16 len_tcp_header,UINT8 *IpSource, UINT8 *IpDest ,UINT8 *buff);
    100 
    101 
    102 
    103 
    104 ackEmul_t* ackEmul_create(TI_HANDLE hOs)
    105 {
    106 	ackEmul_t*		ackEmul;
    107 	ackEmulDB_t*	ackEmulDB;
    108 
    109 	if( hOs  == NULL )
    110 	{
    111 	    WLAN_OS_REPORT(("FATAL ERROR: ackEmul_create(): OS handle Error - Aborting\n"));
    112 		return NULL;
    113 	}
    114 
    115 	ackEmul = os_memoryAlloc(hOs, (sizeof(ackEmul_t)));
    116 
    117 	ackEmulDB = ackEmulDb_create(hOs);
    118 
    119 	if ( (!ackEmul) || (!ackEmulDB) )
    120 	{
    121 		utils_nullMemoryFree(hOs, ackEmul, sizeof(ackEmul_t));
    122 		utils_nullMemoryFree(hOs, ackEmulDB, sizeof(ackEmulDB_t));
    123 	    WLAN_OS_REPORT(("FATAL ERROR: ackEmul_create(): Error Creating ackEmulDB module- Aborting\n"));
    124 		return(NULL);
    125 	}
    126 
    127 	/* reset control module control block */
    128 	os_memoryZero(hOs, ackEmul, (sizeof(ackEmul_t)));
    129 
    130 	ackEmul->pAckEmulDB = ackEmulDB;
    131 
    132 	ackEmul->hOs = hOs;
    133 
    134 	return(ackEmul);
    135 
    136 
    137 }
    138 
    139 TI_STATUS ackEmul_config(ackEmul_t*		ackEmul,
    140 							TI_HANDLE	hWhalCtrl,
    141 							TI_HANDLE	hOs,
    142 							TI_HANDLE	hReport,
    143 							TI_HANDLE	hMemMngr)
    144 {
    145 	/* check parameters validity */
    146 	if( (ackEmul == NULL) || (hOs == NULL) || (hReport == NULL)||
    147 		(hWhalCtrl == NULL) || (hMemMngr == NULL) )
    148 	{
    149 	    WLAN_OS_REPORT(("FATAL ERROR: ackEmul_config(): Parameters Error - Aborting\n"));
    150 		return NOK;
    151 	}
    152 
    153 	/* set objects handles */
    154 	ackEmul->hOs = hOs;
    155 	ackEmul->hReport = hReport;
    156 	ackEmul->hMemMngr = hMemMngr;
    157 	ackEmul->hWhalCtrl = hWhalCtrl;
    158 
    159 	ackEmul->ackEmulationActive = TRUE;
    160 
    161 	ackEmulDb_config(ackEmul->pAckEmulDB,hOs,hReport);
    162 
    163 	/*whalCtrl_setSend4xWackInfo(ackEmul->hWhalCtrl, 0);           */
    164 
    165 	WLAN_REPORT_INIT(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
    166 		(".....ackEmul configured successfully\n"));
    167 
    168 	return OK;
    169 
    170 }
    171 
    172 TI_STATUS ackEmul_destroy(ackEmul_t*	ackEmul)
    173 {
    174 	ackEmulDb_destroy(ackEmul->pAckEmulDB);
    175 
    176 	/* free control module controll block */
    177 	os_memoryFree(ackEmul->hOs, ackEmul, sizeof(ackEmul_t));
    178 
    179 	return OK;
    180 
    181 
    182 }
    183 
    184 
    185 /**********************************************************************************
    186  *                      wdrv_ackEmulationRxPacket()
    187  **********************************************************************************
    188  * DESCRIPTION:	This is the Ack emulation packet receiver main function.
    189  *
    190  * INPUTS:   *pMsdu	 - Pointer to the packet MSDU.
    191  *
    192  * OUTPUT:   None
    193  *
    194  * RETURNS:		None
    195  **********************************************************************************/
    196 TI_STATUS wdrv_ackEmulationRxPacket(ackEmul_t*		ackEmul, mem_MSDU_T *pMsdu)
    197 {
    198 
    199    UINT8 rc;
    200    UINT8 *dataBuf;
    201    dot11_header_t *pDot11Header;
    202    UINT8 *pWlanSnapHeader;
    203    UINT8 *pSnapHeader;
    204    UINT8 *pIpHeader;
    205    UINT16 tcpDataSize;
    206    packetInclude_T packetInclude;
    207    UINT8 sessionIndex, monitorState;
    208    UINT8 activeIndex = 0xff;
    209    UINT16 segmentSize = 0;
    210    UINT8 tiSnapLen = 0;
    211    UINT16 dataLen;
    212    UINT8 WTsessionIndex =0xff;
    213    UINT8 XTag =0;
    214 
    215 
    216    if (ackEmul->ackEmulationActive == FALSE)
    217       return OK;
    218 
    219 
    220    dataBuf = (UINT8 *)memMgr_BufData(pMsdu->firstBDPtr)+ memMgr_BufOffset(pMsdu->firstBDPtr);
    221    dataLen = memMgr_BufLength(pMsdu->firstBDPtr);
    222    pDot11Header = (dot11_header_t*) dataBuf;
    223    /* Find the station Index  */
    224 
    225 
    226    XTag = ((pDot11Header->fc)&0x8000)>>15;
    227    pSnapHeader = dataBuf + WLAN_HDR_LEN;
    228 
    229    pWlanSnapHeader = dataBuf + WLAN_HDR_LEN;
    230    pIpHeader = pWlanSnapHeader + WLAN_SNAP_HDR_LEN;
    231 
    232    /* Chack if SNAP with Y TAG */
    233    rc = wdrv_aeChackSnapWithYtag(ackEmul, pSnapHeader, &tiSnapLen, &activeIndex, &segmentSize);
    234    if(rc == OK)
    235    {
    236    		WLAN_REPORT_WARNING(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
    237 				("Packet with Ytag........\n"));
    238 
    239       /* remove the TI SMAP */
    240       os_memoryMove(NULL, pSnapHeader,pSnapHeader + tiSnapLen, dataLen - WLAN_HDR_LEN - tiSnapLen);
    241       pMsdu->firstBDPtr->length -= tiSnapLen ;
    242       pMsdu->dataLen -= tiSnapLen;
    243 
    244          /* Update table and save template */
    245          wdrv_aeWSourceSaveAckTemplate(ackEmul->pAckEmulDB, 0,activeIndex,dataBuf,pWlanSnapHeader,pIpHeader,(UINT16)pMsdu->dataLen,segmentSize);
    246 
    247 
    248       return OK;
    249    }
    250 
    251    /* Packet without ack emulation TI Snap */
    252 
    253    /* Find the packet type and length */
    254    wdrv_ackEmulationPktType(ackEmul, pWlanSnapHeader,pIpHeader,&packetInclude,&tcpDataSize);
    255 
    256 	switch (packetInclude)
    257    {
    258    case TCP_DATA:
    259    		WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
    260 				("RX packet = TCP_DATA....\n"));
    261 
    262       rc = wdrv_aeWTargetDbFindDataSession(ackEmul->pAckEmulDB, pIpHeader ,&sessionIndex, &monitorState);
    263       if(rc == OK)
    264       {
    265     		WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
    266 				("RX packet XTAG = %d......\n",XTag));
    267 
    268          wdrv_aeDbSetXTagStatus(ackEmul->pAckEmulDB, sessionIndex, XTag);
    269       }
    270       switch (monitorState)
    271       {
    272       case AE_INACTIVE:
    273             rc = wdrv_aeWTargetDbAddSession(ackEmul->pAckEmulDB, pIpHeader);
    274 
    275 			break;
    276 		case AE_STANDBY:
    277          wdrv_ackEmulationDataStandbyState(ackEmul, sessionIndex, pIpHeader);
    278 			break;
    279 		case AE_CANDIDATE_ACTIVE:
    280 			break;
    281 		case AE_ACTIVE:
    282       default:
    283 			break;
    284       }
    285       /*         printf("\n rc= %d  sessionIndex = %d monitorState = %d\n",rc, sessionIndex , monitorState);*/
    286       break;
    287       case TCP_ACK_ONLY:
    288      		WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
    289 				("RX packet = TCP_ACK_ONLY....\n"));
    290 
    291        wdrv_aeWSourceDbUpdateTemplate(ackEmul->pAckEmulDB, pIpHeader,0,&WTsessionIndex);
    292          break;
    293       case OTHER:
    294            WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
    295 				("RX packet = OTHER....\n"));
    296 
    297 	  default:
    298          break;
    299    }
    300 	/*wdrv_aeWTargetDbPrint(ackEmul->pAckEmulDB);*/
    301    return OK;
    302 }
    303 
    304 
    305 /**********************************************************************************
    306  *                      wdrv_ackEmulationTxPacket()
    307  **********************************************************************************
    308  * DESCRIPTION:	This is the Ack emulation packet transmission main function.
    309  *
    310  * INPUTS:   *pMsdu	 - Pointer to the packet MSDU.
    311  *
    312  * OUTPUT:   *discardPacket - If TRUE discard the msdu.
    313  *
    314  * RETURNS:		None
    315  **********************************************************************************/
    316 TI_STATUS wdrv_ackEmulationTxPacket(ackEmul_t*		ackEmul, mem_MSDU_T *pMsdu,int *discardPacket)
    317  {
    318     UINT8		*pDot11Header;
    319     UINT8    *pWlanSnapHeader;
    320     UINT8		*pIpHeader;
    321     UINT16	tcpDataSize;
    322     packetInclude_T packetInclude;
    323     UINT8	sessionIndex = 0xff;
    324    UINT8	monitorState = 0xff;
    325    UINT8		addYTag =FALSE;
    326     UINT8		dropAck =FALSE;
    327     UINT16	firstBdLength = 0;
    328     UINT32	firstBddataOffset = 0;
    329     UINT32	secondBddataOffset = 0;
    330     UINT8 	activeIndex = 0xff;
    331     UINT32	segmentSize = 0;
    332 
    333     *discardPacket = FALSE;
    334     pIpHeader     = NULL;
    335 
    336 
    337     if (ackEmul->ackEmulationActive == FALSE)
    338        return OK;
    339 
    340     firstBdLength = memMgr_BufLength(pMsdu->firstBDPtr);
    341     firstBddataOffset = memMgr_BufOffset(pMsdu->firstBDPtr) ;
    342     pDot11Header = (UINT8 *)memMgr_BufData(pMsdu->firstBDPtr)+firstBddataOffset;
    343 
    344     if (firstBdLength == WLAN_HDR_LEN + WLAN_SNAP_HDR_LEN)
    345     {
    346        /* Packet from Ethernet, the IP heder is in the second data buffer */
    347        if(pMsdu->firstBDPtr->nextBDPtr != NULL)
    348        {
    349           secondBddataOffset = memMgr_BufOffset(pMsdu->firstBDPtr->nextBDPtr);
    350           pIpHeader = (UINT8 *)memMgr_BufData(pMsdu->firstBDPtr->nextBDPtr)+ secondBddataOffset;
    351        }
    352     }
    353     else
    354     {
    355        /* Packet from Wlan  */
    356        pIpHeader = pDot11Header + WLAN_HDR_LEN + WLAN_SNAP_HDR_LEN;
    357     }
    358 
    359     pWlanSnapHeader = pDot11Header + WLAN_HDR_LEN;
    360 
    361    /* Find the packet type and length */
    362     wdrv_ackEmulationPktType(ackEmul, pWlanSnapHeader,pIpHeader ,&packetInclude,&tcpDataSize);
    363 
    364     switch (packetInclude)
    365     {
    366     case TCP_ACK_ONLY:
    367 		WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
    368 				("TX packet = TCP_ACK_ONLY....\n"));
    369 
    370 
    371        wdrv_aeWTargetDbFindAckSession(ackEmul->pAckEmulDB, pIpHeader ,&sessionIndex, &monitorState);
    372 
    373        switch (monitorState)
    374        {
    375        case AE_INACTIVE:
    376 
    377 		   break;
    378        case AE_STANDBY:
    379 
    380 		   wdrv_ackEmulationAckStandbyState(ackEmul, sessionIndex, pIpHeader);
    381 		   break;
    382        case AE_CANDIDATE_ACTIVE:
    383 		   wdrv_ackEmulationAckCandidateActivState(ackEmul, sessionIndex,
    384 			   pIpHeader,
    385 			   &addYTag,
    386 			   &activeIndex,
    387 			   &segmentSize);
    388 		   if(addYTag == TRUE)
    389 		   {
    390 			   wdrv_ackEmulationAddYTag(ackEmul, pDot11Header, firstBdLength, activeIndex, segmentSize);
    391 
    392 			   /* update the MSDU fields */
    393 			   pMsdu->firstBDPtr->length += TI_SNAP_HEADER_LEN+2+TI_SNAP_AE_LEN;
    394 			   pMsdu->dataLen += TI_SNAP_HEADER_LEN+2+TI_SNAP_AE_LEN;
    395 		   }
    396 
    397 		   break;
    398        case AE_ACTIVE:
    399 		   /* Comper Template and drop packet */
    400 		   wdrv_ackEmulationAckActivState(ackEmul, sessionIndex, pIpHeader,&dropAck);
    401 
    402 		   *discardPacket = dropAck;
    403 		   break;
    404 
    405        case AE_TERMINATE:
    406 		   wdrv_ackEmulationAckTerminateState(ackEmul, sessionIndex);
    407 
    408 		   break;
    409        default:
    410 
    411 		   break;
    412        }
    413 
    414 	   break;
    415 	   case TCP_DATA:
    416 		   WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
    417 			   ("TX packet = TCP_DATA....\n"));
    418 
    419 		   break;
    420        case OTHER:
    421 		   WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
    422 			   ("TX packet = OTHER....\n"));
    423        default:
    424 		   break;
    425     }
    426     return OK;
    427 }
    428 
    429 
    430 
    431 /**********************************************************************************
    432  *                      wdrv_ackEmulationPktType()
    433  **********************************************************************************
    434  * DESCRIPTION:	Find the packet type and length.
    435  *
    436  * INPUTS:   pWlanSnapHeader	 - Pointer to the 802.11 SNAP header buffer.
    437  *           pIpHeader         - Pointer to the ip header header buffer.
    438  *
    439  * OUTPUT:   packetInclude     - The packet type, TCP_DATA, TCP_ACK_ONLY or OTHER
    440  *           tcpDataSize       - The packet size (only for tcp packet)
    441  *
    442  * RETURNS:		None
    443  **********************************************************************************/
    444 static void wdrv_ackEmulationPktType(ackEmul_t*		ackEmul, UINT8 *pWlanSnapHeader ,UINT8 *pIpHeader ,
    445                                      packetInclude_T *packetInclude, UINT16 *tcpDataSize)
    446 {
    447    UINT16 pktTotalLen;
    448    UINT8 ipHeaderLen, tcpHeaderLen;
    449 
    450    *tcpDataSize =0;
    451 
    452 
    453 
    454    /* Check if the packet is TCP/IP */
    455    if ((wlan_ntohs(((Wlan_LlcHeader_T*)pWlanSnapHeader)->Type) == IP_PROTOCOL_NUMBER) &&
    456       (*(unsigned char*) ((ULONG)pIpHeader+(ULONG)IP_PROTOCOL_FIELD)== TCP_PROTOCOL))
    457    {
    458       /* Check if the packet include data or Ack only */
    459       pktTotalLen = wlan_ntohs((*(UINT16*)(pIpHeader + IP_TOTAL_LEN_FIELD)));
    460       ipHeaderLen = ((*(unsigned char*)pIpHeader  & 0x0f) * 4);
    461       tcpHeaderLen = ((((*(unsigned char*)(pIpHeader + ipHeaderLen+TCP_OFFSET_FIELD))& 0xf0)>>4) * 4);
    462       *tcpDataSize = pktTotalLen - (ipHeaderLen + tcpHeaderLen);
    463 
    464       if(*tcpDataSize > 0)
    465          *packetInclude = TCP_DATA;
    466       else
    467          *packetInclude = TCP_ACK_ONLY;
    468 
    469    }
    470    else
    471    {
    472       *packetInclude = OTHER;
    473    }
    474 
    475 }
    476 
    477 
    478 
    479 /**********************************************************************************
    480  *                      wdrv_ackEmulationDataStandbyState()
    481  **********************************************************************************
    482  * DESCRIPTION:	This function handle the tcp date packet for session in
    483  *                standby state.
    484  *
    485  * INPUTS:   sessionIndex	 - the session index
    486  *           *pIpHeader     - Pointer to the ip header header buffer.
    487  *
    488  * OUTPUT:   None.
    489  *
    490  * RETURNS:	 None
    491  **********************************************************************************/
    492 static void wdrv_ackEmulationDataStandbyState(ackEmul_t*		ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader)
    493 {
    494 	UINT8 ipHeaderLen = 0;
    495 
    496 	UINT32 prevSequenceNumber =0;
    497 	UINT32 currentSequenceNumber =0;
    498 
    499 	UINT32 prevSegmentSize = 0;
    500 	UINT32 currentSegmentSize =0;
    501 
    502 	UINT8 equalSegmentSizeCounter =0;
    503 
    504 
    505 
    506 	/* Calculate Current Sequence Number */
    507 	ipHeaderLen = ((*(unsigned char*)pIpHeader  & 0x0f) * 4);
    508 	currentSequenceNumber = wlan_ntohl(*(unsigned long*)(pIpHeader+ipHeaderLen+TCP_SEQUENCE_NUMBER_FIELD));
    509 
    510 	wdrv_aeWTargetDbGetSessionSequenceNumber(ackEmul->pAckEmulDB, sessionIndex,&prevSequenceNumber);
    511 	/* Calclate Segment Size */
    512 	wdrv_aeWTargetDbGetSessionSegmentSize(ackEmul->pAckEmulDB, sessionIndex,&prevSegmentSize);
    513 	currentSegmentSize = currentSequenceNumber - prevSequenceNumber;
    514 
    515 	if (prevSegmentSize == currentSegmentSize)
    516 	{
    517 		/* Increase Equal Segment Size Counter */
    518 		wdrv_aeWTargetDbGetIncrSessionEqualSegmentSizeCounter(ackEmul->pAckEmulDB, sessionIndex,&equalSegmentSizeCounter);
    519 		if(equalSegmentSizeCounter == 2 && currentSegmentSize > MIN_LOCK_SEGMENT_SIZE)
    520 		{
    521 			/* Monitor state -> AE_CANDIDATE_ACTIVE */
    522 /*         printf("\n Session %d chabge state to AE_CANDIDATE_ACTIVE with segment size %d\n",
    523             sessionIndex,
    524             currentSegmentSize);*/
    525 			wdrv_aeWTargetDbSetSessionMonitorState(ackEmul->pAckEmulDB, sessionIndex,AE_CANDIDATE_ACTIVE);
    526 		}
    527 
    528 	}
    529 	else
    530 	{
    531 		wdrv_aeWTargetDbSetSessionSegmentSize(ackEmul->pAckEmulDB, sessionIndex,currentSegmentSize);
    532 		wdrv_aeWTargetDbSetSessionEqualSegmentSizeCounter(ackEmul->pAckEmulDB, sessionIndex,0);
    533 	}
    534 
    535 	wdrv_aeWTargetDbSetSessionSequenceNumber(ackEmul->pAckEmulDB, sessionIndex,currentSequenceNumber);
    536 }
    537 
    538 
    539 /**********************************************************************************
    540  *                      wdrv_ackEmulationAckStandbyState()
    541  **********************************************************************************
    542  * DESCRIPTION:	This function handle the tcp ack packet for session in
    543  *                standby state.
    544  *
    545  * INPUTS:   sessionIndex	 - the session index
    546  *           *pIpHeader     - Pointer to the ip header header buffer.
    547  *
    548  * OUTPUT:   None.
    549  *
    550  * RETURNS:	 None
    551  **********************************************************************************/
    552 static void wdrv_ackEmulationAckStandbyState(ackEmul_t*		ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader)
    553 {
    554 
    555    UINT8 ipHeaderLen = 0;
    556 	UINT32 currentAckNumber =0;
    557 
    558    	/* Calculate Current Ack Number */
    559 	ipHeaderLen = ((*(unsigned char*)pIpHeader  & 0x0f) * 4);
    560 	currentAckNumber = wlan_ntohl(*(unsigned long*)(pIpHeader+ipHeaderLen+TCP_ACK_NUMBER_FIELD));
    561 
    562    	/* Set Current Ack Number */
    563 	wdrv_aeWTargetDbSetSessionAckNumber(ackEmul->pAckEmulDB, sessionIndex,currentAckNumber);
    564 
    565 
    566 
    567 }
    568 
    569 /**********************************************************************************
    570  *                      wdrv_ackEmulationAckCandidateActivState()
    571  **********************************************************************************
    572  * DESCRIPTION:	This function handle the tcp ack packet for session in
    573  *                candidate activ state.
    574  *
    575  * INPUTS:   sessionIndex	 - the session index
    576  *           *pIpHeader     - Pointer to the ip header header buffer.
    577  *
    578  * OUTPUT:   *addYTag       - If true, add Ytag to the tcp acp packet
    579  *           *activeIndex   - The activeIndex that assign for this session
    580  *           *segmentSize   - The segment size of this tcp session.
    581  *
    582  * RETURNS:	 None
    583  **********************************************************************************/
    584 static void wdrv_ackEmulationAckCandidateActivState(ackEmul_t*		ackEmul, UINT8 sessionIndex,
    585 																	 UINT8 *pIpHeader,
    586 																	 UINT8 *addYTag,
    587 																	 UINT8 *activeIndex,
    588 																	 UINT32 *segmentSize)
    589 {
    590 
    591    UINT8 ipHeaderLen = 0;
    592 	UINT32 prevAckNumber =0;
    593 	UINT32 currentAckNumber =0;
    594    UINT32 ackCounter =0;
    595 
    596    	/* Calculate Current Ack Number */
    597 	ipHeaderLen = ((*(unsigned char*)pIpHeader  & 0x0f) * 4);
    598 	currentAckNumber = wlan_ntohl(*(unsigned long*)(pIpHeader+ipHeaderLen+TCP_ACK_NUMBER_FIELD));
    599 
    600 	wdrv_aeWTargetDbGetSessionSegmentSize(ackEmul->pAckEmulDB, sessionIndex,segmentSize);
    601 	wdrv_aeWTargetDbGetSessionAckNumber(ackEmul->pAckEmulDB, sessionIndex,&prevAckNumber);
    602 
    603    if((currentAckNumber - prevAckNumber) == *segmentSize *2)
    604    {
    605        WLAN_REPORT_FATAL_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
    606 				("Change State to active............\n"));
    607       /* Change state to Active and update Active index */
    608       if(wdrv_aeWTargetDbSetActiveState(ackEmul->pAckEmulDB, sessionIndex, activeIndex) == OK)
    609       {
    610 
    611 
    612          /* Calculate Ack Counter */
    613          ackCounter = currentAckNumber / (*segmentSize *2);
    614          wdrv_aeWTargetDbSetSessionAckCounter(ackEmul->pAckEmulDB, sessionIndex,ackCounter) ;
    615          /* Save template update Active index */
    616          wdrv_aeWTargetDbSaveAckTemplate(ackEmul->pAckEmulDB, sessionIndex,pIpHeader);
    617          /* add addYTag */
    618 
    619 		 WLAN_REPORT_FATAL_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
    620 				("ADD Y TAG.........!!!!!!!!!!!!\n"));
    621 
    622 			*addYTag = TRUE;
    623 
    624       }
    625    }
    626    wdrv_aeWTargetDbSetSessionAckNumber(ackEmul->pAckEmulDB, sessionIndex,currentAckNumber);
    627 
    628 }
    629 
    630 /**********************************************************************************
    631  *                      wdrv_ackEmulationAckActivState()
    632  **********************************************************************************
    633  * DESCRIPTION:	This function handle the tcp ack packet for session in
    634  *                active state.
    635  *
    636  * INPUTS:   sessionIndex	 - the session index
    637  *           *pIpHeader     - Pointer to the ip header header buffer.
    638  *
    639  * OUTPUT:   *dropAck       - If TRUE discard the packet.
    640  *
    641  * RETURNS:	 None
    642  **********************************************************************************/
    643 static void wdrv_ackEmulationAckActivState(ackEmul_t*		ackEmul, UINT8 sessionIndex, UINT8 *pIpHeader,UINT8 *dropAck)
    644 {
    645    int rc =NOK;
    646 
    647    UINT8 ipHeaderLen = 0;
    648    UINT32 currentAckNumber   =0;
    649    UINT32 prevAckNumber   =0;
    650    UINT32 segmentSize =0;
    651    UINT32 currentAckCounter =0;
    652    UINT32 prevAckCounter =0;
    653    UINT8  activeIndex = 0xff;
    654    UINT32 segmentNumber = 0;
    655    UINT32 prevTimeStamp;
    656    UINT32 currentTimeStamp;
    657    UINT8 newWackInfo = 0;
    658    UINT8 prevWackInfo;
    659    UINT8 prevOwnershipBit;
    660    UINT8 prevActvIndxBits;
    661 	UINT8 prevAckCounterBits;
    662 
    663 
    664    currentTimeStamp =os_timeStampUs(ackEmul->hOs);
    665 
    666    wdrv_aeWTargetDbGetSessionTimeStamp(ackEmul->pAckEmulDB, sessionIndex, &prevTimeStamp);
    667    if(prevTimeStamp != 0)
    668    {
    669       if((WTARGET_ACTIVE_TIME_OUT) < (currentTimeStamp - prevTimeStamp))
    670       {  /* If the delay between two ack packet for the same session grater */
    671          /* than  WTARGET_ACTIVE_TIME_OUT change session state to terminate */
    672          wdrv_aeWTargetDbSetSessionMonitorState(ackEmul->pAckEmulDB, sessionIndex,AE_TERMINATE);
    673        	 /*WLAN_OS_REPORT(("1\n"));*/
    674 		  return;
    675       }
    676    }
    677 
    678 
    679    /* extract the information from prevWackInfo */
    680 
    681    whalCtrl_getSend4xWackInfo(ackEmul->hWhalCtrl, &prevWackInfo);
    682    prevAckCounterBits = (prevWackInfo&0x0f);
    683    prevActvIndxBits = (prevWackInfo&0x10)>>4;
    684    prevOwnershipBit = (prevWackInfo&0x80)>>7;
    685 
    686    /* Calculate Current Ack Number */
    687    ipHeaderLen = ((*(unsigned char*)pIpHeader  & 0x0f) * 4);
    688    currentAckNumber = wlan_ntohl(*(unsigned long*)(pIpHeader+ipHeaderLen+TCP_ACK_NUMBER_FIELD));
    689 
    690    wdrv_aeWTargetDbGetSessionSegmentSize(ackEmul->pAckEmulDB, sessionIndex,&segmentSize);
    691    wdrv_aeWTargetDbGetSessionAckNumber(ackEmul->pAckEmulDB, sessionIndex,&prevAckNumber);
    692 
    693    wdrv_aeWTargetDbGetSessionAckCounter(ackEmul->pAckEmulDB, sessionIndex, &prevAckCounter) ;
    694    wdrv_aeWTargetDbGetSessionActiveIndex(ackEmul->pAckEmulDB, sessionIndex, &activeIndex);
    695 
    696    /* Calculate Ack Counter */
    697    currentAckCounter = currentAckNumber / (segmentSize*2);
    698    if((currentAckNumber - prevAckNumber) == segmentSize *2)
    699    {
    700        	 /*WLAN_OS_REPORT(("--2\n"));*/
    701 
    702 	   if ((currentAckCounter > prevAckCounter) && (currentAckCounter < prevAckCounter + 5))
    703 	   {
    704        	 /*WLAN_OS_REPORT(("----3\n"));*/
    705 		   rc = wdrv_aeWTargetDbCmpAckTemplate(ackEmul->pAckEmulDB, sessionIndex, pIpHeader);
    706 		   if (rc == OK)
    707 		   {
    708 			   /* drop this Ack */
    709 
    710 			   UINT8 Xtag;
    711 
    712 			   wdrv_aeDbGetXTagStatus(ackEmul->pAckEmulDB, sessionIndex,&Xtag);
    713 		       	 /*WLAN_OS_REPORT(("------4 Xtag=%d prevOwnershipBit=%d activeIndex=%d prevActvIndxBits=%d\n",Xtag,prevOwnershipBit,activeIndex,prevActvIndxBits));*/
    714 			   if (((prevOwnershipBit == 1)|| (activeIndex == prevActvIndxBits)) && Xtag)
    715 			   {
    716 				   *dropAck = TRUE;
    717 
    718 			   }
    719 		   }
    720 	   }
    721    }
    722    else
    723    {
    724 		/*WLAN_OS_REPORT(("------99 prevAckNumber=%d,currentAckCounter=%d currentAckNumber=%d segmentSize=%d \n",*/
    725 		/*						  prevAckNumber,   currentAckCounter,   currentAckNumber,   segmentSize));*/
    726    }
    727 
    728   WLAN_REPORT_FATAL_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
    729 		   ("dropAck = %d\n",*dropAck));
    730 
    731    if(*dropAck == TRUE)
    732    {
    733 	   newWackInfo = (((currentAckCounter % K_FACTOR)+1)&0xf); /* Add currentAckCounter MOD K_FACTOR to bit 0-3 */
    734 	   newWackInfo = newWackInfo | (activeIndex << 4);  /* Add activeIndex to bit 4 */
    735 	   whalCtrl_setSend4xWackInfo(ackEmul->hWhalCtrl, newWackInfo);
    736 	   wdrv_aeWTargetDbSetSessionTimeStamp(ackEmul->pAckEmulDB, sessionIndex, currentTimeStamp);
    737    }
    738    else
    739    {
    740 
    741 	   if((prevAckNumber % (segmentSize*2))>(currentAckNumber % (segmentSize*2)))
    742 	   {
    743 		   /* Ack Reorder Problem */
    744 		   newWackInfo = 0xF;
    745 	   }
    746 	   else
    747 	   {
    748 		   if(prevAckCounterBits == 0xF)
    749 		   {
    750 			   /* chack if this wack info send */
    751 			   if(prevOwnershipBit == 1)
    752 				   newWackInfo = 0;
    753 		   }
    754 		   else
    755 		   {
    756                newWackInfo = 0;
    757 		   }
    758 	   }
    759 	   newWackInfo = newWackInfo | (activeIndex << 4);  /* Add activeIndex to bit 4 */
    760 	   whalCtrl_setSend4xWackInfo(ackEmul->hWhalCtrl, newWackInfo);
    761 
    762 	   wdrv_aeWTargetDbSetSessionAckCounter(ackEmul->pAckEmulDB, sessionIndex,currentAckCounter) ;
    763 
    764    }
    765    wdrv_aeWTargetDbSetSessionAckNumber(ackEmul->pAckEmulDB, sessionIndex,currentAckNumber);
    766    segmentNumber = wlan_ntohl(*(unsigned long*)(pIpHeader+ipHeaderLen+TCP_SEQUENCE_NUMBER_FIELD));
    767    wdrv_aeWTargetDbUpdateAckTemplate(ackEmul->pAckEmulDB, sessionIndex,segmentNumber);
    768 
    769 }
    770 
    771 
    772 /**********************************************************************************
    773  *                      wdrv_ackEmulationAckTerminateState()
    774  **********************************************************************************
    775  * DESCRIPTION:	This function handle the tcp ack packet for session in
    776  *                terminate state.
    777  *
    778  * INPUTS:   sessionIndex	 -
    779  *
    780  * OUTPUT:   None
    781  *
    782  * RETURNS:		None
    783  **********************************************************************************/
    784 static void wdrv_ackEmulationAckTerminateState(ackEmul_t*		ackEmul, UINT8 sessionIndex)
    785 {
    786    UINT32 prevTimeStamp;
    787    UINT32 currentTimeStamp = os_timeStampUs(ackEmul->hOs);
    788 
    789    wdrv_aeWTargetDbGetSessionTimeStamp(ackEmul->pAckEmulDB, sessionIndex, &prevTimeStamp);
    790    if(prevTimeStamp != 0)
    791    {
    792       if((WTARGET_TERMINATE_TIME_OUT) < (currentTimeStamp - prevTimeStamp))
    793       {
    794          /* Reset Session */
    795          wdrv_aeWTargetDbResetTuple(ackEmul->pAckEmulDB, sessionIndex);
    796       }
    797    }
    798    return;
    799 }
    800 
    801 /**********************************************************************************
    802  *                      wdrv_ackEmulationAddYTag()
    803  **********************************************************************************
    804  * DESCRIPTION: Add Ytag to the Tcp Ack PAcket
    805  *
    806  * INPUTS:   *pDot11Header	 - Pointer to the 802.11 heder
    807  *           firstBdLength  - The length of the first BD
    808  *           activeIndex    - The active index of the monitor session.
    809  *           segmentSize    - The segmentSize of the monitor session.
    810  *
    811  * OUTPUT:     None
    812  *
    813  * RETURNS:		None
    814  **********************************************************************************/
    815 
    816 /* Tcp Ack without Ytag */
    817 /*  -------------------------------------------
    818    | 802.11 | SSAP |   IP   |  TCP   | Payload |
    819    | header |      | header | header |         |
    820     -------------------------------------------  */
    821 /* Tcp Ack with Ytag */
    822 /*  ---------------------------------------------------------
    823    | 802.11 |  TI  | 802.11 SNAP |   IP   |  TCP   | Payload |
    824    | header | SNAP | header      | header | header |         |
    825     ---------------------------------------------------------  */
    826 
    827 
    828 /* TI Snap */
    829 /*  -------------------------------------------------------------------------
    830    | dsap | SSAP | Control |    OUI   |  Type  |  AE  | AE  |Active |Segment |
    831    | 0xAA | 0xAA |   0x00  | 0x080028 | 0x60D0 | Type | Len | Index |  Size  |
    832     ------------------------------------------------------------------------- */
    833 
    834 
    835 static void wdrv_ackEmulationAddYTag(ackEmul_t*		ackEmul, UINT8 *pDot11Header, UINT16 firstBdLength,
    836 												 UINT8 activeIndex, UINT32 segmentSize)
    837 {
    838 	UINT8 *tempPtr;
    839 	UINT32 moveLen;
    840 
    841 	tempPtr = pDot11Header + WLAN_HDR_LEN;
    842 	moveLen = firstBdLength - WLAN_HDR_LEN;
    843 	os_memoryMove(NULL, tempPtr+TI_SNAP_HEADER_LEN+2+TI_SNAP_AE_LEN ,tempPtr,moveLen);
    844 	os_memoryCopy(NULL, tempPtr,tiSnapHeader,TI_SNAP_HEADER_LEN);
    845 	tempPtr += TI_SNAP_HEADER_LEN;
    846    *(UINT8*)tempPtr = TI_SNAP_AE_TYPE;
    847 	tempPtr ++;
    848 	*(UINT8*)tempPtr = TI_SNAP_AE_LEN; /* Length */
    849 	tempPtr ++;
    850 	*(UINT8*)tempPtr = activeIndex; /* Active Index */
    851 	tempPtr ++;
    852 	*(UINT16*)tempPtr = wlan_ntohs((UINT16)segmentSize); /* Segment Size */
    853 }
    854 
    855 /**********************************************************************************
    856  *                      wdrv_aeChackSnapWithYtag()
    857  **********************************************************************************
    858  * DESCRIPTION: Check if the packet include Ytag
    859  *
    860  * INPUTS:   *pSnapHeader - Pointer to the SNAP heder
    861  *
    862  * OUTPUT:   *tiSnapLen      - The length of the first BD
    863  *           *activeIndex    - The active index.
    864  *           *segmentSize    - The segmentSize.
    865  *
    866  * RETURNS:		Ok if include Ytag, otherwise NOK
    867  **********************************************************************************/
    868 static int wdrv_aeChackSnapWithYtag(ackEmul_t*		ackEmul, UINT8 *pSnapHeader, UINT8 *tiSnapLen,
    869                                     UINT8 *activeIndex, UINT16 *segmentSize)
    870 {
    871 
    872 	/* Chack if SNAP with Y TAG */
    873    if ((os_memoryCompare(ackEmul->hOs, pSnapHeader,tiSnapHeader,TI_SNAP_HEADER_LEN)== 0)&&
    874       (*(UINT8*)(pSnapHeader + TI_SNAP_HEADER_LEN) == TI_SNAP_AE_TYPE))
    875    {
    876 
    877       /* This packet include Ack with Y TAG */
    878 		UINT8* tempPtr;
    879 		UINT8 templen;
    880 		tempPtr = pSnapHeader + TI_SNAP_HEADER_LEN+1;
    881 		templen = *(UINT8*)tempPtr;
    882 		*tiSnapLen = TI_SNAP_HEADER_LEN + 2 + templen;
    883 		tempPtr ++;
    884 		*activeIndex = (UINT8)(wlan_ntohs(*(UINT16*)tempPtr));
    885 		tempPtr +=2;
    886 		*segmentSize = (UINT16)(wlan_ntohl(*(UINT32*)tempPtr));
    887 		return OK;
    888 	}
    889 	else
    890 	{
    891 		return NOK;
    892 	}
    893 }
    894 
    895 int genera = 0;
    896 int modulo_off = 0;
    897 int mod_off = 0;
    898 int mod_on = 0;
    899 
    900 /**********************************************************************************
    901  *                      wdrv_aeWackReceive()
    902  **********************************************************************************
    903  * DESCRIPTION:	Parse the wack info and generate emulated tcp ack
    904  *
    905  * INPUTS:   station	 - The wack source station index.
    906  *           wackInfo - The wackInfo
    907  *
    908  * OUTPUT:   None
    909  *
    910  * RETURNS:		None
    911  **********************************************************************************/
    912 void wdrv_aeWackReceive(ackEmul_t*		ackEmul, UINT16 station, UINT8 wackInfo)
    913 {
    914 	UINT8 ackCounterlowBits;
    915 	UINT8 activeIndex;
    916 	UINT32 oldAckNumber;
    917 	UINT32 newAckNumber;
    918 	UINT32 oldAckCounter;
    919 	UINT32 newAckCounter;
    920 	UINT32 segmentSize;
    921 	UINT32 prevWackTimeStamp;
    922 	UINT32 currentWackTimeStamp;
    923 	UINT32  reorderProblemStatus;
    924 
    925 	static UINT8 prev_wackInfo = 0xff;
    926 
    927 	if(prev_wackInfo != wackInfo)
    928 	{
    929 		prev_wackInfo = wackInfo;
    930 
    931 
    932 		/* extract the information from wackInfo */
    933 		ackCounterlowBits = (wackInfo & 0xf);
    934 		activeIndex      = (wackInfo & 0x10) >> 4;
    935 
    936 
    937 		if (ackCounterlowBits == 0)
    938 			ackCounterlowBits = 0xF;
    939 		else
    940 			ackCounterlowBits --;
    941 
    942 
    943 		if(ackCounterlowBits == 0xF)
    944 			return;
    945 
    946 		if(ackCounterlowBits == 0xE)
    947 		{
    948 			/* Reorder problem is possible */
    949 			wdrv_aeWSourceDbSetSessionAckReorderProblem(ackEmul->pAckEmulDB, station,activeIndex,REORDER_PROBLEM_ON);
    950 			return;
    951 		}
    952 		wdrv_aeWSourceDbGetSessionTimeStamp(ackEmul->pAckEmulDB, station,activeIndex,&prevWackTimeStamp);
    953 		if(prevWackTimeStamp != 0)
    954 		{
    955 			currentWackTimeStamp = os_timeStampUs(ackEmul->hOs);
    956 
    957 			if((WSOURCE_SESSION_TIME_OUT) < (currentWackTimeStamp - prevWackTimeStamp))
    958 			{
    959 				/* reset Wsource session */
    960 				/*WLAN_OS_REPORT((" Reset Wsource session  activeIndex %\n",activeIndex));*/
    961 
    962 				wdrv_aeWSourceDbResetSession(ackEmul->pAckEmulDB, station, activeIndex);
    963 
    964 				return;
    965 			}
    966 
    967 			wdrv_aeWSourceDbSetSessionTimeStamp(ackEmul->pAckEmulDB, station,activeIndex,currentWackTimeStamp);
    968 
    969 			wdrv_aeWSourceDbGetSessionSegmentSize(ackEmul->pAckEmulDB, station,activeIndex,&segmentSize);
    970 
    971 			if(segmentSize != 0)
    972 			{
    973 				wdrv_aeWSourceDbGetSessionAckNumber(ackEmul->pAckEmulDB, station,activeIndex,&oldAckNumber);
    974 				wdrv_aeWSourceDbGetSessionAckCounter(ackEmul->pAckEmulDB, station,activeIndex,&oldAckCounter);
    975 
    976 				/* newACK_counter = (Low_counter - (oldACK_counter mod 2^k) + 2^k + 3) mod 2^k - 3 + oldACK_counter*/
    977 				newAckCounter = ((ackCounterlowBits - (oldAckCounter % K_FACTOR) + K_FACTOR + 3) % K_FACTOR) -3 + oldAckCounter;
    978 
    979 				if(newAckCounter <= oldAckCounter)
    980 					return;
    981 
    982 				wdrv_aeWSourceDbGetSessionAckReorderProblem(ackEmul->pAckEmulDB, station,activeIndex,&reorderProblemStatus);
    983 
    984 				if(reorderProblemStatus == REORDER_PROBLEM_ON)
    985 				{
    986 					newAckNumber = (newAckCounter * (segmentSize*2));
    987 				}
    988 				else
    989 				{
    990 					/* newACK_number = oldACK_number mod (Segment_Size*2) + Rx_Ack_count * (Segment_Size*2)*/
    991 					newAckNumber = (oldAckNumber % (segmentSize*2)) + (newAckCounter * (segmentSize*2));
    992 				}
    993 				/* Generate ack */
    994 				genera++;
    995 				wdrv_aeGenerateAck(ackEmul, station,activeIndex,newAckNumber);
    996 
    997 				wdrv_aeWSourceDbSetSessionAckNumber(ackEmul->pAckEmulDB, station,activeIndex,newAckNumber);
    998 				wdrv_aeWSourceDbSetSessionAckCounter(ackEmul->pAckEmulDB, station,activeIndex,newAckCounter);
    999 			}
   1000 			return;
   1001 
   1002 		}
   1003 
   1004 	}
   1005 }
   1006 /**********************************************************************************
   1007  *                      wdrv_aeGenerateAck()
   1008  **********************************************************************************
   1009  * DESCRIPTION: Generate emulated TCP Ack
   1010  *
   1011  * INPUTS:   sessionIndex	 -
   1012  *           activeIndex
   1013  *           ackNumber
   1014  *
   1015  * OUTPUT:   None
   1016  *
   1017  * RETURNS:		None
   1018  **********************************************************************************/
   1019  static void wdrv_aeGenerateAck(ackEmul_t*		ackEmul, UINT16 stationIndex, UINT8 activeIndex ,UINT32 ackNumber)
   1020  {
   1021 	 mem_MSDU_T *pMsdu;
   1022 	 UINT8 ipHeaderLen;
   1023 	 UINT8 tcpHeaderLen;
   1024 	 UINT8 *pTeplate;
   1025 	 UINT8 *pNewPkt;
   1026 	 UINT16  newPktLen;
   1027 	 UINT8 *ipSource, *ipDest;
   1028 	 UINT8 *pIpHeader, *pTcpHeader;
   1029 	 UINT16 ipChecksum =0;
   1030 	 UINT16 tcpChecksum =0;
   1031 
   1032 	 dot11_header_t *pDot11Header;
   1033 	 UINT8 *pDAddr,*pSAddr;
   1034 
   1035 	WLAN_REPORT_ERROR(ackEmul->hReport, ACK_EMUL_MODULE_LOG,
   1036 				("wdrv_aeGenerateAck....==============================================\n"));
   1037 
   1038 	 wdrv_aeWSourceDbGetAckTemplate(ackEmul->pAckEmulDB, stationIndex, activeIndex, &pTeplate,&ipHeaderLen, &tcpHeaderLen);
   1039 	 if(ipHeaderLen > 0)
   1040 	 {
   1041 		 newPktLen = ipHeaderLen+tcpHeaderLen;
   1042 		 if(wlan_memMngrAllocMSDU(ackEmul->hMemMngr, &pMsdu,newPktLen+OFFSET_802_3_HDR,(allocatingModule_e)(ACK_EMUL_MODULE+ sizeof(DbTescriptor)))==NOK)
   1043 		 {
   1044 			 WLAN_OS_REPORT(( "WDRV_4X: GenerateAck - fail to allocate buildMsduPtr\n"));
   1045 			 return;
   1046 		 }
   1047 		 pNewPkt = (UINT8*)memMgr_BufData(pMsdu->firstBDPtr)+ sizeof(DbTescriptor);
   1048 
   1049 		 os_memoryCopy(ackEmul->hOs, pNewPkt + OFFSET_802_3_HDR -2,pTeplate + WLAN_HDR_LEN+WLAN_SNAP_HDR_LEN -2,newPktLen+2);
   1050 
   1051 		 /* Extract Info from frame header */
   1052 		 pDot11Header = (dot11_header_t *)pTeplate;
   1053 
   1054 		 pDAddr = (UINT8 *)&pDot11Header->address1;
   1055 		 pSAddr = (UINT8 *)((pDot11Header->fc & DOT11_FC_FROM_DS)? &pDot11Header->address3 : &pDot11Header->address2);
   1056 
   1057 		 pMsdu->firstBDPtr->dataOffset =  sizeof(DbTescriptor);
   1058 		 pMsdu->firstBDPtr->length = newPktLen;
   1059 		 pMsdu->dataLen = newPktLen+OFFSET_802_3_HDR;
   1060 
   1061 		 /* Calclate IP Checksum */
   1062 		 pIpHeader = pNewPkt+OFFSET_802_3_HDR;
   1063 		 ipChecksum = wdrv_IpChecksumCalc(ackEmul, ipHeaderLen,pIpHeader);
   1064 
   1065 		 /* Calclate TCP Checksum */
   1066 		 pTcpHeader = pIpHeader + ipHeaderLen;
   1067 		 *(UINT32*)(pTcpHeader+TCP_ACK_NUMBER_FIELD) = wlan_ntohl(ackNumber);
   1068 		 ipSource = pIpHeader+IP_SRC_ADDRESS_FIELD;
   1069 		 ipDest   = pIpHeader+IP_DEST_ADDRESS_FIELD;
   1070 		 tcpChecksum = wdrv_TcpChecksumCalc(ackEmul, tcpHeaderLen, ipSource, ipDest, pTcpHeader);
   1071 		 /* Add the Checksum to the new packet */
   1072 		 *(UINT16*)(pIpHeader+IP_CHECKSUM_FIELD) = wlan_ntohs(ipChecksum);
   1073 		 *(UINT16*)(pTcpHeader+TCP_CHECKSUM_FIELD) = wlan_ntohs(tcpChecksum);
   1074 
   1075 		 /* Generate 802.3 Header */
   1076 		 os_memoryCopy (ackEmul->hOs, pNewPkt, pDAddr, MAC_ADDR_LEN);
   1077 		 os_memoryCopy (ackEmul->hOs, pNewPkt+MAC_ADDR_LEN, pSAddr, MAC_ADDR_LEN);
   1078 
   1079 		 /* Send the emulated ack to the bss Bridge*/
   1080 		 os_receivePacket(ackEmul->hOs, pMsdu, (UINT16)pMsdu->dataLen);
   1081 	 }
   1082  }
   1083 
   1084  /****************************************************************************
   1085  *                      wdrv_aeSetActive()
   1086  ****************************************************************************
   1087  * DESCRIPTION:	Enable/ Desable Ack Emulation
   1088  *
   1089  * INPUTS:
   1090  *
   1091  * OUTPUT:	None
   1092  *
   1093  * RETURNS:	OK or NOK
   1094  ****************************************************************************/
   1095 
   1096 void wdrv_aeSetActive(ackEmul_t*		ackEmul, int status)
   1097 {
   1098 
   1099 /*   if (status == TRUE)
   1100    {
   1101       (void)whal_apiSetSend4xWackInfo(ackEmul->hWhalCtrl, 0);
   1102       (void)whal_apiEnable4xWackFeature(ackEmul->hWhalCtrl);
   1103    }
   1104    if (status == FALSE)
   1105    {
   1106       (void)whal_apiSetSend4xWackInfo(ackEmul->hWhalCtrl, 0);
   1107       (void)whal_apiDisable4xWackFeature(ackEmul->hWhalCtrl);
   1108    }
   1109 */
   1110       ackEmul->ackEmulationActive = status;
   1111 }
   1112 
   1113 
   1114 
   1115 int wdrv_aeGetActive(ackEmul_t*		ackEmul )
   1116 {
   1117    return(ackEmul->ackEmulationActive);
   1118 }
   1119 
   1120 
   1121 
   1122 /*
   1123 **************************************************************************
   1124 Function: wdrv_IpChecksumCalc
   1125 Description: Calculate the 16 bit IP Checksum.
   1126 ***************************************************************************
   1127 */
   1128 
   1129 
   1130 static UINT16 wdrv_IpChecksumCalc(ackEmul_t*		ackEmul, UINT16 len_ip_header, UINT8 *buff)
   1131 {
   1132 UINT16 word16;
   1133 UINT32 sum=0;
   1134 
   1135 UINT16 i;
   1136 	/* make 16 bit words out of every two adjacent 8 bit words in the packet*/
   1137 	/* and add them up*/
   1138 	for (i=0;i<len_ip_header;i=i+2){
   1139 		word16 = wlan_ntohs(*(UINT16*)(buff+i));
   1140 		sum = sum + (UINT32) word16;
   1141 	}
   1142 
   1143 	/* take only 16 bits out of the 32 bit sum*/
   1144 /*temp = (sum & 0xffff0000)>>16;*/
   1145 sum = (sum & 0x0000ffff)+((sum & 0xffff0000)>>16);
   1146 	/* one's complement the result*/
   1147 	sum = ~sum;
   1148 
   1149 return ((UINT16) sum);
   1150 }
   1151 
   1152 /*
   1153 **************************************************************************
   1154 Function: wdrv_TcpChecksumCalc
   1155 Description: Calculate the 16 bit TCP Checksum.
   1156 ***************************************************************************
   1157 */
   1158 
   1159 static UINT16 wdrv_TcpChecksumCalc(ackEmul_t*		ackEmul, UINT16 len_tcp_header,UINT8 *IpSource, UINT8 *IpDest ,UINT8 *buff)
   1160 {
   1161 UINT16 word16;
   1162 UINT32 sum=0;
   1163 UINT16 i;
   1164 
   1165 
   1166 
   1167 	/* add a padding byte = 0 at the end of packet */
   1168 
   1169 		buff[len_tcp_header]=0;
   1170 
   1171 
   1172 	/* make 16 bit words out of every two adjacent 8 bit words in the packet
   1173 	   and add them up */
   1174 	for (i=0;i<len_tcp_header;i=i+2){
   1175 		word16 = wlan_ntohs(*(UINT16*)(buff+i));
   1176 		sum = sum + (UINT32) word16;
   1177 	}
   1178 
   1179 
   1180    /* add the TCP pseudo header which contains:
   1181       the IP source and destinationn addresses, TCP protocol & TCP length */
   1182 
   1183 
   1184    word16 = wlan_ntohs(*(UINT16*)IpSource);
   1185    sum = sum + (UINT32) word16;
   1186    word16 = wlan_ntohs(*(UINT16*)(IpSource+2));
   1187    sum = sum + (UINT32) word16;
   1188    word16 = wlan_ntohs(*(UINT16*)IpDest);
   1189    sum = sum + (UINT32) word16;
   1190    word16 = wlan_ntohs(*(UINT16*)(IpDest+2));
   1191    sum = sum + (UINT32) word16;
   1192    sum = sum + (UINT32)len_tcp_header + 0x06;
   1193 
   1194 
   1195 
   1196 
   1197       /* take only 16 bits out of the 32 bit sum */
   1198 sum = (sum & 0x0000ffff)+((sum & 0xffff0000)>>16);
   1199 	/* one's complement the result */
   1200 	sum = ~sum;
   1201 
   1202 return ((UINT16) sum);
   1203 }
   1204 
   1205 
   1206