PageRenderTime 63ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/net/wireless/tiwlan1251/common/src/core/data_ctrl/Ctrl/4X/DeConcatenator.c

https://bitbucket.org/cyanogenmod/cm-kernel
C | 409 lines | 186 code | 65 blank | 158 comment | 29 complexity | 8b18dd493a02a4120651d5ffd7a7167b MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  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. /* MODULE: */
  38. /* PURPOSE: */
  39. /* */
  40. /***************************************************************************/
  41. #include "DeConcatenator.h"
  42. #include "report.h"
  43. #include "osApi.h"
  44. #include "utils.h"
  45. #include "802_11Defs.h"
  46. #define MAX_DECONACT_LEN 1600 /* Maximum length of real ip packet inside concatination packet */
  47. /*************************************************************************
  48. * concat_create *
  49. **************************************************************************
  50. * DESCRIPTION: This function initializes the Ctrl data module.
  51. *
  52. * INPUT: hOs - handle to Os Abstraction Layer
  53. *
  54. * OUTPUT: TxCmplt_CB - call back function that return to configMngr
  55. * in order to register in the Hal
  56. *
  57. * RETURN: Handle to the allocated Ctrl data control block
  58. ************************************************************************/
  59. deConcatenator_t* deConcat_create(TI_HANDLE hOs)
  60. {
  61. deConcatenator_t* pDeConcatenator;
  62. if( hOs == NULL )
  63. {
  64. WLAN_OS_REPORT(("FATAL ERROR: deConcat_create(): OS handle Error - Aborting\n"));
  65. return NULL;
  66. }
  67. /* alocate concatenator block */
  68. pDeConcatenator = os_memoryAlloc(hOs, (sizeof(deConcatenator_t)));
  69. if (!pDeConcatenator)
  70. {
  71. utils_nullMemoryFree(hOs, pDeConcatenator, sizeof(deConcatenator_t));
  72. WLAN_OS_REPORT(("FATAL ERROR: deConcat_create(): Error Creating DeConcatenator module- Aborting\n"));
  73. return(NULL);
  74. }
  75. /* reset control module control block */
  76. os_memoryZero(hOs, pDeConcatenator, (sizeof(deConcatenator_t)));
  77. pDeConcatenator->hOs = hOs;
  78. return(pDeConcatenator);
  79. }
  80. /***************************************************************************
  81. * ctrlData_config *
  82. ****************************************************************************
  83. * DESCRIPTION: This function configures the Ctrl Data module
  84. *
  85. * INPUTS: hCtrlData - The object
  86. * hOs - Handle to the Os Abstraction Layer
  87. * hReport - Handle to the Report object
  88. * ctrlDataInitParams - pointer to Ctrl module init parameters
  89. * OUTPUT:
  90. *
  91. * RETURNS: OK - Configuration succesfull
  92. * NOK - Configuration unsuccesfull
  93. ***************************************************************************/
  94. TI_STATUS deConcat_config(deConcatenator_t* pDeConcatenator,
  95. TI_HANDLE hOs,
  96. TI_HANDLE hReport,
  97. TI_HANDLE hMemMngr)
  98. {
  99. /* check parameters validity */
  100. if( pDeConcatenator == NULL || hOs == NULL ||
  101. hReport == NULL || hMemMngr == NULL)
  102. {
  103. WLAN_OS_REPORT(("FATAL ERROR: deConcat_config(): Parameters Error - Aborting\n"));
  104. return NOK;
  105. }
  106. /* set objects handles */
  107. pDeConcatenator->hOs = hOs;
  108. pDeConcatenator->hReport = hReport;
  109. pDeConcatenator->hMemMngr = hMemMngr;
  110. WLAN_REPORT_INIT(pDeConcatenator->hReport, DE_CONCATENATOR_MODULE_LOG,
  111. (".....DeConcatenator configured successfully\n"));
  112. return OK;
  113. }
  114. /***************************************************************************
  115. * ctrlData_unLoad *
  116. ****************************************************************************
  117. * DESCRIPTION: This function unload the Ctrl data module.
  118. *
  119. * INPUTS: hCtrlData - the object
  120. *
  121. * OUTPUT:
  122. *
  123. * RETURNS: OK - Unload succesfull
  124. * NOK - Unload unsuccesfull
  125. ***************************************************************************/
  126. TI_STATUS deConcat_destroy(deConcatenator_t* pDeConcatenator)
  127. {
  128. /* free control module controll block */
  129. os_memoryFree(pDeConcatenator->hOs, pDeConcatenator, sizeof(deConcatenator_t));
  130. return OK;
  131. }
  132. /*************************************************************************
  133. * wdrv_rxDeConcatMsdu *
  134. *************************************************************************
  135. DESCRIPTION: This function de concatenates number of MSDUs froma single
  136. MPDU.
  137. INPUT: msduPtr - Pointer to the first MSDU.
  138. OUTPUT:
  139. RETURN: OK : Deconcatenation OK.
  140. NOK: Deconcatenation Faild.
  141. ************************************************************************/
  142. TI_STATUS deConcat_deConcatMsdu(deConcatenator_t* pDeConcatenator,
  143. mem_MSDU_T** MsduPtr)
  144. {
  145. Wdrv4xConcatHeader_t *concatHdrPtr;
  146. dot114xMsdu_t *pdot11fourXHeader;
  147. mem_MSDU_T *firstMsduPtr = NULL;
  148. UINT8 *currPtr;
  149. UINT8 *newDot11HeaderPtr;
  150. UINT16 currentLength;
  151. UINT32 concatLength;
  152. UINT32 rc = OK;
  153. UINT32 parsedLen;
  154. UINT32 msduNum = 0;
  155. BOOL firsdMsduInList = TRUE;
  156. mem_MSDU_T *NextMsduPtr;
  157. mem_MSDU_T *PrevMsduPtr = NULL;
  158. /*print_MsduDataHeader(pDeConcatenator->hMemMngr, *MsduPtr);*/
  159. /*
  160. * The 802.11 header is located in the beggining of the concat frame.
  161. */
  162. pdot11fourXHeader = (dot114xMsdu_t*)memMgr_BufData((*MsduPtr)->firstBDPtr);
  163. concatLength = (*MsduPtr)->dataLen;
  164. /*
  165. * The parsed size is currently the wlan snap and 4x headers.
  166. */
  167. parsedLen = sizeof( dot114xMsdu_t );
  168. currPtr = (UINT8*) pdot11fourXHeader + sizeof(dot114xMsdu_t);
  169. /*
  170. * Start parsing the concatenated MPDU and create an MSDUs.
  171. */
  172. if(parsedLen + sizeof(Wdrv4xConcatHeader_t) >= concatLength)
  173. {
  174. WLAN_REPORT_ERROR(pDeConcatenator->hReport, DE_CONCATENATOR_MODULE_LOG,
  175. ("deConcat_deConcatMsdu: Error Parsing Deconcat Packet: concatLength = %d ",concatLength));
  176. firstMsduPtr = NULL;
  177. rc = NOK;
  178. }
  179. while ( parsedLen + sizeof(Wdrv4xConcatHeader_t) < concatLength )
  180. {
  181. UINT8 numOfPadBytes;
  182. mem_MSDU_T* CurrentMsduPtr;
  183. msduNum++;
  184. concatHdrPtr = (Wdrv4xConcatHeader_t*)currPtr;
  185. currentLength = wlan_htons(concatHdrPtr->len);
  186. if( currentLength > MAX_DECONACT_LEN)
  187. {
  188. WLAN_REPORT_ERROR(pDeConcatenator->hReport, DE_CONCATENATOR_MODULE_LOG,
  189. ("deConcat_deConcatMsdu: Error Parsing Deconcat Packet Len %d ",currentLength));
  190. rc = NOK;
  191. break;
  192. }
  193. currPtr += sizeof(Wdrv4xConcatHeader_t);
  194. /*
  195. * Zero Padding checking.
  196. */
  197. numOfPadBytes = (currentLength+ 2) % 4;
  198. if( numOfPadBytes )
  199. numOfPadBytes = 4 - numOfPadBytes;
  200. /*
  201. * Create MSDU with one buffer for the wlan header.
  202. * and copy the 802.11 header from the MSDU to it.
  203. */
  204. #if 1
  205. /*******************************************************************/
  206. /* Deconcatenation with COPY Solution */
  207. /*******************************************************************/
  208. if( wlan_memMngrAllocMSDU(pDeConcatenator->hMemMngr,
  209. &CurrentMsduPtr,
  210. WLAN_HDR_LEN + currentLength - sizeof(macAddress_t),
  211. DE_CONCAT_MODULE ) != OK)
  212. {
  213. WLAN_REPORT_ERROR(pDeConcatenator->hReport, DE_CONCATENATOR_MODULE_LOG,
  214. ("fail to allocate msdu \n"));
  215. rc = NOK;
  216. break; /* fail to allocate - abort deconcatenation */
  217. }
  218. if(firsdMsduInList == TRUE)
  219. {
  220. firstMsduPtr = CurrentMsduPtr;
  221. firstMsduPtr->prevMSDUinList = NULL;
  222. firsdMsduInList = FALSE;
  223. }
  224. else
  225. {
  226. CurrentMsduPtr->prevMSDUinList = PrevMsduPtr;
  227. PrevMsduPtr->nextMSDUinList = CurrentMsduPtr;
  228. }
  229. CurrentMsduPtr->headerLen = WLAN_HDR_LEN;
  230. newDot11HeaderPtr = (UINT8 *)memMgr_BufData(CurrentMsduPtr->firstBDPtr);
  231. os_memoryCopy(NULL, newDot11HeaderPtr, (char*)pdot11fourXHeader, WLAN_HDR_LEN );
  232. /*
  233. * Copy the SA from the concatenated MSDU to the header.
  234. */
  235. os_memoryCopy(NULL, (void*)&(((dot11_header_t*)newDot11HeaderPtr)->address3),
  236. (void*)&(concatHdrPtr->SaDa),sizeof(macAddress_t) );
  237. /*
  238. * Reading the concatenation More bit, if it is exists, set it in each MSDU's
  239. * order bit. (Used by the Ack emulation)
  240. */
  241. if( pdot11fourXHeader->header4x.txFlags == wlan_htons(WLAN_4X_CONCAT_MORE_BIT) )
  242. ((dot11_header_t*)newDot11HeaderPtr)->fc |= DOT11_FC_ORDER;
  243. else
  244. ((dot11_header_t*)newDot11HeaderPtr)->fc &= ~DOT11_FC_ORDER;
  245. /*
  246. * Copy the SNAP + Payload length to the new data buffer.
  247. * ( 2 copies solution ).
  248. */
  249. os_memoryCopy(NULL, (void*)((UINT32)(newDot11HeaderPtr)+WLAN_HDR_LEN ),
  250. currPtr, currentLength - sizeof(macAddress_t) );
  251. currPtr+= currentLength - sizeof(macAddress_t) + numOfPadBytes;
  252. CurrentMsduPtr->firstBDPtr->length = currentLength - sizeof(macAddress_t) + WLAN_HDR_LEN ;
  253. CurrentMsduPtr->dataLen = CurrentMsduPtr->firstBDPtr->length;
  254. CurrentMsduPtr->firstBDPtr->dataOffset = 0;
  255. CurrentMsduPtr->firstBDPtr->nextBDPtr = NULL;
  256. #else
  257. /*******************************************************************/
  258. /* Deconcatenation with NO COPY Solution */
  259. /*******************************************************************/
  260. if( wlan_memMngrAllocMSDU(pDeConcatenator->hMemMngr, &buildMsduPtr,
  261. sizeof(dot11_header_t),DE_CONCAT_MODULE )==NOK)
  262. {
  263. WLAN_REPORT_ERROR(pDeConcatenator->hReport, DE_CONCATENATOR_MODULE_LOG,
  264. ("fail to allocate msdu \n"));
  265. return NOK;
  266. }
  267. /*
  268. * Copy the 802.11 header to the first buffer. (BssBridge needs the 802.11
  269. * and the SNAP in the same buffer for Ethernet header translation.
  270. */
  271. newDot11HeaderPtr = memMgr_BufData(buildMsduPtr->firstBDPtr);
  272. os_memoryCopy(NULL, newDot11HeaderPtr, (char*)pdot11Header, sizeof(dot11_header_t));
  273. /*
  274. * Copy the SA from the concatenated MSDU to the header.
  275. */
  276. os_memoryCopy(NULL, (void*)&(((dot11_header_t*)newDot11HeaderPtr)->address3),
  277. (void*)&(concatHdrPtr->SaDa),sizeof(macAddress_t) );
  278. /*
  279. * Reading the concatenation More bit, if it is exists, set it in each MSDU's
  280. * order bit. (Used by the Ack emulation)
  281. */
  282. if( pdot11Header->header4x.txFlags == WLAN_4X_CONCAT_MORE_BIT )
  283. ((dot11_header_t*)newDot11HeaderPtr)->fc |= DOT11_FC_ORDER;
  284. else
  285. ((dot11_header_t*)newDot11HeaderPtr)->fc &= ~DOT11_FC_ORDER;
  286. /*
  287. * Copy the SNAP header to the first buffer. (BssBridge needs the 802.11
  288. * and the SNAP in the same buffer for Ethernet header translation.
  289. */
  290. os_memoryCopy(NULL, (void*)((UINT32)(newDot11HeaderPtr)+sizeof(dot11_header_t)),
  291. currPtr, sizeof(Wlan_LlcHeader_T) );
  292. currPtr+= sizeof(Wlan_LlcHeader_T);
  293. buildMsduPtr->firstBDPtr->length = sizeof( dot11_header_t ) + sizeof(Wlan_LlcHeader_T);
  294. /*
  295. * Create a new BD, link it concatenated to the data buffer's SNAP header.
  296. */
  297. if( wlan_memMngrAllocBDs(pDeConcatenator->hMemMngr, 1, &payloadBdPtr) == NOK)
  298. {
  299. WLAN_REPORT_ERROR(pDeConcatenator->hReport, DE_CONCATENATOR_MODULE_LOG,
  300. ("fail to allocate BD \n"));
  301. return NOK;
  302. }
  303. payloadBdPtr->dataBuf = MsduPtr->firstBDPtr->dataBuf;
  304. payloadBdPtr->data = currPtr;
  305. payloadBdPtr->length = currentLength - sizeof(macAddress_t) - sizeof(Wlan_LlcHeader_T);
  306. payloadBdPtr->dataOffset = 0;
  307. payloadBdPtr->nextBDPtr = NULL;
  308. /*
  309. * Link the MSDU first BD (wlan header) to the second one (snap+payload)
  310. * creating a complete MSDU.
  311. */
  312. buildMsduPtr->firstBDPtr->nextBDPtr = payloadBdPtr;
  313. payloadBdPtr->dataBuf->refCount++;
  314. buildMsduPtr->dataLen = buildMsduPtr->firstBDPtr->length + payloadBdPtr->length;
  315. currPtr += currentLength - sizeof(macAddress_t) - sizeof(Wlan_LlcHeader_T) + numOfPadBytes;;
  316. #endif
  317. PrevMsduPtr = CurrentMsduPtr;
  318. parsedLen += currentLength + 2 + numOfPadBytes;
  319. } /* while ( parsedLen < concatLength ) */
  320. /*
  321. * Free the c MSDU.
  322. */
  323. if(rc == OK)
  324. {
  325. wlan_memMngrFreeMSDU(pDeConcatenator->hMemMngr, (*MsduPtr)->handle);
  326. /* update the return msdu */
  327. *MsduPtr = firstMsduPtr;
  328. }
  329. else /* free all allocated MSDUs in case of failure */
  330. {
  331. while(firstMsduPtr)
  332. {
  333. /* Save the next msdu in the list before free the current msdu */
  334. NextMsduPtr = firstMsduPtr->nextMSDUinList;
  335. wlan_memMngrFreeMSDU(pDeConcatenator->hMemMngr, firstMsduPtr->handle);
  336. firstMsduPtr = NextMsduPtr;
  337. }
  338. }
  339. return (TI_STATUS)rc;
  340. }