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