/wl1271_softAP/stad/src/Data_link/TxDataClsfr.c
C | 777 lines | 477 code | 112 blank | 188 comment | 116 complexity | c636011f3eba9d30e2e58a3652379ea9 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
- /*
- * TxDataClsfr.c
- *
- * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name Texas Instruments nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /** \file txDataClsfr.c
- * \brief The Tx Data Classifier sub-module (under txDataQueue module).
- *
- * \see txDataQueue.h (the classifier uses the same object as txDataQueue)
- */
- #define __FILE_ID__ FILE_ID_59
- #include "paramOut.h"
- #include "osApi.h"
- #include "report.h"
- #include "context.h"
- #include "Ethernet.h"
- #include "TWDriver.h"
- #include "txDataQueue.h"
- /**
- * \fn txDataClsfr_Config
- * \brief Configure the classifier paramters
- *
- * Configure the classifier parameters according to the init parameters.
- * Called from the txDataQueue configuration function.
- *
- * \note
- * \param hTxDataQ - The object handle
- * \param pClsfrInitParams - Pointer to the classifier init params
- * \return TI_OK on success or TI_NOK on failure
- * \sa
- */
- TI_STATUS txDataClsfr_Config (TI_HANDLE hTxDataQ, TClsfrParams *pClsfrInitParams)
- {
- TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
- TClsfrParams *pParams = &pTxDataQ->tClsfrParams; /* where to save the new params */
- TI_UINT32 uActualEntryCount;
- TI_UINT32 i, j;
- TI_BOOL bConflictFound;
-
- /* Active classification algorithm */
- pParams->eClsfrType = pClsfrInitParams->eClsfrType;
- /* the number of active entries */
- if (pClsfrInitParams->uNumActiveEntries <= NUM_OF_CLSFR_TABLE_ENTRIES)
- pParams->uNumActiveEntries = pClsfrInitParams->uNumActiveEntries;
- else
- pParams->uNumActiveEntries = NUM_OF_CLSFR_TABLE_ENTRIES;
- /* Initialization of the classification table */
- switch (pParams->eClsfrType)
- {
- case D_TAG_CLSFR:
- pParams->uNumActiveEntries = 0;
- break;
-
- case DSCP_CLSFR:
- uActualEntryCount=0;
- for (i = 0; i < pParams->uNumActiveEntries; i++)
- {
- bConflictFound = TI_FALSE;
- /* check conflict */
- for (j = 0; j < i; j++)
- {
- /* Detect both duplicate and conflicting entries */
- if (pParams->ClsfrTable[j].Dscp.CodePoint == pClsfrInitParams->ClsfrTable[i].Dscp.CodePoint)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_WARNING , "ERROR: txDataClsfr_Config(): duplicate/conflicting classifier entries\n");
- bConflictFound = TI_TRUE;
- }
- }
- if (bConflictFound == TI_FALSE)
- {
- pParams->ClsfrTable[uActualEntryCount].Dscp.CodePoint = pClsfrInitParams->ClsfrTable[i].Dscp.CodePoint;
- pParams->ClsfrTable[uActualEntryCount].DTag = pClsfrInitParams->ClsfrTable[i].DTag;
- uActualEntryCount++;
- }
- }
- pParams->uNumActiveEntries = uActualEntryCount;
- break;
- case PORT_CLSFR:
- uActualEntryCount=0;
- for (i = 0; (i < pParams->uNumActiveEntries) ; i++)
- {
- bConflictFound = TI_FALSE;
- /* check conflict */
- for (j = 0; j < i; j++)
- {
- /* Detect both duplicate and conflicting entries */
- if (pParams->ClsfrTable[j].Dscp.DstPortNum == pClsfrInitParams->ClsfrTable[i].Dscp.DstPortNum)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_WARNING , "ERROR: txDataClsfr_Config(): classifier entries conflict\n");
- bConflictFound = TI_TRUE;
- }
- }
- if (bConflictFound == TI_FALSE)
- {
- pParams->ClsfrTable[uActualEntryCount].Dscp.DstPortNum = pClsfrInitParams->ClsfrTable[i].Dscp.DstPortNum;
- pParams->ClsfrTable[uActualEntryCount].DTag = pClsfrInitParams->ClsfrTable[i].DTag;
- uActualEntryCount++;
- }
- }
- pParams->uNumActiveEntries = uActualEntryCount;
- break;
- case IPPORT_CLSFR:
- uActualEntryCount=0;
- for (i=0; (i < pParams->uNumActiveEntries ) ; i++)
- {
- bConflictFound = TI_FALSE;
- /* check conflict */
- for (j = 0; j < i; j++)
- {
- /* Detect both duplicate and conflicting entries */
- if ((pParams->ClsfrTable[j].Dscp.DstIPPort.DstIPAddress == pClsfrInitParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress)&&
- (pParams->ClsfrTable[j].Dscp.DstIPPort.DstPortNum == pClsfrInitParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum))
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_WARNING , "ERROR: txDataClsfr_Config(): classifier entries conflict\n");
- bConflictFound = TI_TRUE;
- }
- }
- if (bConflictFound == TI_FALSE)
- {
- pParams->ClsfrTable[uActualEntryCount].Dscp.DstIPPort.DstIPAddress = pClsfrInitParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress;
- pParams->ClsfrTable[uActualEntryCount].Dscp.DstIPPort.DstPortNum = pClsfrInitParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum;
- pParams->ClsfrTable[uActualEntryCount].DTag = pClsfrInitParams->ClsfrTable[i].DTag;
- uActualEntryCount++;
- }
- }
- pParams->uNumActiveEntries = uActualEntryCount;
- break;
- default:
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_WARNING , "ERROR: txDataClsfr_Config(): Classifier type -- unknown --> set to D-Tag\n");
- pParams->eClsfrType = D_TAG_CLSFR;
- pParams->uNumActiveEntries = 0;
- break;
- }
-
- return TI_OK;
- }
- /**
- * \fn getIpAndUdpHeader
- * \brief Get IP & UDP headers addresses if exist
- *
- * This function gets the addresses of the IP and UDP headers
- *
- * \note A local inline function!
- * \param pTxDataQ - The object handle
- * \param pPktCtrlBlk - Pointer to the packet
- * \param pIpHeader - Pointer to pointer to IP header
- * \param pUdpHeader - Pointer to pointer to UDP header
- * \return TI_OK on success, TI_NOK if it's not an IP packet
- * \sa
- */
- static inline TI_STATUS getIpAndUdpHeader(TTxDataQ *pTxDataQ,
- TTxCtrlBlk *pPktCtrlBlk,
- TI_UINT8 **pIpHeader,
- TI_UINT8 **pUdpHeader)
- {
- TI_UINT8 *pEthHead = pPktCtrlBlk->tTxnStruct.aBuf[0];
- TI_UINT8 ipHeaderLen = 0;
-
- /* check if frame is IP according to ether type */
- if( ( HTOWLANS(((TEthernetHeader *)pEthHead)->type) ) != ETHERTYPE_IP && ( HTOWLANS(((TEthernetHeader *)pEthHead)->type) ) != ETHERTYPE_ARP)
- {
- TRACE1(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION, " getIpAndUdpHeader: EthTypeLength is not 0x0800 0x%x\n", (int)HTOWLANS(((TEthernetHeader *)pEthHead)->type));
- return TI_NOK;
- }
- /* set the pointer to the beginning of the IP header and calculate it's size */
- *pIpHeader = pPktCtrlBlk->tTxnStruct.aBuf[1];
- ipHeaderLen = ((*(unsigned char*)(*pIpHeader) & 0x0f) * 4);
- /* Set the pointer to the beggining of the TCP/UDP header */
- if (ipHeaderLen == pPktCtrlBlk->tTxnStruct.aLen[1])
- {
- *pUdpHeader = pPktCtrlBlk->tTxnStruct.aBuf[2];
- }
- else
- {
- *pUdpHeader = *pIpHeader + ipHeaderLen;
- }
- return TI_OK;
- }
- /**
- * \fn txDataClsfr_ClassifyTxPacket
- * \brief Configure the classifier paramters
- *
- * This function classifies the given Tx packet according to the classifier parameters.
- * It sets the TID field with the classification result.
- * The classification is according to one of the following methods:
- * - D-Tag - Transparent (TID = Dtag)
- * - DSCP - According to the DSCP field in the IP header - the default method!
- * - Dest UDP-Port
- * - Dest IP-Addr & UDP-Port
- *
- * \note
- * \param hTxDataQ - The object handle
- * \param pPktCtrlBlk - Pointer to the classified packet
- * \param uPacketDtag - The packet priority optionaly set by the OAL
- * \return TI_OK on success, PARAM_VALUE_NOT_VALID in case of input parameters problems.
- * \sa
- */
- TI_STATUS txDataClsfr_ClassifyTxPacket (TI_HANDLE hTxDataQ, TTxCtrlBlk *pPktCtrlBlk, TI_UINT8 uPacketDtag)
- {
- TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
- TClsfrParams *pClsfrParams = &pTxDataQ->tClsfrParams;
- TI_UINT8 *pUdpHeader = NULL;
- TI_UINT8 *pIpHeader = NULL;
- TI_UINT8 uDscp;
- TI_UINT16 uDstUdpPort;
- TI_UINT32 uDstIpAdd;
- TI_UINT32 i;
- pPktCtrlBlk->tTxDescriptor.tid = 0;
- switch(pClsfrParams->eClsfrType)
- {
- /* Trivial mapping D-tag to D-tag */
- case D_TAG_CLSFR:
- if (uPacketDtag > MAX_NUM_OF_802_1d_TAGS)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR , "txDataClsfr_ClassifyTxPacket(): uPacketDtag error\n");
- return PARAM_VALUE_NOT_VALID;
- }
- pPktCtrlBlk->tTxDescriptor.tid = uPacketDtag;
- TRACE1(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION , "Classifier D_TAG_CLSFR. uPacketDtag = %d\n", uPacketDtag);
- break;
- case DSCP_CLSFR:
- if( (getIpAndUdpHeader(pTxDataQ, pPktCtrlBlk, &pIpHeader, &pUdpHeader) != TI_OK)
- || (pIpHeader == NULL) )
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION , "txDataClsfr_ClassifyTxPacket(): DSCP clsfr, getIpAndUdpHeader mismatch\n");
- return PARAM_VALUE_NOT_VALID;
- }
- /* DSCP to D-tag mapping */
- uDscp = *((TI_UINT8 *)(pIpHeader + 1)); /* Fetching the DSCP from the header */
- uDscp = (uDscp >> 2);
-
- /* looking for the specific DSCP, if found, its corresponding D-tag is set to the TID */
- for(i = 0; i < pClsfrParams->uNumActiveEntries; i++)
- {
- if (pClsfrParams->ClsfrTable[i].Dscp.CodePoint == uDscp)
- {
- pPktCtrlBlk->tTxDescriptor.tid = pClsfrParams->ClsfrTable[i].DTag;
- TRACE2(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION , "Classifier DSCP_CLSFR found match - entry %d - Tid = %d\n",i,pPktCtrlBlk->tTxDescriptor.tid);
- break;
- }
- }
- break;
- case PORT_CLSFR:
- if( (getIpAndUdpHeader(pTxDataQ, pPktCtrlBlk, &pIpHeader, &pUdpHeader) != TI_OK) ||
- (pUdpHeader == NULL) )
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION, " txDataClsfr_ClassifyTxPacket() : DstPort clsfr, getIpAndUdpHeader error\n");
- return PARAM_VALUE_NOT_VALID;
- }
- uDstUdpPort = *((TI_UINT16 *)(pUdpHeader + 2));
- uDstUdpPort = HTOWLANS(uDstUdpPort);
-
- /* Looking for the specific port number. If found, its corresponding D-tag is set to the TID. */
- for(i = 0; i < pClsfrParams->uNumActiveEntries; i++)
- {
- if (pClsfrParams->ClsfrTable[i].Dscp.DstPortNum == uDstUdpPort)
- {
- pPktCtrlBlk->tTxDescriptor.tid = pClsfrParams->ClsfrTable[i].DTag;
- TRACE2(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION , "Classifier PORT_CLSFR found match - entry %d - Tid = %d\n", i, pPktCtrlBlk->tTxDescriptor.tid);
- break;
- }
- }
- break;
- case IPPORT_CLSFR:
- if ( (getIpAndUdpHeader(pTxDataQ, pPktCtrlBlk, &pIpHeader, &pUdpHeader) != TI_OK)
- || (pIpHeader == NULL) || (pUdpHeader == NULL) )
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION, "txDataClsfr_ClassifyTxPacket(): Dst IP&Port clsfr, getIpAndUdpHeader error\n");
- return PARAM_VALUE_NOT_VALID;
- }
- uDstUdpPort = *((TI_UINT16 *)(pUdpHeader + 2));
- uDstUdpPort = HTOWLANS(uDstUdpPort);
- uDstIpAdd = *((TI_UINT32 *)(pIpHeader + 16));
-
- /*
- * Looking for the specific pair of dst IP address and dst port number.
- * If found, its corresponding D-tag is set to the TID.
- */
- for(i = 0; i < pClsfrParams->uNumActiveEntries; i++)
- {
- if ((pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress == uDstIpAdd) &&
- (pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum == uDstUdpPort))
- {
- pPktCtrlBlk->tTxDescriptor.tid = pClsfrParams->ClsfrTable[i].DTag;
- TRACE2(pTxDataQ->hReport, REPORT_SEVERITY_INFORMATION , "Classifier IPPORT_CLSFR found match - entry %d - Tid = %d\n", i, pPktCtrlBlk->tTxDescriptor.tid);
- break;
- }
- }
- break;
-
- default:
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "txDataClsfr_ClassifyTxPacket(): eClsfrType error\n");
- }
- return TI_OK;
- }
- /**
- * \fn txDataClsfr_InsertClsfrEntry
- * \brief Insert a new entry to classifier table
- *
- * Add a new entry to the classification table.
- * If the new entry is invalid or conflicts with existing entries, the operation is canceled.
- *
- * \note
- * \param hTxDataQ - The object handle
- * \param pNewEntry - Pointer to the new entry to insert
- * \return TI_OK on success, PARAM_VALUE_NOT_VALID in case of input parameters problems.
- * \sa txDataClsfr_RemoveClsfrEntry
- */
- TI_STATUS txDataClsfr_InsertClsfrEntry(TI_HANDLE hTxDataQ, TClsfrTableEntry *pNewEntry)
- {
- TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
- TClsfrParams *pClsfrParams = &pTxDataQ->tClsfrParams;
- TI_UINT32 i;
- if(pNewEntry == NULL)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): NULL ConfigBuffer pointer Error - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
-
- /* If no available entries, exit */
- if (pClsfrParams->uNumActiveEntries == NUM_OF_CLSFR_TABLE_ENTRIES)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): Bad Number Of Entries - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
-
- if (pClsfrParams->eClsfrType == D_TAG_CLSFR)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): D-Tag classifier - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
- /* Check new entry and conflict with existing entries and if OK, insert to classifier table */
- switch (pClsfrParams->eClsfrType)
- {
- case DSCP_CLSFR:
-
- /* Check entry */
- if ( (pNewEntry->Dscp.CodePoint > CLASSIFIER_CODE_POINT_MAX) ||
- (pNewEntry->DTag > CLASSIFIER_DTAG_MAX) )
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): bad parameter - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
-
- /* Check conflict*/
- for (i = 0; i < pClsfrParams->uNumActiveEntries; i++)
- {
- /* Detect both duplicate and conflicting entries */
- if (pClsfrParams->ClsfrTable[i].Dscp.CodePoint == pNewEntry->Dscp.CodePoint)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): classifier entries conflict - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
- }
- /* Insert new entry to classifier table. */
- /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
- context_EnterCriticalSection (pTxDataQ->hContext);
- pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].Dscp.CodePoint = pNewEntry->Dscp.CodePoint;
- pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].DTag = pNewEntry->DTag;
- context_LeaveCriticalSection (pTxDataQ->hContext);
-
- break;
-
- case PORT_CLSFR:
- /* Check entry */
- if ((pNewEntry->DTag > CLASSIFIER_DTAG_MAX) ||
- (pNewEntry->Dscp.DstPortNum > CLASSIFIER_PORT_MAX-1) ||
- (pNewEntry->Dscp.DstPortNum < CLASSIFIER_PORT_MIN) )
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): bad parameter - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
-
- /* Check conflict*/
- for (i = 0; i < pClsfrParams->uNumActiveEntries; i++)
- {
- /* Detect both duplicate and conflicting entries */
- if ((pClsfrParams->ClsfrTable[i].Dscp.DstPortNum == pNewEntry->Dscp.DstPortNum))
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): classifier entries conflict - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
- }
- /* Insert new entry to classifier table. */
- /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
- context_EnterCriticalSection (pTxDataQ->hContext);
- pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].Dscp.DstPortNum = pNewEntry->Dscp.DstPortNum;
- pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].DTag = pNewEntry->DTag;
- context_LeaveCriticalSection (pTxDataQ->hContext);
-
- break;
-
- case IPPORT_CLSFR:
- /* Check entry */
- if ( (pNewEntry->DTag > CLASSIFIER_DTAG_MAX) ||
- (pNewEntry->Dscp.DstIPPort.DstPortNum > CLASSIFIER_PORT_MAX-1) ||
- (pNewEntry->Dscp.DstIPPort.DstPortNum < CLASSIFIER_PORT_MIN) ||
- (pNewEntry->Dscp.DstIPPort.DstIPAddress > CLASSIFIER_IPADDRESS_MAX-1) ||
- (pNewEntry->Dscp.DstIPPort.DstIPAddress < CLASSIFIER_IPADDRESS_MIN+1) )
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): bad parameter - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
- /* Check conflict*/
- for (i = 0; i < pClsfrParams->uNumActiveEntries; i++)
- {
- /* Detect both duplicate and conflicting entries */
- if ( (pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress == pNewEntry->Dscp.DstIPPort.DstIPAddress) &&
- (pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum == pNewEntry->Dscp.DstIPPort.DstPortNum))
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): classifier entries conflict - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
- }
- /* Insert new entry to classifier table */
- /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
- context_EnterCriticalSection (pTxDataQ->hContext);
- pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].Dscp.DstIPPort.DstIPAddress = pNewEntry->Dscp.DstIPPort.DstIPAddress;
- pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].Dscp.DstIPPort.DstPortNum = pNewEntry->Dscp.DstIPPort.DstPortNum;
- pClsfrParams->ClsfrTable[pClsfrParams->uNumActiveEntries].DTag = pNewEntry->DTag;
- context_LeaveCriticalSection (pTxDataQ->hContext);
- break;
- default:
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): Classifier type -- unknown - Aborting\n");
-
- }
-
- /* Increment the number of classifier active entries */
- pClsfrParams->uNumActiveEntries++;
- return TI_OK;
- }
- /**
- * \fn txDataClsfr_RemoveClsfrEntry
- * \brief Remove an entry from classifier table
- *
- * Remove an entry from classifier table.
- *
- * \note
- * \param hTxDataQ - The object handle
- * \param pRemEntry - Pointer to the entry to remove
- * \return TI_OK on success, PARAM_VALUE_NOT_VALID in case of input parameters problems.
- * \sa txDataClsfr_InsertClsfrEntry
- */
- TI_STATUS txDataClsfr_RemoveClsfrEntry(TI_HANDLE hTxDataQ, TClsfrTableEntry *pRemEntry)
- {
- TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
- TClsfrParams *pClsfrParams = &pTxDataQ->tClsfrParams;
- TI_UINT32 i, j;
- if(pRemEntry == NULL)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): NULL ConfigBuffer pointer Error - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
-
- if (pClsfrParams->uNumActiveEntries == 0)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): Classifier table is empty - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
-
- if (pClsfrParams->eClsfrType == D_TAG_CLSFR)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): D-Tag classifier - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
- /* Check conflicts with classifier table entries */
- /* check all conflicts, if all entries are TI_OK --> insert to classifier table*/
-
- switch (pClsfrParams->eClsfrType)
- {
- case DSCP_CLSFR:
- /* Find the classifier entry */
- i = 0;
- while ((i < pClsfrParams->uNumActiveEntries) &&
- ((pClsfrParams->ClsfrTable[i].Dscp.CodePoint != pRemEntry->Dscp.CodePoint) ||
- (pClsfrParams->ClsfrTable[i].DTag != pRemEntry->DTag)))
- {
- i++;
- }
- /* If we have reached the number of active entries, it means we couldn't find the requested entry */
- if (i == pClsfrParams->uNumActiveEntries)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): Entry not found - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
- /* Shift all entries above the removed one downward */
- /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
- context_EnterCriticalSection (pTxDataQ->hContext);
- for (j = i; j < pClsfrParams->uNumActiveEntries - 1; j++)
- {
- /* Move entries */
- pClsfrParams->ClsfrTable[j].Dscp.CodePoint = pClsfrParams->ClsfrTable[j+1].Dscp.CodePoint;
- pClsfrParams->ClsfrTable[j].DTag = pClsfrParams->ClsfrTable[j+1].DTag;
- }
- context_LeaveCriticalSection (pTxDataQ->hContext);
-
- break;
-
- case PORT_CLSFR:
- /* Find the classifier entry */
- i = 0;
- while ((i < pClsfrParams->uNumActiveEntries) &&
- ((pClsfrParams->ClsfrTable[i].Dscp.DstPortNum != pRemEntry->Dscp.DstPortNum) ||
- (pClsfrParams->ClsfrTable[i].DTag != pRemEntry->DTag)))
- {
- i++;
- }
- /* If we have reached the number of active entries, it means we couldn't find the requested entry */
- if (i == pClsfrParams->uNumActiveEntries)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): Entry not found - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
- /* Shift all entries above the removed one downward */
- /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
- context_EnterCriticalSection (pTxDataQ->hContext);
- for (j = i; j < pClsfrParams->uNumActiveEntries - 1; j++)
- {
- pClsfrParams->ClsfrTable[j].Dscp.DstPortNum = pClsfrParams->ClsfrTable[j+1].Dscp.DstPortNum;
- pClsfrParams->ClsfrTable[j].DTag = pClsfrParams->ClsfrTable[j+1].DTag;
- }
- context_LeaveCriticalSection (pTxDataQ->hContext);
-
- break;
-
- case IPPORT_CLSFR:
- /* Find the classifier entry */
- i = 0;
- while ((i < pClsfrParams->uNumActiveEntries) &&
- ((pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress != pRemEntry->Dscp.DstIPPort.DstIPAddress) ||
- (pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum != pRemEntry->Dscp.DstIPPort.DstPortNum) ||
- (pClsfrParams->ClsfrTable[i].DTag != pRemEntry->DTag)))
- {
- i++;
- }
- /* If we have reached the number of active entries, it means we couldn't find the requested entry */
- if (i == pClsfrParams->uNumActiveEntries)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): Entry not found - Aborting\n");
- return PARAM_VALUE_NOT_VALID;
- }
- /* Shift all entries above the removed one downward. */
- /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
- context_EnterCriticalSection (pTxDataQ->hContext);
- for (j = i; j < pClsfrParams->uNumActiveEntries - 1; j++)
- {
- pClsfrParams->ClsfrTable[j].Dscp.DstIPPort.DstIPAddress = pClsfrParams->ClsfrTable[j+1].Dscp.DstIPPort.DstIPAddress;
- pClsfrParams->ClsfrTable[j].Dscp.DstIPPort.DstPortNum = pClsfrParams->ClsfrTable[j+1].Dscp.DstIPPort.DstPortNum;
- pClsfrParams->ClsfrTable[j].DTag = pClsfrParams->ClsfrTable[j+1].DTag;
- }
- context_LeaveCriticalSection (pTxDataQ->hContext);
- break;
- default:
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "classifier_RemoveClsfrEntry(): Classifier type -- unknown - Aborting\n");
- }
-
- /* Decrement the number of classifier active entries */
- pClsfrParams->uNumActiveEntries--;
- return TI_OK;
- }
- /**
- * \fn txDataClsfr_SetClsfrType & txDataClsfr_GetClsfrType
- * \brief Set / Get classifier type
- *
- * Set / Get classifier type.
- * When setting type, the table is emptied!
- *
- * \note
- * \param hTxDataQ - The object handle
- * \param eNewClsfrType - New type
- * \return TI_OK on success, PARAM_VALUE_NOT_VALID in case of input parameters problems.
- * \sa
- */
- TI_STATUS txDataClsfr_SetClsfrType (TI_HANDLE hTxDataQ, EClsfrType eNewClsfrType)
- {
- TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
- if (eNewClsfrType > CLSFR_TYPE_MAX)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_setClsfrType(): classifier type exceed its MAX \n");
- return PARAM_VALUE_NOT_VALID;
- }
-
- if (pTxDataQ->tClsfrParams.eClsfrType == eNewClsfrType)
- {
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_WARNING, "Classifier_setClsfrType(): equal classifier type --> will empty classifier table \n");
- }
-
- /* Update type and empty table. */
- /* Note: Protect from txDataClsfr_ClassifyTxPacket context preemption. */
- context_EnterCriticalSection (pTxDataQ->hContext);
- pTxDataQ->tClsfrParams.eClsfrType = eNewClsfrType;
- pTxDataQ->tClsfrParams.uNumActiveEntries = 0;
- context_LeaveCriticalSection (pTxDataQ->hContext);
- return TI_OK;
- }
- TI_STATUS txDataClsfr_GetClsfrType (TI_HANDLE hTxDataQ, EClsfrType *pClsfrType)
- {
- TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
- *pClsfrType = pTxDataQ->tClsfrParams.eClsfrType;
- return TI_OK;
- }
- #ifdef TI_DBG
- /**
- * \fn txDataClsfr_PrintClsfrTable
- * \brief Print classifier table
- *
- * Print the classifier table for debug
- *
- * \note
- * \param hTxDataQ - The object handle
- * \return void
- * \sa
- */
- void txDataClsfr_PrintClsfrTable (TI_HANDLE hTxDataQ)
- {
- TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
- TClsfrParams *pClsfrParams = &pTxDataQ->tClsfrParams;
- TI_UINT32 uIpAddr, i;
- if (pClsfrParams->eClsfrType == D_TAG_CLSFR)
- {
- WLAN_OS_REPORT (("D_TAG classifier type selected...Nothing to print...\n"));
- return;
- }
- WLAN_OS_REPORT (("Number of active entries in classifier table : %d\n",pClsfrParams->uNumActiveEntries));
- switch (pClsfrParams->eClsfrType)
- {
- case DSCP_CLSFR:
- WLAN_OS_REPORT (("+------+-------+\n"));
- WLAN_OS_REPORT (("| Code | D-Tag |\n"));
- WLAN_OS_REPORT (("+------+-------+\n"));
- for (i = 0; i < pClsfrParams->uNumActiveEntries; i++)
- {
- WLAN_OS_REPORT (("| %5d | %5d |\n",
- pClsfrParams->ClsfrTable[i].Dscp.CodePoint,pClsfrParams->ClsfrTable[i].DTag));
- }
- WLAN_OS_REPORT (("+-------+-------+\n"));
- break;
- case PORT_CLSFR:
- WLAN_OS_REPORT (("+-------+-------+\n"));
- WLAN_OS_REPORT (("| Port | D-Tag |\n"));
- WLAN_OS_REPORT (("+-------+-------+\n"));
- for (i = 0; i < pClsfrParams->uNumActiveEntries; i++)
- {
- WLAN_OS_REPORT (("| %5d | %5d |\n",
- pClsfrParams->ClsfrTable[i].Dscp.DstPortNum,pClsfrParams->ClsfrTable[i].DTag));
- }
- WLAN_OS_REPORT (("+-------+-------+\n"));
- break;
- case IPPORT_CLSFR:
- WLAN_OS_REPORT (("+-------------+-------+-------+\n"));
- WLAN_OS_REPORT (("| IP Address | Port | D-Tag |\n"));
- WLAN_OS_REPORT (("+-------------+-------+-------+\n"));
- for (i = 0; i < pClsfrParams->uNumActiveEntries; i++)
- {
- uIpAddr = pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress;
- WLAN_OS_REPORT (("| %02x.%02x.%02x.%02x | %5d | %5d |\n",
- (uIpAddr & 0xFF),((uIpAddr >> 8) & (0xFF)),((uIpAddr >> 16) & (0xFF)),((uIpAddr >> 24) & (0xFF)),
- pClsfrParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum, pClsfrParams->ClsfrTable[i].DTag));
- }
- WLAN_OS_REPORT (("+-------------+-------+-------+\n"));
- break;
- default:
- TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_ERROR, "Classifier_InsertClsfrEntry(): Classifier type -- unknown - Aborting\n");
- break;
- }
- }
- #endif /* TI_DBG */