1#include "headers.h"
2
3static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
4
5static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
6
7static UINT CreateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI);
8
9static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
10
11static BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule);
12
13static BOOLEAN DerefPhsRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule);
14
15static UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry);
16
17static UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule);
18
19static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable);
20
21static int phs_compress(S_PHS_RULE *phs_members,unsigned char *in_buf,
22 unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size );
23
24
25static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
26 unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size );
27
28static int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\
29 S_PHS_RULE *phs_rules,UINT *header_size);
30
31
32static ULONG PhsCompress(void* pvContext,
33 B_UINT16 uiVcid,
34 B_UINT16 uiClsId,
35 void *pvInputBuffer,
36 void *pvOutputBuffer,
37 UINT *pOldHeaderSize,
38 UINT *pNewHeaderSize );
39
40static ULONG PhsDeCompress(void* pvContext,
41 B_UINT16 uiVcid,
42 void *pvInputBuffer,
43 void *pvOutputBuffer,
44 UINT *pInHeaderSize,
45 UINT *pOutHeaderSize);
46
47
48
49#define IN
50#define OUT
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72int PHSTransmit(struct bcm_mini_adapter *Adapter,
73 struct sk_buff **pPacket,
74 USHORT Vcid,
75 B_UINT16 uiClassifierRuleID,
76 BOOLEAN bHeaderSuppressionEnabled,
77 UINT *PacketLen,
78 UCHAR bEthCSSupport)
79{
80
81
82 UINT unPHSPktHdrBytesCopied = 0;
83 UINT unPhsOldHdrSize = 0;
84 UINT unPHSNewPktHeaderLen = 0;
85
86 PUCHAR pucPHSPktHdrInBuf =
87 Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf;
88
89 PUCHAR pucPHSPktHdrOutBuf =
90 Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf;
91 UINT usPacketType;
92 UINT BytesToRemove=0;
93 BOOLEAN bPHSI = 0;
94 LONG ulPhsStatus = 0;
95 UINT numBytesCompressed = 0;
96 struct sk_buff *newPacket = NULL;
97 struct sk_buff *Packet = *pPacket;
98
99 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "In PHSTransmit");
100
101 if(!bEthCSSupport)
102 BytesToRemove=ETH_HLEN;
103
104
105
106
107
108 usPacketType=((struct ethhdr *)(Packet->data))->h_proto;
109
110
111 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
112
113 if((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS)
114 {
115
116 unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove);
117 }
118 else
119 {
120 unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS;
121 }
122
123 if( (unPHSPktHdrBytesCopied > 0 ) &&
124 (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS))
125 {
126
127
128
129
130 if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
131 (usPacketType == ETHERNET_FRAMETYPE_IPV6)) &&
132 (bHeaderSuppressionEnabled))
133 {
134 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nTrying to PHS Compress Using Classifier rule 0x%X",uiClassifierRuleID);
135
136
137 unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied;
138 ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext,
139 Vcid,
140 uiClassifierRuleID,
141 pucPHSPktHdrInBuf,
142 pucPHSPktHdrOutBuf,
143 &unPhsOldHdrSize,
144 &unPHSNewPktHeaderLen);
145 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nPHS Old header Size : %d New Header Size %d\n",unPhsOldHdrSize,unPHSNewPktHeaderLen);
146
147 if(unPHSNewPktHeaderLen == unPhsOldHdrSize)
148 {
149 if( ulPhsStatus == STATUS_PHS_COMPRESSED)
150 bPHSI = *pucPHSPktHdrOutBuf;
151 ulPhsStatus = STATUS_PHS_NOCOMPRESSION;
152 }
153
154 if( ulPhsStatus == STATUS_PHS_COMPRESSED)
155 {
156 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHS Sending packet Compressed");
157
158 if(skb_cloned(Packet))
159 {
160 newPacket = skb_copy(Packet, GFP_ATOMIC);
161
162 if(newPacket == NULL)
163 return STATUS_FAILURE;
164
165 dev_kfree_skb(Packet);
166 *pPacket = Packet = newPacket;
167 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
168 }
169
170 numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);
171
172 memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
173 memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
174 skb_pull(Packet, numBytesCompressed);
175
176 return STATUS_SUCCESS;
177 }
178
179 else
180 {
181
182 if(!(skb_headroom(Packet) > 0))
183 {
184 if(skb_cow(Packet, 1))
185 {
186 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n");
187 return STATUS_FAILURE;
188 }
189 }
190 skb_push(Packet, 1);
191
192
193 *(Packet->data + BytesToRemove) = bPHSI;
194 return STATUS_SUCCESS;
195 }
196 }
197 else
198 {
199 if(!bHeaderSuppressionEnabled)
200 {
201 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nHeader Suppression Disabled For SF: No PHS\n");
202 }
203
204 return STATUS_SUCCESS;
205 }
206 }
207
208
209 return STATUS_SUCCESS;
210}
211
212int PHSReceive(struct bcm_mini_adapter *Adapter,
213 USHORT usVcid,
214 struct sk_buff *packet,
215 UINT *punPacketLen,
216 UCHAR *pucEthernetHdr,
217 UINT bHeaderSuppressionEnabled)
218{
219 u32 nStandardPktHdrLen = 0;
220 u32 nTotalsuppressedPktHdrBytes = 0;
221 int ulPhsStatus = 0;
222 PUCHAR pucInBuff = NULL ;
223 UINT TotalBytesAdded = 0;
224 if(!bHeaderSuppressionEnabled)
225 {
226 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet");
227 return ulPhsStatus;
228 }
229
230 pucInBuff = packet->data;
231
232
233 nStandardPktHdrLen = packet->len;
234 ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext,
235 usVcid,
236 pucInBuff,
237 Adapter->ucaPHSPktRestoreBuf,
238 &nTotalsuppressedPktHdrBytes,
239 &nStandardPktHdrLen);
240
241 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
242 nTotalsuppressedPktHdrBytes,nStandardPktHdrLen);
243
244 if(ulPhsStatus != STATUS_PHS_COMPRESSED)
245 {
246 skb_pull(packet, 1);
247 return STATUS_SUCCESS;
248 }
249 else
250 {
251 TotalBytesAdded = nStandardPktHdrLen - nTotalsuppressedPktHdrBytes - PHSI_LEN;
252 if(TotalBytesAdded)
253 {
254 if(skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded))
255 skb_push(packet, TotalBytesAdded);
256 else
257 {
258 if(skb_cow(packet, skb_headroom(packet) + TotalBytesAdded))
259 {
260 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n");
261 return STATUS_FAILURE;
262 }
263
264 skb_push(packet, TotalBytesAdded);
265 }
266 }
267
268 memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
269 }
270
271 return STATUS_SUCCESS;
272}
273
274void DumpFullPacket(UCHAR *pBuf,UINT nPktLen)
275{
276 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
277 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"Dumping Data Packet");
278 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,pBuf,nPktLen);
279}
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension, struct bcm_mini_adapter *Adapter)
295{
296 int i;
297 S_SERVICEFLOW_TABLE *pstServiceFlowTable;
298 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nPHS:phs_init function ");
299
300 if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
301 return -EINVAL;
302
303 pPhsdeviceExtension->pstServiceFlowPhsRulesTable =
304 kzalloc(sizeof(S_SERVICEFLOW_TABLE), GFP_KERNEL);
305
306 if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
307 {
308 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
309 return -ENOMEM;
310 }
311
312 pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable;
313 for(i=0;i<MAX_SERVICEFLOWS;i++)
314 {
315 S_SERVICEFLOW_ENTRY sServiceFlow = pstServiceFlowTable->stSFList[i];
316 sServiceFlow.pstClassifierTable = kzalloc(sizeof(S_CLASSIFIER_TABLE), GFP_KERNEL);
317 if(!sServiceFlow.pstClassifierTable)
318 {
319 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
320 free_phs_serviceflow_rules(pPhsdeviceExtension->
321 pstServiceFlowPhsRulesTable);
322 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
323 return -ENOMEM;
324 }
325 }
326
327 pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
328
329 if(pPhsdeviceExtension->CompressedTxBuffer == NULL)
330 {
331 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
332 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
333 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
334 return -ENOMEM;
335 }
336
337 pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
338 if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
339 {
340 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
341 kfree(pPhsdeviceExtension->CompressedTxBuffer);
342 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
343 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
344 return -ENOMEM;
345 }
346
347
348
349 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successful");
350 return STATUS_SUCCESS;
351}
352
353
354int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt)
355{
356 if(pPHSDeviceExt->pstServiceFlowPhsRulesTable)
357 {
358 free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable);
359 pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
360 }
361
362 kfree(pPHSDeviceExt->CompressedTxBuffer);
363 pPHSDeviceExt->CompressedTxBuffer = NULL;
364
365 kfree(pPHSDeviceExt->UnCompressedRxBuffer);
366 pPHSDeviceExt->UnCompressedRxBuffer = NULL;
367
368 return 0;
369}
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392ULONG PhsUpdateClassifierRule(IN void* pvContext,
393 IN B_UINT16 uiVcid ,
394 IN B_UINT16 uiClsId ,
395 IN S_PHS_RULE *psPhsRule,
396 IN B_UINT8 u8AssociatedPHSI)
397{
398 ULONG lStatus =0;
399 UINT nSFIndex =0 ;
400 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
401 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
402
403
404
405 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
406
407 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS With Corr2 Changes \n");
408
409 if(pDeviceExtension == NULL)
410 {
411 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Invalid Device Extension\n");
412 return ERR_PHS_INVALID_DEVICE_EXETENSION;
413 }
414
415
416 if(u8AssociatedPHSI == 0)
417 {
418 return ERR_PHS_INVALID_PHS_RULE;
419 }
420
421
422
423 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
424 uiVcid,&pstServiceFlowEntry);
425
426 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
427 {
428
429 lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId,
430 pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI);
431 return lStatus;
432 }
433
434
435 lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId,
436 pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI);
437
438 return lStatus;
439}
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI)
460{
461 ULONG lStatus =0;
462 UINT nSFIndex =0, nClsidIndex =0 ;
463 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
464 S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
465 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
466
467
468 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
469
470 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n");
471
472 if(pDeviceExtension)
473 {
474
475
476 nSFIndex = GetServiceFlowEntry(pDeviceExtension
477 ->pstServiceFlowPhsRulesTable,uiVcid,&pstServiceFlowEntry);
478
479 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
480 {
481 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
482 return ERR_SF_MATCH_FAIL;
483 }
484
485 pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable;
486 if(pstClassifierRulesTable)
487 {
488 for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++)
489 {
490 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
491 {
492 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) {
493 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
494 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
495 if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
496 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
497 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0,
498 sizeof(S_CLASSIFIER_ENTRY));
499 }
500 }
501 }
502 }
503
504 }
505 return lStatus;
506}
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 uiClsId)
526{
527 ULONG lStatus =0;
528 UINT nSFIndex =0, nClsidIndex =0 ;
529 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
530 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
531 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
532 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
533
534 if(pDeviceExtension)
535 {
536
537 nSFIndex = GetServiceFlowEntry(pDeviceExtension
538 ->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry);
539 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
540 {
541 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"SFID Match Failed\n");
542 return ERR_SF_MATCH_FAIL;
543 }
544
545 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
546 uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry);
547 if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
548 {
549 if(pstClassifierEntry->pstPhsRule)
550 {
551 if(pstClassifierEntry->pstPhsRule->u8RefCnt)
552 pstClassifierEntry->pstPhsRule->u8RefCnt--;
553 if(0==pstClassifierEntry->pstPhsRule->u8RefCnt)
554 kfree(pstClassifierEntry->pstPhsRule);
555
556 }
557 memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
558 }
559
560 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
561 uiClsId,eOldClassifierRuleContext,&pstClassifierEntry);
562
563 if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
564 {
565 kfree(pstClassifierEntry->pstPhsRule);
566 memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
567 }
568 }
569 return lStatus;
570}
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid)
589{
590
591 ULONG lStatus =0;
592 UINT nSFIndex =0, nClsidIndex =0 ;
593 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
594 S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
595 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
596 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
597 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"====> \n");
598
599 if(pDeviceExtension)
600 {
601
602 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
603 uiVcid,&pstServiceFlowEntry);
604 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
605 {
606 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
607 return ERR_SF_MATCH_FAIL;
608 }
609
610 pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable;
611 if(pstClassifierRulesTable)
612 {
613 for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++)
614 {
615 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
616 {
617 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
618 .pstPhsRule->u8RefCnt)
619 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
620 .pstPhsRule->u8RefCnt--;
621 if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
622 .pstPhsRule->u8RefCnt)
623 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
624 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
625 .pstPhsRule = NULL;
626 }
627 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
628 if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule)
629 {
630 if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
631 .pstPhsRule->u8RefCnt)
632 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
633 .pstPhsRule->u8RefCnt--;
634 if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
635 .pstPhsRule->u8RefCnt)
636 kfree(pstClassifierRulesTable
637 ->stOldPhsRulesList[nClsidIndex].pstPhsRule);
638 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
639 .pstPhsRule = NULL;
640 }
641 memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
642 }
643 }
644 pstServiceFlowEntry->bUsed = FALSE;
645 pstServiceFlowEntry->uiVcid = 0;
646
647 }
648
649 return lStatus;
650}
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674ULONG PhsCompress(IN void* pvContext,
675 IN B_UINT16 uiVcid,
676 IN B_UINT16 uiClsId,
677 IN void *pvInputBuffer,
678 OUT void *pvOutputBuffer,
679 OUT UINT *pOldHeaderSize,
680 OUT UINT *pNewHeaderSize )
681{
682 UINT nSFIndex =0, nClsidIndex =0 ;
683 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
684 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
685 S_PHS_RULE *pstPhsRule = NULL;
686 ULONG lStatus =0;
687 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
688
689
690
691 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
692
693
694 if(pDeviceExtension == NULL)
695 {
696 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Invalid Device Extension\n");
697 lStatus = STATUS_PHS_NOCOMPRESSION ;
698 return lStatus;
699
700 }
701
702 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Suppressing header \n");
703
704
705
706 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
707 uiVcid,&pstServiceFlowEntry);
708 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
709 {
710 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"SFID Match Failed\n");
711 lStatus = STATUS_PHS_NOCOMPRESSION ;
712 return lStatus;
713 }
714
715 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
716 uiClsId,eActiveClassifierRuleContext,&pstClassifierEntry);
717
718 if(nClsidIndex == PHS_INVALID_TABLE_INDEX)
719 {
720 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"No PHS Rule Defined For Classifier\n");
721 lStatus = STATUS_PHS_NOCOMPRESSION ;
722 return lStatus;
723 }
724
725
726
727 pstPhsRule = pstClassifierEntry->pstPhsRule;
728
729 if(!ValidatePHSRuleComplete(pstPhsRule))
730 {
731 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS Rule Defined For Classifier But Not Complete\n");
732 lStatus = STATUS_PHS_NOCOMPRESSION ;
733 return lStatus;
734 }
735
736
737 lStatus = phs_compress(pstPhsRule,(PUCHAR)pvInputBuffer,
738 (PUCHAR)pvOutputBuffer, pOldHeaderSize,pNewHeaderSize);
739
740 if(lStatus == STATUS_PHS_COMPRESSED)
741 {
742 pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1;
743 pstPhsRule->PHSModifiedNumPackets++;
744 }
745 else
746 pstPhsRule->PHSErrorNumPackets++;
747
748 return lStatus;
749}
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770ULONG PhsDeCompress(IN void* pvContext,
771 IN B_UINT16 uiVcid,
772 IN void *pvInputBuffer,
773 OUT void *pvOutputBuffer,
774 OUT UINT *pInHeaderSize,
775 OUT UINT *pOutHeaderSize )
776{
777 UINT nSFIndex =0, nPhsRuleIndex =0 ;
778 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
779 S_PHS_RULE *pstPhsRule = NULL;
780 UINT phsi;
781 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
782 PPHS_DEVICE_EXTENSION pDeviceExtension=
783 (PPHS_DEVICE_EXTENSION)pvContext;
784
785 *pInHeaderSize = 0;
786
787 if(pDeviceExtension == NULL)
788 {
789 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"Invalid Device Extension\n");
790 return ERR_PHS_INVALID_DEVICE_EXETENSION;
791 }
792
793 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"Restoring header\n");
794
795 phsi = *((unsigned char *)(pvInputBuffer));
796 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x\n",phsi);
797 if(phsi == UNCOMPRESSED_PACKET )
798 {
799 return STATUS_PHS_NOCOMPRESSION;
800 }
801
802
803 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
804 uiVcid,&pstServiceFlowEntry);
805 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
806 {
807 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n");
808 return ERR_SF_MATCH_FAIL;
809 }
810
811 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,phsi,
812 eActiveClassifierRuleContext,&pstPhsRule);
813 if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
814 {
815
816 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
817 phsi,eOldClassifierRuleContext,&pstPhsRule);
818 if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
819 {
820 return ERR_PHSRULE_MATCH_FAIL;
821 }
822
823 }
824
825 *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer,
826 (PUCHAR)pvOutputBuffer,pstPhsRule,pOutHeaderSize);
827
828 pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1;
829
830 pstPhsRule->PHSModifiedNumPackets++;
831 return STATUS_PHS_COMPRESSED;
832}
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
848{
849 int i,j;
850 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
851
852 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n");
853 if(psServiceFlowRulesTable)
854 {
855 for(i=0;i<MAX_SERVICEFLOWS;i++)
856 {
857 S_SERVICEFLOW_ENTRY stServiceFlowEntry =
858 psServiceFlowRulesTable->stSFList[i];
859 S_CLASSIFIER_TABLE *pstClassifierRulesTable =
860 stServiceFlowEntry.pstClassifierTable;
861
862 if(pstClassifierRulesTable)
863 {
864 for(j=0;j<MAX_PHSRULE_PER_SF;j++)
865 {
866 if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule)
867 {
868 if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
869 ->u8RefCnt)
870 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
871 ->u8RefCnt--;
872 if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
873 ->u8RefCnt)
874 kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
875 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
876 }
877 if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule)
878 {
879 if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
880 ->u8RefCnt)
881 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
882 ->u8RefCnt--;
883 if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
884 ->u8RefCnt)
885 kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
886 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
887 }
888 }
889 kfree(pstClassifierRulesTable);
890 stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
891 }
892 }
893 }
894
895 kfree(psServiceFlowRulesTable);
896 psServiceFlowRulesTable = NULL;
897}
898
899
900
901static BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
902{
903 if(psPhsRule)
904 {
905 if(!psPhsRule->u8PHSI)
906 {
907
908 return FALSE;
909 }
910
911 if(!psPhsRule->u8PHSS)
912 {
913
914 return FALSE;
915 }
916
917
918 if(!psPhsRule->u8PHSFLength)
919 {
920 return FALSE;
921 }
922 return TRUE;
923 }
924 else
925 {
926 return FALSE;
927 }
928}
929
930UINT GetServiceFlowEntry(IN S_SERVICEFLOW_TABLE *psServiceFlowTable,
931 IN B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry)
932{
933 int i;
934 for(i=0;i<MAX_SERVICEFLOWS;i++)
935 {
936 if(psServiceFlowTable->stSFList[i].bUsed)
937 {
938 if(psServiceFlowTable->stSFList[i].uiVcid == uiVcid)
939 {
940 *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i];
941 return i;
942 }
943 }
944 }
945
946 *ppstServiceFlowEntry = NULL;
947 return PHS_INVALID_TABLE_INDEX;
948}
949
950
951UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
952 IN B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
953 OUT S_CLASSIFIER_ENTRY **ppstClassifierEntry)
954{
955 int i;
956 S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
957 for(i=0;i<MAX_PHSRULE_PER_SF;i++)
958 {
959
960 if(eClsContext == eActiveClassifierRuleContext)
961 {
962 psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i];
963 }
964 else
965 {
966 psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i];
967 }
968
969 if(psClassifierRules->bUsed)
970 {
971 if(psClassifierRules->uiClassifierRuleId == uiClsid)
972 {
973 *ppstClassifierEntry = psClassifierRules;
974 return i;
975 }
976 }
977
978 }
979
980 *ppstClassifierEntry = NULL;
981 return PHS_INVALID_TABLE_INDEX;
982}
983
984static UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
985 IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
986 OUT S_PHS_RULE **ppstPhsRule)
987{
988 int i;
989 S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
990 for(i=0;i<MAX_PHSRULE_PER_SF;i++)
991 {
992 if(eClsContext == eActiveClassifierRuleContext)
993 {
994 pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i];
995 }
996 else
997 {
998 pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i];
999 }
1000 if(pstClassifierRule->bUsed)
1001 {
1002 if(pstClassifierRule->u8PHSI == uiPHSI)
1003 {
1004 *ppstPhsRule = pstClassifierRule->pstPhsRule;
1005 return i;
1006 }
1007 }
1008
1009 }
1010
1011 *ppstPhsRule = NULL;
1012 return PHS_INVALID_TABLE_INDEX;
1013}
1014
1015UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId,
1016 IN S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,
1017 B_UINT8 u8AssociatedPHSI)
1018{
1019
1020 S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
1021 UINT uiStatus = 0;
1022 int iSfIndex;
1023 BOOLEAN bFreeEntryFound =FALSE;
1024
1025 for(iSfIndex=0;iSfIndex < MAX_SERVICEFLOWS;iSfIndex++)
1026 {
1027 if(!psServiceFlowTable->stSFList[iSfIndex].bUsed)
1028 {
1029 bFreeEntryFound = TRUE;
1030 break;
1031 }
1032 }
1033
1034 if(!bFreeEntryFound)
1035 return ERR_SFTABLE_FULL;
1036
1037
1038 psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable;
1039 uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,psPhsRule,
1040 eActiveClassifierRuleContext,u8AssociatedPHSI);
1041 if(uiStatus == PHS_SUCCESS)
1042 {
1043
1044 psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE;
1045 psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid;
1046 }
1047
1048 return uiStatus;
1049
1050}
1051
1052UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
1053 IN B_UINT16 uiClsId,IN S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,
1054 S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI)
1055{
1056 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
1057 UINT uiStatus =PHS_SUCCESS;
1058 UINT nClassifierIndex = 0;
1059 S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
1060 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1061 psaClassifiertable = pstServiceFlowEntry->pstClassifierTable;
1062
1063 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>");
1064
1065
1066 nClassifierIndex =GetClassifierEntry(
1067 pstServiceFlowEntry->pstClassifierTable,uiClsId,
1068 eActiveClassifierRuleContext,&pstClassifierEntry);
1069 if(nClassifierIndex == PHS_INVALID_TABLE_INDEX)
1070 {
1071
1072
1073
1074
1075
1076 uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,
1077 psPhsRule,eActiveClassifierRuleContext,u8AssociatedPHSI);
1078 return uiStatus;
1079 }
1080
1081
1082
1083
1084
1085 if(pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI)
1086 {
1087 if(pstClassifierEntry->pstPhsRule == NULL)
1088 return ERR_PHS_INVALID_PHS_RULE;
1089
1090
1091
1092
1093
1094
1095 if(psPhsRule->u8PHSFLength)
1096 {
1097
1098 memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
1099 psPhsRule->u8PHSF , MAX_PHS_LENGTHS);
1100 }
1101 if(psPhsRule->u8PHSFLength)
1102 {
1103
1104 pstClassifierEntry->pstPhsRule->u8PHSFLength =
1105 psPhsRule->u8PHSFLength;
1106 }
1107 if(psPhsRule->u8PHSMLength)
1108 {
1109
1110 memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
1111 psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
1112 }
1113 if(psPhsRule->u8PHSMLength)
1114 {
1115
1116 pstClassifierEntry->pstPhsRule->u8PHSMLength =
1117 psPhsRule->u8PHSMLength;
1118 }
1119 if(psPhsRule->u8PHSS)
1120 {
1121
1122 pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS;
1123 }
1124
1125
1126 pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV;
1127
1128 }
1129 else
1130 {
1131
1132
1133
1134 uiStatus=UpdateClassifierPHSRule( uiClsId, pstClassifierEntry,
1135 psaClassifiertable, psPhsRule, u8AssociatedPHSI);
1136 }
1137
1138
1139
1140 return uiStatus;
1141}
1142
1143static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
1144 S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
1145 E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI)
1146{
1147 UINT iClassifierIndex = 0;
1148 BOOLEAN bFreeEntryFound = FALSE;
1149 S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
1150 UINT nStatus = PHS_SUCCESS;
1151 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1152 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Inside CreateClassifierPHSRule");
1153 if(psaClassifiertable == NULL)
1154 {
1155 return ERR_INVALID_CLASSIFIERTABLE_FOR_SF;
1156 }
1157
1158 if(eClsContext == eOldClassifierRuleContext)
1159 {
1160
1161
1162
1163 iClassifierIndex =
1164 GetClassifierEntry(psaClassifiertable, uiClsId,
1165 eClsContext,&psClassifierRules);
1166 if(iClassifierIndex != PHS_INVALID_TABLE_INDEX)
1167 {
1168
1169
1170
1171
1172 bFreeEntryFound = TRUE;
1173 }
1174 }
1175
1176 if(!bFreeEntryFound)
1177 {
1178
1179
1180
1181 for(iClassifierIndex = 0; iClassifierIndex <
1182 MAX_PHSRULE_PER_SF; iClassifierIndex++)
1183 {
1184 if(eClsContext == eActiveClassifierRuleContext)
1185 {
1186 psClassifierRules =
1187 &psaClassifiertable->stActivePhsRulesList[iClassifierIndex];
1188 }
1189 else
1190 {
1191 psClassifierRules =
1192 &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
1193 }
1194
1195 if(!psClassifierRules->bUsed)
1196 {
1197 bFreeEntryFound = TRUE;
1198 break;
1199 }
1200 }
1201 }
1202
1203 if(!bFreeEntryFound)
1204 {
1205 if(eClsContext == eActiveClassifierRuleContext)
1206 {
1207 return ERR_CLSASSIFIER_TABLE_FULL;
1208 }
1209 else
1210 {
1211
1212 if(psaClassifiertable->uiOldestPhsRuleIndex >=
1213 MAX_PHSRULE_PER_SF)
1214 {
1215 psaClassifiertable->uiOldestPhsRuleIndex =0;
1216 }
1217
1218 iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex;
1219 psClassifierRules =
1220 &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
1221
1222 (psaClassifiertable->uiOldestPhsRuleIndex)++;
1223 }
1224 }
1225
1226 if(eClsContext == eOldClassifierRuleContext)
1227 {
1228 if(psClassifierRules->pstPhsRule == NULL)
1229 {
1230 psClassifierRules->pstPhsRule = kmalloc(sizeof(S_PHS_RULE),GFP_KERNEL);
1231
1232 if(NULL == psClassifierRules->pstPhsRule)
1233 return ERR_PHSRULE_MEMALLOC_FAIL;
1234 }
1235
1236 psClassifierRules->bUsed = TRUE;
1237 psClassifierRules->uiClassifierRuleId = uiClsId;
1238 psClassifierRules->u8PHSI = psPhsRule->u8PHSI;
1239 psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
1240
1241
1242 memcpy(psClassifierRules->pstPhsRule,
1243 psPhsRule, sizeof(S_PHS_RULE));
1244 }
1245 else
1246 {
1247 nStatus = UpdateClassifierPHSRule(uiClsId,psClassifierRules,
1248 psaClassifiertable,psPhsRule,u8AssociatedPHSI);
1249 }
1250 return nStatus;
1251}
1252
1253
1254static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
1255 IN S_CLASSIFIER_ENTRY *pstClassifierEntry,
1256 S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
1257 B_UINT8 u8AssociatedPHSI)
1258{
1259 S_PHS_RULE *pstAddPhsRule = NULL;
1260 UINT nPhsRuleIndex = 0;
1261 BOOLEAN bPHSRuleOrphaned = FALSE;
1262 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1263 psPhsRule->u8RefCnt =0;
1264
1265
1266 bPHSRuleOrphaned = DerefPhsRule( uiClsId, psaClassifiertable,
1267 pstClassifierEntry->pstPhsRule);
1268
1269
1270 nPhsRuleIndex =GetPhsRuleEntry(psaClassifiertable,u8AssociatedPHSI,
1271 eActiveClassifierRuleContext, &pstAddPhsRule);
1272 if(PHS_INVALID_TABLE_INDEX == nPhsRuleIndex)
1273 {
1274 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier");
1275
1276 if(psPhsRule->u8PHSI == 0)
1277 {
1278 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n");
1279 return ERR_PHS_INVALID_PHS_RULE;
1280 }
1281
1282 if(FALSE == bPHSRuleOrphaned)
1283 {
1284 pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL);
1285 if(NULL == pstClassifierEntry->pstPhsRule)
1286 {
1287 return ERR_PHSRULE_MEMALLOC_FAIL;
1288 }
1289 }
1290 memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
1291
1292 }
1293 else
1294 {
1295
1296 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
1297 if(bPHSRuleOrphaned)
1298 {
1299 kfree(pstClassifierEntry->pstPhsRule);
1300 pstClassifierEntry->pstPhsRule = NULL;
1301 }
1302 pstClassifierEntry->pstPhsRule = pstAddPhsRule;
1303
1304 }
1305 pstClassifierEntry->bUsed = TRUE;
1306 pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI;
1307 pstClassifierEntry->uiClassifierRuleId = uiClsId;
1308 pstClassifierEntry->pstPhsRule->u8RefCnt++;
1309 pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;
1310
1311 return PHS_SUCCESS;
1312
1313}
1314
1315static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
1316{
1317 if(pstPhsRule==NULL)
1318 return FALSE;
1319 if(pstPhsRule->u8RefCnt)
1320 pstPhsRule->u8RefCnt--;
1321 if(0==pstPhsRule->u8RefCnt)
1322 {
1323
1324
1325
1326 return TRUE;
1327 }
1328 else
1329 {
1330 return FALSE;
1331 }
1332}
1333
1334void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)
1335{
1336 int i,j,k,l;
1337 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1338 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules : \n");
1339 for(i=0;i<MAX_SERVICEFLOWS;i++)
1340 {
1341 S_SERVICEFLOW_ENTRY stServFlowEntry =
1342 pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i];
1343 if(stServFlowEntry.bUsed)
1344 {
1345 for(j=0;j<MAX_PHSRULE_PER_SF;j++)
1346 {
1347 for(l=0;l<2;l++)
1348 {
1349 S_CLASSIFIER_ENTRY stClsEntry;
1350 if(l==0)
1351 {
1352 stClsEntry = stServFlowEntry.pstClassifierTable->stActivePhsRulesList[j];
1353 if(stClsEntry.bUsed)
1354 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule : \n");
1355 }
1356 else
1357 {
1358 stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j];
1359 if(stClsEntry.bUsed)
1360 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule : \n");
1361 }
1362 if(stClsEntry.bUsed)
1363 {
1364
1365 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X",stServFlowEntry.uiVcid);
1366 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X",stClsEntry.uiClassifierRuleId);
1367 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X",stClsEntry.u8PHSI);
1368 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n");
1369 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X",stClsEntry.pstPhsRule->u8PHSI);
1370 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ",stClsEntry.pstPhsRule->u8PHSFLength);
1371 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : ");
1372 for(k=0;k<stClsEntry.pstPhsRule->u8PHSFLength;k++)
1373 {
1374 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSF[k]);
1375 }
1376 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X",stClsEntry.pstPhsRule->u8PHSMLength);
1377 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :");
1378 for(k=0;k<stClsEntry.pstPhsRule->u8PHSMLength;k++)
1379 {
1380 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSM[k]);
1381 }
1382 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ",stClsEntry.pstPhsRule->u8PHSS);
1383 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X",stClsEntry.pstPhsRule->u8PHSV);
1384 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n");
1385 }
1386 }
1387 }
1388 }
1389 }
1390}
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
1411 S_PHS_RULE *decomp_phs_rules,UINT *header_size)
1412{
1413 int phss,size=0;
1414 S_PHS_RULE *tmp_memb;
1415 int bit,i=0;
1416 unsigned char *phsf,*phsm;
1417 int in_buf_len = *header_size-1;
1418 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1419 in_buf++;
1420 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"====>\n");
1421 *header_size = 0;
1422
1423 if((decomp_phs_rules == NULL ))
1424 return 0;
1425
1426
1427 tmp_memb = decomp_phs_rules;
1428
1429
1430 phss = tmp_memb->u8PHSS;
1431 phsf = tmp_memb->u8PHSF;
1432 phsm = tmp_memb->u8PHSM;
1433
1434 if(phss > MAX_PHS_LENGTHS)
1435 phss = MAX_PHS_LENGTHS;
1436
1437 while((phss > 0) && (size < in_buf_len))
1438 {
1439 bit = ((*phsm << i)& SUPPRESS);
1440
1441 if(bit == SUPPRESS)
1442 {
1443 *out_buf = *phsf;
1444 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d",
1445 phss,*phsf,*out_buf);
1446 }
1447 else
1448 {
1449 *out_buf = *in_buf;
1450 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d",
1451 phss,*in_buf,*out_buf);
1452 in_buf++;
1453 size++;
1454 }
1455 out_buf++;
1456 phsf++;
1457 phss--;
1458 i++;
1459 *header_size=*header_size + 1;
1460
1461 if(i > MAX_NO_BIT)
1462 {
1463 i=0;
1464 phsm++;
1465 }
1466 }
1467 return size;
1468}
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf
1494 ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
1495{
1496 unsigned char *old_addr = out_buf;
1497 int suppress = 0;
1498 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1499 if(phs_rule == NULL)
1500 {
1501 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nphs_compress(): phs_rule null!");
1502 *out_buf = ZERO_PHSI;
1503 return STATUS_PHS_NOCOMPRESSION;
1504 }
1505
1506
1507 if(phs_rule->u8PHSS <= *new_header_size)
1508 {
1509 *header_size = phs_rule->u8PHSS;
1510 }
1511 else
1512 {
1513 *header_size = *new_header_size;
1514 }
1515
1516 out_buf++;
1517 suppress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF,
1518 phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size);
1519
1520 if(suppress == STATUS_PHS_COMPRESSED)
1521 {
1522 *old_addr = (unsigned char)phs_rule->u8PHSI;
1523 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress phsi %d",phs_rule->u8PHSI);
1524 }
1525 else
1526 {
1527 *old_addr = ZERO_PHSI;
1528 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress PHSV Verification failed");
1529 }
1530 return suppress;
1531}
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
1555 unsigned char *phsf,unsigned char *phsm,unsigned int phss,
1556 unsigned int phsv,UINT* new_header_size)
1557{
1558 unsigned int size=0;
1559 int bit,i=0;
1560 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1561 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf PHSM - 0x%X",*phsm);
1562
1563
1564 if(phss>(*new_header_size))
1565 {
1566 phss=*new_header_size;
1567 }
1568 while(phss > 0)
1569 {
1570 bit = ((*phsm << i)& SUPPRESS);
1571 if(bit == SUPPRESS)
1572 {
1573
1574 if(*in_buffer != *phsf)
1575 {
1576 if(phsv == VERIFY)
1577 {
1578 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf failed for field %d buf %d phsf %d",phss,*in_buffer,*phsf);
1579 return STATUS_PHS_NOCOMPRESSION;
1580 }
1581 }
1582 else
1583 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success for field %d buf %d phsf %d",phss,*in_buffer,*phsf);
1584 }
1585 else
1586 {
1587 *out_buffer = *in_buffer;
1588 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In copying_header input %d out %d",*in_buffer,*out_buffer);
1589 out_buffer++;
1590 size++;
1591 }
1592 in_buffer++;
1593 phsf++;
1594 phss--;
1595 i++;
1596 if(i > MAX_NO_BIT)
1597 {
1598 i=0;
1599 phsm++;
1600 }
1601 }
1602 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success");
1603 *new_header_size = size;
1604 return STATUS_PHS_COMPRESSED;
1605}
1606
1607
1608
1609
1610
1611
1612