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
Classifier_create(TI_HANDLE hOs)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
Classifier_config(classifier_t * pClsfr,TI_HANDLE hOs,TI_HANDLE hReport,clsfr_Params_t * ClsfrInitParams)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
Classifier_destroy(classifier_t * pClsfr)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
Classifier_classifyTxMSDU(classifier_t * pClsfr,mem_MSDU_T * pMsdu,UINT8 packet_DTag)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 ************************************************************************/
classifier_getIpAndUdpHeader(classifier_t * pClsfr,mem_MSDU_T * pMsdu,UINT8 ** pIpHeader,UINT8 ** pUdpHeader)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 ************************************************************************/
Classifier_InsertClsfrEntry(classifier_t * pClsfr,UINT8 NumberOfEntries,clsfr_tableEntry_t * ConfigBufferPtr)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 ************************************************************************/
classifier_RemoveClsfrEntry(classifier_t * pClsfr,clsfr_tableEntry_t * ConfigBufferPtr)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
Classifier_setClsfrType(classifier_t * pClsfr,clsfr_type_e newClsfrType)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
Classifier_getClsfrType(classifier_t * pClsfr,clsfrTypeAndSupport * newClsfrType)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
Classifier_deriveUserPriorityFromStream(classifier_t * pClsfr,STREAM_TRAFFIC_PROPERTIES * pStream)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
Classifier_dbgPrintClsfrTable(classifier_t * pClsfr)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