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 * file Clsfr.c 38 */ 39 40 #include "paramOut.h" 41 #include "Clsfr.h" 42 #include "utils.h" 43 #include "report.h" 44 45 46 #define ETHERNET_HEADER_SIZE 14 47 48 static TI_STATUS classifier_getIpAndUdpHeader(classifier_t* pClsfr, mem_MSDU_T *pMsdu, UINT8 **pIpHeader, UINT8 **pUdpHeader); 49 50 51 52 /************************************************************************* 53 * Classifier_create * 54 ************************************************************************** 55 * DESCRIPTION: This function creates the Classifier module. 56 * 57 * INPUT: hOs - handle to Os Abstraction Layer 58 * 59 * OUTPUT: Pointer to the Classifier module 60 ************************************************************************/ 61 62 classifier_t* Classifier_create(TI_HANDLE hOs) 63 { 64 classifier_t* pClsfr; 65 66 if( hOs == NULL ) 67 return NULL; 68 69 70 /* alocate classifier block */ 71 pClsfr = os_memoryAlloc(hOs, (sizeof(classifier_t))); 72 73 if (!pClsfr) 74 { 75 utils_nullMemoryFree(hOs, pClsfr, sizeof(classifier_t)); 76 return NULL; 77 } 78 79 /* clear the block */ 80 os_memoryZero(hOs, pClsfr, (sizeof(classifier_t))); 81 82 pClsfr->hOs = hOs; 83 84 return(pClsfr); 85 } 86 87 88 89 /****************************************************************************** 90 * Classifier_config * 91 ******************************************************************************* 92 * DESCRIPTION: This function configures the Classifier module. 93 * 94 * INPUT: hOs, hReport - handle to Os Abstraction Layer and to the Report 95 * 96 * OUTPUT: PARAM_VALUE_NOT_VALID in case of problems with input parameters 97 * and OK otherwise 98 ********************************************************************************/ 99 100 101 TI_STATUS Classifier_config(classifier_t* pClsfr, TI_HANDLE hOs, TI_HANDLE hReport, clsfr_Params_t* ClsfrInitParams) 102 { 103 int i,j,actualEntryCount; 104 BOOL conflictFound; 105 106 /* check parameters validity */ 107 if (pClsfr == NULL) 108 return NOK; 109 110 if ( (hOs == NULL) || (hReport == NULL) ) 111 return NOK; 112 113 /* set objects handles */ 114 pClsfr->hOs = hOs; 115 pClsfr->hReport = hReport; 116 117 /* Active classification algorithm */ 118 pClsfr->clsfrParameters.clsfrType = ClsfrInitParams->clsfrType; 119 120 /* the number of active entries */ 121 if (ClsfrInitParams->NumOfActiveEntries <= NUM_OF_CLSFR_TABLE_ENTRIES) 122 pClsfr->clsfrParameters.NumOfActiveEntries = ClsfrInitParams->NumOfActiveEntries; 123 else 124 pClsfr->clsfrParameters.NumOfActiveEntries = NUM_OF_CLSFR_TABLE_ENTRIES; 125 126 /* Initialization of the classification table */ 127 switch (pClsfr->clsfrParameters.clsfrType) 128 { 129 case D_TAG_CLSFR: 130 pClsfr->clsfrParameters.NumOfActiveEntries = 0; 131 break; 132 133 case DSCP_CLSFR: 134 actualEntryCount=0; 135 for (i=0; (i < pClsfr->clsfrParameters.NumOfActiveEntries ) ; i++) 136 { 137 conflictFound = FALSE; 138 /* check conflict */ 139 for (j=0;j<i;j++) 140 { 141 /* Detect both duplicate and conflicting entries */ 142 if (pClsfr->clsfrParameters.ClsfrTable[j].Dscp.CodePoint == ClsfrInitParams->ClsfrTable[i].Dscp.CodePoint) 143 { 144 WLAN_REPORT_WARNING (pClsfr->hReport, CLSFR_MODULE_LOG,("ERROR: Classifier_config(): duplicate/conflicting classifier entries\n")); 145 conflictFound = TRUE; 146 } 147 } 148 if (conflictFound == FALSE) 149 { 150 pClsfr->clsfrParameters.ClsfrTable[actualEntryCount].Dscp.CodePoint = ClsfrInitParams->ClsfrTable[i].Dscp.CodePoint; 151 pClsfr->clsfrParameters.ClsfrTable[actualEntryCount].DTag = ClsfrInitParams->ClsfrTable[i].DTag; 152 actualEntryCount++; 153 } 154 } 155 pClsfr->clsfrParameters.NumOfActiveEntries = actualEntryCount; 156 break; 157 case PORT_CLSFR: 158 actualEntryCount=0; 159 for (i=0; (i < pClsfr->clsfrParameters.NumOfActiveEntries ) ; i++) 160 { 161 conflictFound = FALSE; 162 /* check conflict */ 163 for (j=0;j<i;j++) 164 { 165 /* Detect both duplicate and conflicting entries */ 166 if (pClsfr->clsfrParameters.ClsfrTable[j].Dscp.DstPortNum == ClsfrInitParams->ClsfrTable[i].Dscp.DstPortNum) 167 { 168 WLAN_REPORT_WARNING (pClsfr->hReport, CLSFR_MODULE_LOG,("ERROR: Classifier_config(): classifier entries conflict\n")); 169 conflictFound = TRUE; 170 } 171 } 172 if (conflictFound == FALSE) 173 { 174 pClsfr->clsfrParameters.ClsfrTable[actualEntryCount].Dscp.DstPortNum = ClsfrInitParams->ClsfrTable[i].Dscp.DstPortNum; 175 pClsfr->clsfrParameters.ClsfrTable[actualEntryCount].DTag = ClsfrInitParams->ClsfrTable[i].DTag; 176 actualEntryCount++; 177 } 178 } 179 pClsfr->clsfrParameters.NumOfActiveEntries = actualEntryCount; 180 break; 181 case IPPORT_CLSFR: 182 actualEntryCount=0; 183 for (i=0; (i < pClsfr->clsfrParameters.NumOfActiveEntries ) ; i++) 184 { 185 conflictFound = FALSE; 186 /* check conflict */ 187 for (j=0;j<i;j++) 188 { 189 /* Detect both duplicate and conflicting entries */ 190 if ((pClsfr->clsfrParameters.ClsfrTable[j].Dscp.DstIPPort.DstIPAddress == ClsfrInitParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress)&& 191 (pClsfr->clsfrParameters.ClsfrTable[j].Dscp.DstIPPort.DstPortNum == ClsfrInitParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum)) 192 { 193 WLAN_REPORT_WARNING (pClsfr->hReport, CLSFR_MODULE_LOG,("ERROR: Classifier_config(): classifier entries conflict\n")); 194 conflictFound = TRUE; 195 } 196 } 197 if (conflictFound == FALSE) 198 { 199 pClsfr->clsfrParameters.ClsfrTable[actualEntryCount].Dscp.DstIPPort.DstIPAddress = ClsfrInitParams->ClsfrTable[i].Dscp.DstIPPort.DstIPAddress; 200 pClsfr->clsfrParameters.ClsfrTable[actualEntryCount].Dscp.DstIPPort.DstPortNum = ClsfrInitParams->ClsfrTable[i].Dscp.DstIPPort.DstPortNum; 201 pClsfr->clsfrParameters.ClsfrTable[actualEntryCount].DTag = ClsfrInitParams->ClsfrTable[i].DTag; 202 actualEntryCount++; 203 } 204 } 205 pClsfr->clsfrParameters.NumOfActiveEntries = actualEntryCount; 206 break; 207 default: 208 WLAN_REPORT_WARNING (pClsfr->hReport, CLSFR_MODULE_LOG,("ERROR: Classifier_config(): Classifier type -- unknown --> set to D-Tag\n")); 209 pClsfr->clsfrParameters.clsfrType = D_TAG_CLSFR; 210 pClsfr->clsfrParameters.NumOfActiveEntries = 0; 211 } 212 213 return OK; 214 215 } 216 217 218 /****************************************************************************** 219 * Classifier_destroy * 220 ******************************************************************************* 221 * DESCRIPTION: This function destroys the Classifier module. 222 * 223 * INPUT: the object 224 * 225 * OUTPUT: NOK in case of problems with the input parameter 226 * and OK otherwise 227 ********************************************************************************/ 228 229 TI_STATUS Classifier_destroy(classifier_t* pClsfr) 230 { 231 232 /* check parameters validity */ 233 if( pClsfr == NULL ) 234 return NOK; 235 236 /* free the classifier memory block */ 237 os_memoryFree(pClsfr->hOs, pClsfr, sizeof(classifier_t)); 238 return OK; 239 } 240 241 242 243 /************************************************************************ 244 * Classifier_classifyTxMSDU 245 ************************************************************************ 246 247 Input: 248 249 * pClsfr: pointer to the classifier 250 * pMsdu: pointer to the MSDU 251 * packet_DTag: NDIS Packet 802.1 user priority (UP) 252 253 Output: 254 255 OK on success and PARAM_VALUE_NOT_VALID in case of input parameters problems. 256 If the value PARAM_VALUE_NOT_VALID is returned, the MSDU qosTag field is zero. 257 258 Description: 259 260 This function performs the classification algorithm for the MSDU pointed 261 by pMsdu, according to the classifier parameters. 262 It initializes the qosTag field of the MSDU with the classification algorithm 263 returned value. Note that if the value in the field clsfrType of Clsfr_Params is 264 D_TAG_CLSFR then it performs the trivial classification algorithm from 265 D-tag to D-tag. That is, Msdu->qosTag is set to packet_DTag. 266 For all other classification algorithms, the classification is performed 267 according to the corresponding classifier table. 268 269 ************************************************************************/ 270 271 272 TI_STATUS Classifier_classifyTxMSDU(classifier_t* pClsfr, mem_MSDU_T *pMsdu, UINT8 packet_DTag) 273 { 274 275 UINT8 i; 276 UINT8 *pUdpHeader = NULL; 277 UINT8 *pIpHeader = NULL; 278 UINT8 DSCP; 279 UINT16 dstPortNum; 280 UINT32 dstIPAdd; 281 282 /* Parameters validation */ 283 284 if (pClsfr == NULL) 285 return NOK; 286 287 if (pMsdu == NULL) 288 { 289 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 290 (" Classifier_classifyTxMSDU() : NULL MSDU error \n")); 291 return PARAM_VALUE_NOT_VALID; 292 } 293 294 if ((packet_DTag > MAX_NUM_OF_802_1d_TAGS) && (pClsfr->clsfrParameters.clsfrType == D_TAG_CLSFR)) 295 { 296 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 297 (" Classifier_classifyTxMSDU() : packet_DTag error \n")); 298 pMsdu->qosTag = 0; 299 return PARAM_VALUE_NOT_VALID; 300 } 301 302 /* Initialization */ 303 pMsdu->qosTag = 0; 304 305 switch(pClsfr->clsfrParameters.clsfrType) 306 { 307 case D_TAG_CLSFR: 308 /* Trivial mapping D-tag to D-tag */ 309 pMsdu->qosTag = packet_DTag; 310 WLAN_REPORT_INFORMATION (pClsfr->hReport, CLSFR_MODULE_LOG, ("Classifier D_TAG_CLSFR. pMsdu->qosTag = %d\n",pMsdu->qosTag)); 311 312 break; 313 314 case DSCP_CLSFR: 315 316 if( (classifier_getIpAndUdpHeader(pClsfr, pMsdu, &pIpHeader, &pUdpHeader) != OK) || 317 (pIpHeader == NULL) ) 318 { 319 WLAN_REPORT_INFORMATION(pClsfr->hReport, CLSFR_MODULE_LOG, 320 (" Classifier_classifyTxMSDU() : DSCP clsfr, getIpAndUdpHeader error\n")); 321 return PARAM_VALUE_NOT_VALID; 322 } 323 324 /* DSCP to D-tag mapping */ 325 DSCP = *((UINT8 *)(pIpHeader + 1)); /* Fetching the DSCP from the header */ 326 DSCP = (DSCP >> 2); 327 328 /* looking for the specific DSCP, if the DSCP is found, its corresponding 329 D-tag is set to the qosTag */ 330 for(i = 0; i<pClsfr->clsfrParameters.NumOfActiveEntries; i++ ) 331 { 332 if (pClsfr->clsfrParameters.ClsfrTable[i].Dscp.CodePoint == DSCP) 333 { 334 pMsdu->qosTag = pClsfr->clsfrParameters.ClsfrTable[i].DTag; 335 WLAN_REPORT_INFORMATION (pClsfr->hReport, CLSFR_MODULE_LOG,("Classifier DSCP_CLSFR found match - entry %d - qosTag = %d\n",i,pMsdu->qosTag)); 336 break; 337 } 338 } 339 340 break; 341 342 343 case PORT_CLSFR: 344 if( (classifier_getIpAndUdpHeader(pClsfr, pMsdu, &pIpHeader, &pUdpHeader) != OK) || 345 (pUdpHeader == NULL) ) 346 { 347 WLAN_REPORT_INFORMATION(pClsfr->hReport, CLSFR_MODULE_LOG, 348 (" Classifier_classifyTxMSDU() : DstPort clsfr, getIpAndUdpHeader error\n")); 349 return PARAM_VALUE_NOT_VALID; 350 } 351 352 /* Port to D-tag mapping */ 353 dstPortNum = *((UINT16 *)(pUdpHeader + 2)); /* Fetching the port number from the header */ 354 dstPortNum = ((dstPortNum >> 8) | (dstPortNum << 8)); 355 356 /* looking for the specific port number, if the port number is found, its corresponding 357 D-tag is set to the qosTag */ 358 for(i = 0; i<pClsfr->clsfrParameters.NumOfActiveEntries; i++ ) 359 { 360 if (pClsfr->clsfrParameters.ClsfrTable[i].Dscp.DstPortNum == dstPortNum) 361 { 362 pMsdu->qosTag = pClsfr->clsfrParameters.ClsfrTable[i].DTag; 363 WLAN_REPORT_INFORMATION (pClsfr->hReport, CLSFR_MODULE_LOG,("Classifier PORT_CLSFR found match - entry %d - qosTag = %d\n",i,pMsdu->qosTag)); 364 break; 365 } 366 } 367 break; 368 369 case IPPORT_CLSFR: 370 if( (classifier_getIpAndUdpHeader(pClsfr, pMsdu, &pIpHeader, &pUdpHeader) != OK) || 371 (pIpHeader == NULL) || (pUdpHeader == NULL) ) 372 { 373 WLAN_REPORT_INFORMATION(pClsfr->hReport, CLSFR_MODULE_LOG, 374 (" Classifier_classifyTxMSDU() : Dst IP&Port clsfr, getIpAndUdpHeader error\n")); 375 return PARAM_VALUE_NOT_VALID; 376 } 377 378 /* IP&Port to D-tag mapping */ 379 dstPortNum = *((UINT16 *)(pUdpHeader + 2)); /* Fetching the port number from the header */ 380 dstPortNum = ((dstPortNum >> 8) | (dstPortNum << 8)); 381 { 382 /* Since IP header is 2 bytes aligned we will copy IP as two 16 bits */ 383 /* dstIPAdd = *((UINT32 *)(pIpHeader + 16));*/ 384 UINT16 hiPart, loPart; 385 hiPart = *((UINT16 *) pIpHeader + 8); 386 loPart = *((UINT16 *) pIpHeader + 9); 387 dstIPAdd = (loPart << 16) | hiPart; // account for little endian host and network order 388 389 } 390 391 /* looking for the specific pair of dst IP address and dst port number, if it is found, its corresponding 392 D-tag is set to the qosTag */ 393 for(i = 0; i<pClsfr->clsfrParameters.NumOfActiveEntries; i++ ) 394 { 395 if ((pClsfr->clsfrParameters.ClsfrTable[i].Dscp.DstIPPort.DstIPAddress == dstIPAdd)&& 396 ( pClsfr->clsfrParameters.ClsfrTable[i].Dscp.DstIPPort.DstPortNum == dstPortNum)) 397 { 398 pMsdu->qosTag = pClsfr->clsfrParameters.ClsfrTable[i].DTag; 399 WLAN_REPORT_INFORMATION (pClsfr->hReport, CLSFR_MODULE_LOG,("Classifier IPPORT_CLSFR found match - entry %d - qosTag = %d\n",i,pMsdu->qosTag)); 400 break; 401 } 402 } 403 404 break; 405 406 default: 407 408 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 409 (" Classifier_classifyTxMSDU(): clsfrType error\n")); 410 } 411 412 return OK; 413 } 414 415 416 417 /************************************************************************ 418 * classifier_getIpAndUdpHeader 419 ************************************************************************ 420 421 Input: 422 423 * pClsfr: pointer to the classifier 424 * pMsdu: pointer to the MSDU 425 426 Output: 427 428 * pIpHeader: pointer to the IP header 429 * pUdpHeader: pointer to the UDP header 430 431 Description: 432 433 This function fetch the addresses of the IP and UDP headers 434 435 ************************************************************************/ 436 static TI_STATUS classifier_getIpAndUdpHeader(classifier_t* pClsfr, mem_MSDU_T *pMsdu, UINT8 **pIpHeader, UINT8 **pUdpHeader) 437 { 438 UINT8 ipHeaderLen=0; 439 mem_BD_T* currBD = NULL; 440 UINT16 swapedTypeLength=0; 441 442 443 /* Parameters validation */ 444 445 446 if (pMsdu == NULL) 447 { 448 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 449 (" classifier_getIpAndUdpHeader: NULL MSDU error \n")); 450 return NOK; 451 } 452 453 currBD = pMsdu->firstBDPtr; 454 if( currBD == NULL) 455 { 456 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 457 (" classifier_getIpAndUdpHeader: first BD is NULL \n")); 458 return NOK; 459 } 460 461 swapedTypeLength = wlan_htons(*((UINT16*)(currBD->data+currBD->dataOffset+12)) ); 462 463 /* check if frame is IP according to ether type */ 464 if( swapedTypeLength != 0x0800) 465 { 466 WLAN_REPORT_INFORMATION(pClsfr->hReport, CLSFR_MODULE_LOG, 467 (" classifier_getIpAndUdpHeader: swapedTypeLength is not 0x0800 \n")); 468 return NOK; 469 } 470 471 /*Ronnie: we could have skipped the NO_COPY_NDIS_BUFFERS ifdef (both cases are the same)*/ 472 #ifdef NO_COPY_NDIS_BUFFERS 473 /* 474 in windows - protocols headears are in the same buffer. 475 Headears can not bu split between 2 buffers 476 */ 477 478 /* IP is in first buffer */ 479 *pIpHeader = (UINT8 *)(memMgr_BufData(pMsdu->firstBDPtr)+memMgr_BufOffset(pMsdu->firstBDPtr)) + ETHERNET_HEADER_SIZE; 480 ipHeaderLen = ((*(unsigned char*)(*pIpHeader) & 0x0f) * 4); 481 482 483 /* UDP/TCP is in first buffer */ 484 *pUdpHeader = *pIpHeader + ipHeaderLen; /* Set the pointer to the begining of the TCP/UDP header */ 485 486 487 #else 488 /* set the pointer to the beginning of the IP header and calculate it's size*/ 489 *pIpHeader = (UINT8 *)(memMgr_BufData(pMsdu->firstBDPtr)+memMgr_BufOffset(pMsdu->firstBDPtr)) + ETHERNET_HEADER_SIZE; 490 ipHeaderLen = ((*(unsigned char*)(*pIpHeader) & 0x0f) * 4); 491 *pUdpHeader = *pIpHeader + ipHeaderLen; /* Set the pointer to the beggining of the TCP/UDP header */ 492 #endif 493 return OK; 494 } 495 496 497 498 /************************************************************************ 499 * classifier_InsertClsfrEntry * 500 ************************************************************************ 501 The following API is used to configure the classifier table. Note that 502 this API provides only insert to table service (and not delete). 503 504 Input: 505 506 * pClsfr: pointer to the classifier 507 * NumberOfEntries: number of entries to insert. 508 * ConfigBufferPtr: pointer to the data to insert. 509 510 Output: 511 512 OK on success and PARAM_VALUE_NOT_VALID in case of input parameters problems. 513 If the value PARAM_VALUE_NOT_VALID is returned, the entries insert operation 514 on the classifier table is canceled. 515 516 The value PARAM_VALUE_NOT_VALID is returned upon the following errors: 517 -- NumberOfEntries parameter: 518 a) If it is larger than the available entries in the table. 519 b) If it is smaller than 1. 520 c) If an entry creates conflict with another entry. 521 -- ConfigBufferPtr is pointing on NULL. 522 523 ************************************************************************/ 524 TI_STATUS Classifier_InsertClsfrEntry(classifier_t* pClsfr, UINT8 NumberOfEntries, clsfr_tableEntry_t *ConfigBufferPtr) 525 { 526 527 UINT8 avlEntries; 528 clsfr_tableEntry_t *pSrc; 529 int i,j; 530 531 if(pClsfr == NULL) 532 return NOK; 533 534 if(ConfigBufferPtr == NULL) 535 { 536 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 537 ("Classifier_InsertClsfrEntry(): NULL ConfigBuffer pointer Error - Aborting\n")); 538 return PARAM_VALUE_NOT_VALID; 539 } 540 541 avlEntries = (NUM_OF_CLSFR_TABLE_ENTRIES - (pClsfr->clsfrParameters.NumOfActiveEntries)); 542 if ((NumberOfEntries < 1) || (NumberOfEntries > avlEntries)) 543 { 544 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 545 ("Classifier_InsertClsfrEntry(): Bad Number Of Entries - Aborting\n")); 546 return PARAM_VALUE_NOT_VALID; 547 } 548 549 if (pClsfr->clsfrParameters.clsfrType == D_TAG_CLSFR) 550 { 551 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 552 ("Classifier_InsertClsfrEntry(): D-Tag classifier - Aborting\n")); 553 return PARAM_VALUE_NOT_VALID; 554 } 555 556 /* Check conflicts with classifier table entries */ 557 /* check all conflicts, if all entries are OK --> insert to classifier table*/ 558 559 pSrc = ConfigBufferPtr; 560 561 switch (pClsfr->clsfrParameters.clsfrType) 562 { 563 case DSCP_CLSFR: 564 for (i=0; i< NumberOfEntries ; i++) 565 { 566 /* Check entry */ 567 if ((pSrc[i].Dscp.CodePoint > CLASSIFIER_CODE_POINT_MAX) || (pSrc[i].DTag > CLASSIFIER_DTAG_MAX)) 568 { 569 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 570 ("Classifier_InsertClsfrEntry(): bad parameter - Aborting\n")); 571 return PARAM_VALUE_NOT_VALID; 572 } 573 574 /* Check conflict*/ 575 for (j=0;j<pClsfr->clsfrParameters.NumOfActiveEntries;j++) 576 { 577 /* Detect both duplicate and conflicting entries */ 578 if (pClsfr->clsfrParameters.ClsfrTable[j].Dscp.CodePoint == pSrc[i].Dscp.CodePoint) 579 { 580 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 581 ("Classifier_InsertClsfrEntry(): classifier entries conflict - Aborting\n")); 582 return PARAM_VALUE_NOT_VALID; 583 } 584 } 585 586 } 587 588 /* All new entries are valid --> insert to classifier table */ 589 for (i=0; i< NumberOfEntries ; i++) 590 { 591 pClsfr->clsfrParameters.ClsfrTable[pClsfr->clsfrParameters.NumOfActiveEntries+i].Dscp.CodePoint = pSrc[i].Dscp.CodePoint; 592 pClsfr->clsfrParameters.ClsfrTable[pClsfr->clsfrParameters.NumOfActiveEntries+i].DTag = pSrc[i].DTag; 593 } 594 595 break; 596 597 case PORT_CLSFR: 598 for (i=0; i< NumberOfEntries ; i++) 599 { 600 /* Check entry */ 601 if ((pSrc[i].DTag > CLASSIFIER_DTAG_MAX) || (pSrc[i].Dscp.DstPortNum > CLASSIFIER_PORT_MAX-1) || (pSrc[i].Dscp.DstPortNum < CLASSIFIER_PORT_MIN) ) 602 { 603 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 604 ("Classifier_InsertClsfrEntry(): bad parameter - Aborting\n")); 605 return PARAM_VALUE_NOT_VALID; 606 } 607 608 /* Check conflict*/ 609 for (j=0;j<pClsfr->clsfrParameters.NumOfActiveEntries;j++) 610 { 611 /* Detect both duplicate and conflicting entries */ 612 if ((pClsfr->clsfrParameters.ClsfrTable[j].Dscp.DstPortNum == pSrc[i].Dscp.DstPortNum)) 613 { 614 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 615 ("Classifier_InsertClsfrEntry(): classifier entries conflict - Aborting\n")); 616 return PARAM_VALUE_NOT_VALID; 617 } 618 } 619 620 } 621 622 /* All new entries are valid --> insert to classifier table */ 623 for (i=0; i< NumberOfEntries ; i++) 624 { 625 pClsfr->clsfrParameters.ClsfrTable[pClsfr->clsfrParameters.NumOfActiveEntries+i].Dscp.DstPortNum = pSrc[i].Dscp.DstPortNum; 626 pClsfr->clsfrParameters.ClsfrTable[pClsfr->clsfrParameters.NumOfActiveEntries+i].DTag = pSrc[i].DTag; 627 } 628 629 break; 630 631 case IPPORT_CLSFR: 632 for (i=0; i< NumberOfEntries ; i++) 633 { 634 /* Check entry */ 635 if ( (pSrc[i].DTag > CLASSIFIER_DTAG_MAX) || (pSrc[i].Dscp.DstIPPort.DstPortNum > CLASSIFIER_PORT_MAX-1) || 636 (pSrc[i].Dscp.DstIPPort.DstPortNum < CLASSIFIER_PORT_MIN) || (pSrc[i].Dscp.DstIPPort.DstIPAddress > CLASSIFIER_IPADDRESS_MAX-1) || 637 (pSrc[i].Dscp.DstIPPort.DstIPAddress < CLASSIFIER_IPADDRESS_MIN+1) ) 638 { 639 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 640 ("Classifier_InsertClsfrEntry(): bad parameter - Aborting\n")); 641 return PARAM_VALUE_NOT_VALID; 642 } 643 644 /* Check conflict*/ 645 for (j=0;j<pClsfr->clsfrParameters.NumOfActiveEntries;j++) 646 { 647 /* Detect both duplicate and conflicting entries */ 648 if ( (pClsfr->clsfrParameters.ClsfrTable[j].Dscp.DstIPPort.DstIPAddress == pSrc[i].Dscp.DstIPPort.DstIPAddress) && 649 (pClsfr->clsfrParameters.ClsfrTable[j].Dscp.DstIPPort.DstPortNum == pSrc[i].Dscp.DstIPPort.DstPortNum)) 650 { 651 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 652 ("Classifier_InsertClsfrEntry(): classifier entries conflict - Aborting\n")); 653 return PARAM_VALUE_NOT_VALID; 654 } 655 } 656 657 } 658 659 /* All new entries are valid --> insert to classifier table */ 660 for (i=0; i< NumberOfEntries ; i++) 661 { 662 pClsfr->clsfrParameters.ClsfrTable[pClsfr->clsfrParameters.NumOfActiveEntries+i].Dscp.DstIPPort.DstIPAddress = pSrc[i].Dscp.DstIPPort.DstIPAddress; 663 pClsfr->clsfrParameters.ClsfrTable[pClsfr->clsfrParameters.NumOfActiveEntries+i].Dscp.DstIPPort.DstPortNum = pSrc[i].Dscp.DstIPPort.DstPortNum; 664 pClsfr->clsfrParameters.ClsfrTable[pClsfr->clsfrParameters.NumOfActiveEntries+i].DTag = pSrc[i].DTag; 665 } 666 667 break; 668 669 default: 670 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 671 ("Classifier_InsertClsfrEntry(): Classifier type -- unknown - Aborting\n")); 672 673 } 674 675 /* update the number of classifier active entries */ 676 pClsfr->clsfrParameters.NumOfActiveEntries = pClsfr->clsfrParameters.NumOfActiveEntries + NumberOfEntries; 677 678 return OK; 679 } 680 681 682 /************************************************************************ 683 * classifier_RemoveClsfrEntry * 684 ************************************************************************ 685 The following API is used to remove an entry from the classifier table 686 687 Input: 688 689 * pClsfr: pointer to the classifier 690 * ConfigBufferPtr: pointer to the data to remove. 691 692 Output: 693 OK on success and PARAM_VALUE_NOT_VALID in case of input parameters problems. 694 ************************************************************************/ 695 TI_STATUS classifier_RemoveClsfrEntry(classifier_t* pClsfr, clsfr_tableEntry_t *ConfigBufferPtr) 696 { 697 int i,j; 698 699 if(pClsfr == NULL) 700 return NOK; 701 702 if(ConfigBufferPtr == NULL) 703 { 704 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 705 ("classifier_RemoveClsfrEntry(): NULL ConfigBuffer pointer Error - Aborting\n")); 706 return PARAM_VALUE_NOT_VALID; 707 } 708 709 if (pClsfr->clsfrParameters.NumOfActiveEntries == 0) 710 { 711 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 712 ("classifier_RemoveClsfrEntry(): Classifier table is empty - Aborting\n")); 713 return PARAM_VALUE_NOT_VALID; 714 } 715 716 if (pClsfr->clsfrParameters.clsfrType == D_TAG_CLSFR) 717 { 718 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 719 ("classifier_RemoveClsfrEntry(): D-Tag classifier - Aborting\n")); 720 return PARAM_VALUE_NOT_VALID; 721 } 722 723 /* Check conflicts with classifier table entries */ 724 /* check all conflicts, if all entries are OK --> insert to classifier table*/ 725 726 switch (pClsfr->clsfrParameters.clsfrType) 727 { 728 case DSCP_CLSFR: 729 730 /* Find the classifier entry */ 731 i = 0; 732 while ((i < pClsfr->clsfrParameters.NumOfActiveEntries) && 733 ((pClsfr->clsfrParameters.ClsfrTable[i].Dscp.CodePoint != ConfigBufferPtr->Dscp.CodePoint) || 734 (pClsfr->clsfrParameters.ClsfrTable[i].DTag != ConfigBufferPtr->DTag))) 735 { 736 i++; 737 } 738 739 /* If we have reached the number of active entries, it means we couldn't find the requested entry */ 740 if (i == pClsfr->clsfrParameters.NumOfActiveEntries) 741 { 742 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 743 ("classifier_RemoveClsfrEntry(): Entry not found - Aborting\n")); 744 return PARAM_VALUE_NOT_VALID; 745 } 746 747 /* If there is more than 1 entry, we need to shift all the entries in the table in order to delete the requested entry */ 748 if (pClsfr->clsfrParameters.NumOfActiveEntries > 1) 749 { 750 for (j = i; j < pClsfr->clsfrParameters.NumOfActiveEntries-1; j++) 751 { 752 /* Move entries */ 753 pClsfr->clsfrParameters.ClsfrTable[j].Dscp.CodePoint = pClsfr->clsfrParameters.ClsfrTable[j+1].Dscp.CodePoint; 754 pClsfr->clsfrParameters.ClsfrTable[j].DTag = pClsfr->clsfrParameters.ClsfrTable[j+1].DTag; 755 } 756 } 757 758 break; 759 760 case PORT_CLSFR: 761 762 /* Find the classifier entry */ 763 i = 0; 764 while ((i < pClsfr->clsfrParameters.NumOfActiveEntries) && 765 ((pClsfr->clsfrParameters.ClsfrTable[i].Dscp.DstPortNum != ConfigBufferPtr->Dscp.DstPortNum) || 766 (pClsfr->clsfrParameters.ClsfrTable[i].DTag != ConfigBufferPtr->DTag))) 767 { 768 i++; 769 } 770 771 /* If we have reached the number of active entries, it means we couldn't find the requested entry */ 772 if (i == pClsfr->clsfrParameters.NumOfActiveEntries) 773 { 774 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 775 ("classifier_RemoveClsfrEntry(): Entry not found - Aborting\n")); 776 return PARAM_VALUE_NOT_VALID; 777 } 778 779 /* If there is more than 1 entry, we need to shift all the entries in the table in order to delete the requested entry */ 780 if (pClsfr->clsfrParameters.NumOfActiveEntries > 1) 781 { 782 for (j = i; j < pClsfr->clsfrParameters.NumOfActiveEntries-1; j++) 783 { 784 pClsfr->clsfrParameters.ClsfrTable[j].Dscp.DstPortNum = pClsfr->clsfrParameters.ClsfrTable[j+1].Dscp.DstPortNum; 785 pClsfr->clsfrParameters.ClsfrTable[j].DTag = pClsfr->clsfrParameters.ClsfrTable[j+1].DTag; 786 } 787 } 788 789 break; 790 791 case IPPORT_CLSFR: 792 793 /* Find the classifier entry */ 794 i = 0; 795 while ((i < pClsfr->clsfrParameters.NumOfActiveEntries) && 796 ((pClsfr->clsfrParameters.ClsfrTable[i].Dscp.DstIPPort.DstIPAddress != ConfigBufferPtr->Dscp.DstIPPort.DstIPAddress) || 797 (pClsfr->clsfrParameters.ClsfrTable[i].Dscp.DstIPPort.DstPortNum != ConfigBufferPtr->Dscp.DstIPPort.DstPortNum) || 798 (pClsfr->clsfrParameters.ClsfrTable[i].DTag != ConfigBufferPtr->DTag))) 799 { 800 i++; 801 } 802 803 /* If we have reached the number of active entries, it means we couldn't find the requested entry */ 804 if (i == pClsfr->clsfrParameters.NumOfActiveEntries) 805 { 806 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 807 ("classifier_RemoveClsfrEntry(): Entry not found - Aborting\n")); 808 return PARAM_VALUE_NOT_VALID; 809 } 810 811 /* If there is more than 1 entry, we need to shift all the entries in the table in order to delete the requested entry */ 812 if (pClsfr->clsfrParameters.NumOfActiveEntries > 1) 813 { 814 for (j = i; j < pClsfr->clsfrParameters.NumOfActiveEntries-1; j++) 815 { 816 pClsfr->clsfrParameters.ClsfrTable[j].Dscp.DstIPPort.DstIPAddress = pClsfr->clsfrParameters.ClsfrTable[j+1].Dscp.DstIPPort.DstIPAddress; 817 pClsfr->clsfrParameters.ClsfrTable[j].Dscp.DstIPPort.DstPortNum = pClsfr->clsfrParameters.ClsfrTable[j+1].Dscp.DstIPPort.DstPortNum; 818 pClsfr->clsfrParameters.ClsfrTable[j].DTag = pClsfr->clsfrParameters.ClsfrTable[j+1].DTag; 819 } 820 } 821 822 break; 823 824 default: 825 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 826 ("classifier_RemoveClsfrEntry(): Classifier type -- unknown - Aborting\n")); 827 828 } 829 830 /* update the number of classifier active entries */ 831 pClsfr->clsfrParameters.NumOfActiveEntries--; 832 833 return OK; 834 } 835 836 837 /************************************************************************ 838 * classifier_setClsfrType * 839 ************************************************************************ 840 The following API is used to change the active classifier type. 841 In addition it empties the classifier table. 842 843 Input: 844 845 * pClsfr: pointer to the classifier 846 * newClsfrType: the new classifier type. 847 848 Output: 849 850 OK on success and PARAM_VALUE_NOT_VALID in case of input parameters problems. 851 If the value PARAM_VALUE_NOT_VALID is returned, the classifier type and table are not updated. 852 853 ************************************************************************/ 854 855 TI_STATUS Classifier_setClsfrType(classifier_t* pClsfr, clsfr_type_e newClsfrType) 856 { 857 if( pClsfr == NULL ) 858 return PARAM_VALUE_NOT_VALID; 859 860 if (newClsfrType > CLSFR_TYPE_MAX) 861 { 862 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 863 ("Classifier_setClsfrType(): classifier type exceed its MAX \n")); 864 return PARAM_VALUE_NOT_VALID; 865 } 866 867 868 if ( pClsfr->clsfrParameters.clsfrType == newClsfrType) 869 { 870 WLAN_REPORT_WARNING(pClsfr->hReport, CLSFR_MODULE_LOG, 871 ("Classifier_setClsfrType(): equal classifier type --> will empty classifier table \n")); 872 } 873 874 /* Update type */ 875 pClsfr->clsfrParameters.clsfrType = newClsfrType; 876 /* Empty table */ 877 pClsfr->clsfrParameters.NumOfActiveEntries = 0; 878 879 return OK; 880 } 881 882 TI_STATUS Classifier_getClsfrType (classifier_t* pClsfr, clsfrTypeAndSupport *newClsfrType) 883 { 884 if (pClsfr == NULL) 885 return NOK; 886 887 newClsfrType->ClsfrType = (ULONG)pClsfr->clsfrParameters.clsfrType; 888 return OK; 889 } 890 891 892 /************************************************************************ 893 * Classifier_deriveUserPriorityFromStream 894 ************************************************************************ 895 896 Input: 897 898 * pClsfr: pointer to the classifier 899 * pStream: pointer to stream properties structure 900 901 Output: 902 903 userPriority contains the appropriate qosTag that matches the stream properties. 904 905 OK on success and PARAM_VALUE_NOT_VALID in case of input parameters problems. 906 If the value PARAM_VALUE_NOT_VALID is returned, the MSDU qosTag field is zero. 907 908 Description: 909 910 ************************************************************************/ 911 912 TI_STATUS Classifier_deriveUserPriorityFromStream (classifier_t* pClsfr, STREAM_TRAFFIC_PROPERTIES *pStream) 913 { 914 915 UINT8 i; 916 917 if (pClsfr == NULL) 918 return NOK; 919 920 /* Initialization */ 921 pStream->userPriority = 0; 922 923 switch(pClsfr->clsfrParameters.clsfrType) 924 { 925 case DSCP_CLSFR: 926 /* looking for the specific DSCP, if the DSCP is found, its corresponding D-tag is set to the qosTag */ 927 for(i = 0; i<pClsfr->clsfrParameters.NumOfActiveEntries; i++ ) 928 { 929 if (pClsfr->clsfrParameters.ClsfrTable[i].Dscp.CodePoint == pStream->PktTag) 930 { 931 pStream->userPriority = pClsfr->clsfrParameters.ClsfrTable[i].DTag; 932 return OK; 933 } 934 } 935 break; 936 case PORT_CLSFR: 937 /* looking for the specific port number, if the port number is found, its corresponding D-tag is returned */ 938 for(i = 0; i<pClsfr->clsfrParameters.NumOfActiveEntries; i++ ) 939 { 940 if (pClsfr->clsfrParameters.ClsfrTable[i].Dscp.DstPortNum == pStream->dstPort) 941 { 942 pStream->userPriority = pClsfr->clsfrParameters.ClsfrTable[i].DTag; 943 return OK; 944 } 945 } 946 break; 947 case IPPORT_CLSFR: 948 /* looking for the specific pair of dst IP address and dst port number, if it is found, its corresponding 949 D-tag is set to the qosTag */ 950 for(i = 0; i<pClsfr->clsfrParameters.NumOfActiveEntries; i++ ) 951 { 952 if ((pClsfr->clsfrParameters.ClsfrTable[i].Dscp.DstIPPort.DstIPAddress == pStream->dstIpAddress)&& 953 ( pClsfr->clsfrParameters.ClsfrTable[i].Dscp.DstIPPort.DstPortNum == pStream->dstPort)) 954 { 955 pStream->userPriority = pClsfr->clsfrParameters.ClsfrTable[i].DTag; 956 return OK; 957 } 958 } 959 break; 960 default: 961 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 962 (" Classifier_deriveUserPriorityFromStream(): clsfrType error\n")); 963 } 964 965 #if 0 966 WLAN_OS_REPORT (("UserPriority is %d\n",pStream->userPriority)); 967 #endif 968 969 return OK; 970 } 971 972 973 #ifdef TI_DBG 974 TI_STATUS Classifier_dbgPrintClsfrTable (classifier_t* pClsfr) 975 { 976 int i; 977 UINT32 tmpIpAddr; 978 979 if(pClsfr == NULL) 980 return NOK; 981 982 if (pClsfr->clsfrParameters.clsfrType == D_TAG_CLSFR) 983 { 984 WLAN_OS_REPORT (("D_TAG classifier type selected...Nothing to print...\n")); 985 return OK; 986 } 987 988 WLAN_OS_REPORT (("Number of active entries in classifier table : %d\n",pClsfr->clsfrParameters.NumOfActiveEntries)); 989 990 switch (pClsfr->clsfrParameters.clsfrType) 991 { 992 case DSCP_CLSFR: 993 WLAN_OS_REPORT (("+------+-------+\n")); 994 WLAN_OS_REPORT (("| Code | D-Tag |\n")); 995 WLAN_OS_REPORT (("+------+-------+\n")); 996 997 for (i=0; i< pClsfr->clsfrParameters.NumOfActiveEntries ; i++) 998 { 999 WLAN_OS_REPORT (("| %5d | %5d |\n",pClsfr->clsfrParameters.ClsfrTable[i].Dscp.CodePoint,pClsfr->clsfrParameters.ClsfrTable[i].DTag)); 1000 } 1001 1002 WLAN_OS_REPORT (("+-------+-------+\n")); 1003 break; 1004 case PORT_CLSFR: 1005 WLAN_OS_REPORT (("+-------+-------+\n")); 1006 WLAN_OS_REPORT (("| Port | D-Tag |\n")); 1007 WLAN_OS_REPORT (("+-------+-------+\n")); 1008 1009 for (i=0; i< pClsfr->clsfrParameters.NumOfActiveEntries ; i++) 1010 { 1011 WLAN_OS_REPORT (("| %5d | %5d |\n",pClsfr->clsfrParameters.ClsfrTable[i].Dscp.DstPortNum,pClsfr->clsfrParameters.ClsfrTable[i].DTag)); 1012 } 1013 1014 WLAN_OS_REPORT (("+-------+-------+\n")); 1015 break; 1016 case IPPORT_CLSFR: 1017 1018 WLAN_OS_REPORT (("+-------------+-------+-------+\n")); 1019 WLAN_OS_REPORT (("| IP Address | Port | D-Tag |\n")); 1020 WLAN_OS_REPORT (("+-------------+-------+-------+\n")); 1021 1022 for (i=0; i< pClsfr->clsfrParameters.NumOfActiveEntries ; i++) 1023 { 1024 tmpIpAddr = pClsfr->clsfrParameters.ClsfrTable[i].Dscp.DstIPPort.DstIPAddress; 1025 WLAN_OS_REPORT (("| %02x.%02x.%02x.%02x | %5d | %5d |\n",(tmpIpAddr & 0xFF),((tmpIpAddr >> 8) & (0xFF)),((tmpIpAddr >> 16) & (0xFF)),((tmpIpAddr >> 24) & (0xFF)),pClsfr->clsfrParameters.ClsfrTable[i].Dscp.DstIPPort.DstPortNum,pClsfr->clsfrParameters.ClsfrTable[i].DTag)); 1026 } 1027 1028 WLAN_OS_REPORT (("+-------------+-------+-------+\n")); 1029 break; 1030 default: 1031 WLAN_REPORT_ERROR(pClsfr->hReport, CLSFR_MODULE_LOG, 1032 ("Classifier_InsertClsfrEntry(): Classifier type -- unknown - Aborting\n")); 1033 break; 1034 } 1035 1036 return OK; 1037 1038 1039 } 1040 #endif 1041 1042 1043 1044