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