#include "headers.h"

static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16  uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);

static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16  uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);

static UINT CreateClassifierPHSRule(B_UINT16  uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI);

static UINT UpdateClassifierPHSRule(B_UINT16  uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);

static BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule);

static BOOLEAN DerefPhsRule(B_UINT16  uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule);

static UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry);

static UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule);

static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable);

static int phs_compress(S_PHS_RULE   *phs_members,unsigned char *in_buf,
						unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size );


static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
								unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size );

static int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\
						  S_PHS_RULE   *phs_rules,UINT *header_size);


static ULONG PhsCompress(void* pvContext,
				  B_UINT16 uiVcid,
				  B_UINT16 uiClsId,
				  void *pvInputBuffer,
				  void *pvOutputBuffer,
				  UINT *pOldHeaderSize,
				  UINT *pNewHeaderSize );

static ULONG PhsDeCompress(void* pvContext,
				  B_UINT16 uiVcid,
				  void *pvInputBuffer,
				  void *pvOutputBuffer,
				  UINT *pInHeaderSize,
				  UINT *pOutHeaderSize);



#define IN
#define OUT

/*
Function:				PHSTransmit

Description:			This routine handle PHS(Payload Header Suppression for Tx path.
					It extracts a fragment of the NDIS_PACKET containing the header
					to be suppressed.It then supresses the header by invoking PHS exported compress routine.
					The header data after supression is copied back to the NDIS_PACKET.


Input parameters:		IN PMINI_ADAPTER Adapter         - Miniport Adapter Context
						IN Packet 				- NDIS packet containing data to be transmitted
						IN USHORT Vcid        - vcid pertaining to connection on which the packet is being sent.Used to
										        identify PHS rule to be applied.
						B_UINT16 uiClassifierRuleID - Classifier Rule ID
						BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF.

Return:					STATUS_SUCCESS - If the send was successful.
						Other          - If an error occured.
*/

int PHSTransmit(PMINI_ADAPTER Adapter,
					 struct sk_buff	**pPacket,
					 USHORT Vcid,
					 B_UINT16 uiClassifierRuleID,
					 BOOLEAN bHeaderSuppressionEnabled,
					 UINT *PacketLen,
					 UCHAR bEthCSSupport)
{

	//PHS Sepcific
	UINT    unPHSPktHdrBytesCopied = 0;
	UINT	unPhsOldHdrSize = 0;
	UINT	unPHSNewPktHeaderLen = 0;
	/* Pointer to PHS IN Hdr Buffer */
	PUCHAR pucPHSPktHdrInBuf =
				Adapter->stPhsTxContextInfo.ucaHdrSupressionInBuf;
	/* Pointer to PHS OUT Hdr Buffer */
	PUCHAR  pucPHSPktHdrOutBuf =
					Adapter->stPhsTxContextInfo.ucaHdrSupressionOutBuf;
	UINT       usPacketType;
	UINT       BytesToRemove=0;
	BOOLEAN  bPHSI = 0;
	LONG ulPhsStatus = 0;
	UINT 	numBytesCompressed = 0;
	struct sk_buff *newPacket = NULL;
	struct sk_buff *Packet = *pPacket;

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "In PHSTransmit");

	if(!bEthCSSupport)
		BytesToRemove=ETH_HLEN;
	/*
		Accumulate the header upto the size we support supression
		from NDIS packet
	*/

	usPacketType=((struct ethhdr *)(Packet->data))->h_proto;


	pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
	//considering data after ethernet header
	if((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS)
	{

		unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove);
	}
	else
	{
		unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS;
	}

	if( (unPHSPktHdrBytesCopied > 0 ) &&
		(unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS))
	{


		// Step 2 Supress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf.
	// Suppress only if IP Header and PHS Enabled For the Service Flow
		if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
			(usPacketType == ETHERNET_FRAMETYPE_IPV6)) &&
			(bHeaderSuppressionEnabled))
		{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nTrying to PHS Compress Using Classifier rule 0x%X",uiClassifierRuleID);


				unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied;
				ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext,
					Vcid,
					uiClassifierRuleID,
					pucPHSPktHdrInBuf,
					pucPHSPktHdrOutBuf,
					&unPhsOldHdrSize,
					&unPHSNewPktHeaderLen);
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nPHS Old header Size : %d New Header Size  %d\n",unPhsOldHdrSize,unPHSNewPktHeaderLen);

				if(unPHSNewPktHeaderLen == unPhsOldHdrSize)
				{
					if(  ulPhsStatus == STATUS_PHS_COMPRESSED)
							bPHSI = *pucPHSPktHdrOutBuf;
					ulPhsStatus = STATUS_PHS_NOCOMPRESSION;
				}

				if(  ulPhsStatus == STATUS_PHS_COMPRESSED)
				{
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHS Sending packet Compressed");

					if(skb_cloned(Packet))
					{
						newPacket = skb_copy(Packet, GFP_ATOMIC);

						if(newPacket == NULL)
							return STATUS_FAILURE;

						dev_kfree_skb(Packet);
						*pPacket = Packet = newPacket;
						pucPHSPktHdrInBuf = Packet->data  + BytesToRemove;
					}

					numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);

					memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
					memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
					skb_pull(Packet, numBytesCompressed);

					return STATUS_SUCCESS;
				}

				else
				{
					//if one byte headroom is not available, increase it through skb_cow
					if(!(skb_headroom(Packet) > 0))
					{
						if(skb_cow(Packet, 1))
						{
							BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n");
							return STATUS_FAILURE;
						}
					}
					skb_push(Packet, 1);

					// CAUTION: The MAC Header is getting corrupted here for IP CS - can be saved by copying 14 Bytes.  not needed .... hence corrupting it.
					*(Packet->data + BytesToRemove) = bPHSI;
					return STATUS_SUCCESS;
			}
		}
		else
		{
			if(!bHeaderSuppressionEnabled)
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nHeader Suppression Disabled For SF: No PHS\n");
			}

			return STATUS_SUCCESS;
		}
	}

	//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS");
	return STATUS_SUCCESS;
}

int PHSRecieve(PMINI_ADAPTER Adapter,
					USHORT usVcid,
					struct sk_buff *packet,
					UINT *punPacketLen,
					UCHAR *pucEthernetHdr,
					UINT	bHeaderSuppressionEnabled)
{
	u32   nStandardPktHdrLen            		= 0;
	u32   nTotalsupressedPktHdrBytes  = 0;
	int     ulPhsStatus 		= 0;
	PUCHAR pucInBuff = NULL ;
	UINT TotalBytesAdded = 0;
	if(!bHeaderSuppressionEnabled)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet");
		return ulPhsStatus;
	}

	pucInBuff = packet->data;

	//Restore  PHS suppressed header
	nStandardPktHdrLen = packet->len;
	ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext,
		usVcid,
		pucInBuff,
		Adapter->ucaPHSPktRestoreBuf,
		&nTotalsupressedPktHdrBytes,
		&nStandardPktHdrLen);

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
					nTotalsupressedPktHdrBytes,nStandardPktHdrLen);

	if(ulPhsStatus != STATUS_PHS_COMPRESSED)
	{
		skb_pull(packet, 1);
		return STATUS_SUCCESS;
	}
	else
	{
		TotalBytesAdded = nStandardPktHdrLen - nTotalsupressedPktHdrBytes - PHSI_LEN;
		if(TotalBytesAdded)
		{
			if(skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded))
				skb_push(packet, TotalBytesAdded);
			else
			{
				if(skb_cow(packet, skb_headroom(packet) + TotalBytesAdded))
				{
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n");
					return STATUS_FAILURE;
				}

				skb_push(packet, TotalBytesAdded);
			}
		}

		memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
	}

	return STATUS_SUCCESS;
}

void DumpFullPacket(UCHAR *pBuf,UINT nPktLen)
{
	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"Dumping Data Packet");
    BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,pBuf,nPktLen);
}

//-----------------------------------------------------------------------------
// Procedure:   phs_init
//
// Description: This routine is responsible for allocating memory for classifier and
// PHS rules.
//
// Arguments:
// pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc
//
// Returns:
// TRUE(1)	-If allocation of memory was success full.
// FALSE	-If allocation of memory fails.
//-----------------------------------------------------------------------------
int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)
{
	int i;
	S_SERVICEFLOW_TABLE *pstServiceFlowTable;
    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nPHS:phs_init function ");

	if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
		return -EINVAL;

	pPhsdeviceExtension->pstServiceFlowPhsRulesTable =
		kzalloc(sizeof(S_SERVICEFLOW_TABLE), GFP_KERNEL);

    if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
		return -ENOMEM;
	}

	pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable;
	for(i=0;i<MAX_SERVICEFLOWS;i++)
	{
		S_SERVICEFLOW_ENTRY sServiceFlow = pstServiceFlowTable->stSFList[i];
		sServiceFlow.pstClassifierTable = kzalloc(sizeof(S_CLASSIFIER_TABLE), GFP_KERNEL);
		if(!sServiceFlow.pstClassifierTable)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
			free_phs_serviceflow_rules(pPhsdeviceExtension->
                pstServiceFlowPhsRulesTable);
			pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
			return -ENOMEM;
		}
	}

	pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);

    if(pPhsdeviceExtension->CompressedTxBuffer == NULL)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
		free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
		pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
		return -ENOMEM;
	}

    pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
	if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
		kfree(pPhsdeviceExtension->CompressedTxBuffer);
		free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
		pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
		return -ENOMEM;
	}



	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successfull");
	return STATUS_SUCCESS;
}


int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt)
{
	if(pPHSDeviceExt->pstServiceFlowPhsRulesTable)
	{
		free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable);
		pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
	}

	kfree(pPHSDeviceExt->CompressedTxBuffer);
	pPHSDeviceExt->CompressedTxBuffer = NULL;

	kfree(pPHSDeviceExt->UnCompressedRxBuffer);
	pPHSDeviceExt->UnCompressedRxBuffer = NULL;

	return 0;
}



//PHS functions
/*++
PhsUpdateClassifierRule

Routine Description:
    Exported function to add or modify a PHS Rule.

Arguments:
	IN void* pvContext - PHS Driver Specific Context
	IN B_UINT16 uiVcid    - The Service Flow ID for which the PHS rule applies
	IN B_UINT16  uiClsId   - The Classifier ID within the Service Flow for which the PHS rule applies.
	IN S_PHS_RULE *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table.

Return Value:

    0 if successful,
    >0 Error.

--*/
ULONG PhsUpdateClassifierRule(IN void* pvContext,
								IN B_UINT16  uiVcid ,
								IN B_UINT16  uiClsId   ,
								IN S_PHS_RULE *psPhsRule,
								IN B_UINT8  u8AssociatedPHSI)
{
	ULONG lStatus =0;
	UINT nSFIndex =0 ;
	S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);



	PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS With Corr2 Changes \n");

	if(pDeviceExtension == NULL)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Invalid Device Extension\n");
		return ERR_PHS_INVALID_DEVICE_EXETENSION;
	}


	if(u8AssociatedPHSI == 0)
	{
		return ERR_PHS_INVALID_PHS_RULE;
	}

	/* Retrieve the SFID Entry Index for requested Service Flow */

	nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
	                uiVcid,&pstServiceFlowEntry);

    if(nSFIndex == PHS_INVALID_TABLE_INDEX)
	{
		/* This is a new SF. Create a mapping entry for this */
		lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId,
		      pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI);
		return lStatus;
	}

	/* SF already Exists Add PHS Rule to existing SF */
  	lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId,
  	          pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI);

    return lStatus;
}

/*++
PhsDeletePHSRule

Routine Description:
   Deletes the specified phs Rule within Vcid

Arguments:
	IN void* pvContext - PHS Driver Specific Context
	IN B_UINT16  uiVcid    - The Service Flow ID for which the PHS rule applies
	IN B_UINT8  u8PHSI   - the PHS Index identifying PHS rule to be deleted.

Return Value:

    0 if successful,
    >0 Error.

--*/

ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI)
{
	ULONG lStatus =0;
	UINT nSFIndex =0, nClsidIndex =0 ;
	S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
	S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);


	PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n");

	if(pDeviceExtension)
	{

		//Retrieve the SFID Entry Index for requested Service Flow
		nSFIndex = GetServiceFlowEntry(pDeviceExtension
		      ->pstServiceFlowPhsRulesTable,uiVcid,&pstServiceFlowEntry);

       if(nSFIndex == PHS_INVALID_TABLE_INDEX)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
			return ERR_SF_MATCH_FAIL;
		}

		pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable;
		if(pstClassifierRulesTable)
		{
			for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++)
			{
				if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
				{
					if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI)					{
						if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
							pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
						if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
							kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
						memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0,
							sizeof(S_CLASSIFIER_ENTRY));
					}
				}
			}
		}

	}
	return lStatus;
}

/*++
PhsDeleteClassifierRule

Routine Description:
    Exported function to Delete a PHS Rule for the SFID,CLSID Pair.

Arguments:
	IN void* pvContext - PHS Driver Specific Context
	IN B_UINT16  uiVcid    - The Service Flow ID for which the PHS rule applies
	IN B_UINT16  uiClsId   - The Classifier ID within the Service Flow for which the PHS rule applies.

Return Value:

    0 if successful,
    >0 Error.

--*/
ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16  uiClsId)
{
	ULONG lStatus =0;
	UINT nSFIndex =0, nClsidIndex =0 ;
	S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
	S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
	PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;

	if(pDeviceExtension)
	{
		//Retrieve the SFID Entry Index for requested Service Flow
		nSFIndex = GetServiceFlowEntry(pDeviceExtension
		      ->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry);
		if(nSFIndex == PHS_INVALID_TABLE_INDEX)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"SFID Match Failed\n");
			return ERR_SF_MATCH_FAIL;
		}

		nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
                  uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry);
		if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
		{
			if(pstClassifierEntry->pstPhsRule)
			{
				if(pstClassifierEntry->pstPhsRule->u8RefCnt)
				pstClassifierEntry->pstPhsRule->u8RefCnt--;
				if(0==pstClassifierEntry->pstPhsRule->u8RefCnt)
					kfree(pstClassifierEntry->pstPhsRule);

			}
			memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
		}

		nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
                    uiClsId,eOldClassifierRuleContext,&pstClassifierEntry);

	   if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
		{
			kfree(pstClassifierEntry->pstPhsRule);
			memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
		}
	}
	return lStatus;
}

/*++
PhsDeleteSFRules

Routine Description:
    Exported function to Delete a all PHS Rules for the SFID.

Arguments:
	IN void* pvContext - PHS Driver Specific Context
	IN B_UINT16 uiVcid   - The Service Flow ID for which the PHS rules need to be deleted

Return Value:

    0 if successful,
    >0 Error.

--*/
ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid)
{

	ULONG lStatus =0;
	UINT nSFIndex =0, nClsidIndex =0  ;
	S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
	S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
	PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"====> \n");

	if(pDeviceExtension)
	{
		//Retrieve the SFID Entry Index for requested Service Flow
		nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
		                  uiVcid,&pstServiceFlowEntry);
		if(nSFIndex == PHS_INVALID_TABLE_INDEX)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
			return ERR_SF_MATCH_FAIL;
		}

		pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable;
		if(pstClassifierRulesTable)
		{
			for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++)
			{
				if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
				{
					if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
                                                        .pstPhsRule->u8RefCnt)
						pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
						                                    .pstPhsRule->u8RefCnt--;
					if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
                                                          .pstPhsRule->u8RefCnt)
						kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
					    pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
                                        .pstPhsRule = NULL;
				}
				memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
				if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule)
				{
					if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
                                        .pstPhsRule->u8RefCnt)
						pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
						                  .pstPhsRule->u8RefCnt--;
					if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
                                        .pstPhsRule->u8RefCnt)
						kfree(pstClassifierRulesTable
						      ->stOldPhsRulesList[nClsidIndex].pstPhsRule);
					pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
                              .pstPhsRule = NULL;
				}
				memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
			}
		}
		pstServiceFlowEntry->bUsed = FALSE;
		pstServiceFlowEntry->uiVcid = 0;

	}

	return lStatus;
}


/*++
PhsCompress

Routine Description:
    Exported function to compress the data using PHS.

Arguments:
	IN void* pvContext - PHS Driver Specific Context.
	IN B_UINT16 uiVcid    - The Service Flow ID to which current packet header compression applies.
	IN UINT  uiClsId   - The Classifier ID to which current packet header compression applies.
	IN void *pvInputBuffer - The Input buffer containg packet header data
	IN void *pvOutputBuffer - The output buffer returned by this function after PHS
	IN UINT *pOldHeaderSize  - The actual size of the header before PHS
	IN UINT *pNewHeaderSize - The new size of the header after applying PHS

Return Value:

    0 if successful,
    >0 Error.

--*/
ULONG PhsCompress(IN void* pvContext,
				  IN B_UINT16 uiVcid,
				  IN B_UINT16 uiClsId,
				  IN void *pvInputBuffer,
				  OUT void *pvOutputBuffer,
				  OUT UINT *pOldHeaderSize,
				  OUT UINT *pNewHeaderSize )
{
	UINT nSFIndex =0, nClsidIndex =0  ;
	S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
	S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
	S_PHS_RULE *pstPhsRule = NULL;
	ULONG lStatus =0;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);



	PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;


	if(pDeviceExtension == NULL)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Invalid Device Extension\n");
		lStatus =  STATUS_PHS_NOCOMPRESSION ;
		return lStatus;

	}

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Suppressing header \n");


	//Retrieve the SFID Entry Index for requested Service Flow
	nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
	                  uiVcid,&pstServiceFlowEntry);
	if(nSFIndex == PHS_INVALID_TABLE_INDEX)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"SFID Match Failed\n");
		lStatus =  STATUS_PHS_NOCOMPRESSION ;
		return lStatus;
	}

	nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
                uiClsId,eActiveClassifierRuleContext,&pstClassifierEntry);

    if(nClsidIndex == PHS_INVALID_TABLE_INDEX)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"No PHS Rule Defined For Classifier\n");
		lStatus =  STATUS_PHS_NOCOMPRESSION ;
		return lStatus;
	}


	//get rule from SF id,Cls ID pair and proceed
	pstPhsRule =  pstClassifierEntry->pstPhsRule;

	if(!ValidatePHSRuleComplete(pstPhsRule))
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS Rule Defined For Classifier But Not Complete\n");
		lStatus =  STATUS_PHS_NOCOMPRESSION ;
		return lStatus;
	}

	//Compress Packet
	lStatus = phs_compress(pstPhsRule,(PUCHAR)pvInputBuffer,
	      (PUCHAR)pvOutputBuffer, pOldHeaderSize,pNewHeaderSize);

	if(lStatus == STATUS_PHS_COMPRESSED)
	{
		pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1;
		pstPhsRule->PHSModifiedNumPackets++;
	}
	else
		pstPhsRule->PHSErrorNumPackets++;

	return lStatus;
}

/*++
PhsDeCompress

Routine Description:
    Exported function to restore the packet header in Rx path.

Arguments:
	IN void* pvContext - PHS Driver Specific Context.
	IN B_UINT16 uiVcid    - The Service Flow ID to which current packet header restoration applies.
	IN  void *pvInputBuffer - The Input buffer containg suppressed packet header data
	OUT void *pvOutputBuffer - The output buffer returned by this function after restoration
	OUT UINT *pHeaderSize   - The packet header size after restoration is returned in this parameter.

Return Value:

    0 if successful,
    >0 Error.

--*/
ULONG PhsDeCompress(IN void* pvContext,
				  IN B_UINT16 uiVcid,
				  IN void *pvInputBuffer,
				  OUT void *pvOutputBuffer,
				  OUT UINT *pInHeaderSize,
				  OUT UINT *pOutHeaderSize )
{
	UINT nSFIndex =0, nPhsRuleIndex =0 ;
	S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
	S_PHS_RULE *pstPhsRule = NULL;
	UINT phsi;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
	PPHS_DEVICE_EXTENSION pDeviceExtension=
        (PPHS_DEVICE_EXTENSION)pvContext;

	*pInHeaderSize = 0;

	if(pDeviceExtension == NULL)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Invalid Device Extension\n");
		return ERR_PHS_INVALID_DEVICE_EXETENSION;
	}

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Restoring header \n");

	phsi = *((unsigned char *)(pvInputBuffer));
    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x \n",phsi);
    if(phsi == UNCOMPRESSED_PACKET )
	{
		return STATUS_PHS_NOCOMPRESSION;
	}

	//Retrieve the SFID Entry Index for requested Service Flow
	nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
	      uiVcid,&pstServiceFlowEntry);
	if(nSFIndex == PHS_INVALID_TABLE_INDEX)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n");
		return ERR_SF_MATCH_FAIL;
	}

	nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,phsi,
          eActiveClassifierRuleContext,&pstPhsRule);
	if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
	{
		//Phs Rule does not exist in  active rules table. Lets try in the old rules table.
		nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
		      phsi,eOldClassifierRuleContext,&pstPhsRule);
		if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
		{
			return ERR_PHSRULE_MATCH_FAIL;
		}

	}

	*pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer,
            (PUCHAR)pvOutputBuffer,pstPhsRule,pOutHeaderSize);

	pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1;

	pstPhsRule->PHSModifiedNumPackets++;
	return STATUS_PHS_COMPRESSED;
}


//-----------------------------------------------------------------------------
// Procedure:   free_phs_serviceflow_rules
//
// Description: This routine is responsible for freeing memory allocated for PHS rules.
//
// Arguments:
// rules	- ptr to S_SERVICEFLOW_TABLE structure.
//
// Returns:
// Does not return any value.
//-----------------------------------------------------------------------------

static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
{
	int i,j;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n");
    if(psServiceFlowRulesTable)
	{
		for(i=0;i<MAX_SERVICEFLOWS;i++)
		{
			S_SERVICEFLOW_ENTRY stServiceFlowEntry =
                psServiceFlowRulesTable->stSFList[i];
			S_CLASSIFIER_TABLE *pstClassifierRulesTable =
                stServiceFlowEntry.pstClassifierTable;

			if(pstClassifierRulesTable)
			{
				for(j=0;j<MAX_PHSRULE_PER_SF;j++)
				{
					if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule)
					{
						if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
                                                                                        ->u8RefCnt)
							pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
  							                                                ->u8RefCnt--;
						if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
                                                                ->u8RefCnt)
							kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
						pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
					}
					if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule)
					{
						if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
                                                                ->u8RefCnt)
							pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
							                                          ->u8RefCnt--;
						if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
                                                                      ->u8RefCnt)
							kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
						pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
					}
				}
				kfree(pstClassifierRulesTable);
			    stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
			}
		}
	}

    kfree(psServiceFlowRulesTable);
    psServiceFlowRulesTable = NULL;
}



static BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
{
	if(psPhsRule)
	{
		if(!psPhsRule->u8PHSI)
		{
			// PHSI is not valid
			return FALSE;
		}

		if(!psPhsRule->u8PHSS)
		{
			//PHSS Is Undefined
			return FALSE;
		}

		//Check if PHSF is defines for the PHS Rule
		if(!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF
		{
			return FALSE;
		}
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

UINT GetServiceFlowEntry(IN S_SERVICEFLOW_TABLE *psServiceFlowTable,
    IN B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry)
{
	int  i;
	for(i=0;i<MAX_SERVICEFLOWS;i++)
	{
		if(psServiceFlowTable->stSFList[i].bUsed)
		{
			if(psServiceFlowTable->stSFList[i].uiVcid == uiVcid)
			{
				*ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i];
				return i;
			}
		}
	}

	*ppstServiceFlowEntry = NULL;
	return PHS_INVALID_TABLE_INDEX;
}


UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
        IN B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
        OUT S_CLASSIFIER_ENTRY **ppstClassifierEntry)
{
	int  i;
	S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
	for(i=0;i<MAX_PHSRULE_PER_SF;i++)
	{

		if(eClsContext == eActiveClassifierRuleContext)
		{
			psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i];
		}
		else
		{
			psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i];
		}

		if(psClassifierRules->bUsed)
		{
			if(psClassifierRules->uiClassifierRuleId == uiClsid)
			{
				*ppstClassifierEntry = psClassifierRules;
				return i;
			}
		}

	}

	*ppstClassifierEntry = NULL;
	return PHS_INVALID_TABLE_INDEX;
}

static UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
			    IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
			    OUT S_PHS_RULE **ppstPhsRule)
{
	int  i;
	S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
	for(i=0;i<MAX_PHSRULE_PER_SF;i++)
	{
		if(eClsContext == eActiveClassifierRuleContext)
		{
			pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i];
		}
		else
		{
			pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i];
		}
		if(pstClassifierRule->bUsed)
		{
			if(pstClassifierRule->u8PHSI == uiPHSI)
			{
				*ppstPhsRule = pstClassifierRule->pstPhsRule;
				return i;
			}
		}

	}

	*ppstPhsRule = NULL;
	return PHS_INVALID_TABLE_INDEX;
}

UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16  uiClsId,
                      IN S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,
                      B_UINT8 u8AssociatedPHSI)
{

    S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
	UINT uiStatus = 0;
	int iSfIndex;
	BOOLEAN bFreeEntryFound =FALSE;
	//Check for a free entry in SFID table
	for(iSfIndex=0;iSfIndex < MAX_SERVICEFLOWS;iSfIndex++)
	{
		if(!psServiceFlowTable->stSFList[iSfIndex].bUsed)
		{
			bFreeEntryFound = TRUE;
			break;
		}
	}

	if(!bFreeEntryFound)
		return ERR_SFTABLE_FULL;


	psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable;
	uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,psPhsRule,
	                      eActiveClassifierRuleContext,u8AssociatedPHSI);
	if(uiStatus == PHS_SUCCESS)
	{
		//Add entry at free index to the SF
		psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE;
		psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid;
	}

	return uiStatus;

}

UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
            IN B_UINT16  uiClsId,IN S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,
              S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI)
{
	S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
	UINT uiStatus =PHS_SUCCESS;
	UINT nClassifierIndex = 0;
	S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
    psaClassifiertable = pstServiceFlowEntry->pstClassifierTable;

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>");

	/* Check if the supplied Classifier already exists */
	nClassifierIndex =GetClassifierEntry(
	            pstServiceFlowEntry->pstClassifierTable,uiClsId,
	            eActiveClassifierRuleContext,&pstClassifierEntry);
	if(nClassifierIndex == PHS_INVALID_TABLE_INDEX)
	{
		/*
		    The Classifier doesn't exist. So its a new classifier being added.
		     Add new entry to associate PHS Rule to the Classifier
		*/

		uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,
		    psPhsRule,eActiveClassifierRuleContext,u8AssociatedPHSI);
		return uiStatus;
	}

	/*
	  The Classifier exists.The PHS Rule for this classifier
	  is being modified
	  */
	if(pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI)
	{
		if(pstClassifierEntry->pstPhsRule == NULL)
			return ERR_PHS_INVALID_PHS_RULE;

		/*
		    This rule already exists if any fields are changed for this PHS
		    rule update them.
		 */
		 /* If any part of PHSF is valid then we update PHSF */
		if(psPhsRule->u8PHSFLength)
		{
			//update PHSF
			memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
			    psPhsRule->u8PHSF , MAX_PHS_LENGTHS);
		}
		if(psPhsRule->u8PHSFLength)
		{
			//update PHSFLen
			pstClassifierEntry->pstPhsRule->u8PHSFLength =
			    psPhsRule->u8PHSFLength;
		}
		if(psPhsRule->u8PHSMLength)
		{
			//update PHSM
			memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
			    psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
		}
		if(psPhsRule->u8PHSMLength)
		{
			//update PHSM Len
			pstClassifierEntry->pstPhsRule->u8PHSMLength =
			    psPhsRule->u8PHSMLength;
		}
		if(psPhsRule->u8PHSS)
		{
			//update PHSS
			pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS;
		}

		//update PHSV
		pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV;

	}
	else
	{
		/*
		  A new rule is being set for this classifier.
		*/
		uiStatus=UpdateClassifierPHSRule( uiClsId,  pstClassifierEntry,
		      psaClassifiertable,  psPhsRule, u8AssociatedPHSI);
	}



	return uiStatus;
}

static UINT CreateClassifierPHSRule(IN B_UINT16  uiClsId,
    S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
    E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI)
{
	UINT iClassifierIndex = 0;
	BOOLEAN bFreeEntryFound = FALSE;
	S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
	UINT nStatus = PHS_SUCCESS;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Inside CreateClassifierPHSRule");
    if(psaClassifiertable == NULL)
	{
		return ERR_INVALID_CLASSIFIERTABLE_FOR_SF;
	}

	if(eClsContext == eOldClassifierRuleContext)
	{
		/* If An Old Entry for this classifier ID already exists in the
		    old rules table replace it. */

		iClassifierIndex =
		GetClassifierEntry(psaClassifiertable, uiClsId,
		            eClsContext,&psClassifierRules);
		if(iClassifierIndex != PHS_INVALID_TABLE_INDEX)
		{
			/*
			    The Classifier already exists in the old rules table
		        Lets replace the old classifier with the new one.
			*/
			bFreeEntryFound = TRUE;
		}
	}

	if(!bFreeEntryFound)
	{
		/*
		  Continue to search for a free location to add the rule
		*/
		for(iClassifierIndex = 0; iClassifierIndex <
            MAX_PHSRULE_PER_SF; iClassifierIndex++)
		{
			if(eClsContext == eActiveClassifierRuleContext)
			{
				psClassifierRules =
              &psaClassifiertable->stActivePhsRulesList[iClassifierIndex];
			}
			else
			{
				psClassifierRules =
                &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
			}

			if(!psClassifierRules->bUsed)
			{
				bFreeEntryFound = TRUE;
				break;
			}
		}
	}

	if(!bFreeEntryFound)
	{
		if(eClsContext == eActiveClassifierRuleContext)
		{
			return ERR_CLSASSIFIER_TABLE_FULL;
		}
		else
		{
			//Lets replace the oldest rule if we are looking in old Rule table
			if(psaClassifiertable->uiOldestPhsRuleIndex >=
                MAX_PHSRULE_PER_SF)
			{
				psaClassifiertable->uiOldestPhsRuleIndex =0;
			}

			iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex;
			psClassifierRules =
              &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];

          (psaClassifiertable->uiOldestPhsRuleIndex)++;
		}
	}

	if(eClsContext == eOldClassifierRuleContext)
	{
		if(psClassifierRules->pstPhsRule == NULL)
		{
			psClassifierRules->pstPhsRule = kmalloc(sizeof(S_PHS_RULE),GFP_KERNEL);

          if(NULL == psClassifierRules->pstPhsRule)
				return ERR_PHSRULE_MEMALLOC_FAIL;
		}

		psClassifierRules->bUsed = TRUE;
		psClassifierRules->uiClassifierRuleId = uiClsId;
		psClassifierRules->u8PHSI = psPhsRule->u8PHSI;
		psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;

        /* Update The PHS rule */
		memcpy(psClassifierRules->pstPhsRule,
		    psPhsRule, sizeof(S_PHS_RULE));
	}
	else
	{
		nStatus = UpdateClassifierPHSRule(uiClsId,psClassifierRules,
            psaClassifiertable,psPhsRule,u8AssociatedPHSI);
	}
	return nStatus;
}


static UINT UpdateClassifierPHSRule(IN B_UINT16  uiClsId,
      IN S_CLASSIFIER_ENTRY *pstClassifierEntry,
      S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
      B_UINT8 u8AssociatedPHSI)
{
	S_PHS_RULE *pstAddPhsRule = NULL;
	UINT              nPhsRuleIndex = 0;
	BOOLEAN       bPHSRuleOrphaned = FALSE;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
	psPhsRule->u8RefCnt =0;

	/* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/
	bPHSRuleOrphaned = DerefPhsRule( uiClsId, psaClassifiertable,
	    pstClassifierEntry->pstPhsRule);

	//Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF
	nPhsRuleIndex =GetPhsRuleEntry(psaClassifiertable,u8AssociatedPHSI,
	    eActiveClassifierRuleContext, &pstAddPhsRule);
	if(PHS_INVALID_TABLE_INDEX == nPhsRuleIndex)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier");

		if(psPhsRule->u8PHSI == 0)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n");
			return ERR_PHS_INVALID_PHS_RULE;
		}
		//Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId
		if(FALSE == bPHSRuleOrphaned)
		{
			pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL);
			if(NULL == pstClassifierEntry->pstPhsRule)
			{
				return ERR_PHSRULE_MEMALLOC_FAIL;
			}
		}
		memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));

	}
	else
	{
		//Step 2.b PHS Rule  Exists Tie uiClsId with the existing PHS Rule
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
		if(bPHSRuleOrphaned)
		{
			kfree(pstClassifierEntry->pstPhsRule);
			pstClassifierEntry->pstPhsRule = NULL;
		}
		pstClassifierEntry->pstPhsRule = pstAddPhsRule;

	}
	pstClassifierEntry->bUsed = TRUE;
	pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI;
	pstClassifierEntry->uiClassifierRuleId = uiClsId;
	pstClassifierEntry->pstPhsRule->u8RefCnt++;
	pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;

	return PHS_SUCCESS;

}

static BOOLEAN DerefPhsRule(IN B_UINT16  uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
{
	if(pstPhsRule==NULL)
		return FALSE;
	if(pstPhsRule->u8RefCnt)
		pstPhsRule->u8RefCnt--;
	if(0==pstPhsRule->u8RefCnt)
	{
		/*if(pstPhsRule->u8PHSI)
		//Store the currently active rule into the old rules list
		CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);*/
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)
{
	int i,j,k,l;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules : \n");
	for(i=0;i<MAX_SERVICEFLOWS;i++)
	{
		S_SERVICEFLOW_ENTRY stServFlowEntry =
				pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i];
		if(stServFlowEntry.bUsed)
		{
			for(j=0;j<MAX_PHSRULE_PER_SF;j++)
			{
				for(l=0;l<2;l++)
				{
					S_CLASSIFIER_ENTRY stClsEntry;
					if(l==0)
					{
						stClsEntry = stServFlowEntry.pstClassifierTable->stActivePhsRulesList[j];
						if(stClsEntry.bUsed)
							BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule : \n");
					}
					else
					{
						stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j];
						if(stClsEntry.bUsed)
							BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule : \n");
					}
					if(stClsEntry.bUsed)
					{

						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID  : %#X",stServFlowEntry.uiVcid);
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID  : %#X",stClsEntry.uiClassifierRuleId);
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID  : %#X",stClsEntry.u8PHSI);
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n");
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI  : %#X",stClsEntry.pstPhsRule->u8PHSI);
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ",stClsEntry.pstPhsRule->u8PHSFLength);
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : ");
						for(k=0;k<stClsEntry.pstPhsRule->u8PHSFLength;k++)
						{
							BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X  ",stClsEntry.pstPhsRule->u8PHSF[k]);
						}
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength  : %#X",stClsEntry.pstPhsRule->u8PHSMLength);
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :");
						for(k=0;k<stClsEntry.pstPhsRule->u8PHSMLength;k++)
						{
							BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X  ",stClsEntry.pstPhsRule->u8PHSM[k]);
						}
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ",stClsEntry.pstPhsRule->u8PHSS);
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV  : %#X",stClsEntry.pstPhsRule->u8PHSV);
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n");
					}
				}
			}
		}
	}
}


//-----------------------------------------------------------------------------
// Procedure:   phs_decompress
//
// Description: This routine restores the static fields within the packet.
//
// Arguments:
//	in_buf			- ptr to incoming packet buffer.
//	out_buf			- ptr to output buffer where the suppressed header is copied.
//	decomp_phs_rules - ptr to PHS rule.
//	header_size		- ptr to field which holds the phss or phsf_length.
//
// Returns:
//	size -The number of bytes of dynamic fields present with in the incoming packet
//			header.
//	0	-If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed.
//-----------------------------------------------------------------------------

int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
 S_PHS_RULE   *decomp_phs_rules,UINT *header_size)
{
	int phss,size=0;
	 S_PHS_RULE   *tmp_memb;
	int bit,i=0;
	unsigned char *phsf,*phsm;
	int in_buf_len = *header_size-1;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
	in_buf++;
    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"====>\n");
	*header_size = 0;

	if((decomp_phs_rules == NULL ))
		return 0;


	tmp_memb = decomp_phs_rules;
	//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1  %d",phsi));
	//*header_size = tmp_memb->u8PHSFLength;
	phss         = tmp_memb->u8PHSS;
	phsf         = tmp_memb->u8PHSF;
	phsm         = tmp_memb->u8PHSM;

	if(phss > MAX_PHS_LENGTHS)
		phss = MAX_PHS_LENGTHS;
	//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));
	while((phss > 0) && (size < in_buf_len))
	{
		bit =  ((*phsm << i)& SUPPRESS);

		if(bit == SUPPRESS)
		{
			*out_buf = *phsf;
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss  %d phsf %d ouput %d",
              phss,*phsf,*out_buf);
		}
		else
		{
			*out_buf = *in_buf;
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss  %d input %d ouput %d",
            phss,*in_buf,*out_buf);
			in_buf++;
			size++;
		}
		out_buf++;
		phsf++;
		phss--;
		i++;
		*header_size=*header_size + 1;

		if(i > MAX_NO_BIT)
		{
			i=0;
			phsm++;
		}
	}
	return size;
}




//-----------------------------------------------------------------------------
// Procedure:   phs_compress
//
// Description: This routine suppresses the static fields within the packet.Before
// that it will verify the fields to be suppressed with the corresponding fields in the
// phsf. For verification it checks the phsv field of PHS rule. If set and verification
// succeeds it suppresses the field.If any one static field is found different none of
// the static fields are suppressed then the packet is sent as uncompressed packet with
// phsi=0.
//
// Arguments:
//	phs_rule - ptr to PHS rule.
//	in_buf		- ptr to incoming packet buffer.
//	out_buf		- ptr to output buffer where the suppressed header is copied.
//	header_size	- ptr to field which holds the phss.
//
// Returns:
//	size-The number of bytes copied into the output buffer i.e dynamic fields
//	0	-If PHS rule is NULL.If PHSV field is not set.If the verification fails.
//-----------------------------------------------------------------------------
static int phs_compress(S_PHS_RULE  *phs_rule,unsigned char *in_buf
			,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
{
	unsigned char *old_addr = out_buf;
	int supress = 0;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
    if(phs_rule == NULL)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nphs_compress(): phs_rule null!");
		*out_buf = ZERO_PHSI;
		return STATUS_PHS_NOCOMPRESSION;
	}


	if(phs_rule->u8PHSS <= *new_header_size)
	{
		*header_size = phs_rule->u8PHSS;
	}
	else
	{
		*header_size = *new_header_size;
	}
	//To copy PHSI
	out_buf++;
	supress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF,
        phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size);

	if(supress == STATUS_PHS_COMPRESSED)
	{
		*old_addr = (unsigned char)phs_rule->u8PHSI;
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress phsi %d",phs_rule->u8PHSI);
	}
	else
	{
		*old_addr = ZERO_PHSI;
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress PHSV Verification failed");
	}
	return supress;
}


//-----------------------------------------------------------------------------
// Procedure:	verify_suppress_phsf
//
// Description: This routine verifies the fields of the packet and if all the
// static fields are equal it adds the phsi of that PHS rule.If any static
// field differs it woun't suppress any field.
//
// Arguments:
// rules_set	- ptr to classifier_rules.
// in_buffer	- ptr to incoming packet buffer.
// out_buffer	- ptr to output buffer where the suppressed header is copied.
// phsf			- ptr to phsf.
// phsm			- ptr to phsm.
// phss			- variable holding phss.
//
// Returns:
//	size-The number of bytes copied into the output buffer i.e dynamic fields.
//	0	-Packet has failed the verification.
//-----------------------------------------------------------------------------

static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
				unsigned char *phsf,unsigned char *phsm,unsigned int phss,
				unsigned int phsv,UINT* new_header_size)
{
	unsigned int size=0;
	int bit,i=0;
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf PHSM - 0x%X",*phsm);


	if(phss>(*new_header_size))
	{
		phss=*new_header_size;
	}
	while(phss > 0)
	{
		bit = ((*phsm << i)& SUPPRESS);
		if(bit == SUPPRESS)
		{

			if(*in_buffer != *phsf)
			{
				if(phsv == VERIFY)
				{
					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);
					return STATUS_PHS_NOCOMPRESSION;
				}
			}
			else
				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);
		}
		else
		{
			*out_buffer = *in_buffer;
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In copying_header input %d  out %d",*in_buffer,*out_buffer);
			out_buffer++;
			size++;
		}
		in_buffer++;
		phsf++;
		phss--;
		i++;
		if(i > MAX_NO_BIT)
		{
			i=0;
			phsm++;
		}
	}
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success");
	*new_header_size = size;
	return STATUS_PHS_COMPRESSED;
}






