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#include "whalEndpntEnt_api.h"
38
39
40/* debug counters - temporary to remove*/
41UINT32		duplicateMpdu = 0;
42UINT32		msduFreeNotInOrder = 0;
43UINT32		mpduValidFrames = 0;
44UINT32		duplicateMsdu = 0;
45
46
47/*
48 * ----------------------------------------------------------------------------
49 * Function : collectEntryFree
50 *
51 * Input    :
52 * Output   :
53 * Process  :
54 * Note(s)  :
55 * -----------------------------------------------------------------------------
56 */
57static void collectEntryFree (collectEntry_t* pCollectEnt)
58{
59  	pCollectEnt->seqNum		= 0;
60	pCollectEnt->fragNum	= 0;
61  	pCollectEnt->msduPtr 	= NULL;
62  	pCollectEnt->lastBdPtr 	= NULL;
63  	pCollectEnt->timeStamp	= 0;
64  	pCollectEnt->collect 	= FALSE;
65}
66
67/*
68 * ----------------------------------------------------------------------------
69 * Function : whalEndpnt_Create
70 *
71 * Input    :
72 * Output   :
73 * Process  :
74 * Note(s)  :
75 * -----------------------------------------------------------------------------
76 */
77TI_HANDLE whalEndpnt_Create (TI_HANDLE hWhalCtrl, TI_HANDLE hOs)
78{
79	WHAL_ENDPNT* pWhalEndpnt;
80
81	pWhalEndpnt = (WHAL_ENDPNT *)os_memoryAlloc (hOs, sizeof(WHAL_ENDPNT));
82	if (pWhalEndpnt == NULL)
83		return NULL;
84
85	os_memoryZero (hOs, pWhalEndpnt, sizeof(WHAL_ENDPNT));
86
87	pWhalEndpnt->pWhalCtrl = (WHAL_CTRL *)hWhalCtrl;
88	pWhalEndpnt->hOs = hOs;
89
90	return((TI_HANDLE)pWhalEndpnt);
91}
92
93/*
94 * ----------------------------------------------------------------------------
95 * Function : whalEndpnt_Config
96 *
97 * Input    :
98 * Output   :
99 * Process  :
100 * Note(s)  :
101 * -----------------------------------------------------------------------------
102 */
103int whalEndpnt_Config (TI_HANDLE hWhalEndpnt, whalEndpnt_config_t* pWhalEndpntCfg)
104{
105	WHAL_ENDPNT* pWhalEndpnt = (WHAL_ENDPNT *)hWhalEndpnt;
106
107	/* Save configuration parameters */
108	pWhalEndpnt->hReport = pWhalEndpntCfg->hReport;
109	pWhalEndpnt->hMemMngr = pWhalEndpntCfg->hMemMngr;
110
111    return (OK);
112}
113
114/*
115 * ----------------------------------------------------------------------------
116 * Function : whalEndpnt_IsCollect
117 *
118 * Input    :
119 * Output   :
120 * Process  :
121 * Note(s)  :
122 * -----------------------------------------------------------------------------
123 */
124BOOL whalEndpnt_IsCollect (TI_HANDLE hWhalEndpnt)
125{
126	WHAL_ENDPNT* pWhalEndpnt = (WHAL_ENDPNT *)hWhalEndpnt;
127
128	return (pWhalEndpnt->collectEntry.collect);
129}
130
131/*
132 * ----------------------------------------------------------------------------
133 * Function : whalEndpnt_FragCollect
134 *
135 * Input    :
136 * Output   :
137 * Process  :
138 * Note(s)  :
139 * -----------------------------------------------------------------------------
140 */
141collectStatus_e	whalEndpnt_FragCollect (TI_HANDLE hWhalEndpnt, mem_MSDU_T* pMpdu, mem_MSDU_T** pMsdu)
142{
143    dot11_header_t*	pHeader;
144    UINT32          fragNumber;
145    UINT32          seqNumber;
146    UINT32          moreFrag;
147	WHAL_ENDPNT* 	pWhalEndpnt = (WHAL_ENDPNT *)hWhalEndpnt;
148	collectEntry_t* collectEnt 	= &(pWhalEndpnt->collectEntry);
149
150
151	/* initial checking on the received MPDU*/
152	if ((pMpdu == NULL) || (pMpdu->firstBDPtr == NULL) || (pMpdu->lastBDPtr == NULL))
153		WLAN_REPORT_FATAL_ERROR(pWhalEndpnt->hReport, HAL_RX_MODULE_LOG,
154								(" whalEndpnt_FragCollect: original Mpdu pointers with NULL !\n"));
155
156	*pMsdu = NULL;
157	pHeader = (dot11_header_t*)memMgr_MsduHdrAddr(pMpdu);
158
159	fragNumber = (pHeader->seqCtrl & 0x000F);
160    seqNumber  = (pHeader->seqCtrl & 0xFFF0) >> 4;
161    moreFrag = (pHeader->fc & DOT11_FC_MORE_FRAG);
162
163	if ((seqNumber == collectEnt->seqNum) && (collectEnt->collect == TRUE))
164	{
165		/* This MPDU belongs to the current collection of the MSDU */
166        if (fragNumber == (collectEnt->fragNum+1))
167		{
168            /* This is the next MPDU of the current MSDU */
169            /* Update the new MPDU */
170            collectEnt->fragNum++;
171											  /* (!!!YV) to change WLAN_HDR_LEN to pMpdu->headerLen*/
172			collectEnt->msduPtr->dataLen += (pMpdu->dataLen - WLAN_HDR_LEN); /* Update MSDU length */
173            pMpdu->firstBDPtr->dataOffset += WLAN_HDR_LEN; /* Point to the start of the Data */
174            pMpdu->firstBDPtr->length -= WLAN_HDR_LEN;
175
176			/* internal structure checking*/
177			if (collectEnt->lastBdPtr == NULL)
178            {
179				WLAN_REPORT_ERROR(pWhalEndpnt->hReport, HAL_RX_MODULE_LOG,
180								  (" whalEndpnt_FragCollect: collectEnt->lastBdPtr is NULL !!!!!!!!!!\n"));
181				wlan_memMngrFreeMSDU(pWhalEndpnt->hMemMngr, pMpdu->handle);
182				msduFreeNotInOrder++;
183				return MPDU_DUP_DROP;
184            }
185			collectEnt->lastBdPtr->nextBDPtr = pMpdu->firstBDPtr; /* Update the BD list */
186	        collectEnt->lastBdPtr = pMpdu->lastBDPtr;
187			collectEnt->msduPtr->lastBDPtr = pMpdu->lastBDPtr;
188
189			/* Recycle the recieved MPDU header only*/
190			pMpdu->firstBDPtr = NULL;
191			wlan_memMngrFreeMSDU(pWhalEndpnt->hMemMngr, pMpdu->handle);
192
193            mpduValidFrames++;
194        }
195        else if (fragNumber <= collectEnt->fragNum)
196			 {
197				/* Order ERROR or Duplication- NEED to Drop the recieved MPDU */
198				wlan_memMngrFreeMSDU(pWhalEndpnt->hMemMngr, pMpdu->handle);
199				duplicateMpdu++;
200				return MPDU_DUP_DROP;
201	 		 }
202	 		 else
203			 {
204				/* We lost one of the Fragments fragNumber > (collectEnt->fragNum+1)
205				   Need to free all the Fragments of the current MSDU */
206				wlan_memMngrFreeMSDU(pWhalEndpnt->hMemMngr, pMpdu->handle);
207				wlan_memMngrFreeMSDU(pWhalEndpnt->hMemMngr, collectEnt->msduPtr->handle);
208				collectEntryFree (collectEnt);
209				msduFreeNotInOrder++;
210				return MSDU_DROP;
211			 }
212    }
213    else
214	{
215		/* This MPDU is part of a new MSDU */
216        if (collectEnt->collect == TRUE)
217		{
218            /* Still in the middle of collecting the previous MSDU
219               Need to drop the previous MSDU */
220            wlan_memMngrFreeMSDU(pWhalEndpnt->hMemMngr, collectEnt->msduPtr->handle);
221            collectEntryFree (collectEnt);
222            msduFreeNotInOrder++;
223        }
224
225        if (fragNumber != 0)
226		{
227            /* MPDU not in order. This is should first MPDU and must be 0
228			   Need to drop the MPDU */
229            wlan_memMngrFreeMSDU(pWhalEndpnt->hMemMngr, pMpdu->handle);
230            msduFreeNotInOrder++;
231			WLAN_REPORT_INFORMATION(pWhalEndpnt->hReport, HAL_RX_MODULE_LOG,
232							  (" whalEndpnt_FragCollect:  MPDU not in order. fragNumber = %d seqNumber = %d",
233							  fragNumber, seqNumber));
234
235			return MPDU_DROP;
236        }
237
238	/* New MSDU */
239        mpduValidFrames++;
240        collectEnt->msduPtr = pMpdu;
241	    collectEnt->lastBdPtr = pMpdu->lastBDPtr;
242        collectEnt->collect = TRUE;
243        collectEnt->seqNum = seqNumber;
244
245
246    }
247
248    /* Check if the MSDU collection finished */
249    if (!moreFrag)
250	{
251        /* MSDU collection terminated */
252        *pMsdu = collectEnt->msduPtr;
253        collectEntryFree (collectEnt);
254        return MSDU_READY;
255    }
256
257
258    return MSDU_IN_PROGRESS;
259}
260
261/*
262 * ----------------------------------------------------------------------------
263 * Function : whalEndpnt_Destroy
264 *
265 * Input    :
266 * Output   :
267 * Process  :
268 * Note(s)  :
269 * -----------------------------------------------------------------------------
270 */
271int whalEndpnt_Destroy (TI_HANDLE hWhalEndpnt)
272{
273	WHAL_ENDPNT* pWhalEndpnt = (WHAL_ENDPNT *)hWhalEndpnt;
274
275	if (pWhalEndpnt)
276		os_memoryFree (pWhalEndpnt->hOs, pWhalEndpnt, sizeof(WHAL_ENDPNT));
277
278	return (OK);
279}
280
281
282
283
284