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