PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/wl1271_softAP/stad/src/Data_link/TxDataClsfr.c

https://github.com/MiniCMX/android_hardware_ti_wlan
C | 777 lines | 477 code | 112 blank | 188 comment | 116 complexity | c636011f3eba9d30e2e58a3652379ea9 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. /*
  2. * TxDataClsfr.c
  3. *
  4. * Copyright(c) 1998 - 2010 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. /** \file txDataClsfr.c
  34. * \brief The Tx Data Classifier sub-module (under txDataQueue module).
  35. *
  36. * \see txDataQueue.h (the classifier uses the same object as txDataQueue)
  37. */
  38. #define __FILE_ID__ FILE_ID_59
  39. #include "paramOut.h"
  40. #include "osApi.h"
  41. #include "report.h"
  42. #include "context.h"
  43. #include "Ethernet.h"
  44. #include "TWDriver.h"
  45. #include "txDataQueue.h"
  46. /**
  47. * \fn txDataClsfr_Config
  48. * \brief Configure the classifier paramters
  49. *
  50. * Configure the classifier parameters according to the init parameters.
  51. * Called from the txDataQueue configuration function.
  52. *
  53. * \note
  54. * \param hTxDataQ - The object handle
  55. * \param pClsfrInitParams - Pointer to the classifier init params
  56. * \return TI_OK on success or TI_NOK on failure
  57. * \sa
  58. */
  59. TI_STATUS txDataClsfr_Config (TI_HANDLE hTxDataQ, TClsfrParams *pClsfrInitParams)
  60. {
  61. TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
  62. TClsfrParams *pParams = &pTxDataQ->tClsfrParams; /* where to save the new params */
  63. TI_UINT32 uActualEntryCount;
  64. TI_UINT32 i, j;
  65. TI_BOOL bConflictFound;
  66. /* Active classification algorithm */
  67. pParams->eClsfrType = pClsfrInitParams->eClsfrType;
  68. /* the number of active entries */
  69. if (pClsfrInitParams->uNumActiveEntries <= NUM_OF_CLSFR_TABLE_ENTRIES)
  70. pParams->uNumActiveEntries = pClsfrInitParams->uNumActiveEntries;
  71. else
  72. pParams->uNumActiveEntries = NUM_OF_CLSFR_TABLE_ENTRIES;
  73. /* Initialization of the classification table */
  74. switch (pParams->eClsfrType)
  75. {
  76. case D_TAG_CLSFR:
  77. pParams->uNumActiveEntries = 0;
  78. break;
  79. case DSCP_CLSFR:
  80. uActualEntryCount=0;
  81. for (i = 0; i < pParams->uNumActiveEntries; i++)
  82. {
  83. bConflictFound = TI_FALSE;
  84. /* check conflict */
  85. for (j = 0; j < i; j++)
  86. {
  87. /* Detect both duplicate and conflicting entries */
  88. if (pParams->ClsfrTable[j].Dscp.CodePoint == pClsfrInitParams->ClsfrTable[i].Dscp.CodePoint)
  89. {
  90. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_WARNING , "ERROR: txDataClsfr_Config(): duplicate/conflicting classifier entries\n");
  91. bConflictFound = TI_TRUE;
  92. }
  93. }
  94. if (bConflictFound == TI_FALSE)
  95. {
  96. pParams->ClsfrTable[uActualEntryCount].Dscp.CodePoint = pClsfrInitParams->ClsfrTable[i].Dscp.CodePoint;
  97. pParams->ClsfrTable[uActualEntryCount].DTag = pClsfrInitParams->ClsfrTable[i].DTag;
  98. uActualEntryCount++;
  99. }
  100. }
  101. pParams->uNumActiveEntries = uActualEntryCount;
  102. break;
  103. case PORT_CLSFR:
  104. uActualEntryCount=0;
  105. for (i = 0; (i < pParams->uNumActiveEntries) ; i++)
  106. {
  107. bConflictFound = TI_FALSE;
  108. /* check conflict */
  109. for (j = 0; j < i; j++)
  110. {
  111. /* Detect both duplicate and conflicting entries */
  112. if (pParams->ClsfrTable[j].Dscp.DstPortNum == pClsfrInitParams->ClsfrTable[i].Dscp.DstPortNum)
  113. {
  114. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_WARNING , "ERROR: txDataClsfr_Config(): classifier entries conflict\n");
  115. bConflictFound = TI_TRUE;
  116. }
  117. }
  118. if (bConflictFound == TI_FALSE)
  119. {
  120. pParams->ClsfrTable[uActualEntryCount].Dscp.DstPortNum = pClsfrInitParams->ClsfrTable[i].Dscp.DstPortNum;
  121. pParams->ClsfrTable[uActualEntryCount].DTag = pClsfrInitParams->ClsfrTable[i].DTag;
  122. uActualEntryCount++;
  123. }
  124. }
  125. pParams->uNumActiveEntries = uActualEntryCount;
  126. break;
  127. case IPPORT_CLSFR:
  128. uActualEntryCount=0;
  129. for (i=0; (i < pParams->uNumActiveEntries ) ; i++)
  130. {
  131. bConflictFound = TI_FALSE;
  132. /* check conflict */
  133. for (j = 0; j < i; j++)
  134. {
  135. /* Detect both duplicate and conflicting entries */
  136. if ((pParams->ClsfrTable[j].Dscp.DstIPPort.DstIPAddress == pClsfrInitParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress)&&
  137. (pParams->ClsfrTable[j].Dscp.DstIPPort.DstPortNum == pClsfrInitParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum))
  138. {
  139. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_WARNING , "ERROR: txDataClsfr_Config(): classifier entries conflict\n");
  140. bConflictFound = TI_TRUE;
  141. }
  142. }
  143. if (bConflictFound == TI_FALSE)
  144. {
  145. pParams->ClsfrTable[uActualEntryCount].Dscp.DstIPPort.DstIPAddress = pClsfrInitParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress;
  146. pParams->ClsfrTable[uActualEntryCount].Dscp.DstIPPort.DstPortNum = pClsfrInitParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum;
  147. pParams->ClsfrTable[uActualEntryCount].DTag = pClsfrInitParams->ClsfrTable[i].DTag;
  148. uActualEntryCount++;
  149. }
  150. }
  151. pParams->uNumActiveEntries = uActualEntryCount;
  152. break;
  153. default:
  154. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_WARNING , "ERROR: txDataClsfr_Config(): Classifier type -- unknown --> set to D-Tag\n");
  155. pParams->eClsfrType = D_TAG_CLSFR;
  156. pParams->uNumActiveEntries = 0;
  157. break;
  158. }
  159. return TI_OK;
  160. }
  161. /**
  162. * \fn getIpAndUdpHeader
  163. * \brief Get IP & UDP headers addresses if exist
  164. *
  165. * This function gets the addresses of the IP and UDP headers
  166. *
  167. * \note A local inline function!
  168. * \param pTxDataQ - The object handle
  169. * \param pPktCtrlBlk - Pointer to the packet
  170. * \param pIpHeader - Pointer to pointer to IP header
  171. * \param pUdpHeader - Pointer to pointer to UDP header
  172. * \return TI_OK on success, TI_NOK if it's not an IP packet
  173. * \sa
  174. */
  175. static inline TI_STATUS getIpAndUdpHeader(TTxDataQ *pTxDataQ,
  176. TTxCtrlBlk *pPktCtrlBlk,
  177. TI_UINT8 **pIpHeader,
  178. TI_UINT8 **pUdpHeader)
  179. {
  180. TI_UINT8 *pEthHead = pPktCtrlBlk->tTxnStruct.aBuf[0];
  181. TI_UINT8 ipHeaderLen = 0;
  182. /* check if frame is IP according to ether type */
  183. if( ( HTOWLANS(((TEthernetHeader *)pEthHead)->type) ) != ETHERTYPE_IP && ( HTOWLANS(((TEthernetHeader *)pEthHead)->type) ) != ETHERTYPE_ARP)
  184. {
  185. TRACE1(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION, " getIpAndUdpHeader: EthTypeLength is not 0x0800 0x%x\n", (int)HTOWLANS(((TEthernetHeader *)pEthHead)->type));
  186. return TI_NOK;
  187. }
  188. /* set the pointer to the beginning of the IP header and calculate it's size */
  189. *pIpHeader = pPktCtrlBlk->tTxnStruct.aBuf[1];
  190. ipHeaderLen = ((*(unsigned char*)(*pIpHeader) & 0x0f) * 4);
  191. /* Set the pointer to the beggining of the TCP/UDP header */
  192. if (ipHeaderLen == pPktCtrlBlk->tTxnStruct.aLen[1])
  193. {
  194. *pUdpHeader = pPktCtrlBlk->tTxnStruct.aBuf[2];
  195. }
  196. else
  197. {
  198. *pUdpHeader = *pIpHeader + ipHeaderLen;
  199. }
  200. return TI_OK;
  201. }
  202. /**
  203. * \fn txDataClsfr_ClassifyTxPacket
  204. * \brief Configure the classifier paramters
  205. *
  206. * This function classifies the given Tx packet according to the classifier parameters.
  207. * It sets the TID field with the classification result.
  208. * The classification is according to one of the following methods:
  209. * - D-Tag - Transparent (TID = Dtag)
  210. * - DSCP - According to the DSCP field in the IP header - the default method!
  211. * - Dest UDP-Port
  212. * - Dest IP-Addr & UDP-Port
  213. *
  214. * \note
  215. * \param hTxDataQ - The object handle
  216. * \param pPktCtrlBlk - Pointer to the classified packet
  217. * \param uPacketDtag - The packet priority optionaly set by the OAL
  218. * \return TI_OK on success, PARAM_VALUE_NOT_VALID in case of input parameters problems.
  219. * \sa
  220. */
  221. TI_STATUS txDataClsfr_ClassifyTxPacket (TI_HANDLE hTxDataQ, TTxCtrlBlk *pPktCtrlBlk, TI_UINT8 uPacketDtag)
  222. {
  223. TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
  224. TClsfrParams *pClsfrParams = &pTxDataQ->tClsfrParams;
  225. TI_UINT8 *pUdpHeader = NULL;
  226. TI_UINT8 *pIpHeader = NULL;
  227. TI_UINT8 uDscp;
  228. TI_UINT16 uDstUdpPort;
  229. TI_UINT32 uDstIpAdd;
  230. TI_UINT32 i;
  231. pPktCtrlBlk->tTxDescriptor.tid = 0;
  232. switch(pClsfrParams->eClsfrType)
  233. {
  234. /* Trivial mapping D-tag to D-tag */
  235. case D_TAG_CLSFR:
  236. if (uPacketDtag > MAX_NUM_OF_802_1d_TAGS)
  237. {
  238. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR , "txDataClsfr_ClassifyTxPacket(): uPacketDtag error\n");
  239. return PARAM_VALUE_NOT_VALID;
  240. }
  241. pPktCtrlBlk->tTxDescriptor.tid = uPacketDtag;
  242. TRACE1(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION , "Classifier D_TAG_CLSFR. uPacketDtag = %d\n", uPacketDtag);
  243. break;
  244. case DSCP_CLSFR:
  245. if( (getIpAndUdpHeader(pTxDataQ, pPktCtrlBlk, &pIpHeader, &pUdpHeader) != TI_OK)
  246. || (pIpHeader == NULL) )
  247. {
  248. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION , "txDataClsfr_ClassifyTxPacket(): DSCP clsfr, getIpAndUdpHeader mismatch\n");
  249. return PARAM_VALUE_NOT_VALID;
  250. }
  251. /* DSCP to D-tag mapping */
  252. uDscp = *((TI_UINT8 *)(pIpHeader + 1)); /* Fetching the DSCP from the header */
  253. uDscp = (uDscp >> 2);
  254. /* looking for the specific DSCP, if found, its corresponding D-tag is set to the TID */
  255. for(i = 0; i < pClsfrParams->uNumActiveEntries; i++)
  256. {
  257. if (pClsfrParams->ClsfrTable[i].Dscp.CodePoint == uDscp)
  258. {
  259. pPktCtrlBlk->tTxDescriptor.tid = pClsfrParams->ClsfrTable[i].DTag;
  260. TRACE2(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION , "Classifier DSCP_CLSFR found match - entry %d - Tid = %d\n",i,pPktCtrlBlk->tTxDescriptor.tid);
  261. break;
  262. }
  263. }
  264. break;
  265. case PORT_CLSFR:
  266. if( (getIpAndUdpHeader(pTxDataQ, pPktCtrlBlk, &pIpHeader, &pUdpHeader) != TI_OK) ||
  267. (pUdpHeader == NULL) )
  268. {
  269. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION, " txDataClsfr_ClassifyTxPacket() : DstPort clsfr, getIpAndUdpHeader error\n");
  270. return PARAM_VALUE_NOT_VALID;
  271. }
  272. uDstUdpPort = *((TI_UINT16 *)(pUdpHeader + 2));
  273. uDstUdpPort = HTOWLANS(uDstUdpPort);
  274. /* Looking for the specific port number. If found, its corresponding D-tag is set to the TID. */
  275. for(i = 0; i < pClsfrParams->uNumActiveEntries; i++)
  276. {
  277. if (pClsfrParams->ClsfrTable[i].Dscp.DstPortNum == uDstUdpPort)
  278. {
  279. pPktCtrlBlk->tTxDescriptor.tid = pClsfrParams->ClsfrTable[i].DTag;
  280. TRACE2(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION , "Classifier PORT_CLSFR found match - entry %d - Tid = %d\n", i, pPktCtrlBlk->tTxDescriptor.tid);
  281. break;
  282. }
  283. }
  284. break;
  285. case IPPORT_CLSFR:
  286. if ( (getIpAndUdpHeader(pTxDataQ, pPktCtrlBlk, &pIpHeader, &pUdpHeader) != TI_OK)
  287. || (pIpHeader == NULL) || (pUdpHeader == NULL) )
  288. {
  289. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION, "txDataClsfr_ClassifyTxPacket(): Dst IP&Port clsfr, getIpAndUdpHeader error\n");
  290. return PARAM_VALUE_NOT_VALID;
  291. }
  292. uDstUdpPort = *((TI_UINT16 *)(pUdpHeader + 2));
  293. uDstUdpPort = HTOWLANS(uDstUdpPort);
  294. uDstIpAdd = *((TI_UINT32 *)(pIpHeader + 16));
  295. /*
  296. * Looking for the specific pair of dst IP address and dst port number.
  297. * If found, its corresponding D-tag is set to the TID.
  298. */
  299. for(i = 0; i < pClsfrParams->uNumActiveEntries; i++)
  300. {
  301. if ((pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress == uDstIpAdd) &&
  302. (pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum == uDstUdpPort))
  303. {
  304. pPktCtrlBlk->tTxDescriptor.tid = pClsfrParams->ClsfrTable[i].DTag;
  305. TRACE2(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION , "Classifier IPPORT_CLSFR found match - entry %d - Tid = %d\n", i, pPktCtrlBlk->tTxDescriptor.tid);
  306. break;
  307. }
  308. }
  309. break;
  310. default:
  311. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "txDataClsfr_ClassifyTxPacket(): eClsfrType error\n");
  312. }
  313. return TI_OK;
  314. }
  315. /**
  316. * \fn txDataClsfr_InsertClsfrEntry
  317. * \brief Insert a new entry to classifier table
  318. *
  319. * Add a new entry to the classification table.
  320. * If the new entry is invalid or conflicts with existing entries, the operation is canceled.
  321. *
  322. * \note
  323. * \param hTxDataQ - The object handle
  324. * \param pNewEntry - Pointer to the new entry to insert
  325. * \return TI_OK on success, PARAM_VALUE_NOT_VALID in case of input parameters problems.
  326. * \sa txDataClsfr_RemoveClsfrEntry
  327. */
  328. TI_STATUS txDataClsfr_InsertClsfrEntry(TI_HANDLE hTxDataQ, TClsfrTableEntry *pNewEntry)
  329. {
  330. TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
  331. TClsfrParams *pClsfrParams = &pTxDataQ->tClsfrParams;
  332. TI_UINT32 i;
  333. if(pNewEntry == NULL)
  334. {
  335. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): NULL ConfigBuffer pointer Error - Aborting\n");
  336. return PARAM_VALUE_NOT_VALID;
  337. }
  338. /* If no available entries, exit */
  339. if (pClsfrParams->uNumActiveEntries == NUM_OF_CLSFR_TABLE_ENTRIES)
  340. {
  341. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): Bad Number Of Entries - Aborting\n");
  342. return PARAM_VALUE_NOT_VALID;
  343. }
  344. if (pClsfrParams->eClsfrType == D_TAG_CLSFR)
  345. {
  346. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): D-Tag classifier - Aborting\n");
  347. return PARAM_VALUE_NOT_VALID;
  348. }
  349. /* Check new entry and conflict with existing entries and if OK, insert to classifier table */
  350. switch (pClsfrParams->eClsfrType)
  351. {
  352. case DSCP_CLSFR:
  353. /* Check entry */
  354. if ( (pNewEntry->Dscp.CodePoint > CLASSIFIER_CODE_POINT_MAX) ||
  355. (pNewEntry->DTag > CLASSIFIER_DTAG_MAX) )
  356. {
  357. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): bad parameter - Aborting\n");
  358. return PARAM_VALUE_NOT_VALID;
  359. }
  360. /* Check conflict*/
  361. for (i = 0; i < pClsfrParams->uNumActiveEntries; i++)
  362. {
  363. /* Detect both duplicate and conflicting entries */
  364. if (pClsfrParams->ClsfrTable[i].Dscp.CodePoint == pNewEntry->Dscp.CodePoint)
  365. {
  366. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): classifier entries conflict - Aborting\n");
  367. return PARAM_VALUE_NOT_VALID;
  368. }
  369. }
  370. /* Insert new entry to classifier table. */
  371. /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
  372. context_EnterCriticalSection (pTxDataQ->hContext);
  373. pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].Dscp.CodePoint = pNewEntry->Dscp.CodePoint;
  374. pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].DTag = pNewEntry->DTag;
  375. context_LeaveCriticalSection (pTxDataQ->hContext);
  376. break;
  377. case PORT_CLSFR:
  378. /* Check entry */
  379. if ((pNewEntry->DTag > CLASSIFIER_DTAG_MAX) ||
  380. (pNewEntry->Dscp.DstPortNum > CLASSIFIER_PORT_MAX-1) ||
  381. (pNewEntry->Dscp.DstPortNum < CLASSIFIER_PORT_MIN) )
  382. {
  383. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): bad parameter - Aborting\n");
  384. return PARAM_VALUE_NOT_VALID;
  385. }
  386. /* Check conflict*/
  387. for (i = 0; i < pClsfrParams->uNumActiveEntries; i++)
  388. {
  389. /* Detect both duplicate and conflicting entries */
  390. if ((pClsfrParams->ClsfrTable[i].Dscp.DstPortNum == pNewEntry->Dscp.DstPortNum))
  391. {
  392. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): classifier entries conflict - Aborting\n");
  393. return PARAM_VALUE_NOT_VALID;
  394. }
  395. }
  396. /* Insert new entry to classifier table. */
  397. /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
  398. context_EnterCriticalSection (pTxDataQ->hContext);
  399. pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].Dscp.DstPortNum = pNewEntry->Dscp.DstPortNum;
  400. pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].DTag = pNewEntry->DTag;
  401. context_LeaveCriticalSection (pTxDataQ->hContext);
  402. break;
  403. case IPPORT_CLSFR:
  404. /* Check entry */
  405. if ( (pNewEntry->DTag > CLASSIFIER_DTAG_MAX) ||
  406. (pNewEntry->Dscp.DstIPPort.DstPortNum > CLASSIFIER_PORT_MAX-1) ||
  407. (pNewEntry->Dscp.DstIPPort.DstPortNum < CLASSIFIER_PORT_MIN) ||
  408. (pNewEntry->Dscp.DstIPPort.DstIPAddress > CLASSIFIER_IPADDRESS_MAX-1) ||
  409. (pNewEntry->Dscp.DstIPPort.DstIPAddress < CLASSIFIER_IPADDRESS_MIN+1) )
  410. {
  411. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): bad parameter - Aborting\n");
  412. return PARAM_VALUE_NOT_VALID;
  413. }
  414. /* Check conflict*/
  415. for (i = 0; i < pClsfrParams->uNumActiveEntries; i++)
  416. {
  417. /* Detect both duplicate and conflicting entries */
  418. if ( (pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress == pNewEntry->Dscp.DstIPPort.DstIPAddress) &&
  419. (pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum == pNewEntry->Dscp.DstIPPort.DstPortNum))
  420. {
  421. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): classifier entries conflict - Aborting\n");
  422. return PARAM_VALUE_NOT_VALID;
  423. }
  424. }
  425. /* Insert new entry to classifier table */
  426. /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
  427. context_EnterCriticalSection (pTxDataQ->hContext);
  428. pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].Dscp.DstIPPort.DstIPAddress = pNewEntry->Dscp.DstIPPort.DstIPAddress;
  429. pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].Dscp.DstIPPort.DstPortNum = pNewEntry->Dscp.DstIPPort.DstPortNum;
  430. pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].DTag = pNewEntry->DTag;
  431. context_LeaveCriticalSection (pTxDataQ->hContext);
  432. break;
  433. default:
  434. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): Classifier type -- unknown - Aborting\n");
  435. }
  436. /* Increment the number of classifier active entries */
  437. pClsfrParams->uNumActiveEntries++;
  438. return TI_OK;
  439. }
  440. /**
  441. * \fn txDataClsfr_RemoveClsfrEntry
  442. * \brief Remove an entry from classifier table
  443. *
  444. * Remove an entry from classifier table.
  445. *
  446. * \note
  447. * \param hTxDataQ - The object handle
  448. * \param pRemEntry - Pointer to the entry to remove
  449. * \return TI_OK on success, PARAM_VALUE_NOT_VALID in case of input parameters problems.
  450. * \sa txDataClsfr_InsertClsfrEntry
  451. */
  452. TI_STATUS txDataClsfr_RemoveClsfrEntry(TI_HANDLE hTxDataQ, TClsfrTableEntry *pRemEntry)
  453. {
  454. TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
  455. TClsfrParams *pClsfrParams = &pTxDataQ->tClsfrParams;
  456. TI_UINT32 i, j;
  457. if(pRemEntry == NULL)
  458. {
  459. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): NULL ConfigBuffer pointer Error - Aborting\n");
  460. return PARAM_VALUE_NOT_VALID;
  461. }
  462. if (pClsfrParams->uNumActiveEntries == 0)
  463. {
  464. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): Classifier table is empty - Aborting\n");
  465. return PARAM_VALUE_NOT_VALID;
  466. }
  467. if (pClsfrParams->eClsfrType == D_TAG_CLSFR)
  468. {
  469. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): D-Tag classifier - Aborting\n");
  470. return PARAM_VALUE_NOT_VALID;
  471. }
  472. /* Check conflicts with classifier table entries */
  473. /* check all conflicts, if all entries are TI_OK --> insert to classifier table*/
  474. switch (pClsfrParams->eClsfrType)
  475. {
  476. case DSCP_CLSFR:
  477. /* Find the classifier entry */
  478. i = 0;
  479. while ((i < pClsfrParams->uNumActiveEntries) &&
  480. ((pClsfrParams->ClsfrTable[i].Dscp.CodePoint != pRemEntry->Dscp.CodePoint) ||
  481. (pClsfrParams->ClsfrTable[i].DTag != pRemEntry->DTag)))
  482. {
  483. i++;
  484. }
  485. /* If we have reached the number of active entries, it means we couldn't find the requested entry */
  486. if (i == pClsfrParams->uNumActiveEntries)
  487. {
  488. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): Entry not found - Aborting\n");
  489. return PARAM_VALUE_NOT_VALID;
  490. }
  491. /* Shift all entries above the removed one downward */
  492. /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
  493. context_EnterCriticalSection (pTxDataQ->hContext);
  494. for (j = i; j < pClsfrParams->uNumActiveEntries - 1; j++)
  495. {
  496. /* Move entries */
  497. pClsfrParams->ClsfrTable[j].Dscp.CodePoint = pClsfrParams->ClsfrTable[j+1].Dscp.CodePoint;
  498. pClsfrParams->ClsfrTable[j].DTag = pClsfrParams->ClsfrTable[j+1].DTag;
  499. }
  500. context_LeaveCriticalSection (pTxDataQ->hContext);
  501. break;
  502. case PORT_CLSFR:
  503. /* Find the classifier entry */
  504. i = 0;
  505. while ((i < pClsfrParams->uNumActiveEntries) &&
  506. ((pClsfrParams->ClsfrTable[i].Dscp.DstPortNum != pRemEntry->Dscp.DstPortNum) ||
  507. (pClsfrParams->ClsfrTable[i].DTag != pRemEntry->DTag)))
  508. {
  509. i++;
  510. }
  511. /* If we have reached the number of active entries, it means we couldn't find the requested entry */
  512. if (i == pClsfrParams->uNumActiveEntries)
  513. {
  514. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): Entry not found - Aborting\n");
  515. return PARAM_VALUE_NOT_VALID;
  516. }
  517. /* Shift all entries above the removed one downward */
  518. /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
  519. context_EnterCriticalSection (pTxDataQ->hContext);
  520. for (j = i; j < pClsfrParams->uNumActiveEntries - 1; j++)
  521. {
  522. pClsfrParams->ClsfrTable[j].Dscp.DstPortNum = pClsfrParams->ClsfrTable[j+1].Dscp.DstPortNum;
  523. pClsfrParams->ClsfrTable[j].DTag = pClsfrParams->ClsfrTable[j+1].DTag;
  524. }
  525. context_LeaveCriticalSection (pTxDataQ->hContext);
  526. break;
  527. case IPPORT_CLSFR:
  528. /* Find the classifier entry */
  529. i = 0;
  530. while ((i < pClsfrParams->uNumActiveEntries) &&
  531. ((pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress != pRemEntry->Dscp.DstIPPort.DstIPAddress) ||
  532. (pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum != pRemEntry->Dscp.DstIPPort.DstPortNum) ||
  533. (pClsfrParams->ClsfrTable[i].DTag != pRemEntry->DTag)))
  534. {
  535. i++;
  536. }
  537. /* If we have reached the number of active entries, it means we couldn't find the requested entry */
  538. if (i == pClsfrParams->uNumActiveEntries)
  539. {
  540. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): Entry not found - Aborting\n");
  541. return PARAM_VALUE_NOT_VALID;
  542. }
  543. /* Shift all entries above the removed one downward. */
  544. /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
  545. context_EnterCriticalSection (pTxDataQ->hContext);
  546. for (j = i; j < pClsfrParams->uNumActiveEntries - 1; j++)
  547. {
  548. pClsfrParams->ClsfrTable[j].Dscp.DstIPPort.DstIPAddress = pClsfrParams->ClsfrTable[j+1].Dscp.DstIPPort.DstIPAddress;
  549. pClsfrParams->ClsfrTable[j].Dscp.DstIPPort.DstPortNum = pClsfrParams->ClsfrTable[j+1].Dscp.DstIPPort.DstPortNum;
  550. pClsfrParams->ClsfrTable[j].DTag = pClsfrParams->ClsfrTable[j+1].DTag;
  551. }
  552. context_LeaveCriticalSection (pTxDataQ->hContext);
  553. break;
  554. default:
  555. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): Classifier type -- unknown - Aborting\n");
  556. }
  557. /* Decrement the number of classifier active entries */
  558. pClsfrParams->uNumActiveEntries--;
  559. return TI_OK;
  560. }
  561. /**
  562. * \fn txDataClsfr_SetClsfrType & txDataClsfr_GetClsfrType
  563. * \brief Set / Get classifier type
  564. *
  565. * Set / Get classifier type.
  566. * When setting type, the table is emptied!
  567. *
  568. * \note
  569. * \param hTxDataQ - The object handle
  570. * \param eNewClsfrType - New type
  571. * \return TI_OK on success, PARAM_VALUE_NOT_VALID in case of input parameters problems.
  572. * \sa
  573. */
  574. TI_STATUS txDataClsfr_SetClsfrType (TI_HANDLE hTxDataQ, EClsfrType eNewClsfrType)
  575. {
  576. TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
  577. if (eNewClsfrType > CLSFR_TYPE_MAX)
  578. {
  579. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_setClsfrType(): classifier type exceed its MAX \n");
  580. return PARAM_VALUE_NOT_VALID;
  581. }
  582. if (pTxDataQ->tClsfrParams.eClsfrType == eNewClsfrType)
  583. {
  584. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_WARNING, "Classifier_setClsfrType(): equal classifier type --> will empty classifier table \n");
  585. }
  586. /* Update type and empty table. */
  587. /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
  588. context_EnterCriticalSection (pTxDataQ->hContext);
  589. pTxDataQ->tClsfrParams.eClsfrType = eNewClsfrType;
  590. pTxDataQ->tClsfrParams.uNumActiveEntries = 0;
  591. context_LeaveCriticalSection (pTxDataQ->hContext);
  592. return TI_OK;
  593. }
  594. TI_STATUS txDataClsfr_GetClsfrType (TI_HANDLE hTxDataQ, EClsfrType *pClsfrType)
  595. {
  596. TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
  597. *pClsfrType = pTxDataQ->tClsfrParams.eClsfrType;
  598. return TI_OK;
  599. }
  600. #ifdef TI_DBG
  601. /**
  602. * \fn txDataClsfr_PrintClsfrTable
  603. * \brief Print classifier table
  604. *
  605. * Print the classifier table for debug
  606. *
  607. * \note
  608. * \param hTxDataQ - The object handle
  609. * \return void
  610. * \sa
  611. */
  612. void txDataClsfr_PrintClsfrTable (TI_HANDLE hTxDataQ)
  613. {
  614. TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
  615. TClsfrParams *pClsfrParams = &pTxDataQ->tClsfrParams;
  616. TI_UINT32 uIpAddr, i;
  617. if (pClsfrParams->eClsfrType == D_TAG_CLSFR)
  618. {
  619. WLAN_OS_REPORT (("D_TAG classifier type selected...Nothing to print...\n"));
  620. return;
  621. }
  622. WLAN_OS_REPORT (("Number of active entries in classifier table : %d\n",pClsfrParams->uNumActiveEntries));
  623. switch (pClsfrParams->eClsfrType)
  624. {
  625. case DSCP_CLSFR:
  626. WLAN_OS_REPORT (("+------+-------+\n"));
  627. WLAN_OS_REPORT (("| Code | D-Tag |\n"));
  628. WLAN_OS_REPORT (("+------+-------+\n"));
  629. for (i = 0; i < pClsfrParams->uNumActiveEntries; i++)
  630. {
  631. WLAN_OS_REPORT (("| %5d | %5d |\n",
  632. pClsfrParams->ClsfrTable[i].Dscp.CodePoint,pClsfrParams->ClsfrTable[i].DTag));
  633. }
  634. WLAN_OS_REPORT (("+-------+-------+\n"));
  635. break;
  636. case PORT_CLSFR:
  637. WLAN_OS_REPORT (("+-------+-------+\n"));
  638. WLAN_OS_REPORT (("| Port | D-Tag |\n"));
  639. WLAN_OS_REPORT (("+-------+-------+\n"));
  640. for (i = 0; i < pClsfrParams->uNumActiveEntries; i++)
  641. {
  642. WLAN_OS_REPORT (("| %5d | %5d |\n",
  643. pClsfrParams->ClsfrTable[i].Dscp.DstPortNum,pClsfrParams->ClsfrTable[i].DTag));
  644. }
  645. WLAN_OS_REPORT (("+-------+-------+\n"));
  646. break;
  647. case IPPORT_CLSFR:
  648. WLAN_OS_REPORT (("+-------------+-------+-------+\n"));
  649. WLAN_OS_REPORT (("| IP Address | Port | D-Tag |\n"));
  650. WLAN_OS_REPORT (("+-------------+-------+-------+\n"));
  651. for (i = 0; i < pClsfrParams->uNumActiveEntries; i++)
  652. {
  653. uIpAddr = pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress;
  654. WLAN_OS_REPORT (("| %02x.%02x.%02x.%02x | %5d | %5d |\n",
  655. (uIpAddr & 0xFF),((uIpAddr >> 8) & (0xFF)),((uIpAddr >> 16) & (0xFF)),((uIpAddr >> 24) & (0xFF)),
  656. pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum, pClsfrParams->ClsfrTable[i].DTag));
  657. }
  658. WLAN_OS_REPORT (("+-------------+-------+-------+\n"));
  659. break;
  660. default:
  661. TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): Classifier type -- unknown - Aborting\n");
  662. break;
  663. }
  664. }
  665. #endif /* TI_DBG */