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