3 static UINT
CreateSFToClassifierRuleMapping(B_UINT16 uiVcid
,B_UINT16 uiClsId
,S_SERVICEFLOW_TABLE
*psServiceFlowTable
,S_PHS_RULE
*psPhsRule
,B_UINT8 u8AssociatedPHSI
);
5 static UINT
CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid
,B_UINT16 uiClsId
,S_SERVICEFLOW_ENTRY
*pstServiceFlowEntry
,S_PHS_RULE
*psPhsRule
,B_UINT8 u8AssociatedPHSI
);
7 static UINT
CreateClassifierPHSRule(B_UINT16 uiClsId
,S_CLASSIFIER_TABLE
*psaClassifiertable
,S_PHS_RULE
*psPhsRule
,E_CLASSIFIER_ENTRY_CONTEXT eClsContext
,B_UINT8 u8AssociatedPHSI
);
9 static UINT
UpdateClassifierPHSRule(B_UINT16 uiClsId
,S_CLASSIFIER_ENTRY
*pstClassifierEntry
,S_CLASSIFIER_TABLE
*psaClassifiertable
,S_PHS_RULE
*psPhsRule
,B_UINT8 u8AssociatedPHSI
);
11 static BOOLEAN
ValidatePHSRuleComplete(S_PHS_RULE
*psPhsRule
);
13 static BOOLEAN
DerefPhsRule(B_UINT16 uiClsId
,S_CLASSIFIER_TABLE
*psaClassifiertable
,S_PHS_RULE
*pstPhsRule
);
15 static UINT
GetClassifierEntry(S_CLASSIFIER_TABLE
*pstClassifierTable
,B_UINT32 uiClsid
,E_CLASSIFIER_ENTRY_CONTEXT eClsContext
, S_CLASSIFIER_ENTRY
**ppstClassifierEntry
);
17 static UINT
GetPhsRuleEntry(S_CLASSIFIER_TABLE
*pstClassifierTable
,B_UINT32 uiPHSI
,E_CLASSIFIER_ENTRY_CONTEXT eClsContext
,S_PHS_RULE
**ppstPhsRule
);
19 static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE
*psServiceFlowRulesTable
);
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
);
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
);
28 static int phs_decompress(unsigned char *in_buf
,unsigned char *out_buf
,\
29 S_PHS_RULE
*phs_rules
,UINT
*header_size
);
32 static ULONG
PhsCompress(void* pvContext
,
38 UINT
*pNewHeaderSize
);
40 static ULONG
PhsDeCompress(void* pvContext
,
45 UINT
*pOutHeaderSize
);
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 suppresses the header by invoking PHS exported compress routine.
58 The header data after suppression is copied back to the NDIS_PACKET.
61 Input parameters: IN struct bcm_mini_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.
68 Return: STATUS_SUCCESS - If the send was successful.
69 Other - If an error occured.
72 int PHSTransmit(struct bcm_mini_adapter
*Adapter
,
73 struct sk_buff
**pPacket
,
75 B_UINT16 uiClassifierRuleID
,
76 BOOLEAN bHeaderSuppressionEnabled
,
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
.ucaHdrSuppressionInBuf
;
88 /* Pointer to PHS OUT Hdr Buffer */
89 PUCHAR pucPHSPktHdrOutBuf
=
90 Adapter
->stPhsTxContextInfo
.ucaHdrSuppressionOutBuf
;
95 UINT numBytesCompressed
= 0;
96 struct sk_buff
*newPacket
= NULL
;
97 struct sk_buff
*Packet
= *pPacket
;
99 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_SEND
, DBG_LVL_ALL
, "In PHSTransmit");
102 BytesToRemove
=ETH_HLEN
;
104 Accumulate the header upto the size we support suppression
108 usPacketType
=((struct ethhdr
*)(Packet
->data
))->h_proto
;
111 pucPHSPktHdrInBuf
= Packet
->data
+ BytesToRemove
;
112 //considering data after ethernet header
113 if((*PacketLen
- BytesToRemove
) < MAX_PHS_LENGTHS
)
116 unPHSPktHdrBytesCopied
= (*PacketLen
- BytesToRemove
);
120 unPHSPktHdrBytesCopied
= MAX_PHS_LENGTHS
;
123 if( (unPHSPktHdrBytesCopied
> 0 ) &&
124 (unPHSPktHdrBytesCopied
<= MAX_PHS_LENGTHS
))
128 // Step 2 Suppress 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
))
134 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_SEND
, DBG_LVL_ALL
,"\nTrying to PHS Compress Using Classifier rule 0x%X",uiClassifierRuleID
);
137 unPHSNewPktHeaderLen
= unPHSPktHdrBytesCopied
;
138 ulPhsStatus
= PhsCompress(&Adapter
->stBCMPhsContext
,
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
);
147 if(unPHSNewPktHeaderLen
== unPhsOldHdrSize
)
149 if( ulPhsStatus
== STATUS_PHS_COMPRESSED
)
150 bPHSI
= *pucPHSPktHdrOutBuf
;
151 ulPhsStatus
= STATUS_PHS_NOCOMPRESSION
;
154 if( ulPhsStatus
== STATUS_PHS_COMPRESSED
)
156 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_SEND
, DBG_LVL_ALL
,"PHS Sending packet Compressed");
158 if(skb_cloned(Packet
))
160 newPacket
= skb_copy(Packet
, GFP_ATOMIC
);
162 if(newPacket
== NULL
)
163 return STATUS_FAILURE
;
165 dev_kfree_skb(Packet
);
166 *pPacket
= Packet
= newPacket
;
167 pucPHSPktHdrInBuf
= Packet
->data
+ BytesToRemove
;
170 numBytesCompressed
= unPhsOldHdrSize
- (unPHSNewPktHeaderLen
+PHSI_LEN
);
172 memcpy(pucPHSPktHdrInBuf
+ numBytesCompressed
, pucPHSPktHdrOutBuf
, unPHSNewPktHeaderLen
+ PHSI_LEN
);
173 memcpy(Packet
->data
+ numBytesCompressed
, Packet
->data
, BytesToRemove
);
174 skb_pull(Packet
, numBytesCompressed
);
176 return STATUS_SUCCESS
;
181 //if one byte headroom is not available, increase it through skb_cow
182 if(!(skb_headroom(Packet
) > 0))
184 if(skb_cow(Packet
, 1))
186 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_PRINTK
, 0, 0, "SKB Cow Failed\n");
187 return STATUS_FAILURE
;
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
;
199 if(!bHeaderSuppressionEnabled
)
201 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_SEND
, DBG_LVL_ALL
,"\nHeader Suppression Disabled For SF: No PHS\n");
204 return STATUS_SUCCESS
;
208 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS");
209 return STATUS_SUCCESS
;
212 int PHSReceive(struct bcm_mini_adapter
*Adapter
,
214 struct sk_buff
*packet
,
216 UCHAR
*pucEthernetHdr
,
217 UINT bHeaderSuppressionEnabled
)
219 u32 nStandardPktHdrLen
= 0;
220 u32 nTotalsuppressedPktHdrBytes
= 0;
222 PUCHAR pucInBuff
= NULL
;
223 UINT TotalBytesAdded
= 0;
224 if(!bHeaderSuppressionEnabled
)
226 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_RECEIVE
,DBG_LVL_ALL
,"\nPhs Disabled for incoming packet");
230 pucInBuff
= packet
->data
;
232 //Restore PHS suppressed header
233 nStandardPktHdrLen
= packet
->len
;
234 ulPhsStatus
= PhsDeCompress(&Adapter
->stBCMPhsContext
,
237 Adapter
->ucaPHSPktRestoreBuf
,
238 &nTotalsuppressedPktHdrBytes
,
239 &nStandardPktHdrLen
);
241 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_RECEIVE
,DBG_LVL_ALL
,"\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
242 nTotalsuppressedPktHdrBytes
,nStandardPktHdrLen
);
244 if(ulPhsStatus
!= STATUS_PHS_COMPRESSED
)
247 return STATUS_SUCCESS
;
251 TotalBytesAdded
= nStandardPktHdrLen
- nTotalsuppressedPktHdrBytes
- PHSI_LEN
;
254 if(skb_headroom(packet
) >= (SKB_RESERVE_ETHERNET_HEADER
+ TotalBytesAdded
))
255 skb_push(packet
, TotalBytesAdded
);
258 if(skb_cow(packet
, skb_headroom(packet
) + TotalBytesAdded
))
260 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_PRINTK
, 0, 0, "cow failed in receive\n");
261 return STATUS_FAILURE
;
264 skb_push(packet
, TotalBytesAdded
);
268 memcpy(packet
->data
, Adapter
->ucaPHSPktRestoreBuf
, nStandardPktHdrLen
);
271 return STATUS_SUCCESS
;
274 void DumpFullPacket(UCHAR
*pBuf
,UINT nPktLen
)
276 struct bcm_mini_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
);
281 //-----------------------------------------------------------------------------
282 // Procedure: phs_init
284 // Description: This routine is responsible for allocating memory for classifier and
288 // pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc
291 // TRUE(1) -If allocation of memory was success full.
292 // FALSE -If allocation of memory fails.
293 //-----------------------------------------------------------------------------
294 int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension
, struct bcm_mini_adapter
*Adapter
)
297 S_SERVICEFLOW_TABLE
*pstServiceFlowTable
;
298 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_DISPATCH
, DBG_LVL_ALL
, "\nPHS:phs_init function ");
300 if(pPhsdeviceExtension
->pstServiceFlowPhsRulesTable
)
303 pPhsdeviceExtension
->pstServiceFlowPhsRulesTable
=
304 kzalloc(sizeof(S_SERVICEFLOW_TABLE
), GFP_KERNEL
);
306 if(!pPhsdeviceExtension
->pstServiceFlowPhsRulesTable
)
308 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_DISPATCH
, DBG_LVL_ALL
, "\nAllocation ServiceFlowPhsRulesTable failed");
312 pstServiceFlowTable
= pPhsdeviceExtension
->pstServiceFlowPhsRulesTable
;
313 for(i
=0;i
<MAX_SERVICEFLOWS
;i
++)
315 S_SERVICEFLOW_ENTRY sServiceFlow
= pstServiceFlowTable
->stSFList
[i
];
316 sServiceFlow
.pstClassifierTable
= kzalloc(sizeof(S_CLASSIFIER_TABLE
), GFP_KERNEL
);
317 if(!sServiceFlow
.pstClassifierTable
)
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
;
327 pPhsdeviceExtension
->CompressedTxBuffer
= kmalloc(PHS_BUFFER_SIZE
, GFP_KERNEL
);
329 if(pPhsdeviceExtension
->CompressedTxBuffer
== NULL
)
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
;
337 pPhsdeviceExtension
->UnCompressedRxBuffer
= kmalloc(PHS_BUFFER_SIZE
, GFP_KERNEL
);
338 if(pPhsdeviceExtension
->UnCompressedRxBuffer
== NULL
)
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
;
349 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_DISPATCH
, DBG_LVL_ALL
, "\n phs_init Successfull");
350 return STATUS_SUCCESS
;
354 int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt
)
356 if(pPHSDeviceExt
->pstServiceFlowPhsRulesTable
)
358 free_phs_serviceflow_rules(pPHSDeviceExt
->pstServiceFlowPhsRulesTable
);
359 pPHSDeviceExt
->pstServiceFlowPhsRulesTable
= NULL
;
362 kfree(pPHSDeviceExt
->CompressedTxBuffer
);
363 pPHSDeviceExt
->CompressedTxBuffer
= NULL
;
365 kfree(pPHSDeviceExt
->UnCompressedRxBuffer
);
366 pPHSDeviceExt
->UnCompressedRxBuffer
= NULL
;
375 PhsUpdateClassifierRule
378 Exported function to add or modify a PHS Rule.
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.
392 ULONG
PhsUpdateClassifierRule(IN
void* pvContext
,
394 IN B_UINT16 uiClsId
,
395 IN S_PHS_RULE
*psPhsRule
,
396 IN B_UINT8 u8AssociatedPHSI
)
400 S_SERVICEFLOW_ENTRY
*pstServiceFlowEntry
= NULL
;
401 struct bcm_mini_adapter
*Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
405 PPHS_DEVICE_EXTENSION pDeviceExtension
= (PPHS_DEVICE_EXTENSION
)pvContext
;
407 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_DISPATCH
, DBG_LVL_ALL
,"PHS With Corr2 Changes \n");
409 if(pDeviceExtension
== NULL
)
411 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_DISPATCH
, DBG_LVL_ALL
,"Invalid Device Extension\n");
412 return ERR_PHS_INVALID_DEVICE_EXETENSION
;
416 if(u8AssociatedPHSI
== 0)
418 return ERR_PHS_INVALID_PHS_RULE
;
421 /* Retrieve the SFID Entry Index for requested Service Flow */
423 nSFIndex
= GetServiceFlowEntry(pDeviceExtension
->pstServiceFlowPhsRulesTable
,
424 uiVcid
,&pstServiceFlowEntry
);
426 if(nSFIndex
== PHS_INVALID_TABLE_INDEX
)
428 /* This is a new SF. Create a mapping entry for this */
429 lStatus
= CreateSFToClassifierRuleMapping(uiVcid
, uiClsId
,
430 pDeviceExtension
->pstServiceFlowPhsRulesTable
, psPhsRule
, u8AssociatedPHSI
);
434 /* SF already Exists Add PHS Rule to existing SF */
435 lStatus
= CreateClassiferToPHSRuleMapping(uiVcid
, uiClsId
,
436 pstServiceFlowEntry
, psPhsRule
, u8AssociatedPHSI
);
445 Deletes the specified phs Rule within Vcid
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.
459 ULONG
PhsDeletePHSRule(IN
void* pvContext
,IN B_UINT16 uiVcid
,IN B_UINT8 u8PHSI
)
462 UINT nSFIndex
=0, nClsidIndex
=0 ;
463 S_SERVICEFLOW_ENTRY
*pstServiceFlowEntry
= NULL
;
464 S_CLASSIFIER_TABLE
*pstClassifierRulesTable
= NULL
;
465 struct bcm_mini_adapter
*Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
468 PPHS_DEVICE_EXTENSION pDeviceExtension
= (PPHS_DEVICE_EXTENSION
)pvContext
;
470 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_DISPATCH
, DBG_LVL_ALL
, "======>\n");
475 //Retrieve the SFID Entry Index for requested Service Flow
476 nSFIndex
= GetServiceFlowEntry(pDeviceExtension
477 ->pstServiceFlowPhsRulesTable
,uiVcid
,&pstServiceFlowEntry
);
479 if(nSFIndex
== PHS_INVALID_TABLE_INDEX
)
481 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_DISPATCH
, DBG_LVL_ALL
, "SFID Match Failed\n");
482 return ERR_SF_MATCH_FAIL
;
485 pstClassifierRulesTable
=pstServiceFlowEntry
->pstClassifierTable
;
486 if(pstClassifierRulesTable
)
488 for(nClsidIndex
=0;nClsidIndex
<MAX_PHSRULE_PER_SF
;nClsidIndex
++)
490 if(pstClassifierRulesTable
->stActivePhsRulesList
[nClsidIndex
].bUsed
&& pstClassifierRulesTable
->stActivePhsRulesList
[nClsidIndex
].pstPhsRule
)
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
));
509 PhsDeleteClassifierRule
512 Exported function to Delete a PHS Rule for the SFID,CLSID Pair.
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.
525 ULONG
PhsDeleteClassifierRule(IN
void* pvContext
,IN B_UINT16 uiVcid
,IN B_UINT16 uiClsId
)
528 UINT nSFIndex
=0, nClsidIndex
=0 ;
529 S_SERVICEFLOW_ENTRY
*pstServiceFlowEntry
= NULL
;
530 S_CLASSIFIER_ENTRY
*pstClassifierEntry
= NULL
;
531 struct bcm_mini_adapter
*Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
532 PPHS_DEVICE_EXTENSION pDeviceExtension
= (PPHS_DEVICE_EXTENSION
)pvContext
;
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
)
541 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_DISPATCH
, DBG_LVL_ALL
,"SFID Match Failed\n");
542 return ERR_SF_MATCH_FAIL
;
545 nClsidIndex
= GetClassifierEntry(pstServiceFlowEntry
->pstClassifierTable
,
546 uiClsId
, eActiveClassifierRuleContext
, &pstClassifierEntry
);
547 if((nClsidIndex
!= PHS_INVALID_TABLE_INDEX
) && (!pstClassifierEntry
->bUnclassifiedPHSRule
))
549 if(pstClassifierEntry
->pstPhsRule
)
551 if(pstClassifierEntry
->pstPhsRule
->u8RefCnt
)
552 pstClassifierEntry
->pstPhsRule
->u8RefCnt
--;
553 if(0==pstClassifierEntry
->pstPhsRule
->u8RefCnt
)
554 kfree(pstClassifierEntry
->pstPhsRule
);
557 memset(pstClassifierEntry
, 0, sizeof(S_CLASSIFIER_ENTRY
));
560 nClsidIndex
= GetClassifierEntry(pstServiceFlowEntry
->pstClassifierTable
,
561 uiClsId
,eOldClassifierRuleContext
,&pstClassifierEntry
);
563 if((nClsidIndex
!= PHS_INVALID_TABLE_INDEX
) && (!pstClassifierEntry
->bUnclassifiedPHSRule
))
565 kfree(pstClassifierEntry
->pstPhsRule
);
566 memset(pstClassifierEntry
, 0, sizeof(S_CLASSIFIER_ENTRY
));
576 Exported function to Delete a all PHS Rules for the SFID.
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
588 ULONG
PhsDeleteSFRules(IN
void* pvContext
,IN B_UINT16 uiVcid
)
592 UINT nSFIndex
=0, nClsidIndex
=0 ;
593 S_SERVICEFLOW_ENTRY
*pstServiceFlowEntry
= NULL
;
594 S_CLASSIFIER_TABLE
*pstClassifierRulesTable
= NULL
;
595 struct bcm_mini_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");
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
)
606 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_DISPATCH
, DBG_LVL_ALL
, "SFID Match Failed\n");
607 return ERR_SF_MATCH_FAIL
;
610 pstClassifierRulesTable
=pstServiceFlowEntry
->pstClassifierTable
;
611 if(pstClassifierRulesTable
)
613 for(nClsidIndex
=0;nClsidIndex
<MAX_PHSRULE_PER_SF
;nClsidIndex
++)
615 if(pstClassifierRulesTable
->stActivePhsRulesList
[nClsidIndex
].pstPhsRule
)
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
]
627 memset(&pstClassifierRulesTable
->stActivePhsRulesList
[nClsidIndex
], 0, sizeof(S_CLASSIFIER_ENTRY
));
628 if(pstClassifierRulesTable
->stOldPhsRulesList
[nClsidIndex
].pstPhsRule
)
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
]
641 memset(&pstClassifierRulesTable
->stOldPhsRulesList
[nClsidIndex
], 0, sizeof(S_CLASSIFIER_ENTRY
));
644 pstServiceFlowEntry
->bUsed
= FALSE
;
645 pstServiceFlowEntry
->uiVcid
= 0;
657 Exported function to compress the data using PHS.
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
674 ULONG
PhsCompress(IN
void* pvContext
,
677 IN
void *pvInputBuffer
,
678 OUT
void *pvOutputBuffer
,
679 OUT UINT
*pOldHeaderSize
,
680 OUT UINT
*pNewHeaderSize
)
682 UINT nSFIndex
=0, nClsidIndex
=0 ;
683 S_SERVICEFLOW_ENTRY
*pstServiceFlowEntry
= NULL
;
684 S_CLASSIFIER_ENTRY
*pstClassifierEntry
= NULL
;
685 S_PHS_RULE
*pstPhsRule
= NULL
;
687 struct bcm_mini_adapter
*Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
691 PPHS_DEVICE_EXTENSION pDeviceExtension
= (PPHS_DEVICE_EXTENSION
)pvContext
;
694 if(pDeviceExtension
== NULL
)
696 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_SEND
, DBG_LVL_ALL
,"Invalid Device Extension\n");
697 lStatus
= STATUS_PHS_NOCOMPRESSION
;
702 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_SEND
, DBG_LVL_ALL
,"Suppressing header \n");
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
)
710 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_SEND
, DBG_LVL_ALL
,"SFID Match Failed\n");
711 lStatus
= STATUS_PHS_NOCOMPRESSION
;
715 nClsidIndex
= GetClassifierEntry(pstServiceFlowEntry
->pstClassifierTable
,
716 uiClsId
,eActiveClassifierRuleContext
,&pstClassifierEntry
);
718 if(nClsidIndex
== PHS_INVALID_TABLE_INDEX
)
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
;
726 //get rule from SF id,Cls ID pair and proceed
727 pstPhsRule
= pstClassifierEntry
->pstPhsRule
;
729 if(!ValidatePHSRuleComplete(pstPhsRule
))
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
;
737 lStatus
= phs_compress(pstPhsRule
,(PUCHAR
)pvInputBuffer
,
738 (PUCHAR
)pvOutputBuffer
, pOldHeaderSize
,pNewHeaderSize
);
740 if(lStatus
== STATUS_PHS_COMPRESSED
)
742 pstPhsRule
->PHSModifiedBytes
+= *pOldHeaderSize
- *pNewHeaderSize
- 1;
743 pstPhsRule
->PHSModifiedNumPackets
++;
746 pstPhsRule
->PHSErrorNumPackets
++;
755 Exported function to restore the packet header in Rx path.
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.
770 ULONG
PhsDeCompress(IN
void* pvContext
,
772 IN
void *pvInputBuffer
,
773 OUT
void *pvOutputBuffer
,
774 OUT UINT
*pInHeaderSize
,
775 OUT UINT
*pOutHeaderSize
)
777 UINT nSFIndex
=0, nPhsRuleIndex
=0 ;
778 S_SERVICEFLOW_ENTRY
*pstServiceFlowEntry
= NULL
;
779 S_PHS_RULE
*pstPhsRule
= NULL
;
781 struct bcm_mini_adapter
*Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
782 PPHS_DEVICE_EXTENSION pDeviceExtension
=
783 (PPHS_DEVICE_EXTENSION
)pvContext
;
787 if(pDeviceExtension
== NULL
)
789 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_RECEIVE
,DBG_LVL_ALL
,"Invalid Device Extension\n");
790 return ERR_PHS_INVALID_DEVICE_EXETENSION
;
793 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_RECEIVE
,DBG_LVL_ALL
,"Restoring header\n");
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
)
799 return STATUS_PHS_NOCOMPRESSION
;
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
)
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
;
811 nPhsRuleIndex
= GetPhsRuleEntry(pstServiceFlowEntry
->pstClassifierTable
,phsi
,
812 eActiveClassifierRuleContext
,&pstPhsRule
);
813 if(nPhsRuleIndex
== PHS_INVALID_TABLE_INDEX
)
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
)
820 return ERR_PHSRULE_MATCH_FAIL
;
825 *pInHeaderSize
= phs_decompress((PUCHAR
)pvInputBuffer
,
826 (PUCHAR
)pvOutputBuffer
,pstPhsRule
,pOutHeaderSize
);
828 pstPhsRule
->PHSModifiedBytes
+= *pOutHeaderSize
- *pInHeaderSize
- 1;
830 pstPhsRule
->PHSModifiedNumPackets
++;
831 return STATUS_PHS_COMPRESSED
;
835 //-----------------------------------------------------------------------------
836 // Procedure: free_phs_serviceflow_rules
838 // Description: This routine is responsible for freeing memory allocated for PHS rules.
841 // rules - ptr to S_SERVICEFLOW_TABLE structure.
844 // Does not return any value.
845 //-----------------------------------------------------------------------------
847 static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE
*psServiceFlowRulesTable
)
850 struct bcm_mini_adapter
*Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
852 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_DISPATCH
, DBG_LVL_ALL
, "=======>\n");
853 if(psServiceFlowRulesTable
)
855 for(i
=0;i
<MAX_SERVICEFLOWS
;i
++)
857 S_SERVICEFLOW_ENTRY stServiceFlowEntry
=
858 psServiceFlowRulesTable
->stSFList
[i
];
859 S_CLASSIFIER_TABLE
*pstClassifierRulesTable
=
860 stServiceFlowEntry
.pstClassifierTable
;
862 if(pstClassifierRulesTable
)
864 for(j
=0;j
<MAX_PHSRULE_PER_SF
;j
++)
866 if(pstClassifierRulesTable
->stActivePhsRulesList
[j
].pstPhsRule
)
868 if(pstClassifierRulesTable
->stActivePhsRulesList
[j
].pstPhsRule
870 pstClassifierRulesTable
->stActivePhsRulesList
[j
].pstPhsRule
872 if(0==pstClassifierRulesTable
->stActivePhsRulesList
[j
].pstPhsRule
874 kfree(pstClassifierRulesTable
->stActivePhsRulesList
[j
].pstPhsRule
);
875 pstClassifierRulesTable
->stActivePhsRulesList
[j
].pstPhsRule
= NULL
;
877 if(pstClassifierRulesTable
->stOldPhsRulesList
[j
].pstPhsRule
)
879 if(pstClassifierRulesTable
->stOldPhsRulesList
[j
].pstPhsRule
881 pstClassifierRulesTable
->stOldPhsRulesList
[j
].pstPhsRule
883 if(0==pstClassifierRulesTable
->stOldPhsRulesList
[j
].pstPhsRule
885 kfree(pstClassifierRulesTable
->stOldPhsRulesList
[j
].pstPhsRule
);
886 pstClassifierRulesTable
->stOldPhsRulesList
[j
].pstPhsRule
= NULL
;
889 kfree(pstClassifierRulesTable
);
890 stServiceFlowEntry
.pstClassifierTable
= pstClassifierRulesTable
= NULL
;
895 kfree(psServiceFlowRulesTable
);
896 psServiceFlowRulesTable
= NULL
;
901 static BOOLEAN
ValidatePHSRuleComplete(IN S_PHS_RULE
*psPhsRule
)
905 if(!psPhsRule
->u8PHSI
)
911 if(!psPhsRule
->u8PHSS
)
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
930 UINT
GetServiceFlowEntry(IN S_SERVICEFLOW_TABLE
*psServiceFlowTable
,
931 IN B_UINT16 uiVcid
,S_SERVICEFLOW_ENTRY
**ppstServiceFlowEntry
)
934 for(i
=0;i
<MAX_SERVICEFLOWS
;i
++)
936 if(psServiceFlowTable
->stSFList
[i
].bUsed
)
938 if(psServiceFlowTable
->stSFList
[i
].uiVcid
== uiVcid
)
940 *ppstServiceFlowEntry
= &psServiceFlowTable
->stSFList
[i
];
946 *ppstServiceFlowEntry
= NULL
;
947 return PHS_INVALID_TABLE_INDEX
;
951 UINT
GetClassifierEntry(IN S_CLASSIFIER_TABLE
*pstClassifierTable
,
952 IN B_UINT32 uiClsid
,E_CLASSIFIER_ENTRY_CONTEXT eClsContext
,
953 OUT S_CLASSIFIER_ENTRY
**ppstClassifierEntry
)
956 S_CLASSIFIER_ENTRY
*psClassifierRules
= NULL
;
957 for(i
=0;i
<MAX_PHSRULE_PER_SF
;i
++)
960 if(eClsContext
== eActiveClassifierRuleContext
)
962 psClassifierRules
= &pstClassifierTable
->stActivePhsRulesList
[i
];
966 psClassifierRules
= &pstClassifierTable
->stOldPhsRulesList
[i
];
969 if(psClassifierRules
->bUsed
)
971 if(psClassifierRules
->uiClassifierRuleId
== uiClsid
)
973 *ppstClassifierEntry
= psClassifierRules
;
980 *ppstClassifierEntry
= NULL
;
981 return PHS_INVALID_TABLE_INDEX
;
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
)
989 S_CLASSIFIER_ENTRY
*pstClassifierRule
= NULL
;
990 for(i
=0;i
<MAX_PHSRULE_PER_SF
;i
++)
992 if(eClsContext
== eActiveClassifierRuleContext
)
994 pstClassifierRule
= &pstClassifierTable
->stActivePhsRulesList
[i
];
998 pstClassifierRule
= &pstClassifierTable
->stOldPhsRulesList
[i
];
1000 if(pstClassifierRule
->bUsed
)
1002 if(pstClassifierRule
->u8PHSI
== uiPHSI
)
1004 *ppstPhsRule
= pstClassifierRule
->pstPhsRule
;
1011 *ppstPhsRule
= NULL
;
1012 return PHS_INVALID_TABLE_INDEX
;
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
)
1020 S_CLASSIFIER_TABLE
*psaClassifiertable
= NULL
;
1023 BOOLEAN bFreeEntryFound
=FALSE
;
1024 //Check for a free entry in SFID table
1025 for(iSfIndex
=0;iSfIndex
< MAX_SERVICEFLOWS
;iSfIndex
++)
1027 if(!psServiceFlowTable
->stSFList
[iSfIndex
].bUsed
)
1029 bFreeEntryFound
= TRUE
;
1034 if(!bFreeEntryFound
)
1035 return ERR_SFTABLE_FULL
;
1038 psaClassifiertable
= psServiceFlowTable
->stSFList
[iSfIndex
].pstClassifierTable
;
1039 uiStatus
= CreateClassifierPHSRule(uiClsId
,psaClassifiertable
,psPhsRule
,
1040 eActiveClassifierRuleContext
,u8AssociatedPHSI
);
1041 if(uiStatus
== PHS_SUCCESS
)
1043 //Add entry at free index to the SF
1044 psServiceFlowTable
->stSFList
[iSfIndex
].bUsed
= TRUE
;
1045 psServiceFlowTable
->stSFList
[iSfIndex
].uiVcid
= uiVcid
;
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
)
1056 S_CLASSIFIER_ENTRY
*pstClassifierEntry
= NULL
;
1057 UINT uiStatus
=PHS_SUCCESS
;
1058 UINT nClassifierIndex
= 0;
1059 S_CLASSIFIER_TABLE
*psaClassifiertable
= NULL
;
1060 struct bcm_mini_adapter
*Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
1061 psaClassifiertable
= pstServiceFlowEntry
->pstClassifierTable
;
1063 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_DISPATCH
, DBG_LVL_ALL
, "==>");
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
)
1072 The Classifier doesn't exist. So its a new classifier being added.
1073 Add new entry to associate PHS Rule to the Classifier
1076 uiStatus
= CreateClassifierPHSRule(uiClsId
,psaClassifiertable
,
1077 psPhsRule
,eActiveClassifierRuleContext
,u8AssociatedPHSI
);
1082 The Classifier exists.The PHS Rule for this classifier
1085 if(pstClassifierEntry
->u8PHSI
== psPhsRule
->u8PHSI
)
1087 if(pstClassifierEntry
->pstPhsRule
== NULL
)
1088 return ERR_PHS_INVALID_PHS_RULE
;
1091 This rule already exists if any fields are changed for this PHS
1094 /* If any part of PHSF is valid then we update PHSF */
1095 if(psPhsRule
->u8PHSFLength
)
1098 memcpy(pstClassifierEntry
->pstPhsRule
->u8PHSF
,
1099 psPhsRule
->u8PHSF
, MAX_PHS_LENGTHS
);
1101 if(psPhsRule
->u8PHSFLength
)
1104 pstClassifierEntry
->pstPhsRule
->u8PHSFLength
=
1105 psPhsRule
->u8PHSFLength
;
1107 if(psPhsRule
->u8PHSMLength
)
1110 memcpy(pstClassifierEntry
->pstPhsRule
->u8PHSM
,
1111 psPhsRule
->u8PHSM
, MAX_PHS_LENGTHS
);
1113 if(psPhsRule
->u8PHSMLength
)
1116 pstClassifierEntry
->pstPhsRule
->u8PHSMLength
=
1117 psPhsRule
->u8PHSMLength
;
1119 if(psPhsRule
->u8PHSS
)
1122 pstClassifierEntry
->pstPhsRule
->u8PHSS
= psPhsRule
->u8PHSS
;
1126 pstClassifierEntry
->pstPhsRule
->u8PHSV
= psPhsRule
->u8PHSV
;
1132 A new rule is being set for this classifier.
1134 uiStatus
=UpdateClassifierPHSRule( uiClsId
, pstClassifierEntry
,
1135 psaClassifiertable
, psPhsRule
, 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
)
1147 UINT iClassifierIndex
= 0;
1148 BOOLEAN bFreeEntryFound
= FALSE
;
1149 S_CLASSIFIER_ENTRY
*psClassifierRules
= NULL
;
1150 UINT nStatus
= PHS_SUCCESS
;
1151 struct bcm_mini_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
)
1155 return ERR_INVALID_CLASSIFIERTABLE_FOR_SF
;
1158 if(eClsContext
== eOldClassifierRuleContext
)
1160 /* If An Old Entry for this classifier ID already exists in the
1161 old rules table replace it. */
1164 GetClassifierEntry(psaClassifiertable
, uiClsId
,
1165 eClsContext
,&psClassifierRules
);
1166 if(iClassifierIndex
!= PHS_INVALID_TABLE_INDEX
)
1169 The Classifier already exists in the old rules table
1170 Lets replace the old classifier with the new one.
1172 bFreeEntryFound
= TRUE
;
1176 if(!bFreeEntryFound
)
1179 Continue to search for a free location to add the rule
1181 for(iClassifierIndex
= 0; iClassifierIndex
<
1182 MAX_PHSRULE_PER_SF
; iClassifierIndex
++)
1184 if(eClsContext
== eActiveClassifierRuleContext
)
1187 &psaClassifiertable
->stActivePhsRulesList
[iClassifierIndex
];
1192 &psaClassifiertable
->stOldPhsRulesList
[iClassifierIndex
];
1195 if(!psClassifierRules
->bUsed
)
1197 bFreeEntryFound
= TRUE
;
1203 if(!bFreeEntryFound
)
1205 if(eClsContext
== eActiveClassifierRuleContext
)
1207 return ERR_CLSASSIFIER_TABLE_FULL
;
1211 //Lets replace the oldest rule if we are looking in old Rule table
1212 if(psaClassifiertable
->uiOldestPhsRuleIndex
>=
1215 psaClassifiertable
->uiOldestPhsRuleIndex
=0;
1218 iClassifierIndex
= psaClassifiertable
->uiOldestPhsRuleIndex
;
1220 &psaClassifiertable
->stOldPhsRulesList
[iClassifierIndex
];
1222 (psaClassifiertable
->uiOldestPhsRuleIndex
)++;
1226 if(eClsContext
== eOldClassifierRuleContext
)
1228 if(psClassifierRules
->pstPhsRule
== NULL
)
1230 psClassifierRules
->pstPhsRule
= kmalloc(sizeof(S_PHS_RULE
),GFP_KERNEL
);
1232 if(NULL
== psClassifierRules
->pstPhsRule
)
1233 return ERR_PHSRULE_MEMALLOC_FAIL
;
1236 psClassifierRules
->bUsed
= TRUE
;
1237 psClassifierRules
->uiClassifierRuleId
= uiClsId
;
1238 psClassifierRules
->u8PHSI
= psPhsRule
->u8PHSI
;
1239 psClassifierRules
->bUnclassifiedPHSRule
= psPhsRule
->bUnclassifiedPHSRule
;
1241 /* Update The PHS rule */
1242 memcpy(psClassifierRules
->pstPhsRule
,
1243 psPhsRule
, sizeof(S_PHS_RULE
));
1247 nStatus
= UpdateClassifierPHSRule(uiClsId
,psClassifierRules
,
1248 psaClassifiertable
,psPhsRule
,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
)
1259 S_PHS_RULE
*pstAddPhsRule
= NULL
;
1260 UINT nPhsRuleIndex
= 0;
1261 BOOLEAN bPHSRuleOrphaned
= FALSE
;
1262 struct bcm_mini_adapter
*Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
1263 psPhsRule
->u8RefCnt
=0;
1265 /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/
1266 bPHSRuleOrphaned
= DerefPhsRule( uiClsId
, psaClassifiertable
,
1267 pstClassifierEntry
->pstPhsRule
);
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
)
1274 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_DISPATCH
, DBG_LVL_ALL
, "\nAdding New PHSRuleEntry For Classifier");
1276 if(psPhsRule
->u8PHSI
== 0)
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
;
1281 //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId
1282 if(FALSE
== bPHSRuleOrphaned
)
1284 pstClassifierEntry
->pstPhsRule
= kmalloc(sizeof(S_PHS_RULE
), GFP_KERNEL
);
1285 if(NULL
== pstClassifierEntry
->pstPhsRule
)
1287 return ERR_PHSRULE_MEMALLOC_FAIL
;
1290 memcpy(pstClassifierEntry
->pstPhsRule
, psPhsRule
, sizeof(S_PHS_RULE
));
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
)
1299 kfree(pstClassifierEntry
->pstPhsRule
);
1300 pstClassifierEntry
->pstPhsRule
= NULL
;
1302 pstClassifierEntry
->pstPhsRule
= pstAddPhsRule
;
1305 pstClassifierEntry
->bUsed
= TRUE
;
1306 pstClassifierEntry
->u8PHSI
= pstClassifierEntry
->pstPhsRule
->u8PHSI
;
1307 pstClassifierEntry
->uiClassifierRuleId
= uiClsId
;
1308 pstClassifierEntry
->pstPhsRule
->u8RefCnt
++;
1309 pstClassifierEntry
->bUnclassifiedPHSRule
= pstClassifierEntry
->pstPhsRule
->bUnclassifiedPHSRule
;
1315 static BOOLEAN
DerefPhsRule(IN B_UINT16 uiClsId
,S_CLASSIFIER_TABLE
*psaClassifiertable
,S_PHS_RULE
*pstPhsRule
)
1317 if(pstPhsRule
==NULL
)
1319 if(pstPhsRule
->u8RefCnt
)
1320 pstPhsRule
->u8RefCnt
--;
1321 if(0==pstPhsRule
->u8RefCnt
)
1323 /*if(pstPhsRule->u8PHSI)
1324 //Store the currently active rule into the old rules list
1325 CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);*/
1334 void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension
)
1337 struct bcm_mini_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
++)
1341 S_SERVICEFLOW_ENTRY stServFlowEntry
=
1342 pDeviceExtension
->pstServiceFlowPhsRulesTable
->stSFList
[i
];
1343 if(stServFlowEntry
.bUsed
)
1345 for(j
=0;j
<MAX_PHSRULE_PER_SF
;j
++)
1349 S_CLASSIFIER_ENTRY stClsEntry
;
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");
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");
1362 if(stClsEntry
.bUsed
)
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
++)
1374 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, DUMP_INFO
, (DBG_LVL_ALL
|DBG_NO_FUNC_PRINT
), "%#X ",stClsEntry
.pstPhsRule
->u8PHSF
[k
]);
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
++)
1380 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, DUMP_INFO
, (DBG_LVL_ALL
|DBG_NO_FUNC_PRINT
), "%#X ",stClsEntry
.pstPhsRule
->u8PHSM
[k
]);
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");
1393 //-----------------------------------------------------------------------------
1394 // Procedure: phs_decompress
1396 // Description: This routine restores the static fields within the packet.
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.
1405 // size -The number of bytes of dynamic fields present with in the incoming packet
1407 // 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed.
1408 //-----------------------------------------------------------------------------
1410 int phs_decompress(unsigned char *in_buf
,unsigned char *out_buf
,
1411 S_PHS_RULE
*decomp_phs_rules
,UINT
*header_size
)
1414 S_PHS_RULE
*tmp_memb
;
1416 unsigned char *phsf
,*phsm
;
1417 int in_buf_len
= *header_size
-1;
1418 struct bcm_mini_adapter
*Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
1420 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_OTHERS
, PHS_RECEIVE
,DBG_LVL_ALL
,"====>\n");
1423 if((decomp_phs_rules
== NULL
))
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
;
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
))
1439 bit
= ((*phsm
<< i
)& SUPPRESS
);
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
);
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
);
1459 *header_size
=*header_size
+ 1;
1473 //-----------------------------------------------------------------------------
1474 // Procedure: phs_compress
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
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.
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 //-----------------------------------------------------------------------------
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
)
1496 unsigned char *old_addr
= out_buf
;
1498 struct bcm_mini_adapter
*Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
1499 if(phs_rule
== NULL
)
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
;
1507 if(phs_rule
->u8PHSS
<= *new_header_size
)
1509 *header_size
= phs_rule
->u8PHSS
;
1513 *header_size
= *new_header_size
;
1517 suppress
= verify_suppress_phsf(in_buf
,out_buf
,phs_rule
->u8PHSF
,
1518 phs_rule
->u8PHSM
, phs_rule
->u8PHSS
, phs_rule
->u8PHSV
,new_header_size
);
1520 if(suppress
== STATUS_PHS_COMPRESSED
)
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
);
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");
1534 //-----------------------------------------------------------------------------
1535 // Procedure: verify_suppress_phsf
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.
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.
1550 // size-The number of bytes copied into the output buffer i.e dynamic fields.
1551 // 0 -Packet has failed the verification.
1552 //-----------------------------------------------------------------------------
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
)
1558 unsigned int size
=0;
1560 struct bcm_mini_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
);
1564 if(phss
>(*new_header_size
))
1566 phss
=*new_header_size
;
1570 bit
= ((*phsm
<< i
)& SUPPRESS
);
1574 if(*in_buffer
!= *phsf
)
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
;
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
);
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
);
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
;