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