beceem: remove OS wrapper library
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / bcm / PHSModule.c
blobe0456b291d6c9b04496a7cdc873747a2c59d78c2
1 #include "headers.h"
3 #define IN
4 #define OUT
6 void DumpDataPacketHeader(PUCHAR pPkt);
8 /*
9 Function: PHSTransmit
11 Description: This routine handle PHS(Payload Header Suppression for Tx path.
12 It extracts a fragment of the NDIS_PACKET containing the header
13 to be suppressed.It then supresses the header by invoking PHS exported compress routine.
14 The header data after supression is copied back to the NDIS_PACKET.
17 Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
18 IN Packet - NDIS packet containing data to be transmitted
19 IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to
20 identify PHS rule to be applied.
21 B_UINT16 uiClassifierRuleID - Classifier Rule ID
22 BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF.
24 Return: STATUS_SUCCESS - If the send was successful.
25 Other - If an error occured.
28 int PHSTransmit(PMINI_ADAPTER Adapter,
29 struct sk_buff **pPacket,
30 USHORT Vcid,
31 B_UINT16 uiClassifierRuleID,
32 BOOLEAN bHeaderSuppressionEnabled,
33 UINT *PacketLen,
34 UCHAR bEthCSSupport)
37 //PHS Sepcific
38 UINT unPHSPktHdrBytesCopied = 0;
39 UINT unPhsOldHdrSize = 0;
40 UINT unPHSNewPktHeaderLen = 0;
41 /* Pointer to PHS IN Hdr Buffer */
42 PUCHAR pucPHSPktHdrInBuf =
43 Adapter->stPhsTxContextInfo.ucaHdrSupressionInBuf;
44 /* Pointer to PHS OUT Hdr Buffer */
45 PUCHAR pucPHSPktHdrOutBuf =
46 Adapter->stPhsTxContextInfo.ucaHdrSupressionOutBuf;
47 UINT usPacketType;
48 UINT BytesToRemove=0;
49 BOOLEAN bPHSI = 0;
50 LONG ulPhsStatus = 0;
51 UINT numBytesCompressed = 0;
52 struct sk_buff *newPacket = NULL;
53 struct sk_buff *Packet = *pPacket;
55 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "In PHSTransmit");
57 if(!bEthCSSupport)
58 BytesToRemove=ETH_HLEN;
60 Accumulate the header upto the size we support supression
61 from NDIS packet
64 usPacketType=((struct ethhdr *)(Packet->data))->h_proto;
67 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
68 //considering data after ethernet header
69 if((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS)
72 unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove);
74 else
76 unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS;
79 if( (unPHSPktHdrBytesCopied > 0 ) &&
80 (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS))
84 //DumpDataPacketHeader(pucPHSPktHdrInBuf);
86 // Step 2 Supress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf.
87 // Suppress only if IP Header and PHS Enabled For the Service Flow
88 if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
89 (usPacketType == ETHERNET_FRAMETYPE_IPV6)) &&
90 (bHeaderSuppressionEnabled))
92 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nTrying to PHS Compress Using Classifier rule 0x%X",uiClassifierRuleID);
95 unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied;
96 ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext,
97 Vcid,
98 uiClassifierRuleID,
99 pucPHSPktHdrInBuf,
100 pucPHSPktHdrOutBuf,
101 &unPhsOldHdrSize,
102 &unPHSNewPktHeaderLen);
103 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nPHS Old header Size : %d New Header Size %d\n",unPhsOldHdrSize,unPHSNewPktHeaderLen);
105 if(unPHSNewPktHeaderLen == unPhsOldHdrSize)
107 if( ulPhsStatus == STATUS_PHS_COMPRESSED)
108 bPHSI = *pucPHSPktHdrOutBuf;
109 ulPhsStatus = STATUS_PHS_NOCOMPRESSION;
112 if( ulPhsStatus == STATUS_PHS_COMPRESSED)
114 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHS Sending packet Compressed");
116 if(skb_cloned(Packet))
118 newPacket = skb_copy(Packet, GFP_ATOMIC);
120 if(newPacket == NULL)
121 return STATUS_FAILURE;
123 dev_kfree_skb(Packet);
124 *pPacket = Packet = newPacket;
125 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
128 numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);
130 memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
131 memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
132 skb_pull(Packet, numBytesCompressed);
134 return STATUS_SUCCESS;
137 else
139 //if one byte headroom is not available, increase it through skb_cow
140 if(!(skb_headroom(Packet) > 0))
142 if(skb_cow(Packet, 1))
144 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n");
145 return STATUS_FAILURE;
148 skb_push(Packet, 1);
150 // CAUTION: The MAC Header is getting corrupted here for IP CS - can be saved by copying 14 Bytes. not needed .... hence corrupting it.
151 *(Packet->data + BytesToRemove) = bPHSI;
152 return STATUS_SUCCESS;
155 else
157 if(!bHeaderSuppressionEnabled)
159 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nHeader Suppression Disabled For SF: No PHS\n");
162 return STATUS_SUCCESS;
166 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS");
167 return STATUS_SUCCESS;
170 int PHSRecieve(PMINI_ADAPTER Adapter,
171 USHORT usVcid,
172 struct sk_buff *packet,
173 UINT *punPacketLen,
174 UCHAR *pucEthernetHdr,
175 UINT bHeaderSuppressionEnabled)
177 u32 nStandardPktHdrLen = 0;
178 u32 nTotalsupressedPktHdrBytes = 0;
179 int ulPhsStatus = 0;
180 PUCHAR pucInBuff = NULL ;
181 UINT TotalBytesAdded = 0;
182 if(!bHeaderSuppressionEnabled)
184 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet");
185 return ulPhsStatus;
188 pucInBuff = packet->data;
190 //Restore PHS suppressed header
191 nStandardPktHdrLen = packet->len;
192 ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext,
193 usVcid,
194 pucInBuff,
195 Adapter->ucaPHSPktRestoreBuf,
196 &nTotalsupressedPktHdrBytes,
197 &nStandardPktHdrLen);
199 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
200 nTotalsupressedPktHdrBytes,nStandardPktHdrLen);
202 if(ulPhsStatus != STATUS_PHS_COMPRESSED)
204 skb_pull(packet, 1);
205 return STATUS_SUCCESS;
207 else
209 TotalBytesAdded = nStandardPktHdrLen - nTotalsupressedPktHdrBytes - PHSI_LEN;
210 if(TotalBytesAdded)
212 if(skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded))
213 skb_push(packet, TotalBytesAdded);
214 else
216 if(skb_cow(packet, skb_headroom(packet) + TotalBytesAdded))
218 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n");
219 return STATUS_FAILURE;
222 skb_push(packet, TotalBytesAdded);
226 memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
229 return STATUS_SUCCESS;
232 void DumpDataPacketHeader(PUCHAR pPkt)
234 struct iphdr *iphd = (struct iphdr*)pPkt;
235 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
236 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Phs Send/Recieve : IP Packet Hdr \n");
237 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"TOS : %x \n",iphd->tos);
238 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Src IP : %x \n",iphd->saddr);
239 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Dest IP : %x \n \n",iphd->daddr);
243 void DumpFullPacket(UCHAR *pBuf,UINT nPktLen)
245 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
246 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"Dumping Data Packet");
247 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,pBuf,nPktLen);
250 //-----------------------------------------------------------------------------
251 // Procedure: phs_init
253 // Description: This routine is responsible for allocating memory for classifier and
254 // PHS rules.
256 // Arguments:
257 // pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc
259 // Returns:
260 // TRUE(1) -If allocation of memory was success full.
261 // FALSE -If allocation of memory fails.
262 //-----------------------------------------------------------------------------
263 int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)
265 int i;
266 S_SERVICEFLOW_TABLE *pstServiceFlowTable;
267 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nPHS:phs_init function ");
269 if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
270 return -EINVAL;
272 pPhsdeviceExtension->pstServiceFlowPhsRulesTable =
273 kzalloc(sizeof(S_SERVICEFLOW_TABLE), GFP_KERNEL);
275 if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
277 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
278 return -ENOMEM;
281 pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable;
282 for(i=0;i<MAX_SERVICEFLOWS;i++)
284 S_SERVICEFLOW_ENTRY sServiceFlow = pstServiceFlowTable->stSFList[i];
285 sServiceFlow.pstClassifierTable = kzalloc(sizeof(S_CLASSIFIER_TABLE), GFP_KERNEL);
286 if(!sServiceFlow.pstClassifierTable)
288 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
289 free_phs_serviceflow_rules(pPhsdeviceExtension->
290 pstServiceFlowPhsRulesTable);
291 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
292 return -ENOMEM;
296 pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
298 if(pPhsdeviceExtension->CompressedTxBuffer == NULL)
300 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
301 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
302 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
303 return -ENOMEM;
306 pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
307 if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
309 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
310 kfree(pPhsdeviceExtension->CompressedTxBuffer);
311 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
312 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
313 return -ENOMEM;
318 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successfull");
319 return STATUS_SUCCESS;
323 int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt)
325 if(pPHSDeviceExt->pstServiceFlowPhsRulesTable)
327 free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable);
328 pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
331 kfree(pPHSDeviceExt->CompressedTxBuffer);
332 pPHSDeviceExt->CompressedTxBuffer = NULL;
334 kfree(pPHSDeviceExt->UnCompressedRxBuffer);
335 pPHSDeviceExt->UnCompressedRxBuffer = NULL;
337 return 0;
342 //PHS functions
343 /*++
344 PhsUpdateClassifierRule
346 Routine Description:
347 Exported function to add or modify a PHS Rule.
349 Arguments:
350 IN void* pvContext - PHS Driver Specific Context
351 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
352 IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
353 IN S_PHS_RULE *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table.
355 Return Value:
357 0 if successful,
358 >0 Error.
360 --*/
361 ULONG PhsUpdateClassifierRule(IN void* pvContext,
362 IN B_UINT16 uiVcid ,
363 IN B_UINT16 uiClsId ,
364 IN S_PHS_RULE *psPhsRule,
365 IN B_UINT8 u8AssociatedPHSI)
367 ULONG lStatus =0;
368 UINT nSFIndex =0 ;
369 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
370 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
374 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
376 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS With Corr2 Changes \n");
378 if(pDeviceExtension == NULL)
380 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Invalid Device Extension\n");
381 return ERR_PHS_INVALID_DEVICE_EXETENSION;
385 if(u8AssociatedPHSI == 0)
387 return ERR_PHS_INVALID_PHS_RULE;
390 /* Retrieve the SFID Entry Index for requested Service Flow */
392 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
393 uiVcid,&pstServiceFlowEntry);
395 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
397 /* This is a new SF. Create a mapping entry for this */
398 lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId,
399 pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI);
400 return lStatus;
403 /* SF already Exists Add PHS Rule to existing SF */
404 lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId,
405 pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI);
407 return lStatus;
410 /*++
411 PhsDeletePHSRule
413 Routine Description:
414 Deletes the specified phs Rule within Vcid
416 Arguments:
417 IN void* pvContext - PHS Driver Specific Context
418 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
419 IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted.
421 Return Value:
423 0 if successful,
424 >0 Error.
426 --*/
428 ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI)
430 ULONG lStatus =0;
431 UINT nSFIndex =0, nClsidIndex =0 ;
432 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
433 S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
434 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
437 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
439 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n");
441 if(pDeviceExtension)
444 //Retrieve the SFID Entry Index for requested Service Flow
445 nSFIndex = GetServiceFlowEntry(pDeviceExtension
446 ->pstServiceFlowPhsRulesTable,uiVcid,&pstServiceFlowEntry);
448 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
450 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
451 return ERR_SF_MATCH_FAIL;
454 pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable;
455 if(pstClassifierRulesTable)
457 for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++)
459 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
461 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) {
462 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
463 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
464 if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
465 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
466 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0,
467 sizeof(S_CLASSIFIER_ENTRY));
474 return lStatus;
477 /*++
478 PhsDeleteClassifierRule
480 Routine Description:
481 Exported function to Delete a PHS Rule for the SFID,CLSID Pair.
483 Arguments:
484 IN void* pvContext - PHS Driver Specific Context
485 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
486 IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
488 Return Value:
490 0 if successful,
491 >0 Error.
493 --*/
494 ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 uiClsId)
496 ULONG lStatus =0;
497 UINT nSFIndex =0, nClsidIndex =0 ;
498 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
499 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
500 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
501 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
503 if(pDeviceExtension)
505 //Retrieve the SFID Entry Index for requested Service Flow
506 nSFIndex = GetServiceFlowEntry(pDeviceExtension
507 ->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry);
508 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
510 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"SFID Match Failed\n");
511 return ERR_SF_MATCH_FAIL;
514 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
515 uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry);
516 if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
518 if(pstClassifierEntry->pstPhsRule)
520 if(pstClassifierEntry->pstPhsRule->u8RefCnt)
521 pstClassifierEntry->pstPhsRule->u8RefCnt--;
522 if(0==pstClassifierEntry->pstPhsRule->u8RefCnt)
523 kfree(pstClassifierEntry->pstPhsRule);
526 memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
529 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
530 uiClsId,eOldClassifierRuleContext,&pstClassifierEntry);
532 if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
534 kfree(pstClassifierEntry->pstPhsRule);
535 memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
538 return lStatus;
541 /*++
542 PhsDeleteSFRules
544 Routine Description:
545 Exported function to Delete a all PHS Rules for the SFID.
547 Arguments:
548 IN void* pvContext - PHS Driver Specific Context
549 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted
551 Return Value:
553 0 if successful,
554 >0 Error.
556 --*/
557 ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid)
560 ULONG lStatus =0;
561 UINT nSFIndex =0, nClsidIndex =0 ;
562 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
563 S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
564 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
565 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
566 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"====> \n");
568 if(pDeviceExtension)
570 //Retrieve the SFID Entry Index for requested Service Flow
571 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
572 uiVcid,&pstServiceFlowEntry);
573 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
575 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
576 return ERR_SF_MATCH_FAIL;
579 pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable;
580 if(pstClassifierRulesTable)
582 for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++)
584 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
586 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
587 .pstPhsRule->u8RefCnt)
588 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
589 .pstPhsRule->u8RefCnt--;
590 if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
591 .pstPhsRule->u8RefCnt)
592 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
593 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
594 .pstPhsRule = NULL;
596 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
597 if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule)
599 if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
600 .pstPhsRule->u8RefCnt)
601 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
602 .pstPhsRule->u8RefCnt--;
603 if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
604 .pstPhsRule->u8RefCnt)
605 kfree(pstClassifierRulesTable
606 ->stOldPhsRulesList[nClsidIndex].pstPhsRule);
607 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
608 .pstPhsRule = NULL;
610 memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
613 pstServiceFlowEntry->bUsed = FALSE;
614 pstServiceFlowEntry->uiVcid = 0;
618 return lStatus;
622 /*++
623 PhsCompress
625 Routine Description:
626 Exported function to compress the data using PHS.
628 Arguments:
629 IN void* pvContext - PHS Driver Specific Context.
630 IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies.
631 IN UINT uiClsId - The Classifier ID to which current packet header compression applies.
632 IN void *pvInputBuffer - The Input buffer containg packet header data
633 IN void *pvOutputBuffer - The output buffer returned by this function after PHS
634 IN UINT *pOldHeaderSize - The actual size of the header before PHS
635 IN UINT *pNewHeaderSize - The new size of the header after applying PHS
637 Return Value:
639 0 if successful,
640 >0 Error.
642 --*/
643 ULONG PhsCompress(IN void* pvContext,
644 IN B_UINT16 uiVcid,
645 IN B_UINT16 uiClsId,
646 IN void *pvInputBuffer,
647 OUT void *pvOutputBuffer,
648 OUT UINT *pOldHeaderSize,
649 OUT UINT *pNewHeaderSize )
651 UINT nSFIndex =0, nClsidIndex =0 ;
652 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
653 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
654 S_PHS_RULE *pstPhsRule = NULL;
655 ULONG lStatus =0;
656 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
660 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
663 if(pDeviceExtension == NULL)
665 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Invalid Device Extension\n");
666 lStatus = STATUS_PHS_NOCOMPRESSION ;
667 return lStatus;
671 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Suppressing header \n");
674 //Retrieve the SFID Entry Index for requested Service Flow
675 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
676 uiVcid,&pstServiceFlowEntry);
677 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
679 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"SFID Match Failed\n");
680 lStatus = STATUS_PHS_NOCOMPRESSION ;
681 return lStatus;
684 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
685 uiClsId,eActiveClassifierRuleContext,&pstClassifierEntry);
687 if(nClsidIndex == PHS_INVALID_TABLE_INDEX)
689 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"No PHS Rule Defined For Classifier\n");
690 lStatus = STATUS_PHS_NOCOMPRESSION ;
691 return lStatus;
695 //get rule from SF id,Cls ID pair and proceed
696 pstPhsRule = pstClassifierEntry->pstPhsRule;
698 if(!ValidatePHSRuleComplete(pstPhsRule))
700 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS Rule Defined For Classifier But Not Complete\n");
701 lStatus = STATUS_PHS_NOCOMPRESSION ;
702 return lStatus;
705 //Compress Packet
706 lStatus = phs_compress(pstPhsRule,(PUCHAR)pvInputBuffer,
707 (PUCHAR)pvOutputBuffer, pOldHeaderSize,pNewHeaderSize);
709 if(lStatus == STATUS_PHS_COMPRESSED)
711 pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1;
712 pstPhsRule->PHSModifiedNumPackets++;
714 else
715 pstPhsRule->PHSErrorNumPackets++;
717 return lStatus;
720 /*++
721 PhsDeCompress
723 Routine Description:
724 Exported function to restore the packet header in Rx path.
726 Arguments:
727 IN void* pvContext - PHS Driver Specific Context.
728 IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies.
729 IN void *pvInputBuffer - The Input buffer containg suppressed packet header data
730 OUT void *pvOutputBuffer - The output buffer returned by this function after restoration
731 OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter.
733 Return Value:
735 0 if successful,
736 >0 Error.
738 --*/
739 ULONG PhsDeCompress(IN void* pvContext,
740 IN B_UINT16 uiVcid,
741 IN void *pvInputBuffer,
742 OUT void *pvOutputBuffer,
743 OUT UINT *pInHeaderSize,
744 OUT UINT *pOutHeaderSize )
746 UINT nSFIndex =0, nPhsRuleIndex =0 ;
747 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
748 S_PHS_RULE *pstPhsRule = NULL;
749 UINT phsi;
750 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
751 PPHS_DEVICE_EXTENSION pDeviceExtension=
752 (PPHS_DEVICE_EXTENSION)pvContext;
754 *pInHeaderSize = 0;
756 if(pDeviceExtension == NULL)
758 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Invalid Device Extension\n");
759 return ERR_PHS_INVALID_DEVICE_EXETENSION;
762 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Restoring header \n");
764 phsi = *((unsigned char *)(pvInputBuffer));
765 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x \n",phsi);
766 if(phsi == UNCOMPRESSED_PACKET )
768 return STATUS_PHS_NOCOMPRESSION;
771 //Retrieve the SFID Entry Index for requested Service Flow
772 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
773 uiVcid,&pstServiceFlowEntry);
774 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
776 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n");
777 return ERR_SF_MATCH_FAIL;
780 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,phsi,
781 eActiveClassifierRuleContext,&pstPhsRule);
782 if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
784 //Phs Rule does not exist in active rules table. Lets try in the old rules table.
785 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
786 phsi,eOldClassifierRuleContext,&pstPhsRule);
787 if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
789 return ERR_PHSRULE_MATCH_FAIL;
794 *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer,
795 (PUCHAR)pvOutputBuffer,pstPhsRule,pOutHeaderSize);
797 pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1;
799 pstPhsRule->PHSModifiedNumPackets++;
800 return STATUS_PHS_COMPRESSED;
804 //-----------------------------------------------------------------------------
805 // Procedure: free_phs_serviceflow_rules
807 // Description: This routine is responsible for freeing memory allocated for PHS rules.
809 // Arguments:
810 // rules - ptr to S_SERVICEFLOW_TABLE structure.
812 // Returns:
813 // Does not return any value.
814 //-----------------------------------------------------------------------------
816 void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
818 int i,j;
819 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
821 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n");
822 if(psServiceFlowRulesTable)
824 for(i=0;i<MAX_SERVICEFLOWS;i++)
826 S_SERVICEFLOW_ENTRY stServiceFlowEntry =
827 psServiceFlowRulesTable->stSFList[i];
828 S_CLASSIFIER_TABLE *pstClassifierRulesTable =
829 stServiceFlowEntry.pstClassifierTable;
831 if(pstClassifierRulesTable)
833 for(j=0;j<MAX_PHSRULE_PER_SF;j++)
835 if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule)
837 if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
838 ->u8RefCnt)
839 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
840 ->u8RefCnt--;
841 if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
842 ->u8RefCnt)
843 kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
844 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
846 if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule)
848 if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
849 ->u8RefCnt)
850 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
851 ->u8RefCnt--;
852 if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
853 ->u8RefCnt)
854 kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
855 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
858 kfree(pstClassifierRulesTable);
859 stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
864 kfree(psServiceFlowRulesTable);
865 psServiceFlowRulesTable = NULL;
870 BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
872 if(psPhsRule)
874 if(!psPhsRule->u8PHSI)
876 // PHSI is not valid
877 return FALSE;
880 if(!psPhsRule->u8PHSS)
882 //PHSS Is Undefined
883 return FALSE;
886 //Check if PHSF is defines for the PHS Rule
887 if(!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF
889 return FALSE;
891 return TRUE;
893 else
895 return FALSE;
899 UINT GetServiceFlowEntry(IN S_SERVICEFLOW_TABLE *psServiceFlowTable,
900 IN B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry)
902 int i;
903 for(i=0;i<MAX_SERVICEFLOWS;i++)
905 if(psServiceFlowTable->stSFList[i].bUsed)
907 if(psServiceFlowTable->stSFList[i].uiVcid == uiVcid)
909 *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i];
910 return i;
915 *ppstServiceFlowEntry = NULL;
916 return PHS_INVALID_TABLE_INDEX;
920 UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
921 IN B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
922 OUT S_CLASSIFIER_ENTRY **ppstClassifierEntry)
924 int i;
925 S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
926 for(i=0;i<MAX_PHSRULE_PER_SF;i++)
929 if(eClsContext == eActiveClassifierRuleContext)
931 psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i];
933 else
935 psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i];
938 if(psClassifierRules->bUsed)
940 if(psClassifierRules->uiClassifierRuleId == uiClsid)
942 *ppstClassifierEntry = psClassifierRules;
943 return i;
949 *ppstClassifierEntry = NULL;
950 return PHS_INVALID_TABLE_INDEX;
953 UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
954 IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
955 OUT S_PHS_RULE **ppstPhsRule)
957 int i;
958 S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
959 for(i=0;i<MAX_PHSRULE_PER_SF;i++)
961 if(eClsContext == eActiveClassifierRuleContext)
963 pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i];
965 else
967 pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i];
969 if(pstClassifierRule->bUsed)
971 if(pstClassifierRule->u8PHSI == uiPHSI)
973 *ppstPhsRule = pstClassifierRule->pstPhsRule;
974 return i;
980 *ppstPhsRule = NULL;
981 return PHS_INVALID_TABLE_INDEX;
984 UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId,
985 IN S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,
986 B_UINT8 u8AssociatedPHSI)
989 S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
990 UINT uiStatus = 0;
991 int iSfIndex;
992 BOOLEAN bFreeEntryFound =FALSE;
993 //Check for a free entry in SFID table
994 for(iSfIndex=0;iSfIndex < MAX_SERVICEFLOWS;iSfIndex++)
996 if(!psServiceFlowTable->stSFList[iSfIndex].bUsed)
998 bFreeEntryFound = TRUE;
999 break;
1003 if(!bFreeEntryFound)
1004 return ERR_SFTABLE_FULL;
1007 psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable;
1008 uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,psPhsRule,
1009 eActiveClassifierRuleContext,u8AssociatedPHSI);
1010 if(uiStatus == PHS_SUCCESS)
1012 //Add entry at free index to the SF
1013 psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE;
1014 psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid;
1017 return uiStatus;
1021 UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
1022 IN B_UINT16 uiClsId,IN S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,
1023 S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI)
1025 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
1026 UINT uiStatus =PHS_SUCCESS;
1027 UINT nClassifierIndex = 0;
1028 S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
1029 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1030 psaClassifiertable = pstServiceFlowEntry->pstClassifierTable;
1032 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>");
1034 /* Check if the supplied Classifier already exists */
1035 nClassifierIndex =GetClassifierEntry(
1036 pstServiceFlowEntry->pstClassifierTable,uiClsId,
1037 eActiveClassifierRuleContext,&pstClassifierEntry);
1038 if(nClassifierIndex == PHS_INVALID_TABLE_INDEX)
1041 The Classifier doesn't exist. So its a new classifier being added.
1042 Add new entry to associate PHS Rule to the Classifier
1045 uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,
1046 psPhsRule,eActiveClassifierRuleContext,u8AssociatedPHSI);
1047 return uiStatus;
1051 The Classifier exists.The PHS Rule for this classifier
1052 is being modified
1054 if(pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI)
1056 if(pstClassifierEntry->pstPhsRule == NULL)
1057 return ERR_PHS_INVALID_PHS_RULE;
1060 This rule already exists if any fields are changed for this PHS
1061 rule update them.
1063 /* If any part of PHSF is valid then we update PHSF */
1064 if(psPhsRule->u8PHSFLength)
1066 //update PHSF
1067 memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
1068 psPhsRule->u8PHSF , MAX_PHS_LENGTHS);
1070 if(psPhsRule->u8PHSFLength)
1072 //update PHSFLen
1073 pstClassifierEntry->pstPhsRule->u8PHSFLength =
1074 psPhsRule->u8PHSFLength;
1076 if(psPhsRule->u8PHSMLength)
1078 //update PHSM
1079 memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
1080 psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
1082 if(psPhsRule->u8PHSMLength)
1084 //update PHSM Len
1085 pstClassifierEntry->pstPhsRule->u8PHSMLength =
1086 psPhsRule->u8PHSMLength;
1088 if(psPhsRule->u8PHSS)
1090 //update PHSS
1091 pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS;
1094 //update PHSV
1095 pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV;
1098 else
1101 A new rule is being set for this classifier.
1103 uiStatus=UpdateClassifierPHSRule( uiClsId, pstClassifierEntry,
1104 psaClassifiertable, psPhsRule, u8AssociatedPHSI);
1109 return uiStatus;
1112 UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
1113 S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
1114 E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI)
1116 UINT iClassifierIndex = 0;
1117 BOOLEAN bFreeEntryFound = FALSE;
1118 S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
1119 UINT nStatus = PHS_SUCCESS;
1120 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1121 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Inside CreateClassifierPHSRule");
1122 if(psaClassifiertable == NULL)
1124 return ERR_INVALID_CLASSIFIERTABLE_FOR_SF;
1127 if(eClsContext == eOldClassifierRuleContext)
1129 /* If An Old Entry for this classifier ID already exists in the
1130 old rules table replace it. */
1132 iClassifierIndex =
1133 GetClassifierEntry(psaClassifiertable, uiClsId,
1134 eClsContext,&psClassifierRules);
1135 if(iClassifierIndex != PHS_INVALID_TABLE_INDEX)
1138 The Classifier already exists in the old rules table
1139 Lets replace the old classifier with the new one.
1141 bFreeEntryFound = TRUE;
1145 if(!bFreeEntryFound)
1148 Continue to search for a free location to add the rule
1150 for(iClassifierIndex = 0; iClassifierIndex <
1151 MAX_PHSRULE_PER_SF; iClassifierIndex++)
1153 if(eClsContext == eActiveClassifierRuleContext)
1155 psClassifierRules =
1156 &psaClassifiertable->stActivePhsRulesList[iClassifierIndex];
1158 else
1160 psClassifierRules =
1161 &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
1164 if(!psClassifierRules->bUsed)
1166 bFreeEntryFound = TRUE;
1167 break;
1172 if(!bFreeEntryFound)
1174 if(eClsContext == eActiveClassifierRuleContext)
1176 return ERR_CLSASSIFIER_TABLE_FULL;
1178 else
1180 //Lets replace the oldest rule if we are looking in old Rule table
1181 if(psaClassifiertable->uiOldestPhsRuleIndex >=
1182 MAX_PHSRULE_PER_SF)
1184 psaClassifiertable->uiOldestPhsRuleIndex =0;
1187 iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex;
1188 psClassifierRules =
1189 &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
1191 (psaClassifiertable->uiOldestPhsRuleIndex)++;
1195 if(eClsContext == eOldClassifierRuleContext)
1197 if(psClassifierRules->pstPhsRule == NULL)
1199 psClassifierRules->pstPhsRule = kmalloc(sizeof(S_PHS_RULE),GFP_KERNEL);
1201 if(NULL == psClassifierRules->pstPhsRule)
1202 return ERR_PHSRULE_MEMALLOC_FAIL;
1205 psClassifierRules->bUsed = TRUE;
1206 psClassifierRules->uiClassifierRuleId = uiClsId;
1207 psClassifierRules->u8PHSI = psPhsRule->u8PHSI;
1208 psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
1210 /* Update The PHS rule */
1211 memcpy(psClassifierRules->pstPhsRule,
1212 psPhsRule, sizeof(S_PHS_RULE));
1214 else
1216 nStatus = UpdateClassifierPHSRule(uiClsId,psClassifierRules,
1217 psaClassifiertable,psPhsRule,u8AssociatedPHSI);
1219 return nStatus;
1223 UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
1224 IN S_CLASSIFIER_ENTRY *pstClassifierEntry,
1225 S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
1226 B_UINT8 u8AssociatedPHSI)
1228 S_PHS_RULE *pstAddPhsRule = NULL;
1229 UINT nPhsRuleIndex = 0;
1230 BOOLEAN bPHSRuleOrphaned = FALSE;
1231 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1232 psPhsRule->u8RefCnt =0;
1234 /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/
1235 bPHSRuleOrphaned = DerefPhsRule( uiClsId, psaClassifiertable,
1236 pstClassifierEntry->pstPhsRule);
1238 //Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF
1239 nPhsRuleIndex =GetPhsRuleEntry(psaClassifiertable,u8AssociatedPHSI,
1240 eActiveClassifierRuleContext, &pstAddPhsRule);
1241 if(PHS_INVALID_TABLE_INDEX == nPhsRuleIndex)
1243 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier");
1245 if(psPhsRule->u8PHSI == 0)
1247 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n");
1248 return ERR_PHS_INVALID_PHS_RULE;
1250 //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId
1251 if(FALSE == bPHSRuleOrphaned)
1253 pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL);
1254 if(NULL == pstClassifierEntry->pstPhsRule)
1256 return ERR_PHSRULE_MEMALLOC_FAIL;
1259 memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
1262 else
1264 //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule
1265 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
1266 if(bPHSRuleOrphaned)
1268 kfree(pstClassifierEntry->pstPhsRule);
1269 pstClassifierEntry->pstPhsRule = NULL;
1271 pstClassifierEntry->pstPhsRule = pstAddPhsRule;
1274 pstClassifierEntry->bUsed = TRUE;
1275 pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI;
1276 pstClassifierEntry->uiClassifierRuleId = uiClsId;
1277 pstClassifierEntry->pstPhsRule->u8RefCnt++;
1278 pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;
1280 return PHS_SUCCESS;
1284 BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
1286 if(pstPhsRule==NULL)
1287 return FALSE;
1288 if(pstPhsRule->u8RefCnt)
1289 pstPhsRule->u8RefCnt--;
1290 if(0==pstPhsRule->u8RefCnt)
1292 /*if(pstPhsRule->u8PHSI)
1293 //Store the currently active rule into the old rules list
1294 CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);*/
1295 return TRUE;
1297 else
1299 return FALSE;
1303 static void DumpBuffer(PVOID BuffVAddress, int xferSize)
1305 int i;
1306 int iPrintLength;
1307 PUCHAR temp=(PUCHAR)BuffVAddress;
1308 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1309 iPrintLength=(xferSize<32?xferSize:32);
1310 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n");
1312 for (i=0;i < iPrintLength;i++) {
1313 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "%x|",temp[i]);
1315 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n");
1319 void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)
1321 int i,j,k,l;
1322 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1323 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules : \n");
1324 for(i=0;i<MAX_SERVICEFLOWS;i++)
1326 S_SERVICEFLOW_ENTRY stServFlowEntry =
1327 pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i];
1328 if(stServFlowEntry.bUsed)
1330 for(j=0;j<MAX_PHSRULE_PER_SF;j++)
1332 for(l=0;l<2;l++)
1334 S_CLASSIFIER_ENTRY stClsEntry;
1335 if(l==0)
1337 stClsEntry = stServFlowEntry.pstClassifierTable->stActivePhsRulesList[j];
1338 if(stClsEntry.bUsed)
1339 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule : \n");
1341 else
1343 stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j];
1344 if(stClsEntry.bUsed)
1345 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule : \n");
1347 if(stClsEntry.bUsed)
1350 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X",stServFlowEntry.uiVcid);
1351 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X",stClsEntry.uiClassifierRuleId);
1352 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X",stClsEntry.u8PHSI);
1353 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n");
1354 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X",stClsEntry.pstPhsRule->u8PHSI);
1355 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ",stClsEntry.pstPhsRule->u8PHSFLength);
1356 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : ");
1357 for(k=0;k<stClsEntry.pstPhsRule->u8PHSFLength;k++)
1359 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSF[k]);
1361 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X",stClsEntry.pstPhsRule->u8PHSMLength);
1362 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :");
1363 for(k=0;k<stClsEntry.pstPhsRule->u8PHSMLength;k++)
1365 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSM[k]);
1367 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ",stClsEntry.pstPhsRule->u8PHSS);
1368 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X",stClsEntry.pstPhsRule->u8PHSV);
1369 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n");
1378 //-----------------------------------------------------------------------------
1379 // Procedure: phs_decompress
1381 // Description: This routine restores the static fields within the packet.
1383 // Arguments:
1384 // in_buf - ptr to incoming packet buffer.
1385 // out_buf - ptr to output buffer where the suppressed header is copied.
1386 // decomp_phs_rules - ptr to PHS rule.
1387 // header_size - ptr to field which holds the phss or phsf_length.
1389 // Returns:
1390 // size -The number of bytes of dynamic fields present with in the incoming packet
1391 // header.
1392 // 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed.
1393 //-----------------------------------------------------------------------------
1395 int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
1396 S_PHS_RULE *decomp_phs_rules,UINT *header_size)
1398 int phss,size=0;
1399 S_PHS_RULE *tmp_memb;
1400 int bit,i=0;
1401 unsigned char *phsf,*phsm;
1402 int in_buf_len = *header_size-1;
1403 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1404 in_buf++;
1405 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"====>\n");
1406 *header_size = 0;
1408 if((decomp_phs_rules == NULL ))
1409 return 0;
1412 tmp_memb = decomp_phs_rules;
1413 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
1414 //*header_size = tmp_memb->u8PHSFLength;
1415 phss = tmp_memb->u8PHSS;
1416 phsf = tmp_memb->u8PHSF;
1417 phsm = tmp_memb->u8PHSM;
1419 if(phss > MAX_PHS_LENGTHS)
1420 phss = MAX_PHS_LENGTHS;
1421 //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));
1422 while((phss > 0) && (size < in_buf_len))
1424 bit = ((*phsm << i)& SUPPRESS);
1426 if(bit == SUPPRESS)
1428 *out_buf = *phsf;
1429 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d",
1430 phss,*phsf,*out_buf);
1432 else
1434 *out_buf = *in_buf;
1435 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d",
1436 phss,*in_buf,*out_buf);
1437 in_buf++;
1438 size++;
1440 out_buf++;
1441 phsf++;
1442 phss--;
1443 i++;
1444 *header_size=*header_size + 1;
1446 if(i > MAX_NO_BIT)
1448 i=0;
1449 phsm++;
1452 return size;
1458 //-----------------------------------------------------------------------------
1459 // Procedure: phs_compress
1461 // Description: This routine suppresses the static fields within the packet.Before
1462 // that it will verify the fields to be suppressed with the corresponding fields in the
1463 // phsf. For verification it checks the phsv field of PHS rule. If set and verification
1464 // succeeds it suppresses the field.If any one static field is found different none of
1465 // the static fields are suppressed then the packet is sent as uncompressed packet with
1466 // phsi=0.
1468 // Arguments:
1469 // phs_rule - ptr to PHS rule.
1470 // in_buf - ptr to incoming packet buffer.
1471 // out_buf - ptr to output buffer where the suppressed header is copied.
1472 // header_size - ptr to field which holds the phss.
1474 // Returns:
1475 // size-The number of bytes copied into the output buffer i.e dynamic fields
1476 // 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails.
1477 //-----------------------------------------------------------------------------
1478 int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf
1479 ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
1481 unsigned char *old_addr = out_buf;
1482 int supress = 0;
1483 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1484 if(phs_rule == NULL)
1486 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nphs_compress(): phs_rule null!");
1487 *out_buf = ZERO_PHSI;
1488 return STATUS_PHS_NOCOMPRESSION;
1492 if(phs_rule->u8PHSS <= *new_header_size)
1494 *header_size = phs_rule->u8PHSS;
1496 else
1498 *header_size = *new_header_size;
1500 //To copy PHSI
1501 out_buf++;
1502 supress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF,
1503 phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size);
1505 if(supress == STATUS_PHS_COMPRESSED)
1507 *old_addr = (unsigned char)phs_rule->u8PHSI;
1508 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress phsi %d",phs_rule->u8PHSI);
1510 else
1512 *old_addr = ZERO_PHSI;
1513 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress PHSV Verification failed");
1515 return supress;
1519 //-----------------------------------------------------------------------------
1520 // Procedure: verify_suppress_phsf
1522 // Description: This routine verifies the fields of the packet and if all the
1523 // static fields are equal it adds the phsi of that PHS rule.If any static
1524 // field differs it woun't suppress any field.
1526 // Arguments:
1527 // rules_set - ptr to classifier_rules.
1528 // in_buffer - ptr to incoming packet buffer.
1529 // out_buffer - ptr to output buffer where the suppressed header is copied.
1530 // phsf - ptr to phsf.
1531 // phsm - ptr to phsm.
1532 // phss - variable holding phss.
1534 // Returns:
1535 // size-The number of bytes copied into the output buffer i.e dynamic fields.
1536 // 0 -Packet has failed the verification.
1537 //-----------------------------------------------------------------------------
1539 int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
1540 unsigned char *phsf,unsigned char *phsm,unsigned int phss,
1541 unsigned int phsv,UINT* new_header_size)
1543 unsigned int size=0;
1544 int bit,i=0;
1545 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1546 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf PHSM - 0x%X",*phsm);
1549 if(phss>(*new_header_size))
1551 phss=*new_header_size;
1553 while(phss > 0)
1555 bit = ((*phsm << i)& SUPPRESS);
1556 if(bit == SUPPRESS)
1559 if(*in_buffer != *phsf)
1561 if(phsv == VERIFY)
1563 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);
1564 return STATUS_PHS_NOCOMPRESSION;
1567 else
1568 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);
1570 else
1572 *out_buffer = *in_buffer;
1573 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In copying_header input %d out %d",*in_buffer,*out_buffer);
1574 out_buffer++;
1575 size++;
1577 in_buffer++;
1578 phsf++;
1579 phss--;
1580 i++;
1581 if(i > MAX_NO_BIT)
1583 i=0;
1584 phsm++;
1587 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success");
1588 *new_header_size = size;
1589 return STATUS_PHS_COMPRESSED;