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