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