#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 suppresses the header by invoking PHS exported compress routine.
					The header data after suppression is copied back to the NDIS_PACKET.


Input parameters:		IN struct bcm_mini_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 occurred.
*/

int PHSTransmit(struct bcm_mini_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.ucaHdrSuppressionInBuf;
	/* Pointer to PHS OUT Hdr Buffer */
	PUCHAR  pucPHSPktHdrOutBuf =
					Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf;
	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 suppression
		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 Suppress 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 PHSReceive(struct bcm_mini_adapter *Adapter,
					USHORT usVcid,
					struct sk_buff *packet,
					UINT *punPacketLen,
					UCHAR *pucEthernetHdr,
					UINT	bHeaderSuppressionEnabled)
{
	u32   nStandardPktHdrLen            		= 0;
	u32   nTotalsuppressedPktHdrBytes  = 0;
	int     ulPhsStatus 		= 0;
	PUCHAR pucInBuff = NULL ;
	UINT TotalBytesAdded = 0;
	if(!bHeaderSuppressionEnabled)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,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,
		&nTotalsuppressedPktHdrBytes,
		&nStandardPktHdrLen);

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
					nTotalsuppressedPktHdrBytes,nStandardPktHdrLen);

	if(ulPhsStatus != STATUS_PHS_COMPRESSED)
	{
		skb_pull(packet, 1);
		return STATUS_SUCCESS;
	}
	else
	{
		TotalBytesAdded = nStandardPktHdrLen - nTotalsuppressedPktHdrBytes - 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)
{
	struct bcm_mini_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, struct bcm_mini_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 Successful");
	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;
	struct bcm_mini_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;
	struct bcm_mini_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;
	struct bcm_mini_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;
	struct bcm_mini_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;
	struct bcm_mini_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;
	struct bcm_mini_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_RECEIVE,DBG_LVL_ALL,"Invalid Device Extension\n");
		return ERR_PHS_INVALID_DEVICE_EXETENSION;
	}

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

	phsi = *((unsigned char *)(pvInputBuffer));
    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,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_RECEIVE,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;
	struct bcm_mini_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;
	struct bcm_mini_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;
	struct bcm_mini_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;
	struct bcm_mini_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;
	struct bcm_mini_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;
	struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
	in_buf++;
    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,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_RECEIVE,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_RECEIVE,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_RECEIVE,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_RECEIVE,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 suppress = 0;
	struct bcm_mini_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++;
	suppress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF,
        phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size);

	if(suppress == 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 suppress;
}


//-----------------------------------------------------------------------------
// 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;
	struct bcm_mini_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;
}






