Linux Audio

Check our new training course

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