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