Merge tag 'sound-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
[linux-2.6-block.git] / drivers / staging / bcm / PHSModule.c
CommitLineData
f8942e07
SH
1#include "headers.h"
2
9dd47ee7
SH
3static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
4
5static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
6
7static UINT CreateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI);
8
9static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
10
11static BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule);
12
13static BOOLEAN DerefPhsRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule);
14
15static UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry);
16
17static UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule);
18
19static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable);
20
21static int phs_compress(S_PHS_RULE *phs_members,unsigned char *in_buf,
22 unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size );
23
24
25static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
26 unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size );
27
28static int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\
29 S_PHS_RULE *phs_rules,UINT *header_size);
30
31
32static ULONG PhsCompress(void* pvContext,
33 B_UINT16 uiVcid,
34 B_UINT16 uiClsId,
35 void *pvInputBuffer,
36 void *pvOutputBuffer,
37 UINT *pOldHeaderSize,
38 UINT *pNewHeaderSize );
39
40static ULONG PhsDeCompress(void* pvContext,
41 B_UINT16 uiVcid,
42 void *pvInputBuffer,
43 void *pvOutputBuffer,
44 UINT *pInHeaderSize,
45 UINT *pOutHeaderSize);
46
47
48
f8942e07
SH
49#define IN
50#define OUT
51
f8942e07
SH
52/*
53Function: PHSTransmit
54
55Description: This routine handle PHS(Payload Header Suppression for Tx path.
56 It extracts a fragment of the NDIS_PACKET containing the header
f922ffc0
PM
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.
f8942e07
SH
59
60
2979460d 61Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context
f8942e07
SH
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
68Return: STATUS_SUCCESS - If the send was successful.
ae0c514c 69 Other - If an error occurred.
f8942e07
SH
70*/
71
2979460d 72int PHSTransmit(struct bcm_mini_adapter *Adapter,
f8942e07
SH
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 =
b38e274f 87 Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf;
f8942e07
SH
88 /* Pointer to PHS OUT Hdr Buffer */
89 PUCHAR pucPHSPktHdrOutBuf =
b38e274f 90 Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf;
f8942e07
SH
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 /*
f922ffc0 104 Accumulate the header upto the size we support suppression
f8942e07
SH
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
f922ffc0 128 // Step 2 Suppress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf.
f8942e07
SH
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
082e889b 165 dev_kfree_skb(Packet);
f8942e07
SH
166 *pPacket = Packet = newPacket;
167 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
168 }
169
170 numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);
171
082e889b
SH
172 memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
173 memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
f8942e07
SH
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
2979460d 212int PHSReceive(struct bcm_mini_adapter *Adapter,
f8942e07
SH
213 USHORT usVcid,
214 struct sk_buff *packet,
215 UINT *punPacketLen,
216 UCHAR *pucEthernetHdr,
217 UINT bHeaderSuppressionEnabled)
218{
219 u32 nStandardPktHdrLen = 0;
b38e274f 220 u32 nTotalsuppressedPktHdrBytes = 0;
f8942e07
SH
221 int ulPhsStatus = 0;
222 PUCHAR pucInBuff = NULL ;
223 UINT TotalBytesAdded = 0;
224 if(!bHeaderSuppressionEnabled)
225 {
ceeb6fec 226 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet");
f8942e07
SH
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,
b38e274f 238 &nTotalsuppressedPktHdrBytes,
f8942e07
SH
239 &nStandardPktHdrLen);
240
f922ffc0 241 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
b38e274f 242 nTotalsuppressedPktHdrBytes,nStandardPktHdrLen);
f8942e07
SH
243
244 if(ulPhsStatus != STATUS_PHS_COMPRESSED)
245 {
246 skb_pull(packet, 1);
247 return STATUS_SUCCESS;
248 }
249 else
250 {
b38e274f 251 TotalBytesAdded = nStandardPktHdrLen - nTotalsuppressedPktHdrBytes - PHSI_LEN;
f8942e07
SH
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
082e889b 268 memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
f8942e07
SH
269 }
270
271 return STATUS_SUCCESS;
272}
273
f8942e07
SH
274void DumpFullPacket(UCHAR *pBuf,UINT nPktLen)
275{
2979460d 276 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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//-----------------------------------------------------------------------------
2979460d 294int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension, struct bcm_mini_adapter *Adapter)
f8942e07
SH
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 =
082e889b 304 kzalloc(sizeof(S_SERVICEFLOW_TABLE), GFP_KERNEL);
f8942e07 305
082e889b 306 if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
f8942e07
SH
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];
082e889b
SH
316 sServiceFlow.pstClassifierTable = kzalloc(sizeof(S_CLASSIFIER_TABLE), GFP_KERNEL);
317 if(!sServiceFlow.pstClassifierTable)
f8942e07
SH
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
082e889b 327 pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
f8942e07
SH
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
082e889b 337 pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
f8942e07
SH
338 if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
339 {
340 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
082e889b 341 kfree(pPhsdeviceExtension->CompressedTxBuffer);
f8942e07
SH
342 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
343 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
344 return -ENOMEM;
345 }
346
347
348
ae0c514c 349 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successful");
f8942e07
SH
350 return STATUS_SUCCESS;
351}
352
353
354int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt)
355{
356 if(pPHSDeviceExt->pstServiceFlowPhsRulesTable)
357 {
358 free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable);
359 pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
360 }
361
082e889b
SH
362 kfree(pPHSDeviceExt->CompressedTxBuffer);
363 pPHSDeviceExt->CompressedTxBuffer = NULL;
364
365 kfree(pPHSDeviceExt->UnCompressedRxBuffer);
366 pPHSDeviceExt->UnCompressedRxBuffer = NULL;
f8942e07
SH
367
368 return 0;
369}
370
371
372
373//PHS functions
374/*++
375PhsUpdateClassifierRule
376
377Routine Description:
378 Exported function to add or modify a PHS Rule.
379
380Arguments:
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
386Return Value:
387
388 0 if successful,
389 >0 Error.
390
391--*/
392ULONG PhsUpdateClassifierRule(IN void* pvContext,
393 IN B_UINT16 uiVcid ,
394 IN B_UINT16 uiClsId ,
395 IN S_PHS_RULE *psPhsRule,
396 IN B_UINT8 u8AssociatedPHSI)
397{
398 ULONG lStatus =0;
399 UINT nSFIndex =0 ;
400 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
2979460d 401 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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/*++
442PhsDeletePHSRule
443
444Routine Description:
445 Deletes the specified phs Rule within Vcid
446
447Arguments:
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
452Return Value:
453
454 0 if successful,
455 >0 Error.
456
457--*/
458
459ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI)
460{
461 ULONG lStatus =0;
462 UINT nSFIndex =0, nClsidIndex =0 ;
463 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
464 S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
2979460d 465 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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 {
082e889b
SH
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,
f8942e07
SH
498 sizeof(S_CLASSIFIER_ENTRY));
499 }
500 }
501 }
502 }
503
504 }
505 return lStatus;
506}
507
508/*++
509PhsDeleteClassifierRule
510
511Routine Description:
512 Exported function to Delete a PHS Rule for the SFID,CLSID Pair.
513
514Arguments:
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
519Return Value:
520
521 0 if successful,
522 >0 Error.
523
524--*/
525ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 uiClsId)
526{
527 ULONG lStatus =0;
528 UINT nSFIndex =0, nClsidIndex =0 ;
529 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
530 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
2979460d 531 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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)
082e889b 554 kfree(pstClassifierEntry->pstPhsRule);
f8942e07
SH
555
556 }
082e889b 557 memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
f8942e07
SH
558 }
559
560 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
561 uiClsId,eOldClassifierRuleContext,&pstClassifierEntry);
562
563 if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
564 {
082e889b
SH
565 kfree(pstClassifierEntry->pstPhsRule);
566 memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
f8942e07
SH
567 }
568 }
569 return lStatus;
570}
571
572/*++
573PhsDeleteSFRules
574
575Routine Description:
576 Exported function to Delete a all PHS Rules for the SFID.
577
578Arguments:
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
582Return Value:
583
584 0 if successful,
585 >0 Error.
586
587--*/
588ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid)
589{
590
591 ULONG lStatus =0;
592 UINT nSFIndex =0, nClsidIndex =0 ;
593 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
594 S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
2979460d 595 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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)
082e889b 623 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
f8942e07
SH
624 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
625 .pstPhsRule = NULL;
626 }
082e889b 627 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
f8942e07
SH
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)
082e889b
SH
636 kfree(pstClassifierRulesTable
637 ->stOldPhsRulesList[nClsidIndex].pstPhsRule);
f8942e07
SH
638 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
639 .pstPhsRule = NULL;
640 }
082e889b 641 memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
f8942e07
SH
642 }
643 }
644 pstServiceFlowEntry->bUsed = FALSE;
645 pstServiceFlowEntry->uiVcid = 0;
646
647 }
648
649 return lStatus;
650}
651
652
653/*++
654PhsCompress
655
656Routine Description:
657 Exported function to compress the data using PHS.
658
659Arguments:
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
668Return Value:
669
670 0 if successful,
671 >0 Error.
672
673--*/
674ULONG PhsCompress(IN void* pvContext,
675 IN B_UINT16 uiVcid,
676 IN B_UINT16 uiClsId,
677 IN void *pvInputBuffer,
678 OUT void *pvOutputBuffer,
679 OUT UINT *pOldHeaderSize,
680 OUT UINT *pNewHeaderSize )
681{
682 UINT nSFIndex =0, nClsidIndex =0 ;
683 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
684 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
685 S_PHS_RULE *pstPhsRule = NULL;
686 ULONG lStatus =0;
2979460d 687 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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/*++
752PhsDeCompress
753
754Routine Description:
755 Exported function to restore the packet header in Rx path.
756
757Arguments:
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
764Return Value:
765
766 0 if successful,
767 >0 Error.
768
769--*/
770ULONG PhsDeCompress(IN void* pvContext,
771 IN B_UINT16 uiVcid,
772 IN void *pvInputBuffer,
773 OUT void *pvOutputBuffer,
774 OUT UINT *pInHeaderSize,
775 OUT UINT *pOutHeaderSize )
776{
777 UINT nSFIndex =0, nPhsRuleIndex =0 ;
778 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
779 S_PHS_RULE *pstPhsRule = NULL;
780 UINT phsi;
2979460d 781 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
782 PPHS_DEVICE_EXTENSION pDeviceExtension=
783 (PPHS_DEVICE_EXTENSION)pvContext;
784
785 *pInHeaderSize = 0;
786
787 if(pDeviceExtension == NULL)
788 {
ceeb6fec 789 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"Invalid Device Extension\n");
f8942e07
SH
790 return ERR_PHS_INVALID_DEVICE_EXETENSION;
791 }
792
ceeb6fec 793 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"Restoring header\n");
f8942e07
SH
794
795 phsi = *((unsigned char *)(pvInputBuffer));
ceeb6fec 796 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x\n",phsi);
f8942e07
SH
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 {
ceeb6fec 807 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n");
f8942e07
SH
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
9dd47ee7 847static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
f8942e07
SH
848{
849 int i,j;
2979460d 850 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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)
082e889b 874 kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
f8942e07
SH
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)
082e889b 885 kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
f8942e07
SH
886 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
887 }
888 }
082e889b 889 kfree(pstClassifierRulesTable);
f8942e07
SH
890 stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
891 }
892 }
893 }
894
082e889b
SH
895 kfree(psServiceFlowRulesTable);
896 psServiceFlowRulesTable = NULL;
f8942e07
SH
897}
898
899
900
9dd47ee7 901static BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
f8942e07
SH
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
930UINT GetServiceFlowEntry(IN S_SERVICEFLOW_TABLE *psServiceFlowTable,
931 IN B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry)
932{
933 int i;
934 for(i=0;i<MAX_SERVICEFLOWS;i++)
935 {
936 if(psServiceFlowTable->stSFList[i].bUsed)
937 {
938 if(psServiceFlowTable->stSFList[i].uiVcid == uiVcid)
939 {
940 *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i];
941 return i;
942 }
943 }
944 }
945
946 *ppstServiceFlowEntry = NULL;
947 return PHS_INVALID_TABLE_INDEX;
948}
949
950
951UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
952 IN B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
953 OUT S_CLASSIFIER_ENTRY **ppstClassifierEntry)
954{
955 int i;
956 S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
957 for(i=0;i<MAX_PHSRULE_PER_SF;i++)
958 {
959
960 if(eClsContext == eActiveClassifierRuleContext)
961 {
962 psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i];
963 }
964 else
965 {
966 psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i];
967 }
968
969 if(psClassifierRules->bUsed)
970 {
971 if(psClassifierRules->uiClassifierRuleId == uiClsid)
972 {
973 *ppstClassifierEntry = psClassifierRules;
974 return i;
975 }
976 }
977
978 }
979
980 *ppstClassifierEntry = NULL;
981 return PHS_INVALID_TABLE_INDEX;
982}
983
9dd47ee7
SH
984static UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
985 IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
986 OUT S_PHS_RULE **ppstPhsRule)
f8942e07
SH
987{
988 int i;
989 S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
990 for(i=0;i<MAX_PHSRULE_PER_SF;i++)
991 {
992 if(eClsContext == eActiveClassifierRuleContext)
993 {
994 pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i];
995 }
996 else
997 {
998 pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i];
999 }
1000 if(pstClassifierRule->bUsed)
1001 {
1002 if(pstClassifierRule->u8PHSI == uiPHSI)
1003 {
1004 *ppstPhsRule = pstClassifierRule->pstPhsRule;
1005 return i;
1006 }
1007 }
1008
1009 }
1010
1011 *ppstPhsRule = NULL;
1012 return PHS_INVALID_TABLE_INDEX;
1013}
1014
1015UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId,
1016 IN S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,
1017 B_UINT8 u8AssociatedPHSI)
1018{
1019
1020 S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
1021 UINT uiStatus = 0;
1022 int iSfIndex;
1023 BOOLEAN bFreeEntryFound =FALSE;
1024 //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
1052UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
1053 IN B_UINT16 uiClsId,IN S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,
1054 S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI)
1055{
1056 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
1057 UINT uiStatus =PHS_SUCCESS;
1058 UINT nClassifierIndex = 0;
1059 S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
2979460d 1060 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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
082e889b 1098 memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
f8942e07
SH
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
082e889b 1110 memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
f8942e07
SH
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
9dd47ee7 1143static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
f8942e07
SH
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;
2979460d 1151 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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 {
082e889b 1230 psClassifierRules->pstPhsRule = kmalloc(sizeof(S_PHS_RULE),GFP_KERNEL);
f8942e07
SH
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 */
082e889b 1242 memcpy(psClassifierRules->pstPhsRule,
f8942e07
SH
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
9dd47ee7 1254static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
f8942e07
SH
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;
2979460d 1262 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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 {
082e889b 1284 pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL);
f8942e07
SH
1285 if(NULL == pstClassifierEntry->pstPhsRule)
1286 {
1287 return ERR_PHSRULE_MEMALLOC_FAIL;
1288 }
1289 }
082e889b 1290 memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
f8942e07
SH
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 {
082e889b 1299 kfree(pstClassifierEntry->pstPhsRule);
f8942e07 1300 pstClassifierEntry->pstPhsRule = NULL;
f8942e07
SH
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
9dd47ee7 1315static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
f8942e07
SH
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
f8942e07
SH
1334void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)
1335{
1336 int i,j,k,l;
2979460d 1337 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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
1410int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
1411 S_PHS_RULE *decomp_phs_rules,UINT *header_size)
1412{
1413 int phss,size=0;
1414 S_PHS_RULE *tmp_memb;
1415 int bit,i=0;
1416 unsigned char *phsf,*phsm;
1417 int in_buf_len = *header_size-1;
2979460d 1418 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07 1419 in_buf++;
ceeb6fec 1420 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"====>\n");
f8942e07
SH
1421 *header_size = 0;
1422
1423 if((decomp_phs_rules == NULL ))
1424 return 0;
1425
1426
1427 tmp_memb = decomp_phs_rules;
ceeb6fec 1428 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
f8942e07
SH
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;
ceeb6fec 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));
f8942e07
SH
1437 while((phss > 0) && (size < in_buf_len))
1438 {
1439 bit = ((*phsm << i)& SUPPRESS);
1440
1441 if(bit == SUPPRESS)
1442 {
1443 *out_buf = *phsf;
ceeb6fec 1444 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d",
f8942e07
SH
1445 phss,*phsf,*out_buf);
1446 }
1447 else
1448 {
1449 *out_buf = *in_buf;
ceeb6fec 1450 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d",
f8942e07
SH
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//-----------------------------------------------------------------------------
9dd47ee7
SH
1493static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf
1494 ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
f8942e07
SH
1495{
1496 unsigned char *old_addr = out_buf;
b38e274f 1497 int suppress = 0;
2979460d 1498 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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++;
b38e274f 1517 suppress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF,
f8942e07
SH
1518 phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size);
1519
b38e274f 1520 if(suppress == STATUS_PHS_COMPRESSED)
f8942e07
SH
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 }
b38e274f 1530 return suppress;
f8942e07
SH
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
9dd47ee7
SH
1554static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
1555 unsigned char *phsf,unsigned char *phsm,unsigned int phss,
1556 unsigned int phsv,UINT* new_header_size)
f8942e07
SH
1557{
1558 unsigned int size=0;
1559 int bit,i=0;
2979460d 1560 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
f8942e07
SH
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