3 static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid, B_UINT16 uiClsId, struct bcm_phs_table *psServiceFlowTable, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI);
5 static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid, B_UINT16 uiClsId, struct bcm_phs_entry *pstServiceFlowEntry, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI);
7 static UINT CreateClassifierPHSRule(B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, enum bcm_phs_classifier_context eClsContext, B_UINT8 u8AssociatedPHSI);
9 static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId, struct bcm_phs_classifier_entry *pstClassifierEntry, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI);
11 static BOOLEAN ValidatePHSRuleComplete(struct bcm_phs_rule *psPhsRule);
13 static BOOLEAN DerefPhsRule(B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule);
15 static UINT GetClassifierEntry(struct bcm_phs_classifier_table *pstClassifierTable, B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext, struct bcm_phs_classifier_entry **ppstClassifierEntry);
17 static UINT GetPhsRuleEntry(struct bcm_phs_classifier_table *pstClassifierTable, B_UINT32 uiPHSI, enum bcm_phs_classifier_context eClsContext, struct bcm_phs_rule **ppstPhsRule);
19 static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable);
21 static int phs_compress(struct bcm_phs_rule *phs_members, unsigned char *in_buf,
22 unsigned char *out_buf, unsigned int *header_size, UINT *new_header_size);
24 static int verify_suppress_phsf(unsigned char *in_buffer, unsigned char *out_buffer,
25 unsigned char *phsf, unsigned char *phsm, unsigned int phss, unsigned int phsv, UINT *new_header_size);
27 static int phs_decompress(unsigned char *in_buf, unsigned char *out_buf,
28 struct bcm_phs_rule *phs_rules, UINT *header_size);
30 static ULONG PhsCompress(void *pvContext,
36 UINT *pNewHeaderSize);
38 static ULONG PhsDeCompress(void *pvContext,
43 UINT *pOutHeaderSize);
50 Description: This routine handle PHS(Payload Header Suppression for Tx path.
51 It extracts a fragment of the NDIS_PACKET containing the header
52 to be suppressed. It then suppresses the header by invoking PHS exported compress routine.
53 The header data after suppression is copied back to the NDIS_PACKET.
55 Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context
56 IN Packet - NDIS packet containing data to be transmitted
57 IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to
58 identify PHS rule to be applied.
59 B_UINT16 uiClassifierRuleID - Classifier Rule ID
60 BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF.
62 Return: STATUS_SUCCESS - If the send was successful.
63 Other - If an error occurred.
66 int PHSTransmit(struct bcm_mini_adapter *Adapter,
67 struct sk_buff **pPacket,
69 B_UINT16 uiClassifierRuleID,
70 BOOLEAN bHeaderSuppressionEnabled,
75 UINT unPHSPktHdrBytesCopied = 0;
76 UINT unPhsOldHdrSize = 0;
77 UINT unPHSNewPktHeaderLen = 0;
78 /* Pointer to PHS IN Hdr Buffer */
79 PUCHAR pucPHSPktHdrInBuf = Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf;
80 /* Pointer to PHS OUT Hdr Buffer */
81 PUCHAR pucPHSPktHdrOutBuf = Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf;
83 UINT BytesToRemove = 0;
86 UINT numBytesCompressed = 0;
87 struct sk_buff *newPacket = NULL;
88 struct sk_buff *Packet = *pPacket;
90 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "In PHSTransmit");
93 BytesToRemove = ETH_HLEN;
95 Accumulate the header upto the size we support suppression
99 usPacketType = ((struct ethhdr *)(Packet->data))->h_proto;
101 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
102 //considering data after ethernet header
103 if ((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS)
105 unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove);
109 unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS;
112 if ((unPHSPktHdrBytesCopied > 0) &&
113 (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS))
115 // Step 2 Suppress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf.
116 // Suppress only if IP Header and PHS Enabled For the Service Flow
117 if (((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
118 (usPacketType == ETHERNET_FRAMETYPE_IPV6)) &&
119 (bHeaderSuppressionEnabled))
121 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nTrying to PHS Compress Using Classifier rule 0x%X", uiClassifierRuleID);
122 unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied;
123 ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext,
129 &unPHSNewPktHeaderLen);
130 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nPHS Old header Size : %d New Header Size %d\n", unPhsOldHdrSize, unPHSNewPktHeaderLen);
132 if (unPHSNewPktHeaderLen == unPhsOldHdrSize)
134 if (ulPhsStatus == STATUS_PHS_COMPRESSED)
135 bPHSI = *pucPHSPktHdrOutBuf;
137 ulPhsStatus = STATUS_PHS_NOCOMPRESSION;
140 if (ulPhsStatus == STATUS_PHS_COMPRESSED)
142 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "PHS Sending packet Compressed");
144 if (skb_cloned(Packet))
146 newPacket = skb_copy(Packet, GFP_ATOMIC);
148 if (newPacket == NULL)
149 return STATUS_FAILURE;
151 dev_kfree_skb(Packet);
152 *pPacket = Packet = newPacket;
153 pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
156 numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen + PHSI_LEN);
158 memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
159 memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
160 skb_pull(Packet, numBytesCompressed);
162 return STATUS_SUCCESS;
166 //if one byte headroom is not available, increase it through skb_cow
167 if (!(skb_headroom(Packet) > 0))
169 if (skb_cow(Packet, 1))
171 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n");
172 return STATUS_FAILURE;
177 // CAUTION: The MAC Header is getting corrupted here for IP CS - can be saved by copying 14 Bytes. not needed .... hence corrupting it.
178 *(Packet->data + BytesToRemove) = bPHSI;
179 return STATUS_SUCCESS;
184 if (!bHeaderSuppressionEnabled)
186 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nHeader Suppression Disabled For SF: No PHS\n");
189 return STATUS_SUCCESS;
193 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS");
194 return STATUS_SUCCESS;
197 int PHSReceive(struct bcm_mini_adapter *Adapter,
199 struct sk_buff *packet,
201 UCHAR *pucEthernetHdr,
202 UINT bHeaderSuppressionEnabled)
204 u32 nStandardPktHdrLen = 0;
205 u32 nTotalsuppressedPktHdrBytes = 0;
207 PUCHAR pucInBuff = NULL;
208 UINT TotalBytesAdded = 0;
210 if (!bHeaderSuppressionEnabled)
212 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nPhs Disabled for incoming packet");
216 pucInBuff = packet->data;
218 //Restore PHS suppressed header
219 nStandardPktHdrLen = packet->len;
220 ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext,
223 Adapter->ucaPHSPktRestoreBuf,
224 &nTotalsuppressedPktHdrBytes,
225 &nStandardPktHdrLen);
227 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
228 nTotalsuppressedPktHdrBytes, nStandardPktHdrLen);
230 if (ulPhsStatus != STATUS_PHS_COMPRESSED)
233 return STATUS_SUCCESS;
237 TotalBytesAdded = nStandardPktHdrLen - nTotalsuppressedPktHdrBytes - PHSI_LEN;
240 if (skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded))
241 skb_push(packet, TotalBytesAdded);
244 if (skb_cow(packet, skb_headroom(packet) + TotalBytesAdded))
246 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n");
247 return STATUS_FAILURE;
250 skb_push(packet, TotalBytesAdded);
254 memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
257 return STATUS_SUCCESS;
260 void DumpFullPacket(UCHAR *pBuf, UINT nPktLen)
262 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
264 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dumping Data Packet");
265 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, pBuf, nPktLen);
268 //-----------------------------------------------------------------------------
269 // Procedure: phs_init
271 // Description: This routine is responsible for allocating memory for classifier and
275 // pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc
278 // TRUE(1) -If allocation of memory was success full.
279 // FALSE -If allocation of memory fails.
280 //-----------------------------------------------------------------------------
281 int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, struct bcm_mini_adapter *Adapter)
284 struct bcm_phs_table *pstServiceFlowTable;
286 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nPHS:phs_init function");
288 if (pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
291 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = kzalloc(sizeof(struct bcm_phs_table), GFP_KERNEL);
293 if (!pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
295 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
299 pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable;
300 for (i = 0; i < MAX_SERVICEFLOWS; i++)
302 struct bcm_phs_entry sServiceFlow = pstServiceFlowTable->stSFList[i];
303 sServiceFlow.pstClassifierTable = kzalloc(sizeof(struct bcm_phs_classifier_table), GFP_KERNEL);
304 if (!sServiceFlow.pstClassifierTable)
306 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
307 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
308 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
313 pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
314 if (pPhsdeviceExtension->CompressedTxBuffer == NULL)
316 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
317 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
318 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
322 pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
323 if (pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
325 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
326 kfree(pPhsdeviceExtension->CompressedTxBuffer);
327 free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
328 pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
332 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successful");
333 return STATUS_SUCCESS;
336 int PhsCleanup(IN struct bcm_phs_extension *pPHSDeviceExt)
338 if (pPHSDeviceExt->pstServiceFlowPhsRulesTable)
340 free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable);
341 pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
344 kfree(pPHSDeviceExt->CompressedTxBuffer);
345 pPHSDeviceExt->CompressedTxBuffer = NULL;
347 kfree(pPHSDeviceExt->UnCompressedRxBuffer);
348 pPHSDeviceExt->UnCompressedRxBuffer = NULL;
355 PhsUpdateClassifierRule
358 Exported function to add or modify a PHS Rule.
361 IN void* pvContext - PHS Driver Specific Context
362 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
363 IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
364 IN struct bcm_phs_rule *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table.
372 ULONG PhsUpdateClassifierRule(IN void *pvContext,
374 IN B_UINT16 uiClsId ,
375 IN struct bcm_phs_rule *psPhsRule,
376 IN B_UINT8 u8AssociatedPHSI)
380 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
381 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
382 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
384 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "PHS With Corr2 Changes\n");
386 if (pDeviceExtension == NULL)
388 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "Invalid Device Extension\n");
389 return ERR_PHS_INVALID_DEVICE_EXETENSION;
392 if (u8AssociatedPHSI == 0)
394 return ERR_PHS_INVALID_PHS_RULE;
397 /* Retrieve the SFID Entry Index for requested Service Flow */
398 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
399 uiVcid, &pstServiceFlowEntry);
401 if (nSFIndex == PHS_INVALID_TABLE_INDEX)
403 /* This is a new SF. Create a mapping entry for this */
404 lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId,
405 pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI);
409 /* SF already Exists Add PHS Rule to existing SF */
410 lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId,
411 pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI);
420 Deletes the specified phs Rule within Vcid
423 IN void* pvContext - PHS Driver Specific Context
424 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
425 IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted.
434 ULONG PhsDeletePHSRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT8 u8PHSI)
437 UINT nSFIndex = 0, nClsidIndex = 0;
438 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
439 struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL;
440 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
441 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
443 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n");
445 if (pDeviceExtension)
447 //Retrieve the SFID Entry Index for requested Service Flow
448 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry);
450 if (nSFIndex == PHS_INVALID_TABLE_INDEX)
452 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
453 return ERR_SF_MATCH_FAIL;
456 pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable;
457 if (pstClassifierRulesTable)
459 for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++)
461 if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
463 if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI)
465 if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
466 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
468 if (0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
469 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
471 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0,
472 sizeof(struct bcm_phs_classifier_entry));
482 PhsDeleteClassifierRule
485 Exported function to Delete a PHS Rule for the SFID,CLSID Pair.
488 IN void* pvContext - PHS Driver Specific Context
489 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
490 IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
498 ULONG PhsDeleteClassifierRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT16 uiClsId)
501 UINT nSFIndex = 0, nClsidIndex = 0;
502 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
503 struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
504 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
505 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
507 if (pDeviceExtension)
509 //Retrieve the SFID Entry Index for requested Service Flow
510 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry);
511 if (nSFIndex == PHS_INVALID_TABLE_INDEX)
513 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
514 return ERR_SF_MATCH_FAIL;
517 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
518 uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry);
519 if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
521 if (pstClassifierEntry->pstPhsRule)
523 if (pstClassifierEntry->pstPhsRule->u8RefCnt)
524 pstClassifierEntry->pstPhsRule->u8RefCnt--;
526 if (0 == pstClassifierEntry->pstPhsRule->u8RefCnt)
527 kfree(pstClassifierEntry->pstPhsRule);
529 memset(pstClassifierEntry, 0, sizeof(struct bcm_phs_classifier_entry));
532 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
533 uiClsId, eOldClassifierRuleContext, &pstClassifierEntry);
535 if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
537 kfree(pstClassifierEntry->pstPhsRule);
538 memset(pstClassifierEntry, 0, sizeof(struct bcm_phs_classifier_entry));
548 Exported function to Delete a all PHS Rules for the SFID.
551 IN void* pvContext - PHS Driver Specific Context
552 IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted
560 ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid)
563 UINT nSFIndex = 0, nClsidIndex = 0;
564 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
565 struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL;
566 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
567 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
569 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "====>\n");
571 if (pDeviceExtension)
573 //Retrieve the SFID Entry Index for requested Service Flow
574 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
575 uiVcid, &pstServiceFlowEntry);
576 if (nSFIndex == PHS_INVALID_TABLE_INDEX)
578 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
579 return ERR_SF_MATCH_FAIL;
582 pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable;
583 if (pstClassifierRulesTable)
585 for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++)
587 if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
589 if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
590 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
592 if (0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
593 kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
595 pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule = NULL;
597 memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(struct bcm_phs_classifier_entry));
598 if (pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule)
600 if (pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
601 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
603 if (0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
604 kfree(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule);
606 pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule = NULL;
608 memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(struct bcm_phs_classifier_entry));
611 pstServiceFlowEntry->bUsed = FALSE;
612 pstServiceFlowEntry->uiVcid = 0;
622 Exported function to compress the data using PHS.
625 IN void* pvContext - PHS Driver Specific Context.
626 IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies.
627 IN UINT uiClsId - The Classifier ID to which current packet header compression applies.
628 IN void *pvInputBuffer - The Input buffer containg packet header data
629 IN void *pvOutputBuffer - The output buffer returned by this function after PHS
630 IN UINT *pOldHeaderSize - The actual size of the header before PHS
631 IN UINT *pNewHeaderSize - The new size of the header after applying PHS
639 ULONG PhsCompress(IN void *pvContext,
642 IN void *pvInputBuffer,
643 OUT void *pvOutputBuffer,
644 OUT UINT *pOldHeaderSize,
645 OUT UINT *pNewHeaderSize)
647 UINT nSFIndex = 0, nClsidIndex = 0;
648 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
649 struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
650 struct bcm_phs_rule *pstPhsRule = NULL;
652 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
653 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
655 if (pDeviceExtension == NULL)
657 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "Invalid Device Extension\n");
658 lStatus = STATUS_PHS_NOCOMPRESSION;
662 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "Suppressing header\n");
664 //Retrieve the SFID Entry Index for requested Service Flow
665 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
666 uiVcid, &pstServiceFlowEntry);
667 if (nSFIndex == PHS_INVALID_TABLE_INDEX)
669 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "SFID Match Failed\n");
670 lStatus = STATUS_PHS_NOCOMPRESSION;
674 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
675 uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry);
677 if (nClsidIndex == PHS_INVALID_TABLE_INDEX)
679 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "No PHS Rule Defined For Classifier\n");
680 lStatus = STATUS_PHS_NOCOMPRESSION;
684 //get rule from SF id,Cls ID pair and proceed
685 pstPhsRule = pstClassifierEntry->pstPhsRule;
686 if (!ValidatePHSRuleComplete(pstPhsRule))
688 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "PHS Rule Defined For Classifier But Not Complete\n");
689 lStatus = STATUS_PHS_NOCOMPRESSION;
694 lStatus = phs_compress(pstPhsRule, (PUCHAR)pvInputBuffer,
695 (PUCHAR)pvOutputBuffer, pOldHeaderSize, pNewHeaderSize);
697 if (lStatus == STATUS_PHS_COMPRESSED)
699 pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1;
700 pstPhsRule->PHSModifiedNumPackets++;
703 pstPhsRule->PHSErrorNumPackets++;
712 Exported function to restore the packet header in Rx path.
715 IN void* pvContext - PHS Driver Specific Context.
716 IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies.
717 IN void *pvInputBuffer - The Input buffer containg suppressed packet header data
718 OUT void *pvOutputBuffer - The output buffer returned by this function after restoration
719 OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter.
727 ULONG PhsDeCompress(IN void *pvContext,
729 IN void *pvInputBuffer,
730 OUT void *pvOutputBuffer,
731 OUT UINT *pInHeaderSize,
732 OUT UINT *pOutHeaderSize)
734 UINT nSFIndex = 0, nPhsRuleIndex = 0;
735 struct bcm_phs_entry *pstServiceFlowEntry = NULL;
736 struct bcm_phs_rule *pstPhsRule = NULL;
738 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
739 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
742 if (pDeviceExtension == NULL)
744 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "Invalid Device Extension\n");
745 return ERR_PHS_INVALID_DEVICE_EXETENSION;
748 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "Restoring header\n");
750 phsi = *((unsigned char *)(pvInputBuffer));
751 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "PHSI To Be Used For restore : %x\n", phsi);
752 if (phsi == UNCOMPRESSED_PACKET)
754 return STATUS_PHS_NOCOMPRESSION;
757 //Retrieve the SFID Entry Index for requested Service Flow
758 nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
759 uiVcid, &pstServiceFlowEntry);
760 if (nSFIndex == PHS_INVALID_TABLE_INDEX)
762 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "SFID Match Failed During Lookup\n");
763 return ERR_SF_MATCH_FAIL;
766 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, phsi,
767 eActiveClassifierRuleContext, &pstPhsRule);
768 if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
770 //Phs Rule does not exist in active rules table. Lets try in the old rules table.
771 nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
772 phsi, eOldClassifierRuleContext, &pstPhsRule);
773 if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
775 return ERR_PHSRULE_MATCH_FAIL;
779 *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer,
780 (PUCHAR)pvOutputBuffer, pstPhsRule, pOutHeaderSize);
782 pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1;
784 pstPhsRule->PHSModifiedNumPackets++;
785 return STATUS_PHS_COMPRESSED;
788 //-----------------------------------------------------------------------------
789 // Procedure: free_phs_serviceflow_rules
791 // Description: This routine is responsible for freeing memory allocated for PHS rules.
794 // rules - ptr to S_SERVICEFLOW_TABLE structure.
797 // Does not return any value.
798 //-----------------------------------------------------------------------------
800 static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable)
803 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
805 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n");
807 if (psServiceFlowRulesTable)
809 for (i = 0; i < MAX_SERVICEFLOWS; i++)
811 struct bcm_phs_entry stServiceFlowEntry = psServiceFlowRulesTable->stSFList[i];
812 struct bcm_phs_classifier_table *pstClassifierRulesTable = stServiceFlowEntry.pstClassifierTable;
814 if (pstClassifierRulesTable)
816 for (j = 0; j < MAX_PHSRULE_PER_SF; j++)
818 if (pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule)
820 if (pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt)
821 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt--;
823 if (0 == pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt)
824 kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
826 pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
829 if (pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule)
831 if (pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt)
832 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt--;
834 if (0 == pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt)
835 kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
837 pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
840 kfree(pstClassifierRulesTable);
841 stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
846 kfree(psServiceFlowRulesTable);
847 psServiceFlowRulesTable = NULL;
850 static BOOLEAN ValidatePHSRuleComplete(IN struct bcm_phs_rule *psPhsRule)
854 if (!psPhsRule->u8PHSI)
860 if (!psPhsRule->u8PHSS)
866 //Check if PHSF is defines for the PHS Rule
867 if (!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF
880 UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable,
882 struct bcm_phs_entry **ppstServiceFlowEntry)
886 for (i = 0; i < MAX_SERVICEFLOWS; i++)
888 if (psServiceFlowTable->stSFList[i].bUsed)
890 if (psServiceFlowTable->stSFList[i].uiVcid == uiVcid)
892 *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i];
898 *ppstServiceFlowEntry = NULL;
899 return PHS_INVALID_TABLE_INDEX;
902 UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
903 IN B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext,
904 OUT struct bcm_phs_classifier_entry **ppstClassifierEntry)
907 struct bcm_phs_classifier_entry *psClassifierRules = NULL;
909 for (i = 0; i < MAX_PHSRULE_PER_SF; i++)
911 if (eClsContext == eActiveClassifierRuleContext)
913 psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i];
917 psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i];
920 if (psClassifierRules->bUsed)
922 if (psClassifierRules->uiClassifierRuleId == uiClsid)
924 *ppstClassifierEntry = psClassifierRules;
930 *ppstClassifierEntry = NULL;
931 return PHS_INVALID_TABLE_INDEX;
934 static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
935 IN B_UINT32 uiPHSI, enum bcm_phs_classifier_context eClsContext,
936 OUT struct bcm_phs_rule **ppstPhsRule)
939 struct bcm_phs_classifier_entry *pstClassifierRule = NULL;
941 for (i = 0; i < MAX_PHSRULE_PER_SF; i++)
943 if (eClsContext == eActiveClassifierRuleContext)
945 pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i];
949 pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i];
952 if (pstClassifierRule->bUsed)
954 if (pstClassifierRule->u8PHSI == uiPHSI)
956 *ppstPhsRule = pstClassifierRule->pstPhsRule;
963 return PHS_INVALID_TABLE_INDEX;
966 UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16 uiClsId,
967 IN struct bcm_phs_table *psServiceFlowTable,
968 struct bcm_phs_rule *psPhsRule,
969 B_UINT8 u8AssociatedPHSI)
971 struct bcm_phs_classifier_table *psaClassifiertable = NULL;
974 BOOLEAN bFreeEntryFound = FALSE;
976 //Check for a free entry in SFID table
977 for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++)
979 if (!psServiceFlowTable->stSFList[iSfIndex].bUsed)
981 bFreeEntryFound = TRUE;
986 if (!bFreeEntryFound)
987 return ERR_SFTABLE_FULL;
989 psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable;
990 uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable, psPhsRule,
991 eActiveClassifierRuleContext, u8AssociatedPHSI);
992 if (uiStatus == PHS_SUCCESS)
994 //Add entry at free index to the SF
995 psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE;
996 psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid;
1002 UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
1003 IN B_UINT16 uiClsId,
1004 IN struct bcm_phs_entry *pstServiceFlowEntry,
1005 struct bcm_phs_rule *psPhsRule,
1006 B_UINT8 u8AssociatedPHSI)
1008 struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
1009 UINT uiStatus = PHS_SUCCESS;
1010 UINT nClassifierIndex = 0;
1011 struct bcm_phs_classifier_table *psaClassifiertable = NULL;
1012 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1014 psaClassifiertable = pstServiceFlowEntry->pstClassifierTable;
1016 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>");
1018 /* Check if the supplied Classifier already exists */
1019 nClassifierIndex = GetClassifierEntry(
1020 pstServiceFlowEntry->pstClassifierTable,
1022 eActiveClassifierRuleContext,
1023 &pstClassifierEntry);
1025 if (nClassifierIndex == PHS_INVALID_TABLE_INDEX)
1028 The Classifier doesn't exist. So its a new classifier being added.
1029 Add new entry to associate PHS Rule to the Classifier
1032 uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable,
1034 eActiveClassifierRuleContext,
1040 The Classifier exists.The PHS Rule for this classifier
1044 if (pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI)
1046 if (pstClassifierEntry->pstPhsRule == NULL)
1047 return ERR_PHS_INVALID_PHS_RULE;
1050 This rule already exists if any fields are changed for this PHS
1053 /* If any part of PHSF is valid then we update PHSF */
1054 if (psPhsRule->u8PHSFLength)
1057 memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
1058 psPhsRule->u8PHSF, MAX_PHS_LENGTHS);
1061 if (psPhsRule->u8PHSFLength)
1064 pstClassifierEntry->pstPhsRule->u8PHSFLength = psPhsRule->u8PHSFLength;
1067 if (psPhsRule->u8PHSMLength)
1070 memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
1071 psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
1074 if (psPhsRule->u8PHSMLength)
1077 pstClassifierEntry->pstPhsRule->u8PHSMLength =
1078 psPhsRule->u8PHSMLength;
1081 if (psPhsRule->u8PHSS)
1084 pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS;
1088 pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV;
1093 A new rule is being set for this classifier.
1095 uiStatus = UpdateClassifierPHSRule(uiClsId, pstClassifierEntry,
1096 psaClassifiertable, psPhsRule, u8AssociatedPHSI);
1102 static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
1103 struct bcm_phs_classifier_table *psaClassifiertable,
1104 struct bcm_phs_rule *psPhsRule,
1105 enum bcm_phs_classifier_context eClsContext,
1106 B_UINT8 u8AssociatedPHSI)
1108 UINT iClassifierIndex = 0;
1109 BOOLEAN bFreeEntryFound = FALSE;
1110 struct bcm_phs_classifier_entry *psClassifierRules = NULL;
1111 UINT nStatus = PHS_SUCCESS;
1112 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1114 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "Inside CreateClassifierPHSRule");
1116 if (psaClassifiertable == NULL)
1118 return ERR_INVALID_CLASSIFIERTABLE_FOR_SF;
1121 if (eClsContext == eOldClassifierRuleContext)
1123 /* If An Old Entry for this classifier ID already exists in the
1124 old rules table replace it. */
1127 GetClassifierEntry(psaClassifiertable, uiClsId,
1128 eClsContext, &psClassifierRules);
1130 if (iClassifierIndex != PHS_INVALID_TABLE_INDEX)
1133 The Classifier already exists in the old rules table
1134 Lets replace the old classifier with the new one.
1136 bFreeEntryFound = TRUE;
1140 if (!bFreeEntryFound)
1143 Continue to search for a free location to add the rule
1145 for (iClassifierIndex = 0; iClassifierIndex <
1146 MAX_PHSRULE_PER_SF; iClassifierIndex++)
1148 if (eClsContext == eActiveClassifierRuleContext)
1150 psClassifierRules = &psaClassifiertable->stActivePhsRulesList[iClassifierIndex];
1154 psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
1157 if (!psClassifierRules->bUsed)
1159 bFreeEntryFound = TRUE;
1165 if (!bFreeEntryFound)
1167 if (eClsContext == eActiveClassifierRuleContext)
1169 return ERR_CLSASSIFIER_TABLE_FULL;
1173 //Lets replace the oldest rule if we are looking in old Rule table
1174 if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF)
1176 psaClassifiertable->uiOldestPhsRuleIndex = 0;
1179 iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex;
1180 psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
1182 (psaClassifiertable->uiOldestPhsRuleIndex)++;
1186 if (eClsContext == eOldClassifierRuleContext)
1188 if (psClassifierRules->pstPhsRule == NULL)
1190 psClassifierRules->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule), GFP_KERNEL);
1192 if (NULL == psClassifierRules->pstPhsRule)
1193 return ERR_PHSRULE_MEMALLOC_FAIL;
1196 psClassifierRules->bUsed = TRUE;
1197 psClassifierRules->uiClassifierRuleId = uiClsId;
1198 psClassifierRules->u8PHSI = psPhsRule->u8PHSI;
1199 psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
1201 /* Update The PHS rule */
1202 memcpy(psClassifierRules->pstPhsRule, psPhsRule, sizeof(struct bcm_phs_rule));
1206 nStatus = UpdateClassifierPHSRule(uiClsId, psClassifierRules,
1207 psaClassifiertable, psPhsRule, u8AssociatedPHSI);
1213 static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
1214 IN struct bcm_phs_classifier_entry *pstClassifierEntry,
1215 struct bcm_phs_classifier_table *psaClassifiertable,
1216 struct bcm_phs_rule *psPhsRule,
1217 B_UINT8 u8AssociatedPHSI)
1219 struct bcm_phs_rule *pstAddPhsRule = NULL;
1220 UINT nPhsRuleIndex = 0;
1221 BOOLEAN bPHSRuleOrphaned = FALSE;
1222 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1224 psPhsRule->u8RefCnt = 0;
1226 /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/
1227 bPHSRuleOrphaned = DerefPhsRule(uiClsId, psaClassifiertable,
1228 pstClassifierEntry->pstPhsRule);
1230 //Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF
1231 nPhsRuleIndex = GetPhsRuleEntry(psaClassifiertable, u8AssociatedPHSI,
1232 eActiveClassifierRuleContext, &pstAddPhsRule);
1233 if (PHS_INVALID_TABLE_INDEX == nPhsRuleIndex)
1235 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier");
1237 if (psPhsRule->u8PHSI == 0)
1239 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n");
1240 return ERR_PHS_INVALID_PHS_RULE;
1243 //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId
1244 if (FALSE == bPHSRuleOrphaned)
1246 pstClassifierEntry->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule), GFP_KERNEL);
1247 if (NULL == pstClassifierEntry->pstPhsRule)
1249 return ERR_PHSRULE_MEMALLOC_FAIL;
1252 memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(struct bcm_phs_rule));
1256 //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule
1257 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
1258 if (bPHSRuleOrphaned)
1260 kfree(pstClassifierEntry->pstPhsRule);
1261 pstClassifierEntry->pstPhsRule = NULL;
1263 pstClassifierEntry->pstPhsRule = pstAddPhsRule;
1266 pstClassifierEntry->bUsed = TRUE;
1267 pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI;
1268 pstClassifierEntry->uiClassifierRuleId = uiClsId;
1269 pstClassifierEntry->pstPhsRule->u8RefCnt++;
1270 pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;
1275 static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule)
1277 if (pstPhsRule == NULL)
1280 if (pstPhsRule->u8RefCnt)
1281 pstPhsRule->u8RefCnt--;
1283 if (0 == pstPhsRule->u8RefCnt)
1285 /*if(pstPhsRule->u8PHSI)
1286 //Store the currently active rule into the old rules list
1287 CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);*/
1296 void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension)
1299 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1301 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules :\n");
1303 for (i = 0; i < MAX_SERVICEFLOWS; i++)
1305 struct bcm_phs_entry stServFlowEntry =
1306 pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i];
1307 if (stServFlowEntry.bUsed)
1309 for (j = 0; j < MAX_PHSRULE_PER_SF; j++)
1311 for (l = 0; l < 2; l++)
1313 struct bcm_phs_classifier_entry stClsEntry;
1317 stClsEntry = stServFlowEntry.pstClassifierTable->stActivePhsRulesList[j];
1318 if (stClsEntry.bUsed)
1319 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule :\n");
1323 stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j];
1324 if (stClsEntry.bUsed)
1325 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule :\n");
1327 if (stClsEntry.bUsed)
1329 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X", stServFlowEntry.uiVcid);
1330 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X", stClsEntry.uiClassifierRuleId);
1331 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X", stClsEntry.u8PHSI);
1332 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n");
1333 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X", stClsEntry.pstPhsRule->u8PHSI);
1334 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ", stClsEntry.pstPhsRule->u8PHSFLength);
1335 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : ");
1337 for (k = 0 ; k < stClsEntry.pstPhsRule->u8PHSFLength; k++)
1339 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", stClsEntry.pstPhsRule->u8PHSF[k]);
1341 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X", stClsEntry.pstPhsRule->u8PHSMLength);
1342 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :");
1344 for (k = 0; k < stClsEntry.pstPhsRule->u8PHSMLength; k++)
1346 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", stClsEntry.pstPhsRule->u8PHSM[k]);
1348 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ", stClsEntry.pstPhsRule->u8PHSS);
1349 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X", stClsEntry.pstPhsRule->u8PHSV);
1350 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n");
1358 //-----------------------------------------------------------------------------
1359 // Procedure: phs_decompress
1361 // Description: This routine restores the static fields within the packet.
1364 // in_buf - ptr to incoming packet buffer.
1365 // out_buf - ptr to output buffer where the suppressed header is copied.
1366 // decomp_phs_rules - ptr to PHS rule.
1367 // header_size - ptr to field which holds the phss or phsf_length.
1370 // size -The number of bytes of dynamic fields present with in the incoming packet
1372 // 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed.
1373 //-----------------------------------------------------------------------------
1375 int phs_decompress(unsigned char *in_buf,
1376 unsigned char *out_buf,
1377 struct bcm_phs_rule *decomp_phs_rules,
1381 struct bcm_phs_rule *tmp_memb;
1383 unsigned char *phsf, *phsm;
1384 int in_buf_len = *header_size - 1;
1385 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1389 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "====>\n");
1392 if ((decomp_phs_rules == NULL))
1395 tmp_memb = decomp_phs_rules;
1396 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
1397 //*header_size = tmp_memb->u8PHSFLength;
1398 phss = tmp_memb->u8PHSS;
1399 phsf = tmp_memb->u8PHSF;
1400 phsm = tmp_memb->u8PHSM;
1402 if (phss > MAX_PHS_LENGTHS)
1403 phss = MAX_PHS_LENGTHS;
1405 //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));
1406 while ((phss > 0) && (size < in_buf_len))
1408 bit = ((*phsm << i) & SUPPRESS);
1410 if (bit == SUPPRESS)
1413 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nDECOMP:In phss %d phsf %d ouput %d",
1414 phss, *phsf, *out_buf);
1419 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nDECOMP:In phss %d input %d ouput %d",
1420 phss, *in_buf, *out_buf);
1428 *header_size = *header_size + 1;
1440 //-----------------------------------------------------------------------------
1441 // Procedure: phs_compress
1443 // Description: This routine suppresses the static fields within the packet.Before
1444 // that it will verify the fields to be suppressed with the corresponding fields in the
1445 // phsf. For verification it checks the phsv field of PHS rule. If set and verification
1446 // succeeds it suppresses the field.If any one static field is found different none of
1447 // the static fields are suppressed then the packet is sent as uncompressed packet with
1451 // phs_rule - ptr to PHS rule.
1452 // in_buf - ptr to incoming packet buffer.
1453 // out_buf - ptr to output buffer where the suppressed header is copied.
1454 // header_size - ptr to field which holds the phss.
1457 // size-The number of bytes copied into the output buffer i.e dynamic fields
1458 // 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails.
1459 //-----------------------------------------------------------------------------
1460 static int phs_compress(struct bcm_phs_rule *phs_rule,
1461 unsigned char *in_buf,
1462 unsigned char *out_buf,
1464 UINT *new_header_size)
1466 unsigned char *old_addr = out_buf;
1468 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1470 if (phs_rule == NULL)
1472 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nphs_compress(): phs_rule null!");
1473 *out_buf = ZERO_PHSI;
1474 return STATUS_PHS_NOCOMPRESSION;
1477 if (phs_rule->u8PHSS <= *new_header_size)
1479 *header_size = phs_rule->u8PHSS;
1483 *header_size = *new_header_size;
1488 suppress = verify_suppress_phsf(in_buf, out_buf, phs_rule->u8PHSF,
1489 phs_rule->u8PHSM, phs_rule->u8PHSS,
1490 phs_rule->u8PHSV, new_header_size);
1492 if (suppress == STATUS_PHS_COMPRESSED)
1494 *old_addr = (unsigned char)phs_rule->u8PHSI;
1495 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In phs_compress phsi %d", phs_rule->u8PHSI);
1499 *old_addr = ZERO_PHSI;
1500 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In phs_compress PHSV Verification failed");
1506 //-----------------------------------------------------------------------------
1507 // Procedure: verify_suppress_phsf
1509 // Description: This routine verifies the fields of the packet and if all the
1510 // static fields are equal it adds the phsi of that PHS rule.If any static
1511 // field differs it woun't suppress any field.
1514 // rules_set - ptr to classifier_rules.
1515 // in_buffer - ptr to incoming packet buffer.
1516 // out_buffer - ptr to output buffer where the suppressed header is copied.
1517 // phsf - ptr to phsf.
1518 // phsm - ptr to phsm.
1519 // phss - variable holding phss.
1522 // size-The number of bytes copied into the output buffer i.e dynamic fields.
1523 // 0 -Packet has failed the verification.
1524 //-----------------------------------------------------------------------------
1526 static int verify_suppress_phsf(unsigned char *in_buffer,
1527 unsigned char *out_buffer,
1528 unsigned char *phsf,
1529 unsigned char *phsm,
1532 UINT *new_header_size)
1534 unsigned int size = 0;
1536 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
1538 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In verify_phsf PHSM - 0x%X", *phsm);
1540 if (phss > (*new_header_size))
1542 phss = *new_header_size;
1547 bit = ((*phsm << i) & SUPPRESS);
1548 if (bit == SUPPRESS)
1550 if (*in_buffer != *phsf)
1554 BCM_DEBUG_PRINT(Adapter,
1558 "\nCOMP:In verify_phsf failed for field %d buf %d phsf %d",
1562 return STATUS_PHS_NOCOMPRESSION;
1566 BCM_DEBUG_PRINT(Adapter,
1570 "\nCOMP:In verify_phsf success for field %d buf %d phsf %d",
1577 *out_buffer = *in_buffer;
1578 BCM_DEBUG_PRINT(Adapter,
1582 "\nCOMP:In copying_header input %d out %d",
1600 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In verify_phsf success");
1601 *new_header_size = size;
1602 return STATUS_PHS_COMPRESSED;