1 #include "headers.h"
2 
3 static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16  uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
4 
5 static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16  uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
6 
7 static UINT CreateClassifierPHSRule(B_UINT16  uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI);
8 
9 static UINT UpdateClassifierPHSRule(B_UINT16  uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
10 
11 static BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule);
12 
13 static BOOLEAN DerefPhsRule(B_UINT16  uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule);
14 
15 static UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry);
16 
17 static UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule);
18 
19 static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable);
20 
21 static 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 
25 static 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 
28 static int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\
29 						  S_PHS_RULE   *phs_rules,UINT *header_size);
30 
31 
32 static 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 
40 static 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 /*
53 Function:				PHSTransmit
54 
55 Description:			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 
61 Input 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 
68 Return:					STATUS_SUCCESS - If the send was successful.
69 						Other          - If an error occured.
70 */
71 
PHSTransmit(PMINI_ADAPTER Adapter,struct sk_buff ** pPacket,USHORT Vcid,B_UINT16 uiClassifierRuleID,BOOLEAN bHeaderSuppressionEnabled,UINT * PacketLen,UCHAR bEthCSSupport)72 int 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 
PHSReceive(PMINI_ADAPTER Adapter,USHORT usVcid,struct sk_buff * packet,UINT * punPacketLen,UCHAR * pucEthernetHdr,UINT bHeaderSuppressionEnabled)212 int 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 
DumpFullPacket(UCHAR * pBuf,UINT nPktLen)274 void 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 //-----------------------------------------------------------------------------
phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)294 int 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 
PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt)354 int 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 /*++
375 PhsUpdateClassifierRule
376 
377 Routine Description:
378     Exported function to add or modify a PHS Rule.
379 
380 Arguments:
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 
386 Return Value:
387 
388     0 if successful,
389     >0 Error.
390 
391 --*/
PhsUpdateClassifierRule(IN void * pvContext,IN B_UINT16 uiVcid,IN B_UINT16 uiClsId,IN S_PHS_RULE * psPhsRule,IN B_UINT8 u8AssociatedPHSI)392 ULONG 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 /*++
442 PhsDeletePHSRule
443 
444 Routine Description:
445    Deletes the specified phs Rule within Vcid
446 
447 Arguments:
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 
452 Return Value:
453 
454     0 if successful,
455     >0 Error.
456 
457 --*/
458 
PhsDeletePHSRule(IN void * pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI)459 ULONG 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 /*++
509 PhsDeleteClassifierRule
510 
511 Routine Description:
512     Exported function to Delete a PHS Rule for the SFID,CLSID Pair.
513 
514 Arguments:
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 
519 Return Value:
520 
521     0 if successful,
522     >0 Error.
523 
524 --*/
PhsDeleteClassifierRule(IN void * pvContext,IN B_UINT16 uiVcid,IN B_UINT16 uiClsId)525 ULONG 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 /*++
573 PhsDeleteSFRules
574 
575 Routine Description:
576     Exported function to Delete a all PHS Rules for the SFID.
577 
578 Arguments:
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 
582 Return Value:
583 
584     0 if successful,
585     >0 Error.
586 
587 --*/
PhsDeleteSFRules(IN void * pvContext,IN B_UINT16 uiVcid)588 ULONG 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 /*++
654 PhsCompress
655 
656 Routine Description:
657     Exported function to compress the data using PHS.
658 
659 Arguments:
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 
668 Return Value:
669 
670     0 if successful,
671     >0 Error.
672 
673 --*/
PhsCompress(IN void * pvContext,IN B_UINT16 uiVcid,IN B_UINT16 uiClsId,IN void * pvInputBuffer,OUT void * pvOutputBuffer,OUT UINT * pOldHeaderSize,OUT UINT * pNewHeaderSize)674 ULONG 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 /*++
752 PhsDeCompress
753 
754 Routine Description:
755     Exported function to restore the packet header in Rx path.
756 
757 Arguments:
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 
764 Return Value:
765 
766     0 if successful,
767     >0 Error.
768 
769 --*/
PhsDeCompress(IN void * pvContext,IN B_UINT16 uiVcid,IN void * pvInputBuffer,OUT void * pvOutputBuffer,OUT UINT * pInHeaderSize,OUT UINT * pOutHeaderSize)770 ULONG 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 
free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE * psServiceFlowRulesTable)847 static 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 
ValidatePHSRuleComplete(IN S_PHS_RULE * psPhsRule)901 static 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 
GetServiceFlowEntry(IN S_SERVICEFLOW_TABLE * psServiceFlowTable,IN B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY ** ppstServiceFlowEntry)930 UINT 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 
GetClassifierEntry(IN S_CLASSIFIER_TABLE * pstClassifierTable,IN B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,OUT S_CLASSIFIER_ENTRY ** ppstClassifierEntry)951 UINT 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 
GetPhsRuleEntry(IN S_CLASSIFIER_TABLE * pstClassifierTable,IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,OUT S_PHS_RULE ** ppstPhsRule)984 static 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 
CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId,IN S_SERVICEFLOW_TABLE * psServiceFlowTable,S_PHS_RULE * psPhsRule,B_UINT8 u8AssociatedPHSI)1015 UINT 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 
CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId,IN S_SERVICEFLOW_ENTRY * pstServiceFlowEntry,S_PHS_RULE * psPhsRule,B_UINT8 u8AssociatedPHSI)1052 UINT 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 
CreateClassifierPHSRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE * psaClassifiertable,S_PHS_RULE * psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI)1143 static 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 
UpdateClassifierPHSRule(IN B_UINT16 uiClsId,IN S_CLASSIFIER_ENTRY * pstClassifierEntry,S_CLASSIFIER_TABLE * psaClassifiertable,S_PHS_RULE * psPhsRule,B_UINT8 u8AssociatedPHSI)1254 static 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 
DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE * psaClassifiertable,S_PHS_RULE * pstPhsRule)1315 static 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 
DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)1334 void 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 
phs_decompress(unsigned char * in_buf,unsigned char * out_buf,S_PHS_RULE * decomp_phs_rules,UINT * header_size)1410 int 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 //-----------------------------------------------------------------------------
phs_compress(S_PHS_RULE * phs_rule,unsigned char * in_buf,unsigned char * out_buf,UINT * header_size,UINT * new_header_size)1493 static 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 
verify_suppress_phsf(unsigned char * in_buffer,unsigned char * out_buffer,unsigned char * phsf,unsigned char * phsm,unsigned int phss,unsigned int phsv,UINT * new_header_size)1554 static 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 
1612