Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / bcm / PHSModule.c
1 #include "headers.h"
2
3 static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
4
5 static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
6
7 static UINT CreateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI);
8
9 static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
10
11 static BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule);
12
13 static BOOLEAN DerefPhsRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule);
14
15 static UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry);
16
17 static UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule);
18
19 static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable);
20
21 static int phs_compress(S_PHS_RULE *phs_members,unsigned char *in_buf,
22 unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size );
23
24
25 static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
26 unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size );
27
28 static int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\
29 S_PHS_RULE *phs_rules,UINT *header_size);
30
31
32 static ULONG PhsCompress(void* pvContext,
33 B_UINT16 uiVcid,
34 B_UINT16 uiClsId,
35 void *pvInputBuffer,
36 void *pvOutputBuffer,
37 UINT *pOldHeaderSize,
38 UINT *pNewHeaderSize );
39
40 static ULONG PhsDeCompress(void* pvContext,
41 B_UINT16 uiVcid,
42 void *pvInputBuffer,
43 void *pvOutputBuffer,
44 UINT *pInHeaderSize,
45 UINT *pOutHeaderSize);
46
47
48
49 #define IN
50 #define OUT
51
52 /*
53 Function: PHSTransmit
54
55 Description: This routine handle PHS(Payload Header Suppression for Tx path.
56 It extracts a fragment of the NDIS_PACKET containing the header
57 to be suppressed.It then supresses the header by invoking PHS exported compress routine.
58 The header data after supression is copied back to the NDIS_PACKET.
59
60
61 Input 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
68 Return: STATUS_SUCCESS - If the send was successful.
69 Other - If an error occured.
70 */
71
72 int 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
128 // 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
165 dev_kfree_skb(Packet);
166 *pPacket = Packet = newPacket;
167 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
168 }
169
170 numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);
171
172 memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
173 memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
174 skb_pull(Packet, numBytesCompressed);
175
176 return STATUS_SUCCESS;
177 }
178
179 else
180 {
181 //if one byte headroom is not available, increase it through skb_cow
182 if(!(skb_headroom(Packet) > 0))
183 {
184 if(skb_cow(Packet, 1))
185 {
186 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n");
187 return STATUS_FAILURE;
188 }
189 }
190 skb_push(Packet, 1);
191
192 // CAUTION: The MAC Header is getting corrupted here for IP CS - can be saved by copying 14 Bytes. not needed .... hence corrupting it.
193 *(Packet->data + BytesToRemove) = bPHSI;
194 return STATUS_SUCCESS;
195 }
196 }
197 else
198 {
199 if(!bHeaderSuppressionEnabled)
200 {
201 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nHeader Suppression Disabled For SF: No PHS\n");
202 }
203
204 return STATUS_SUCCESS;
205 }
206 }
207
208 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS");
209 return STATUS_SUCCESS;
210 }
211
212 int PHSRecieve(PMINI_ADAPTER Adapter,
213 USHORT usVcid,
214 struct sk_buff *packet,
215 UINT *punPacketLen,
216 UCHAR *pucEthernetHdr,
217 UINT bHeaderSuppressionEnabled)
218 {
219 u32 nStandardPktHdrLen = 0;
220 u32 nTotalsupressedPktHdrBytes = 0;
221 int ulPhsStatus = 0;
222 PUCHAR pucInBuff = NULL ;
223 UINT TotalBytesAdded = 0;
224 if(!bHeaderSuppressionEnabled)
225 {
226 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet");
227 return ulPhsStatus;
228 }
229
230 pucInBuff = packet->data;
231
232 //Restore PHS suppressed header
233 nStandardPktHdrLen = packet->len;
234 ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext,
235 usVcid,
236 pucInBuff,
237 Adapter->ucaPHSPktRestoreBuf,
238 &nTotalsupressedPktHdrBytes,
239 &nStandardPktHdrLen);
240
241 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
242 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
268 memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
269 }
270
271 return STATUS_SUCCESS;
272 }
273
274 void 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 //-----------------------------------------------------------------------------
294 int 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 =
304 kzalloc(sizeof(S_SERVICEFLOW_TABLE), GFP_KERNEL);
305
306 if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
307 {
308 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
309 return -ENOMEM;
310 }
311
312 pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable;
313 for(i=0;i<MAX_SERVICEFLOWS;i++)
314 {
315 S_SERVICEFLOW_ENTRY sServiceFlow = pstServiceFlowTable->stSFList[i];
316 sServiceFlow.pstClassifierTable = kzalloc(sizeof(S_CLASSIFIER_TABLE), GFP_KERNEL);
317 if(!sServiceFlow.pstClassifierTable)
318 {
319 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
320 free_phs_serviceflow_rules(pPhsdeviceExtension->
321 pstServiceFlowPhsRulesTable);
322 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
323 return -ENOMEM;
324 }
325 }
326
327 pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
328
329 if(pPhsdeviceExtension->CompressedTxBuffer == NULL)
330 {
331 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
332 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
333 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
334 return -ENOMEM;
335 }
336
337 pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
338 if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
339 {
340 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
341 kfree(pPhsdeviceExtension->CompressedTxBuffer);
342 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
343 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
344 return -ENOMEM;
345 }
346
347
348
349 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successfull");
350 return STATUS_SUCCESS;
351 }
352
353
354 int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt)
355 {
356 if(pPHSDeviceExt->pstServiceFlowPhsRulesTable)
357 {
358 free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable);
359 pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
360 }
361
362 kfree(pPHSDeviceExt->CompressedTxBuffer);
363 pPHSDeviceExt->CompressedTxBuffer = NULL;
364
365 kfree(pPHSDeviceExt->UnCompressedRxBuffer);
366 pPHSDeviceExt->UnCompressedRxBuffer = NULL;
367
368 return 0;
369 }
370
371
372
373 //PHS functions
374 /*++
375 PhsUpdateClassifierRule
376
377 Routine Description:
378 Exported function to add or modify a PHS Rule.
379
380 Arguments:
381 IN void* pvContext - PHS Driver Specific Context
382 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
383 IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
384 IN S_PHS_RULE *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table.
385
386 Return Value:
387
388 0 if successful,
389 >0 Error.
390
391 --*/
392 ULONG PhsUpdateClassifierRule(IN void* pvContext,
393 IN B_UINT16 uiVcid ,
394 IN B_UINT16 uiClsId ,
395 IN S_PHS_RULE *psPhsRule,
396 IN B_UINT8 u8AssociatedPHSI)
397 {
398 ULONG lStatus =0;
399 UINT nSFIndex =0 ;
400 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
401 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 /*++
442 PhsDeletePHSRule
443
444 Routine Description:
445 Deletes the specified phs Rule within Vcid
446
447 Arguments:
448 IN void* pvContext - PHS Driver Specific Context
449 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
450 IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted.
451
452 Return Value:
453
454 0 if successful,
455 >0 Error.
456
457 --*/
458
459 ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI)
460 {
461 ULONG lStatus =0;
462 UINT nSFIndex =0, nClsidIndex =0 ;
463 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
464 S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
465 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 {
492 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) {
493 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
494 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
495 if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
496 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
497 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0,
498 sizeof(S_CLASSIFIER_ENTRY));
499 }
500 }
501 }
502 }
503
504 }
505 return lStatus;
506 }
507
508 /*++
509 PhsDeleteClassifierRule
510
511 Routine Description:
512 Exported function to Delete a PHS Rule for the SFID,CLSID Pair.
513
514 Arguments:
515 IN void* pvContext - PHS Driver Specific Context
516 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
517 IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
518
519 Return Value:
520
521 0 if successful,
522 >0 Error.
523
524 --*/
525 ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 uiClsId)
526 {
527 ULONG lStatus =0;
528 UINT nSFIndex =0, nClsidIndex =0 ;
529 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
530 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
531 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)
554 kfree(pstClassifierEntry->pstPhsRule);
555
556 }
557 memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
558 }
559
560 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
561 uiClsId,eOldClassifierRuleContext,&pstClassifierEntry);
562
563 if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
564 {
565 kfree(pstClassifierEntry->pstPhsRule);
566 memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
567 }
568 }
569 return lStatus;
570 }
571
572 /*++
573 PhsDeleteSFRules
574
575 Routine Description:
576 Exported function to Delete a all PHS Rules for the SFID.
577
578 Arguments:
579 IN void* pvContext - PHS Driver Specific Context
580 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted
581
582 Return Value:
583
584 0 if successful,
585 >0 Error.
586
587 --*/
588 ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid)
589 {
590
591 ULONG lStatus =0;
592 UINT nSFIndex =0, nClsidIndex =0 ;
593 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
594 S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
595 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)
623 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
624 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
625 .pstPhsRule = NULL;
626 }
627 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
628 if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule)
629 {
630 if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
631 .pstPhsRule->u8RefCnt)
632 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
633 .pstPhsRule->u8RefCnt--;
634 if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
635 .pstPhsRule->u8RefCnt)
636 kfree(pstClassifierRulesTable
637 ->stOldPhsRulesList[nClsidIndex].pstPhsRule);
638 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
639 .pstPhsRule = NULL;
640 }
641 memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
642 }
643 }
644 pstServiceFlowEntry->bUsed = FALSE;
645 pstServiceFlowEntry->uiVcid = 0;
646
647 }
648
649 return lStatus;
650 }
651
652
653 /*++
654 PhsCompress
655
656 Routine Description:
657 Exported function to compress the data using PHS.
658
659 Arguments:
660 IN void* pvContext - PHS Driver Specific Context.
661 IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies.
662 IN UINT uiClsId - The Classifier ID to which current packet header compression applies.
663 IN void *pvInputBuffer - The Input buffer containg packet header data
664 IN void *pvOutputBuffer - The output buffer returned by this function after PHS
665 IN UINT *pOldHeaderSize - The actual size of the header before PHS
666 IN UINT *pNewHeaderSize - The new size of the header after applying PHS
667
668 Return Value:
669
670 0 if successful,
671 >0 Error.
672
673 --*/
674 ULONG PhsCompress(IN void* pvContext,
675 IN B_UINT16 uiVcid,
676 IN B_UINT16 uiClsId,
677 IN void *pvInputBuffer,
678 OUT void *pvOutputBuffer,
679 OUT UINT *pOldHeaderSize,
680 OUT UINT *pNewHeaderSize )
681 {
682 UINT nSFIndex =0, nClsidIndex =0 ;
683 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
684 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
685 S_PHS_RULE *pstPhsRule = NULL;
686 ULONG lStatus =0;
687 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 /*++
752 PhsDeCompress
753
754 Routine Description:
755 Exported function to restore the packet header in Rx path.
756
757 Arguments:
758 IN void* pvContext - PHS Driver Specific Context.
759 IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies.
760 IN void *pvInputBuffer - The Input buffer containg suppressed packet header data
761 OUT void *pvOutputBuffer - The output buffer returned by this function after restoration
762 OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter.
763
764 Return Value:
765
766 0 if successful,
767 >0 Error.
768
769 --*/
770 ULONG PhsDeCompress(IN void* pvContext,
771 IN B_UINT16 uiVcid,
772 IN void *pvInputBuffer,
773 OUT void *pvOutputBuffer,
774 OUT UINT *pInHeaderSize,
775 OUT UINT *pOutHeaderSize )
776 {
777 UINT nSFIndex =0, nPhsRuleIndex =0 ;
778 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
779 S_PHS_RULE *pstPhsRule = NULL;
780 UINT phsi;
781 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 {
789 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Invalid Device Extension\n");
790 return ERR_PHS_INVALID_DEVICE_EXETENSION;
791 }
792
793 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Restoring header \n");
794
795 phsi = *((unsigned char *)(pvInputBuffer));
796 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x \n",phsi);
797 if(phsi == UNCOMPRESSED_PACKET )
798 {
799 return STATUS_PHS_NOCOMPRESSION;
800 }
801
802 //Retrieve the SFID Entry Index for requested Service Flow
803 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
804 uiVcid,&pstServiceFlowEntry);
805 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
806 {
807 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n");
808 return ERR_SF_MATCH_FAIL;
809 }
810
811 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,phsi,
812 eActiveClassifierRuleContext,&pstPhsRule);
813 if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
814 {
815 //Phs Rule does not exist in active rules table. Lets try in the old rules table.
816 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
817 phsi,eOldClassifierRuleContext,&pstPhsRule);
818 if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
819 {
820 return ERR_PHSRULE_MATCH_FAIL;
821 }
822
823 }
824
825 *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer,
826 (PUCHAR)pvOutputBuffer,pstPhsRule,pOutHeaderSize);
827
828 pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1;
829
830 pstPhsRule->PHSModifiedNumPackets++;
831 return STATUS_PHS_COMPRESSED;
832 }
833
834
835 //-----------------------------------------------------------------------------
836 // Procedure: free_phs_serviceflow_rules
837 //
838 // Description: This routine is responsible for freeing memory allocated for PHS rules.
839 //
840 // Arguments:
841 // rules - ptr to S_SERVICEFLOW_TABLE structure.
842 //
843 // Returns:
844 // Does not return any value.
845 //-----------------------------------------------------------------------------
846
847 static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
848 {
849 int i,j;
850 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)
874 kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
875 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
876 }
877 if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule)
878 {
879 if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
880 ->u8RefCnt)
881 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
882 ->u8RefCnt--;
883 if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
884 ->u8RefCnt)
885 kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
886 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
887 }
888 }
889 kfree(pstClassifierRulesTable);
890 stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
891 }
892 }
893 }
894
895 kfree(psServiceFlowRulesTable);
896 psServiceFlowRulesTable = NULL;
897 }
898
899
900
901 static BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
902 {
903 if(psPhsRule)
904 {
905 if(!psPhsRule->u8PHSI)
906 {
907 // PHSI is not valid
908 return FALSE;
909 }
910
911 if(!psPhsRule->u8PHSS)
912 {
913 //PHSS Is Undefined
914 return FALSE;
915 }
916
917 //Check if PHSF is defines for the PHS Rule
918 if(!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF
919 {
920 return FALSE;
921 }
922 return TRUE;
923 }
924 else
925 {
926 return FALSE;
927 }
928 }
929
930 UINT GetServiceFlowEntry(IN S_SERVICEFLOW_TABLE *psServiceFlowTable,
931 IN B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry)
932 {
933 int i;
934 for(i=0;i<MAX_SERVICEFLOWS;i++)
935 {
936 if(psServiceFlowTable->stSFList[i].bUsed)
937 {
938 if(psServiceFlowTable->stSFList[i].uiVcid == uiVcid)
939 {
940 *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i];
941 return i;
942 }
943 }
944 }
945
946 *ppstServiceFlowEntry = NULL;
947 return PHS_INVALID_TABLE_INDEX;
948 }
949
950
951 UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
952 IN B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
953 OUT S_CLASSIFIER_ENTRY **ppstClassifierEntry)
954 {
955 int i;
956 S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
957 for(i=0;i<MAX_PHSRULE_PER_SF;i++)
958 {
959
960 if(eClsContext == eActiveClassifierRuleContext)
961 {
962 psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i];
963 }
964 else
965 {
966 psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i];
967 }
968
969 if(psClassifierRules->bUsed)
970 {
971 if(psClassifierRules->uiClassifierRuleId == uiClsid)
972 {
973 *ppstClassifierEntry = psClassifierRules;
974 return i;
975 }
976 }
977
978 }
979
980 *ppstClassifierEntry = NULL;
981 return PHS_INVALID_TABLE_INDEX;
982 }
983
984 static UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
985 IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
986 OUT S_PHS_RULE **ppstPhsRule)
987 {
988 int i;
989 S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
990 for(i=0;i<MAX_PHSRULE_PER_SF;i++)
991 {
992 if(eClsContext == eActiveClassifierRuleContext)
993 {
994 pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i];
995 }
996 else
997 {
998 pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i];
999 }
1000 if(pstClassifierRule->bUsed)
1001 {
1002 if(pstClassifierRule->u8PHSI == uiPHSI)
1003 {
1004 *ppstPhsRule = pstClassifierRule->pstPhsRule;
1005 return i;
1006 }
1007 }
1008
1009 }
1010
1011 *ppstPhsRule = NULL;
1012 return PHS_INVALID_TABLE_INDEX;
1013 }
1014
1015 UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId,
1016 IN S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,
1017 B_UINT8 u8AssociatedPHSI)
1018 {
1019
1020 S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
1021 UINT uiStatus = 0;
1022 int iSfIndex;
1023 BOOLEAN bFreeEntryFound =FALSE;
1024 //Check for a free entry in SFID table
1025 for(iSfIndex=0;iSfIndex < MAX_SERVICEFLOWS;iSfIndex++)
1026 {
1027 if(!psServiceFlowTable->stSFList[iSfIndex].bUsed)
1028 {
1029 bFreeEntryFound = TRUE;
1030 break;
1031 }
1032 }
1033
1034 if(!bFreeEntryFound)
1035 return ERR_SFTABLE_FULL;
1036
1037
1038 psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable;
1039 uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,psPhsRule,
1040 eActiveClassifierRuleContext,u8AssociatedPHSI);
1041 if(uiStatus == PHS_SUCCESS)
1042 {
1043 //Add entry at free index to the SF
1044 psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE;
1045 psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid;
1046 }
1047
1048 return uiStatus;
1049
1050 }
1051
1052 UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
1053 IN B_UINT16 uiClsId,IN S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,
1054 S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI)
1055 {
1056 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
1057 UINT uiStatus =PHS_SUCCESS;
1058 UINT nClassifierIndex = 0;
1059 S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
1060 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
1098 memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
1099 psPhsRule->u8PHSF , MAX_PHS_LENGTHS);
1100 }
1101 if(psPhsRule->u8PHSFLength)
1102 {
1103 //update PHSFLen
1104 pstClassifierEntry->pstPhsRule->u8PHSFLength =
1105 psPhsRule->u8PHSFLength;
1106 }
1107 if(psPhsRule->u8PHSMLength)
1108 {
1109 //update PHSM
1110 memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
1111 psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
1112 }
1113 if(psPhsRule->u8PHSMLength)
1114 {
1115 //update PHSM Len
1116 pstClassifierEntry->pstPhsRule->u8PHSMLength =
1117 psPhsRule->u8PHSMLength;
1118 }
1119 if(psPhsRule->u8PHSS)
1120 {
1121 //update PHSS
1122 pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS;
1123 }
1124
1125 //update PHSV
1126 pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV;
1127
1128 }
1129 else
1130 {
1131 /*
1132 A new rule is being set for this classifier.
1133 */
1134 uiStatus=UpdateClassifierPHSRule( uiClsId, pstClassifierEntry,
1135 psaClassifiertable, psPhsRule, u8AssociatedPHSI);
1136 }
1137
1138
1139
1140 return uiStatus;
1141 }
1142
1143 static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
1144 S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
1145 E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI)
1146 {
1147 UINT iClassifierIndex = 0;
1148 BOOLEAN bFreeEntryFound = FALSE;
1149 S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
1150 UINT nStatus = PHS_SUCCESS;
1151 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 {
1230 psClassifierRules->pstPhsRule = kmalloc(sizeof(S_PHS_RULE),GFP_KERNEL);
1231
1232 if(NULL == psClassifierRules->pstPhsRule)
1233 return ERR_PHSRULE_MEMALLOC_FAIL;
1234 }
1235
1236 psClassifierRules->bUsed = TRUE;
1237 psClassifierRules->uiClassifierRuleId = uiClsId;
1238 psClassifierRules->u8PHSI = psPhsRule->u8PHSI;
1239 psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
1240
1241 /* Update The PHS rule */
1242 memcpy(psClassifierRules->pstPhsRule,
1243 psPhsRule, sizeof(S_PHS_RULE));
1244 }
1245 else
1246 {
1247 nStatus = UpdateClassifierPHSRule(uiClsId,psClassifierRules,
1248 psaClassifiertable,psPhsRule,u8AssociatedPHSI);
1249 }
1250 return nStatus;
1251 }
1252
1253
1254 static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
1255 IN S_CLASSIFIER_ENTRY *pstClassifierEntry,
1256 S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
1257 B_UINT8 u8AssociatedPHSI)
1258 {
1259 S_PHS_RULE *pstAddPhsRule = NULL;
1260 UINT nPhsRuleIndex = 0;
1261 BOOLEAN bPHSRuleOrphaned = FALSE;
1262 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 {
1284 pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL);
1285 if(NULL == pstClassifierEntry->pstPhsRule)
1286 {
1287 return ERR_PHSRULE_MEMALLOC_FAIL;
1288 }
1289 }
1290 memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
1291
1292 }
1293 else
1294 {
1295 //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule
1296 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
1297 if(bPHSRuleOrphaned)
1298 {
1299 kfree(pstClassifierEntry->pstPhsRule);
1300 pstClassifierEntry->pstPhsRule = NULL;
1301 }
1302 pstClassifierEntry->pstPhsRule = pstAddPhsRule;
1303
1304 }
1305 pstClassifierEntry->bUsed = TRUE;
1306 pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI;
1307 pstClassifierEntry->uiClassifierRuleId = uiClsId;
1308 pstClassifierEntry->pstPhsRule->u8RefCnt++;
1309 pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;
1310
1311 return PHS_SUCCESS;
1312
1313 }
1314
1315 static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
1316 {
1317 if(pstPhsRule==NULL)
1318 return FALSE;
1319 if(pstPhsRule->u8RefCnt)
1320 pstPhsRule->u8RefCnt--;
1321 if(0==pstPhsRule->u8RefCnt)
1322 {
1323 /*if(pstPhsRule->u8PHSI)
1324 //Store the currently active rule into the old rules list
1325 CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);*/
1326 return TRUE;
1327 }
1328 else
1329 {
1330 return FALSE;
1331 }
1332 }
1333
1334 void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)
1335 {
1336 int i,j,k,l;
1337 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
1410 int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
1411 S_PHS_RULE *decomp_phs_rules,UINT *header_size)
1412 {
1413 int phss,size=0;
1414 S_PHS_RULE *tmp_memb;
1415 int bit,i=0;
1416 unsigned char *phsf,*phsm;
1417 int in_buf_len = *header_size-1;
1418 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1419 in_buf++;
1420 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"====>\n");
1421 *header_size = 0;
1422
1423 if((decomp_phs_rules == NULL ))
1424 return 0;
1425
1426
1427 tmp_memb = decomp_phs_rules;
1428 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
1429 //*header_size = tmp_memb->u8PHSFLength;
1430 phss = tmp_memb->u8PHSS;
1431 phsf = tmp_memb->u8PHSF;
1432 phsm = tmp_memb->u8PHSM;
1433
1434 if(phss > MAX_PHS_LENGTHS)
1435 phss = MAX_PHS_LENGTHS;
1436 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI %d phss %d index %d",phsi,phss,index));
1437 while((phss > 0) && (size < in_buf_len))
1438 {
1439 bit = ((*phsm << i)& SUPPRESS);
1440
1441 if(bit == SUPPRESS)
1442 {
1443 *out_buf = *phsf;
1444 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d",
1445 phss,*phsf,*out_buf);
1446 }
1447 else
1448 {
1449 *out_buf = *in_buf;
1450 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d",
1451 phss,*in_buf,*out_buf);
1452 in_buf++;
1453 size++;
1454 }
1455 out_buf++;
1456 phsf++;
1457 phss--;
1458 i++;
1459 *header_size=*header_size + 1;
1460
1461 if(i > MAX_NO_BIT)
1462 {
1463 i=0;
1464 phsm++;
1465 }
1466 }
1467 return size;
1468 }
1469
1470
1471
1472
1473 //-----------------------------------------------------------------------------
1474 // Procedure: phs_compress
1475 //
1476 // Description: This routine suppresses the static fields within the packet.Before
1477 // that it will verify the fields to be suppressed with the corresponding fields in the
1478 // phsf. For verification it checks the phsv field of PHS rule. If set and verification
1479 // succeeds it suppresses the field.If any one static field is found different none of
1480 // the static fields are suppressed then the packet is sent as uncompressed packet with
1481 // phsi=0.
1482 //
1483 // Arguments:
1484 // phs_rule - ptr to PHS rule.
1485 // in_buf - ptr to incoming packet buffer.
1486 // out_buf - ptr to output buffer where the suppressed header is copied.
1487 // header_size - ptr to field which holds the phss.
1488 //
1489 // Returns:
1490 // size-The number of bytes copied into the output buffer i.e dynamic fields
1491 // 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails.
1492 //-----------------------------------------------------------------------------
1493 static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf
1494 ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
1495 {
1496 unsigned char *old_addr = out_buf;
1497 int 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
1554 static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
1555 unsigned char *phsf,unsigned char *phsm,unsigned int phss,
1556 unsigned int phsv,UINT* new_header_size)
1557 {
1558 unsigned int size=0;
1559 int bit,i=0;
1560 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