blob: 4aa2b71a40ebe40a1d5c27b8506443955e18e650 [file] [log] [blame]
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001#include "headers.h"
2
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04003static 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
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070049#define IN
50#define OUT
51
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070052/*
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
57 to be suppressed.It then supresses the header by invoking PHS exported compress routine.
58 The header data after supression is copied back to the NDIS_PACKET.
59
60
61Input parameters: IN PMINI_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
68Return: STATUS_SUCCESS - If the send was successful.
69 Other - If an error occured.
70*/
71
72int PHSTransmit(PMINI_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.ucaHdrSupressionInBuf;
88 /* Pointer to PHS OUT Hdr Buffer */
89 PUCHAR pucPHSPktHdrOutBuf =
90 Adapter->stPhsTxContextInfo.ucaHdrSupressionOutBuf;
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 supression
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
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700128 // Step 2 Supress 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
Stephen Hemminger082e8892010-11-01 09:35:21 -0400165 dev_kfree_skb(Packet);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700166 *pPacket = Packet = newPacket;
167 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
168 }
169
170 numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);
171
Stephen Hemminger082e8892010-11-01 09:35:21 -0400172 memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
173 memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700174 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
Joe Perchesceeb6fe2011-06-23 11:40:18 -0700212int PHSReceive(PMINI_ADAPTER Adapter,
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700213 USHORT usVcid,
214 struct sk_buff *packet,
215 UINT *punPacketLen,
216 UCHAR *pucEthernetHdr,
217 UINT bHeaderSuppressionEnabled)
218{
219 u32 nStandardPktHdrLen = 0;
220 u32 nTotalsupressedPktHdrBytes = 0;
221 int ulPhsStatus = 0;
222 PUCHAR pucInBuff = NULL ;
223 UINT TotalBytesAdded = 0;
224 if(!bHeaderSuppressionEnabled)
225 {
Joe Perchesceeb6fe2011-06-23 11:40:18 -0700226 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700227 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 &nTotalsupressedPktHdrBytes,
239 &nStandardPktHdrLen);
240
Joe Perchesceeb6fe2011-06-23 11:40:18 -0700241 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700242 nTotalsupressedPktHdrBytes,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 - nTotalsupressedPktHdrBytes - 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
Stephen Hemminger082e8892010-11-01 09:35:21 -0400268 memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700269 }
270
271 return STATUS_SUCCESS;
272}
273
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700274void DumpFullPacket(UCHAR *pBuf,UINT nPktLen)
275{
276 PMINI_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//-----------------------------------------------------------------------------
294int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_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 =
Stephen Hemminger082e8892010-11-01 09:35:21 -0400304 kzalloc(sizeof(S_SERVICEFLOW_TABLE), GFP_KERNEL);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700305
Stephen Hemminger082e8892010-11-01 09:35:21 -0400306 if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700307 {
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];
Stephen Hemminger082e8892010-11-01 09:35:21 -0400316 sServiceFlow.pstClassifierTable = kzalloc(sizeof(S_CLASSIFIER_TABLE), GFP_KERNEL);
317 if(!sServiceFlow.pstClassifierTable)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700318 {
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
Stephen Hemminger082e8892010-11-01 09:35:21 -0400327 pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700328
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
Stephen Hemminger082e8892010-11-01 09:35:21 -0400337 pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700338 if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
339 {
340 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
Stephen Hemminger082e8892010-11-01 09:35:21 -0400341 kfree(pPhsdeviceExtension->CompressedTxBuffer);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700342 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 Successfull");
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
Stephen Hemminger082e8892010-11-01 09:35:21 -0400362 kfree(pPHSDeviceExt->CompressedTxBuffer);
363 pPHSDeviceExt->CompressedTxBuffer = NULL;
364
365 kfree(pPHSDeviceExt->UnCompressedRxBuffer);
366 pPHSDeviceExt->UnCompressedRxBuffer = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700367
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;
401 PMINI_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/*++
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;
465 PMINI_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 {
Stephen Hemminger082e8892010-11-01 09:35:21 -0400492 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,
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700498 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;
531 PMINI_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)
Stephen Hemminger082e8892010-11-01 09:35:21 -0400554 kfree(pstClassifierEntry->pstPhsRule);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700555
556 }
Stephen Hemminger082e8892010-11-01 09:35:21 -0400557 memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700558 }
559
560 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
561 uiClsId,eOldClassifierRuleContext,&pstClassifierEntry);
562
563 if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
564 {
Stephen Hemminger082e8892010-11-01 09:35:21 -0400565 kfree(pstClassifierEntry->pstPhsRule);
566 memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700567 }
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;
595 PMINI_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)
Stephen Hemminger082e8892010-11-01 09:35:21 -0400623 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700624 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
625 .pstPhsRule = NULL;
626 }
Stephen Hemminger082e8892010-11-01 09:35:21 -0400627 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700628 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)
Stephen Hemminger082e8892010-11-01 09:35:21 -0400636 kfree(pstClassifierRulesTable
637 ->stOldPhsRulesList[nClsidIndex].pstPhsRule);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700638 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
639 .pstPhsRule = NULL;
640 }
Stephen Hemminger082e8892010-11-01 09:35:21 -0400641 memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700642 }
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;
687 PMINI_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/*++
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;
781 PMINI_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 {
Joe Perchesceeb6fe2011-06-23 11:40:18 -0700789 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"Invalid Device Extension\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700790 return ERR_PHS_INVALID_DEVICE_EXETENSION;
791 }
792
Joe Perchesceeb6fe2011-06-23 11:40:18 -0700793 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"Restoring header\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700794
795 phsi = *((unsigned char *)(pvInputBuffer));
Joe Perchesceeb6fe2011-06-23 11:40:18 -0700796 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x\n",phsi);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700797 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 {
Joe Perchesceeb6fe2011-06-23 11:40:18 -0700807 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700808 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
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -0400847static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700848{
849 int i,j;
850 PMINI_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)
Stephen Hemminger082e8892010-11-01 09:35:21 -0400874 kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700875 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)
Stephen Hemminger082e8892010-11-01 09:35:21 -0400885 kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700886 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
887 }
888 }
Stephen Hemminger082e8892010-11-01 09:35:21 -0400889 kfree(pstClassifierRulesTable);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700890 stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
891 }
892 }
893 }
894
Stephen Hemminger082e8892010-11-01 09:35:21 -0400895 kfree(psServiceFlowRulesTable);
896 psServiceFlowRulesTable = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700897}
898
899
900
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -0400901static BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700902{
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
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -0400984static UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
985 IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
986 OUT S_PHS_RULE **ppstPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700987{
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;
1060 PMINI_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
Stephen Hemminger082e8892010-11-01 09:35:21 -04001098 memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001099 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
Stephen Hemminger082e8892010-11-01 09:35:21 -04001110 memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001111 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
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04001143static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001144 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 PMINI_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 {
Stephen Hemminger082e8892010-11-01 09:35:21 -04001230 psClassifierRules->pstPhsRule = kmalloc(sizeof(S_PHS_RULE),GFP_KERNEL);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001231
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 */
Stephen Hemminger082e8892010-11-01 09:35:21 -04001242 memcpy(psClassifierRules->pstPhsRule,
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001243 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
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04001254static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001255 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 PMINI_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 {
Stephen Hemminger082e8892010-11-01 09:35:21 -04001284 pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001285 if(NULL == pstClassifierEntry->pstPhsRule)
1286 {
1287 return ERR_PHSRULE_MEMALLOC_FAIL;
1288 }
1289 }
Stephen Hemminger082e8892010-11-01 09:35:21 -04001290 memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001291
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 {
Stephen Hemminger082e8892010-11-01 09:35:21 -04001299 kfree(pstClassifierEntry->pstPhsRule);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001300 pstClassifierEntry->pstPhsRule = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001301 }
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
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04001315static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001316{
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
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001334void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)
1335{
1336 int i,j,k,l;
1337 PMINI_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
1410int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
1411 S_PHS_RULE *decomp_phs_rules,UINT *header_size)
1412{
1413 int phss,size=0;
1414 S_PHS_RULE *tmp_memb;
1415 int bit,i=0;
1416 unsigned char *phsf,*phsm;
1417 int in_buf_len = *header_size-1;
1418 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1419 in_buf++;
Joe Perchesceeb6fe2011-06-23 11:40:18 -07001420 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"====>\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001421 *header_size = 0;
1422
1423 if((decomp_phs_rules == NULL ))
1424 return 0;
1425
1426
1427 tmp_memb = decomp_phs_rules;
Joe Perchesceeb6fe2011-06-23 11:40:18 -07001428 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001429 //*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;
Joe Perchesceeb6fe2011-06-23 11:40:18 -07001436 //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));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001437 while((phss > 0) && (size < in_buf_len))
1438 {
1439 bit = ((*phsm << i)& SUPPRESS);
1440
1441 if(bit == SUPPRESS)
1442 {
1443 *out_buf = *phsf;
Joe Perchesceeb6fe2011-06-23 11:40:18 -07001444 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d",
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001445 phss,*phsf,*out_buf);
1446 }
1447 else
1448 {
1449 *out_buf = *in_buf;
Joe Perchesceeb6fe2011-06-23 11:40:18 -07001450 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d",
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001451 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//-----------------------------------------------------------------------------
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04001493static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf
1494 ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001495{
1496 unsigned char *old_addr = out_buf;
1497 int supress = 0;
1498 PMINI_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 supress = 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(supress == 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 supress;
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
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04001554static 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)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001557{
1558 unsigned int size=0;
1559 int bit,i=0;
1560 PMINI_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