staging/bcm: add sparse annotations
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / bcm / PHSModule.c
blob8a38cf43e79549cbfe39450179f71075843e3ee2
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 bcm_kfree_skb(Packet);
124 *pPacket = Packet = newPacket;
125 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
128 numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);
130 OsalMemMove(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
131 OsalMemMove(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 OsalMemMove(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 (S_SERVICEFLOW_TABLE*)OsalMemAlloc(sizeof(S_SERVICEFLOW_TABLE),
274 PHS_MEM_TAG);
276 if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
278 OsalZeroMemory(pPhsdeviceExtension->pstServiceFlowPhsRulesTable,
279 sizeof(S_SERVICEFLOW_TABLE));
281 else
283 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
284 return -ENOMEM;
287 pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable;
288 for(i=0;i<MAX_SERVICEFLOWS;i++)
290 S_SERVICEFLOW_ENTRY sServiceFlow = pstServiceFlowTable->stSFList[i];
291 sServiceFlow.pstClassifierTable = (S_CLASSIFIER_TABLE*)OsalMemAlloc(
292 sizeof(S_CLASSIFIER_TABLE), PHS_MEM_TAG);
293 if(sServiceFlow.pstClassifierTable)
295 OsalZeroMemory(sServiceFlow.pstClassifierTable,sizeof(S_CLASSIFIER_TABLE));
296 pstServiceFlowTable->stSFList[i].pstClassifierTable = sServiceFlow.pstClassifierTable;
298 else
300 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
301 free_phs_serviceflow_rules(pPhsdeviceExtension->
302 pstServiceFlowPhsRulesTable);
303 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
304 return -ENOMEM;
309 pPhsdeviceExtension->CompressedTxBuffer =
310 OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG);
312 if(pPhsdeviceExtension->CompressedTxBuffer == NULL)
314 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
315 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
316 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
317 return -ENOMEM;
320 pPhsdeviceExtension->UnCompressedRxBuffer =
321 OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG);
322 if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
324 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
325 OsalMemFree(pPhsdeviceExtension->CompressedTxBuffer,PHS_BUFFER_SIZE);
326 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
327 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
328 return -ENOMEM;
333 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successfull");
334 return STATUS_SUCCESS;
338 int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt)
340 if(pPHSDeviceExt->pstServiceFlowPhsRulesTable)
342 free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable);
343 pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
346 if(pPHSDeviceExt->CompressedTxBuffer)
348 OsalMemFree(pPHSDeviceExt->CompressedTxBuffer,PHS_BUFFER_SIZE);
349 pPHSDeviceExt->CompressedTxBuffer = NULL;
351 if(pPHSDeviceExt->UnCompressedRxBuffer)
353 OsalMemFree(pPHSDeviceExt->UnCompressedRxBuffer,PHS_BUFFER_SIZE);
354 pPHSDeviceExt->UnCompressedRxBuffer = NULL;
357 return 0;
362 //PHS functions
363 /*++
364 PhsUpdateClassifierRule
366 Routine Description:
367 Exported function to add or modify a PHS Rule.
369 Arguments:
370 IN void* pvContext - PHS Driver Specific Context
371 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
372 IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
373 IN S_PHS_RULE *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table.
375 Return Value:
377 0 if successful,
378 >0 Error.
380 --*/
381 ULONG PhsUpdateClassifierRule(IN void* pvContext,
382 IN B_UINT16 uiVcid ,
383 IN B_UINT16 uiClsId ,
384 IN S_PHS_RULE *psPhsRule,
385 IN B_UINT8 u8AssociatedPHSI)
387 ULONG lStatus =0;
388 UINT nSFIndex =0 ;
389 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
390 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
394 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
396 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS With Corr2 Changes \n");
398 if(pDeviceExtension == NULL)
400 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Invalid Device Extension\n");
401 return ERR_PHS_INVALID_DEVICE_EXETENSION;
405 if(u8AssociatedPHSI == 0)
407 return ERR_PHS_INVALID_PHS_RULE;
410 /* Retrieve the SFID Entry Index for requested Service Flow */
412 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
413 uiVcid,&pstServiceFlowEntry);
415 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
417 /* This is a new SF. Create a mapping entry for this */
418 lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId,
419 pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI);
420 return lStatus;
423 /* SF already Exists Add PHS Rule to existing SF */
424 lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId,
425 pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI);
427 return lStatus;
430 /*++
431 PhsDeletePHSRule
433 Routine Description:
434 Deletes the specified phs Rule within Vcid
436 Arguments:
437 IN void* pvContext - PHS Driver Specific Context
438 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
439 IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted.
441 Return Value:
443 0 if successful,
444 >0 Error.
446 --*/
448 ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI)
450 ULONG lStatus =0;
451 UINT nSFIndex =0, nClsidIndex =0 ;
452 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
453 S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
454 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
457 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
459 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n");
461 if(pDeviceExtension)
464 //Retrieve the SFID Entry Index for requested Service Flow
465 nSFIndex = GetServiceFlowEntry(pDeviceExtension
466 ->pstServiceFlowPhsRulesTable,uiVcid,&pstServiceFlowEntry);
468 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
470 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
471 return ERR_SF_MATCH_FAIL;
474 pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable;
475 if(pstClassifierRulesTable)
477 for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++)
479 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
481 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
482 .pstPhsRule->u8PHSI == u8PHSI)
484 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule
485 ->u8RefCnt)
486 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule
487 ->u8RefCnt--;
488 if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
489 .pstPhsRule->u8RefCnt)
490 OsalMemFree(pstClassifierRulesTable
491 ->stActivePhsRulesList[nClsidIndex].pstPhsRule,
492 sizeof(S_PHS_RULE));
493 OsalZeroMemory(&pstClassifierRulesTable
494 ->stActivePhsRulesList[nClsidIndex],
495 sizeof(S_CLASSIFIER_ENTRY));
502 return lStatus;
505 /*++
506 PhsDeleteClassifierRule
508 Routine Description:
509 Exported function to Delete a PHS Rule for the SFID,CLSID Pair.
511 Arguments:
512 IN void* pvContext - PHS Driver Specific Context
513 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
514 IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
516 Return Value:
518 0 if successful,
519 >0 Error.
521 --*/
522 ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 uiClsId)
524 ULONG lStatus =0;
525 UINT nSFIndex =0, nClsidIndex =0 ;
526 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
527 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
528 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
529 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
531 if(pDeviceExtension)
533 //Retrieve the SFID Entry Index for requested Service Flow
534 nSFIndex = GetServiceFlowEntry(pDeviceExtension
535 ->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry);
536 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
538 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"SFID Match Failed\n");
539 return ERR_SF_MATCH_FAIL;
542 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
543 uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry);
544 if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
546 if(pstClassifierEntry->pstPhsRule)
548 if(pstClassifierEntry->pstPhsRule->u8RefCnt)
549 pstClassifierEntry->pstPhsRule->u8RefCnt--;
550 if(0==pstClassifierEntry->pstPhsRule->u8RefCnt)
551 OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
554 OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY));
557 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
558 uiClsId,eOldClassifierRuleContext,&pstClassifierEntry);
560 if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
562 if(pstClassifierEntry->pstPhsRule)
563 //Delete the classifier entry
564 OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
565 OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY));
568 return lStatus;
571 /*++
572 PhsDeleteSFRules
574 Routine Description:
575 Exported function to Delete a all PHS Rules for the SFID.
577 Arguments:
578 IN void* pvContext - PHS Driver Specific Context
579 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted
581 Return Value:
583 0 if successful,
584 >0 Error.
586 --*/
587 ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid)
590 ULONG lStatus =0;
591 UINT nSFIndex =0, nClsidIndex =0 ;
592 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
593 S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
594 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
595 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
596 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"====> \n");
598 if(pDeviceExtension)
600 //Retrieve the SFID Entry Index for requested Service Flow
601 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
602 uiVcid,&pstServiceFlowEntry);
603 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
605 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
606 return ERR_SF_MATCH_FAIL;
609 pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable;
610 if(pstClassifierRulesTable)
612 for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++)
614 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
616 if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
617 .pstPhsRule->u8RefCnt)
618 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
619 .pstPhsRule->u8RefCnt--;
620 if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
621 .pstPhsRule->u8RefCnt)
622 OsalMemFree(pstClassifierRulesTable
623 ->stActivePhsRulesList[nClsidIndex].pstPhsRule,
624 sizeof(S_PHS_RULE));
625 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
626 .pstPhsRule = NULL;
628 OsalZeroMemory(&pstClassifierRulesTable
629 ->stActivePhsRulesList[nClsidIndex],sizeof(S_CLASSIFIER_ENTRY));
630 if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule)
632 if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
633 .pstPhsRule->u8RefCnt)
634 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
635 .pstPhsRule->u8RefCnt--;
636 if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
637 .pstPhsRule->u8RefCnt)
638 OsalMemFree(pstClassifierRulesTable
639 ->stOldPhsRulesList[nClsidIndex].pstPhsRule,
640 sizeof(S_PHS_RULE));
641 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
642 .pstPhsRule = NULL;
644 OsalZeroMemory(&pstClassifierRulesTable
645 ->stOldPhsRulesList[nClsidIndex],
646 sizeof(S_CLASSIFIER_ENTRY));
649 pstServiceFlowEntry->bUsed = FALSE;
650 pstServiceFlowEntry->uiVcid = 0;
654 return lStatus;
658 /*++
659 PhsCompress
661 Routine Description:
662 Exported function to compress the data using PHS.
664 Arguments:
665 IN void* pvContext - PHS Driver Specific Context.
666 IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies.
667 IN UINT uiClsId - The Classifier ID to which current packet header compression applies.
668 IN void *pvInputBuffer - The Input buffer containg packet header data
669 IN void *pvOutputBuffer - The output buffer returned by this function after PHS
670 IN UINT *pOldHeaderSize - The actual size of the header before PHS
671 IN UINT *pNewHeaderSize - The new size of the header after applying PHS
673 Return Value:
675 0 if successful,
676 >0 Error.
678 --*/
679 ULONG PhsCompress(IN void* pvContext,
680 IN B_UINT16 uiVcid,
681 IN B_UINT16 uiClsId,
682 IN void *pvInputBuffer,
683 OUT void *pvOutputBuffer,
684 OUT UINT *pOldHeaderSize,
685 OUT UINT *pNewHeaderSize )
687 UINT nSFIndex =0, nClsidIndex =0 ;
688 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
689 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
690 S_PHS_RULE *pstPhsRule = NULL;
691 ULONG lStatus =0;
692 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
696 PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
699 if(pDeviceExtension == NULL)
701 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Invalid Device Extension\n");
702 lStatus = STATUS_PHS_NOCOMPRESSION ;
703 return lStatus;
707 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Suppressing header \n");
710 //Retrieve the SFID Entry Index for requested Service Flow
711 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
712 uiVcid,&pstServiceFlowEntry);
713 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
715 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"SFID Match Failed\n");
716 lStatus = STATUS_PHS_NOCOMPRESSION ;
717 return lStatus;
720 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
721 uiClsId,eActiveClassifierRuleContext,&pstClassifierEntry);
723 if(nClsidIndex == PHS_INVALID_TABLE_INDEX)
725 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"No PHS Rule Defined For Classifier\n");
726 lStatus = STATUS_PHS_NOCOMPRESSION ;
727 return lStatus;
731 //get rule from SF id,Cls ID pair and proceed
732 pstPhsRule = pstClassifierEntry->pstPhsRule;
734 if(!ValidatePHSRuleComplete(pstPhsRule))
736 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS Rule Defined For Classifier But Not Complete\n");
737 lStatus = STATUS_PHS_NOCOMPRESSION ;
738 return lStatus;
741 //Compress Packet
742 lStatus = phs_compress(pstPhsRule,(PUCHAR)pvInputBuffer,
743 (PUCHAR)pvOutputBuffer, pOldHeaderSize,pNewHeaderSize);
745 if(lStatus == STATUS_PHS_COMPRESSED)
747 pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1;
748 pstPhsRule->PHSModifiedNumPackets++;
750 else
751 pstPhsRule->PHSErrorNumPackets++;
753 return lStatus;
756 /*++
757 PhsDeCompress
759 Routine Description:
760 Exported function to restore the packet header in Rx path.
762 Arguments:
763 IN void* pvContext - PHS Driver Specific Context.
764 IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies.
765 IN void *pvInputBuffer - The Input buffer containg suppressed packet header data
766 OUT void *pvOutputBuffer - The output buffer returned by this function after restoration
767 OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter.
769 Return Value:
771 0 if successful,
772 >0 Error.
774 --*/
775 ULONG PhsDeCompress(IN void* pvContext,
776 IN B_UINT16 uiVcid,
777 IN void *pvInputBuffer,
778 OUT void *pvOutputBuffer,
779 OUT UINT *pInHeaderSize,
780 OUT UINT *pOutHeaderSize )
782 UINT nSFIndex =0, nPhsRuleIndex =0 ;
783 S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
784 S_PHS_RULE *pstPhsRule = NULL;
785 UINT phsi;
786 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
787 PPHS_DEVICE_EXTENSION pDeviceExtension=
788 (PPHS_DEVICE_EXTENSION)pvContext;
790 *pInHeaderSize = 0;
792 if(pDeviceExtension == NULL)
794 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Invalid Device Extension\n");
795 return ERR_PHS_INVALID_DEVICE_EXETENSION;
798 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Restoring header \n");
800 phsi = *((unsigned char *)(pvInputBuffer));
801 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x \n",phsi);
802 if(phsi == UNCOMPRESSED_PACKET )
804 return STATUS_PHS_NOCOMPRESSION;
807 //Retrieve the SFID Entry Index for requested Service Flow
808 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
809 uiVcid,&pstServiceFlowEntry);
810 if(nSFIndex == PHS_INVALID_TABLE_INDEX)
812 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n");
813 return ERR_SF_MATCH_FAIL;
816 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,phsi,
817 eActiveClassifierRuleContext,&pstPhsRule);
818 if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
820 //Phs Rule does not exist in active rules table. Lets try in the old rules table.
821 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
822 phsi,eOldClassifierRuleContext,&pstPhsRule);
823 if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
825 return ERR_PHSRULE_MATCH_FAIL;
830 *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer,
831 (PUCHAR)pvOutputBuffer,pstPhsRule,pOutHeaderSize);
833 pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1;
835 pstPhsRule->PHSModifiedNumPackets++;
836 return STATUS_PHS_COMPRESSED;
840 //-----------------------------------------------------------------------------
841 // Procedure: free_phs_serviceflow_rules
843 // Description: This routine is responsible for freeing memory allocated for PHS rules.
845 // Arguments:
846 // rules - ptr to S_SERVICEFLOW_TABLE structure.
848 // Returns:
849 // Does not return any value.
850 //-----------------------------------------------------------------------------
852 void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
854 int i,j;
855 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
857 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n");
858 if(psServiceFlowRulesTable)
860 for(i=0;i<MAX_SERVICEFLOWS;i++)
862 S_SERVICEFLOW_ENTRY stServiceFlowEntry =
863 psServiceFlowRulesTable->stSFList[i];
864 S_CLASSIFIER_TABLE *pstClassifierRulesTable =
865 stServiceFlowEntry.pstClassifierTable;
867 if(pstClassifierRulesTable)
869 for(j=0;j<MAX_PHSRULE_PER_SF;j++)
871 if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule)
873 if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
874 ->u8RefCnt)
875 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
876 ->u8RefCnt--;
877 if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
878 ->u8RefCnt)
879 OsalMemFree(pstClassifierRulesTable->stActivePhsRulesList[j].
880 pstPhsRule, sizeof(S_PHS_RULE));
881 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
883 if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule)
885 if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
886 ->u8RefCnt)
887 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
888 ->u8RefCnt--;
889 if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
890 ->u8RefCnt)
891 OsalMemFree(pstClassifierRulesTable->stOldPhsRulesList[j]
892 .pstPhsRule,sizeof(S_PHS_RULE));
893 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
896 OsalMemFree(pstClassifierRulesTable,sizeof(S_CLASSIFIER_TABLE));
897 stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
902 OsalMemFree(psServiceFlowRulesTable,sizeof(S_SERVICEFLOW_TABLE));
903 psServiceFlowRulesTable = NULL;
908 BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
910 if(psPhsRule)
912 if(!psPhsRule->u8PHSI)
914 // PHSI is not valid
915 return FALSE;
918 if(!psPhsRule->u8PHSS)
920 //PHSS Is Undefined
921 return FALSE;
924 //Check if PHSF is defines for the PHS Rule
925 if(!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF
927 return FALSE;
929 return TRUE;
931 else
933 return FALSE;
937 UINT GetServiceFlowEntry(IN S_SERVICEFLOW_TABLE *psServiceFlowTable,
938 IN B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry)
940 int i;
941 for(i=0;i<MAX_SERVICEFLOWS;i++)
943 if(psServiceFlowTable->stSFList[i].bUsed)
945 if(psServiceFlowTable->stSFList[i].uiVcid == uiVcid)
947 *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i];
948 return i;
953 *ppstServiceFlowEntry = NULL;
954 return PHS_INVALID_TABLE_INDEX;
958 UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
959 IN B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
960 OUT S_CLASSIFIER_ENTRY **ppstClassifierEntry)
962 int i;
963 S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
964 for(i=0;i<MAX_PHSRULE_PER_SF;i++)
967 if(eClsContext == eActiveClassifierRuleContext)
969 psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i];
971 else
973 psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i];
976 if(psClassifierRules->bUsed)
978 if(psClassifierRules->uiClassifierRuleId == uiClsid)
980 *ppstClassifierEntry = psClassifierRules;
981 return i;
987 *ppstClassifierEntry = NULL;
988 return PHS_INVALID_TABLE_INDEX;
991 UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
992 IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
993 OUT S_PHS_RULE **ppstPhsRule)
995 int i;
996 S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
997 for(i=0;i<MAX_PHSRULE_PER_SF;i++)
999 if(eClsContext == eActiveClassifierRuleContext)
1001 pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i];
1003 else
1005 pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i];
1007 if(pstClassifierRule->bUsed)
1009 if(pstClassifierRule->u8PHSI == uiPHSI)
1011 *ppstPhsRule = pstClassifierRule->pstPhsRule;
1012 return i;
1018 *ppstPhsRule = NULL;
1019 return PHS_INVALID_TABLE_INDEX;
1022 UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId,
1023 IN S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,
1024 B_UINT8 u8AssociatedPHSI)
1027 S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
1028 UINT uiStatus = 0;
1029 int iSfIndex;
1030 BOOLEAN bFreeEntryFound =FALSE;
1031 //Check for a free entry in SFID table
1032 for(iSfIndex=0;iSfIndex < MAX_SERVICEFLOWS;iSfIndex++)
1034 if(!psServiceFlowTable->stSFList[iSfIndex].bUsed)
1036 bFreeEntryFound = TRUE;
1037 break;
1041 if(!bFreeEntryFound)
1042 return ERR_SFTABLE_FULL;
1045 psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable;
1046 uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,psPhsRule,
1047 eActiveClassifierRuleContext,u8AssociatedPHSI);
1048 if(uiStatus == PHS_SUCCESS)
1050 //Add entry at free index to the SF
1051 psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE;
1052 psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid;
1055 return uiStatus;
1059 UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
1060 IN B_UINT16 uiClsId,IN S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,
1061 S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI)
1063 S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
1064 UINT uiStatus =PHS_SUCCESS;
1065 UINT nClassifierIndex = 0;
1066 S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
1067 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1068 psaClassifiertable = pstServiceFlowEntry->pstClassifierTable;
1070 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>");
1072 /* Check if the supplied Classifier already exists */
1073 nClassifierIndex =GetClassifierEntry(
1074 pstServiceFlowEntry->pstClassifierTable,uiClsId,
1075 eActiveClassifierRuleContext,&pstClassifierEntry);
1076 if(nClassifierIndex == PHS_INVALID_TABLE_INDEX)
1079 The Classifier doesn't exist. So its a new classifier being added.
1080 Add new entry to associate PHS Rule to the Classifier
1083 uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,
1084 psPhsRule,eActiveClassifierRuleContext,u8AssociatedPHSI);
1085 return uiStatus;
1089 The Classifier exists.The PHS Rule for this classifier
1090 is being modified
1092 if(pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI)
1094 if(pstClassifierEntry->pstPhsRule == NULL)
1095 return ERR_PHS_INVALID_PHS_RULE;
1098 This rule already exists if any fields are changed for this PHS
1099 rule update them.
1101 /* If any part of PHSF is valid then we update PHSF */
1102 if(psPhsRule->u8PHSFLength)
1104 //update PHSF
1105 OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSF,
1106 psPhsRule->u8PHSF , MAX_PHS_LENGTHS);
1108 if(psPhsRule->u8PHSFLength)
1110 //update PHSFLen
1111 pstClassifierEntry->pstPhsRule->u8PHSFLength =
1112 psPhsRule->u8PHSFLength;
1114 if(psPhsRule->u8PHSMLength)
1116 //update PHSM
1117 OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSM,
1118 psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
1120 if(psPhsRule->u8PHSMLength)
1122 //update PHSM Len
1123 pstClassifierEntry->pstPhsRule->u8PHSMLength =
1124 psPhsRule->u8PHSMLength;
1126 if(psPhsRule->u8PHSS)
1128 //update PHSS
1129 pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS;
1132 //update PHSV
1133 pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV;
1136 else
1139 A new rule is being set for this classifier.
1141 uiStatus=UpdateClassifierPHSRule( uiClsId, pstClassifierEntry,
1142 psaClassifiertable, psPhsRule, u8AssociatedPHSI);
1147 return uiStatus;
1150 UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
1151 S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
1152 E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI)
1154 UINT iClassifierIndex = 0;
1155 BOOLEAN bFreeEntryFound = FALSE;
1156 S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
1157 UINT nStatus = PHS_SUCCESS;
1158 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1159 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Inside CreateClassifierPHSRule");
1160 if(psaClassifiertable == NULL)
1162 return ERR_INVALID_CLASSIFIERTABLE_FOR_SF;
1165 if(eClsContext == eOldClassifierRuleContext)
1167 /* If An Old Entry for this classifier ID already exists in the
1168 old rules table replace it. */
1170 iClassifierIndex =
1171 GetClassifierEntry(psaClassifiertable, uiClsId,
1172 eClsContext,&psClassifierRules);
1173 if(iClassifierIndex != PHS_INVALID_TABLE_INDEX)
1176 The Classifier already exists in the old rules table
1177 Lets replace the old classifier with the new one.
1179 bFreeEntryFound = TRUE;
1183 if(!bFreeEntryFound)
1186 Continue to search for a free location to add the rule
1188 for(iClassifierIndex = 0; iClassifierIndex <
1189 MAX_PHSRULE_PER_SF; iClassifierIndex++)
1191 if(eClsContext == eActiveClassifierRuleContext)
1193 psClassifierRules =
1194 &psaClassifiertable->stActivePhsRulesList[iClassifierIndex];
1196 else
1198 psClassifierRules =
1199 &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
1202 if(!psClassifierRules->bUsed)
1204 bFreeEntryFound = TRUE;
1205 break;
1210 if(!bFreeEntryFound)
1212 if(eClsContext == eActiveClassifierRuleContext)
1214 return ERR_CLSASSIFIER_TABLE_FULL;
1216 else
1218 //Lets replace the oldest rule if we are looking in old Rule table
1219 if(psaClassifiertable->uiOldestPhsRuleIndex >=
1220 MAX_PHSRULE_PER_SF)
1222 psaClassifiertable->uiOldestPhsRuleIndex =0;
1225 iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex;
1226 psClassifierRules =
1227 &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
1229 (psaClassifiertable->uiOldestPhsRuleIndex)++;
1233 if(eClsContext == eOldClassifierRuleContext)
1235 if(psClassifierRules->pstPhsRule == NULL)
1237 psClassifierRules->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc
1238 (sizeof(S_PHS_RULE),PHS_MEM_TAG);
1240 if(NULL == psClassifierRules->pstPhsRule)
1241 return ERR_PHSRULE_MEMALLOC_FAIL;
1244 psClassifierRules->bUsed = TRUE;
1245 psClassifierRules->uiClassifierRuleId = uiClsId;
1246 psClassifierRules->u8PHSI = psPhsRule->u8PHSI;
1247 psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
1249 /* Update The PHS rule */
1250 OsalMemMove(psClassifierRules->pstPhsRule,
1251 psPhsRule, sizeof(S_PHS_RULE));
1253 else
1255 nStatus = UpdateClassifierPHSRule(uiClsId,psClassifierRules,
1256 psaClassifiertable,psPhsRule,u8AssociatedPHSI);
1258 return nStatus;
1262 UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
1263 IN S_CLASSIFIER_ENTRY *pstClassifierEntry,
1264 S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
1265 B_UINT8 u8AssociatedPHSI)
1267 S_PHS_RULE *pstAddPhsRule = NULL;
1268 UINT nPhsRuleIndex = 0;
1269 BOOLEAN bPHSRuleOrphaned = FALSE;
1270 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1271 psPhsRule->u8RefCnt =0;
1273 /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/
1274 bPHSRuleOrphaned = DerefPhsRule( uiClsId, psaClassifiertable,
1275 pstClassifierEntry->pstPhsRule);
1277 //Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF
1278 nPhsRuleIndex =GetPhsRuleEntry(psaClassifiertable,u8AssociatedPHSI,
1279 eActiveClassifierRuleContext, &pstAddPhsRule);
1280 if(PHS_INVALID_TABLE_INDEX == nPhsRuleIndex)
1282 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier");
1284 if(psPhsRule->u8PHSI == 0)
1286 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n");
1287 return ERR_PHS_INVALID_PHS_RULE;
1289 //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId
1290 if(FALSE == bPHSRuleOrphaned)
1292 pstClassifierEntry->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc(sizeof(S_PHS_RULE),PHS_MEM_TAG);
1293 if(NULL == pstClassifierEntry->pstPhsRule)
1295 return ERR_PHSRULE_MEMALLOC_FAIL;
1298 OsalMemMove(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
1301 else
1303 //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule
1304 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
1305 if(bPHSRuleOrphaned)
1307 if(pstClassifierEntry->pstPhsRule)
1309 //Just Free the PHS Rule as Ref Count is Zero
1310 OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
1311 pstClassifierEntry->pstPhsRule = NULL;
1316 pstClassifierEntry->pstPhsRule = pstAddPhsRule;
1319 pstClassifierEntry->bUsed = TRUE;
1320 pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI;
1321 pstClassifierEntry->uiClassifierRuleId = uiClsId;
1322 pstClassifierEntry->pstPhsRule->u8RefCnt++;
1323 pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;
1325 return PHS_SUCCESS;
1329 BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
1331 if(pstPhsRule==NULL)
1332 return FALSE;
1333 if(pstPhsRule->u8RefCnt)
1334 pstPhsRule->u8RefCnt--;
1335 if(0==pstPhsRule->u8RefCnt)
1337 /*if(pstPhsRule->u8PHSI)
1338 //Store the currently active rule into the old rules list
1339 CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);*/
1340 return TRUE;
1342 else
1344 return FALSE;
1348 static void DumpBuffer(PVOID BuffVAddress, int xferSize)
1350 int i;
1351 int iPrintLength;
1352 PUCHAR temp=(PUCHAR)BuffVAddress;
1353 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1354 iPrintLength=(xferSize<32?xferSize:32);
1355 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n");
1357 for (i=0;i < iPrintLength;i++) {
1358 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "%x|",temp[i]);
1360 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n");
1364 void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)
1366 int i,j,k,l;
1367 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1368 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules : \n");
1369 for(i=0;i<MAX_SERVICEFLOWS;i++)
1371 S_SERVICEFLOW_ENTRY stServFlowEntry =
1372 pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i];
1373 if(stServFlowEntry.bUsed)
1375 for(j=0;j<MAX_PHSRULE_PER_SF;j++)
1377 for(l=0;l<2;l++)
1379 S_CLASSIFIER_ENTRY stClsEntry;
1380 if(l==0)
1382 stClsEntry = stServFlowEntry.pstClassifierTable->stActivePhsRulesList[j];
1383 if(stClsEntry.bUsed)
1384 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule : \n");
1386 else
1388 stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j];
1389 if(stClsEntry.bUsed)
1390 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule : \n");
1392 if(stClsEntry.bUsed)
1395 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X",stServFlowEntry.uiVcid);
1396 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X",stClsEntry.uiClassifierRuleId);
1397 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X",stClsEntry.u8PHSI);
1398 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n");
1399 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X",stClsEntry.pstPhsRule->u8PHSI);
1400 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ",stClsEntry.pstPhsRule->u8PHSFLength);
1401 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : ");
1402 for(k=0;k<stClsEntry.pstPhsRule->u8PHSFLength;k++)
1404 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSF[k]);
1406 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X",stClsEntry.pstPhsRule->u8PHSMLength);
1407 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :");
1408 for(k=0;k<stClsEntry.pstPhsRule->u8PHSMLength;k++)
1410 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSM[k]);
1412 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ",stClsEntry.pstPhsRule->u8PHSS);
1413 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X",stClsEntry.pstPhsRule->u8PHSV);
1414 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n");
1423 //-----------------------------------------------------------------------------
1424 // Procedure: phs_decompress
1426 // Description: This routine restores the static fields within the packet.
1428 // Arguments:
1429 // in_buf - ptr to incoming packet buffer.
1430 // out_buf - ptr to output buffer where the suppressed header is copied.
1431 // decomp_phs_rules - ptr to PHS rule.
1432 // header_size - ptr to field which holds the phss or phsf_length.
1434 // Returns:
1435 // size -The number of bytes of dynamic fields present with in the incoming packet
1436 // header.
1437 // 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed.
1438 //-----------------------------------------------------------------------------
1440 int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
1441 S_PHS_RULE *decomp_phs_rules,UINT *header_size)
1443 int phss,size=0;
1444 S_PHS_RULE *tmp_memb;
1445 int bit,i=0;
1446 unsigned char *phsf,*phsm;
1447 int in_buf_len = *header_size-1;
1448 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1449 in_buf++;
1450 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"====>\n");
1451 *header_size = 0;
1453 if((decomp_phs_rules == NULL ))
1454 return 0;
1457 tmp_memb = decomp_phs_rules;
1458 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
1459 //*header_size = tmp_memb->u8PHSFLength;
1460 phss = tmp_memb->u8PHSS;
1461 phsf = tmp_memb->u8PHSF;
1462 phsm = tmp_memb->u8PHSM;
1464 if(phss > MAX_PHS_LENGTHS)
1465 phss = MAX_PHS_LENGTHS;
1466 //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));
1467 while((phss > 0) && (size < in_buf_len))
1469 bit = ((*phsm << i)& SUPPRESS);
1471 if(bit == SUPPRESS)
1473 *out_buf = *phsf;
1474 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d",
1475 phss,*phsf,*out_buf);
1477 else
1479 *out_buf = *in_buf;
1480 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d",
1481 phss,*in_buf,*out_buf);
1482 in_buf++;
1483 size++;
1485 out_buf++;
1486 phsf++;
1487 phss--;
1488 i++;
1489 *header_size=*header_size + 1;
1491 if(i > MAX_NO_BIT)
1493 i=0;
1494 phsm++;
1497 return size;
1503 //-----------------------------------------------------------------------------
1504 // Procedure: phs_compress
1506 // Description: This routine suppresses the static fields within the packet.Before
1507 // that it will verify the fields to be suppressed with the corresponding fields in the
1508 // phsf. For verification it checks the phsv field of PHS rule. If set and verification
1509 // succeeds it suppresses the field.If any one static field is found different none of
1510 // the static fields are suppressed then the packet is sent as uncompressed packet with
1511 // phsi=0.
1513 // Arguments:
1514 // phs_rule - ptr to PHS rule.
1515 // in_buf - ptr to incoming packet buffer.
1516 // out_buf - ptr to output buffer where the suppressed header is copied.
1517 // header_size - ptr to field which holds the phss.
1519 // Returns:
1520 // size-The number of bytes copied into the output buffer i.e dynamic fields
1521 // 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails.
1522 //-----------------------------------------------------------------------------
1523 int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf
1524 ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
1526 unsigned char *old_addr = out_buf;
1527 int supress = 0;
1528 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1529 if(phs_rule == NULL)
1531 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nphs_compress(): phs_rule null!");
1532 *out_buf = ZERO_PHSI;
1533 return STATUS_PHS_NOCOMPRESSION;
1537 if(phs_rule->u8PHSS <= *new_header_size)
1539 *header_size = phs_rule->u8PHSS;
1541 else
1543 *header_size = *new_header_size;
1545 //To copy PHSI
1546 out_buf++;
1547 supress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF,
1548 phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size);
1550 if(supress == STATUS_PHS_COMPRESSED)
1552 *old_addr = (unsigned char)phs_rule->u8PHSI;
1553 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress phsi %d",phs_rule->u8PHSI);
1555 else
1557 *old_addr = ZERO_PHSI;
1558 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress PHSV Verification failed");
1560 return supress;
1564 //-----------------------------------------------------------------------------
1565 // Procedure: verify_suppress_phsf
1567 // Description: This routine verifies the fields of the packet and if all the
1568 // static fields are equal it adds the phsi of that PHS rule.If any static
1569 // field differs it woun't suppress any field.
1571 // Arguments:
1572 // rules_set - ptr to classifier_rules.
1573 // in_buffer - ptr to incoming packet buffer.
1574 // out_buffer - ptr to output buffer where the suppressed header is copied.
1575 // phsf - ptr to phsf.
1576 // phsm - ptr to phsm.
1577 // phss - variable holding phss.
1579 // Returns:
1580 // size-The number of bytes copied into the output buffer i.e dynamic fields.
1581 // 0 -Packet has failed the verification.
1582 //-----------------------------------------------------------------------------
1584 int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
1585 unsigned char *phsf,unsigned char *phsm,unsigned int phss,
1586 unsigned int phsv,UINT* new_header_size)
1588 unsigned int size=0;
1589 int bit,i=0;
1590 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
1591 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf PHSM - 0x%X",*phsm);
1594 if(phss>(*new_header_size))
1596 phss=*new_header_size;
1598 while(phss > 0)
1600 bit = ((*phsm << i)& SUPPRESS);
1601 if(bit == SUPPRESS)
1604 if(*in_buffer != *phsf)
1606 if(phsv == VERIFY)
1608 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);
1609 return STATUS_PHS_NOCOMPRESSION;
1612 else
1613 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);
1615 else
1617 *out_buffer = *in_buffer;
1618 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In copying_header input %d out %d",*in_buffer,*out_buffer);
1619 out_buffer++;
1620 size++;
1622 in_buffer++;
1623 phsf++;
1624 phss--;
1625 i++;
1626 if(i > MAX_NO_BIT)
1628 i=0;
1629 phsm++;
1632 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success");
1633 *new_header_size = size;
1634 return STATUS_PHS_COMPRESSED;