diff options
Diffstat (limited to 'drivers/staging/bcm/PHSModule.c')
-rw-r--r-- | drivers/staging/bcm/PHSModule.c | 1703 |
1 files changed, 0 insertions, 1703 deletions
diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c deleted file mode 100644 index 5f4e503d54ec..000000000000 --- a/drivers/staging/bcm/PHSModule.c +++ /dev/null @@ -1,1703 +0,0 @@ -#include "headers.h" - -static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid, - B_UINT16 uiClsId, - struct bcm_phs_table *psServiceFlowTable, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI); - -static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid, - B_UINT16 uiClsId, - struct bcm_phs_entry *pstServiceFlowEntry, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI); - -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); - -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); - -static bool ValidatePHSRuleComplete(const struct bcm_phs_rule *psPhsRule); - -static bool DerefPhsRule(B_UINT16 uiClsId, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *pstPhsRule); - -static UINT GetClassifierEntry(struct bcm_phs_classifier_table *pstClassifierTable, - B_UINT32 uiClsid, - enum bcm_phs_classifier_context eClsContext, - struct bcm_phs_classifier_entry **ppstClassifierEntry); - -static UINT GetPhsRuleEntry(struct bcm_phs_classifier_table *pstClassifierTable, - B_UINT32 uiPHSI, - enum bcm_phs_classifier_context eClsContext, - struct bcm_phs_rule **ppstPhsRule); - -static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable); - -static int phs_compress(struct bcm_phs_rule *phs_members, - unsigned char *in_buf, - unsigned char *out_buf, - unsigned int *header_size, - UINT *new_header_size); - -static int verify_suppress_phsf(unsigned char *in_buffer, - unsigned char *out_buffer, - unsigned char *phsf, - unsigned char *phsm, - unsigned int phss, - unsigned int phsv, - UINT *new_header_size); - -static int phs_decompress(unsigned char *in_buf, - unsigned char *out_buf, - struct bcm_phs_rule *phs_rules, - UINT *header_size); - -static ULONG PhsCompress(void *pvContext, - B_UINT16 uiVcid, - B_UINT16 uiClsId, - void *pvInputBuffer, - void *pvOutputBuffer, - UINT *pOldHeaderSize, - UINT *pNewHeaderSize); - -static ULONG PhsDeCompress(void *pvContext, - B_UINT16 uiVcid, - void *pvInputBuffer, - void *pvOutputBuffer, - UINT *pInHeaderSize, - UINT *pOutHeaderSize); - -#define IN -#define OUT - -/* - * Function: PHSTransmit - * Description: This routine handle PHS(Payload Header Suppression for Tx path. - * It extracts a fragment of the NDIS_PACKET containing the header - * to be suppressed. It then suppresses the header by invoking PHS exported compress routine. - * The header data after suppression is copied back to the NDIS_PACKET. - * - * Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context - * IN Packet - NDIS packet containing data to be transmitted - * IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to - * identify PHS rule to be applied. - * B_UINT16 uiClassifierRuleID - Classifier Rule ID - * BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF. - * - * Return: STATUS_SUCCESS - If the send was successful. - * Other - If an error occurred. - */ - -int PHSTransmit(struct bcm_mini_adapter *Adapter, - struct sk_buff **pPacket, - USHORT Vcid, - B_UINT16 uiClassifierRuleID, - bool bHeaderSuppressionEnabled, - UINT *PacketLen, - UCHAR bEthCSSupport) -{ - /* PHS Sepcific */ - UINT unPHSPktHdrBytesCopied = 0; - UINT unPhsOldHdrSize = 0; - UINT unPHSNewPktHeaderLen = 0; - /* Pointer to PHS IN Hdr Buffer */ - PUCHAR pucPHSPktHdrInBuf = - Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf; - /* Pointer to PHS OUT Hdr Buffer */ - PUCHAR pucPHSPktHdrOutBuf = - Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf; - UINT usPacketType; - UINT BytesToRemove = 0; - bool bPHSI = 0; - LONG ulPhsStatus = 0; - UINT numBytesCompressed = 0; - struct sk_buff *newPacket = NULL; - struct sk_buff *Packet = *pPacket; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "In PHSTransmit"); - - if (!bEthCSSupport) - BytesToRemove = ETH_HLEN; - /* - * Accumulate the header upto the size we support suppression - * from NDIS packet - */ - - usPacketType = ((struct ethhdr *)(Packet->data))->h_proto; - - pucPHSPktHdrInBuf = Packet->data + BytesToRemove; - /* considering data after ethernet header */ - if ((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS) - unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove); - else - unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS; - - if ((unPHSPktHdrBytesCopied > 0) && - (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) { - - /* - * Step 2 Suppress Header using PHS and fill into intermediate - * ucaPHSPktHdrOutBuf. - * Suppress only if IP Header and PHS Enabled For the - * Service Flow - */ - if (((usPacketType == ETHERNET_FRAMETYPE_IPV4) || - (usPacketType == ETHERNET_FRAMETYPE_IPV6)) && - (bHeaderSuppressionEnabled)) { - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, - DBG_LVL_ALL, - "\nTrying to PHS Compress Using Classifier rule 0x%X", - uiClassifierRuleID); - unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied; - ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext, - Vcid, - uiClassifierRuleID, - pucPHSPktHdrInBuf, - pucPHSPktHdrOutBuf, - &unPhsOldHdrSize, - &unPHSNewPktHeaderLen); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, - DBG_LVL_ALL, - "\nPHS Old header Size : %d New Header Size %d\n", - unPhsOldHdrSize, unPHSNewPktHeaderLen); - - if (unPHSNewPktHeaderLen == unPhsOldHdrSize) { - - if (ulPhsStatus == STATUS_PHS_COMPRESSED) - bPHSI = *pucPHSPktHdrOutBuf; - - ulPhsStatus = STATUS_PHS_NOCOMPRESSION; - } - - if (ulPhsStatus == STATUS_PHS_COMPRESSED) { - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - PHS_SEND, DBG_LVL_ALL, - "PHS Sending packet Compressed"); - - if (skb_cloned(Packet)) { - newPacket = - skb_copy(Packet, GFP_ATOMIC); - - if (newPacket == NULL) - return STATUS_FAILURE; - - dev_kfree_skb(Packet); - *pPacket = Packet = newPacket; - pucPHSPktHdrInBuf = - Packet->data + BytesToRemove; - } - - numBytesCompressed = unPhsOldHdrSize - - (unPHSNewPktHeaderLen + PHSI_LEN); - - memcpy(pucPHSPktHdrInBuf + numBytesCompressed, - pucPHSPktHdrOutBuf, - unPHSNewPktHeaderLen + PHSI_LEN); - memcpy(Packet->data + numBytesCompressed, - Packet->data, BytesToRemove); - skb_pull(Packet, numBytesCompressed); - - return STATUS_SUCCESS; - } else { - /* if one byte headroom is not available, - * increase it through skb_cow - */ - if (!(skb_headroom(Packet) > 0)) { - - if (skb_cow(Packet, 1)) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_PRINTK, - 0, 0, - "SKB Cow Failed\n"); - return STATUS_FAILURE; - } - } - skb_push(Packet, 1); - - /* - * CAUTION: The MAC Header is getting corrupted - * here for IP CS - can be saved by copying 14 - * Bytes. not needed .... hence corrupting it. - */ - *(Packet->data + BytesToRemove) = bPHSI; - return STATUS_SUCCESS; - } - } else { - - if (!bHeaderSuppressionEnabled) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - PHS_SEND, DBG_LVL_ALL, - "\nHeader Suppression Disabled For SF: No PHS\n"); - - return STATUS_SUCCESS; - } - } - - /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - * "PHSTransmit : Dumping data packet After PHS"); */ - return STATUS_SUCCESS; -} - -int PHSReceive(struct bcm_mini_adapter *Adapter, - USHORT usVcid, - struct sk_buff *packet, - UINT *punPacketLen, - UCHAR *pucEthernetHdr, - UINT bHeaderSuppressionEnabled) -{ - u32 nStandardPktHdrLen = 0; - u32 nTotalsuppressedPktHdrBytes = 0; - int ulPhsStatus = 0; - PUCHAR pucInBuff = NULL; - UINT TotalBytesAdded = 0; - - if (!bHeaderSuppressionEnabled) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, - "\nPhs Disabled for incoming packet"); - return ulPhsStatus; - } - - pucInBuff = packet->data; - - /* Restore PHS suppressed header */ - nStandardPktHdrLen = packet->len; - ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext, - usVcid, - pucInBuff, - Adapter->ucaPHSPktRestoreBuf, - &nTotalsuppressedPktHdrBytes, - &nStandardPktHdrLen); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, - "\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", - nTotalsuppressedPktHdrBytes, nStandardPktHdrLen); - - if (ulPhsStatus != STATUS_PHS_COMPRESSED) { - skb_pull(packet, 1); - return STATUS_SUCCESS; - } else { - TotalBytesAdded = nStandardPktHdrLen - - nTotalsuppressedPktHdrBytes - PHSI_LEN; - - if (TotalBytesAdded) { - if (skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded)) - skb_push(packet, TotalBytesAdded); - else { - if (skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_PRINTK, 0, 0, - "cow failed in receive\n"); - return STATUS_FAILURE; - } - - skb_push(packet, TotalBytesAdded); - } - } - - memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, - nStandardPktHdrLen); - } - - return STATUS_SUCCESS; -} - -void DumpFullPacket(UCHAR *pBuf, UINT nPktLen) -{ - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, - "Dumping Data Packet"); - BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, - pBuf, nPktLen); -} - -/* - * Procedure: phs_init - * - * Description: This routine is responsible for allocating memory for classifier - * and PHS rules. - * - * Arguments: - * pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules - * and PHS Rules , RX, TX buffer etc - * - * Returns: - * TRUE(1) -If allocation of memory was successful. - * FALSE -If allocation of memory fails. - */ -int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, - struct bcm_mini_adapter *Adapter) -{ - int i; - struct bcm_phs_table *pstServiceFlowTable; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "\nPHS:phs_init function"); - - if (pPhsdeviceExtension->pstServiceFlowPhsRulesTable) - return -EINVAL; - - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = - kzalloc(sizeof(struct bcm_phs_table), GFP_KERNEL); - - if (!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, - "\nAllocation ServiceFlowPhsRulesTable failed"); - return -ENOMEM; - } - - pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable; - for (i = 0; i < MAX_SERVICEFLOWS; i++) { - struct bcm_phs_entry sServiceFlow = - pstServiceFlowTable->stSFList[i]; - sServiceFlow.pstClassifierTable = - kzalloc(sizeof(struct bcm_phs_classifier_table), - GFP_KERNEL); - if (!sServiceFlow.pstClassifierTable) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "\nAllocation failed"); - free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; - return -ENOMEM; - } - } - - pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); - if (pPhsdeviceExtension->CompressedTxBuffer == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "\nAllocation failed"); - free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; - return -ENOMEM; - } - - pPhsdeviceExtension->UnCompressedRxBuffer = - kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); - if (pPhsdeviceExtension->UnCompressedRxBuffer == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "\nAllocation failed"); - kfree(pPhsdeviceExtension->CompressedTxBuffer); - free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; - return -ENOMEM; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "\n phs_init Successful"); - return STATUS_SUCCESS; -} - -int PhsCleanup(IN struct bcm_phs_extension *pPHSDeviceExt) -{ - if (pPHSDeviceExt->pstServiceFlowPhsRulesTable) { - free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable); - pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL; - } - - kfree(pPHSDeviceExt->CompressedTxBuffer); - pPHSDeviceExt->CompressedTxBuffer = NULL; - - kfree(pPHSDeviceExt->UnCompressedRxBuffer); - pPHSDeviceExt->UnCompressedRxBuffer = NULL; - - return 0; -} - -/* - * PHS functions - * PhsUpdateClassifierRule - * - * Routine Description: - * Exported function to add or modify a PHS Rule. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context - * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies - * IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. - * IN struct bcm_phs_rule *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table. - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -ULONG PhsUpdateClassifierRule(IN void *pvContext, - IN B_UINT16 uiVcid , - IN B_UINT16 uiClsId , - IN struct bcm_phs_rule *psPhsRule, - IN B_UINT8 u8AssociatedPHSI) -{ - ULONG lStatus = 0; - UINT nSFIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "PHS With Corr2 Changes\n"); - - if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "Invalid Device Extension\n"); - return ERR_PHS_INVALID_DEVICE_EXETENSION; - } - - if (u8AssociatedPHSI == 0) - return ERR_PHS_INVALID_PHS_RULE; - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - /* This is a new SF. Create a mapping entry for this */ - lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId, - pDeviceExtension->pstServiceFlowPhsRulesTable, - psPhsRule, - u8AssociatedPHSI); - return lStatus; - } - - /* SF already Exists Add PHS Rule to existing SF */ - lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId, - pstServiceFlowEntry, - psPhsRule, - u8AssociatedPHSI); - - return lStatus; -} - -/* - * PhsDeletePHSRule - * - * Routine Description: - * Deletes the specified phs Rule within Vcid - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context - * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies - * IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted. - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -ULONG PhsDeletePHSRule(IN void *pvContext, - IN B_UINT16 uiVcid, - IN B_UINT8 u8PHSI) -{ - UINT nSFIndex = 0, nClsidIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; - struct bcm_phs_classifier_entry *curr_entry; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "======>\n"); - - if (pDeviceExtension) { - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "SFID Match Failed\n"); - return ERR_SF_MATCH_FAIL; - } - - pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable; - if (pstClassifierRulesTable) { - for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) { - curr_entry = &pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]; - if (curr_entry->bUsed && - curr_entry->pstPhsRule && - (curr_entry->pstPhsRule->u8PHSI == u8PHSI)) { - - if (curr_entry->pstPhsRule->u8RefCnt) - curr_entry->pstPhsRule->u8RefCnt--; - - if (0 == curr_entry->pstPhsRule->u8RefCnt) - kfree(curr_entry->pstPhsRule); - - memset(curr_entry, - 0, - sizeof(struct bcm_phs_classifier_entry)); - } - } - } - } - return 0; -} - -/* - * PhsDeleteClassifierRule - * - * Routine Description: - * Exported function to Delete a PHS Rule for the SFID,CLSID Pair. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context - * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies - * IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -ULONG PhsDeleteClassifierRule(IN void *pvContext, - IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId) -{ - UINT nSFIndex = 0, nClsidIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_classifier_entry *pstClassifierEntry = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - - if (!pDeviceExtension) - goto out; - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "SFID Match Failed\n"); - return ERR_SF_MATCH_FAIL; - } - - nClsidIndex = - GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, - uiClsId, - eActiveClassifierRuleContext, - &pstClassifierEntry); - - if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && - (!pstClassifierEntry->bUnclassifiedPHSRule)) { - if (pstClassifierEntry->pstPhsRule) { - if (pstClassifierEntry->pstPhsRule->u8RefCnt) - pstClassifierEntry->pstPhsRule->u8RefCnt--; - - if (0 == pstClassifierEntry->pstPhsRule->u8RefCnt) - kfree(pstClassifierEntry->pstPhsRule); - } - memset(pstClassifierEntry, 0, - sizeof(struct bcm_phs_classifier_entry)); - } - - nClsidIndex = - GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, - uiClsId, - eOldClassifierRuleContext, - &pstClassifierEntry); - - if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && - (!pstClassifierEntry->bUnclassifiedPHSRule)) { - kfree(pstClassifierEntry->pstPhsRule); - memset(pstClassifierEntry, 0, - sizeof(struct bcm_phs_classifier_entry)); - } - -out: - return 0; -} - -/* - * PhsDeleteSFRules - * - * Routine Description: - * Exported function to Delete a all PHS Rules for the SFID. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context - * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid) -{ - UINT nSFIndex = 0, nClsidIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - struct bcm_phs_classifier_entry *curr_clsf_entry; - struct bcm_phs_classifier_entry *curr_rules_list; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "====>\n"); - - if (!pDeviceExtension) - goto out; - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "SFID Match Failed\n"); - return ERR_SF_MATCH_FAIL; - } - - pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable; - if (pstClassifierRulesTable) { - for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) { - curr_clsf_entry = - &pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]; - - curr_rules_list = - &pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]; - - if (curr_clsf_entry->pstPhsRule) { - - if (curr_clsf_entry->pstPhsRule->u8RefCnt) - curr_clsf_entry->pstPhsRule->u8RefCnt--; - - if (0 == curr_clsf_entry->pstPhsRule->u8RefCnt) - kfree(curr_clsf_entry->pstPhsRule); - - curr_clsf_entry->pstPhsRule = NULL; - } - memset(curr_clsf_entry, 0, - sizeof(struct bcm_phs_classifier_entry)); - if (curr_rules_list->pstPhsRule) { - - if (curr_rules_list->pstPhsRule->u8RefCnt) - curr_rules_list->pstPhsRule->u8RefCnt--; - - if (0 == curr_rules_list->pstPhsRule->u8RefCnt) - kfree(curr_rules_list->pstPhsRule); - - curr_rules_list->pstPhsRule = NULL; - } - memset(curr_rules_list, 0, - sizeof(struct bcm_phs_classifier_entry)); - } - } - pstServiceFlowEntry->bUsed = false; - pstServiceFlowEntry->uiVcid = 0; - -out: - return 0; -} - -/* - * PhsCompress - * - * Routine Description: - * Exported function to compress the data using PHS. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context. - * IN B_UINT16 uiVcid - The Service Flow ID to which current - * packet header compression applies. - * IN UINT uiClsId - The Classifier ID to which current packet - * header compression applies. - * IN void *pvInputBuffer - The Input buffer containg packet header - * data - * IN void *pvOutputBuffer - The output buffer returned by this - * function after PHS - * IN UINT *pOldHeaderSize - The actual size of the header before PHS - * IN UINT *pNewHeaderSize - The new size of the header after applying - * PHS - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -static ULONG PhsCompress(IN void *pvContext, - IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId, - IN void *pvInputBuffer, - OUT void *pvOutputBuffer, - OUT UINT *pOldHeaderSize, - OUT UINT *pNewHeaderSize) -{ - UINT nSFIndex = 0, nClsidIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_classifier_entry *pstClassifierEntry = NULL; - struct bcm_phs_rule *pstPhsRule = NULL; - ULONG lStatus = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - - if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "Invalid Device Extension\n"); - lStatus = STATUS_PHS_NOCOMPRESSION; - return lStatus; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "Suppressing header\n"); - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "SFID Match Failed\n"); - lStatus = STATUS_PHS_NOCOMPRESSION; - return lStatus; - } - - nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, - uiClsId, eActiveClassifierRuleContext, - &pstClassifierEntry); - - if (nClsidIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "No PHS Rule Defined For Classifier\n"); - lStatus = STATUS_PHS_NOCOMPRESSION; - return lStatus; - } - - /* get rule from SF id,Cls ID pair and proceed */ - pstPhsRule = pstClassifierEntry->pstPhsRule; - if (!ValidatePHSRuleComplete(pstPhsRule)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "PHS Rule Defined For Classifier But Not Complete\n"); - lStatus = STATUS_PHS_NOCOMPRESSION; - return lStatus; - } - - /* Compress Packet */ - lStatus = phs_compress(pstPhsRule, - (PUCHAR)pvInputBuffer, - (PUCHAR)pvOutputBuffer, - pOldHeaderSize, - pNewHeaderSize); - - if (lStatus == STATUS_PHS_COMPRESSED) { - pstPhsRule->PHSModifiedBytes += - *pOldHeaderSize - *pNewHeaderSize - 1; - pstPhsRule->PHSModifiedNumPackets++; - } else { - pstPhsRule->PHSErrorNumPackets++; - } - - return lStatus; -} - -/* - * PhsDeCompress - * - * Routine Description: - * Exported function to restore the packet header in Rx path. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context. - * IN B_UINT16 uiVcid - The Service Flow ID to which current - * packet header restoration applies. - * IN void *pvInputBuffer - The Input buffer containg suppressed - * packet header data - * OUT void *pvOutputBuffer - The output buffer returned by this - * function after restoration - * OUT UINT *pHeaderSize - The packet header size after restoration - * is returned in this parameter. - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -static ULONG PhsDeCompress(IN void *pvContext, - IN B_UINT16 uiVcid, - IN void *pvInputBuffer, - OUT void *pvOutputBuffer, - OUT UINT *pInHeaderSize, - OUT UINT *pOutHeaderSize) -{ - UINT nSFIndex = 0, nPhsRuleIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_rule *pstPhsRule = NULL; - UINT phsi; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - - *pInHeaderSize = 0; - if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, "Invalid Device Extension\n"); - return ERR_PHS_INVALID_DEVICE_EXETENSION; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, - "Restoring header\n"); - - phsi = *((unsigned char *)(pvInputBuffer)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, - "PHSI To Be Used For restore : %x\n", phsi); - if (phsi == UNCOMPRESSED_PACKET) - return STATUS_PHS_NOCOMPRESSION; - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, - "SFID Match Failed During Lookup\n"); - return ERR_SF_MATCH_FAIL; - } - - nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, - phsi, - eActiveClassifierRuleContext, - &pstPhsRule); - if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) { - /* Phs Rule does not exist in active rules table. Lets try - * in the old rules table. */ - nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, - phsi, - eOldClassifierRuleContext, - &pstPhsRule); - if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) - return ERR_PHSRULE_MATCH_FAIL; - } - - *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer, - (PUCHAR)pvOutputBuffer, - pstPhsRule, - pOutHeaderSize); - - pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1; - - pstPhsRule->PHSModifiedNumPackets++; - return STATUS_PHS_COMPRESSED; -} - -/* - * Procedure: free_phs_serviceflow_rules - * - * Description: This routine is responsible for freeing memory allocated for - * PHS rules. - * - * Arguments: - * rules - ptr to S_SERVICEFLOW_TABLE structure. - * - * Returns: - * Does not return any value. - */ -static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable) -{ - int i, j; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_classifier_entry *curr_act_rules_list; - struct bcm_phs_classifier_entry *curr_old_rules_list; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "=======>\n"); - - if (!psServiceFlowRulesTable) - goto out; - - for (i = 0; i < MAX_SERVICEFLOWS; i++) { - struct bcm_phs_entry stServiceFlowEntry = - psServiceFlowRulesTable->stSFList[i]; - struct bcm_phs_classifier_table *pstClassifierRulesTable = - stServiceFlowEntry.pstClassifierTable; - - if (pstClassifierRulesTable) { - for (j = 0; j < MAX_PHSRULE_PER_SF; j++) { - curr_act_rules_list = - &pstClassifierRulesTable->stActivePhsRulesList[j]; - - curr_old_rules_list = - &pstClassifierRulesTable->stOldPhsRulesList[j]; - - if (curr_act_rules_list->pstPhsRule) { - - if (curr_act_rules_list->pstPhsRule->u8RefCnt) - curr_act_rules_list->pstPhsRule->u8RefCnt--; - - if (0 == curr_act_rules_list->pstPhsRule->u8RefCnt) - kfree(curr_act_rules_list->pstPhsRule); - - curr_act_rules_list->pstPhsRule = NULL; - } - - if (curr_old_rules_list->pstPhsRule) { - - if (curr_old_rules_list->pstPhsRule->u8RefCnt) - curr_old_rules_list->pstPhsRule->u8RefCnt--; - - if (0 == curr_old_rules_list->pstPhsRule->u8RefCnt) - kfree(curr_old_rules_list->pstPhsRule); - - curr_old_rules_list->pstPhsRule = NULL; - } - } - kfree(pstClassifierRulesTable); - stServiceFlowEntry.pstClassifierTable = - pstClassifierRulesTable = NULL; - } - } - -out: - - kfree(psServiceFlowRulesTable); - psServiceFlowRulesTable = NULL; -} - -static bool ValidatePHSRuleComplete(IN const struct bcm_phs_rule *psPhsRule) -{ - return (psPhsRule && - psPhsRule->u8PHSI && - psPhsRule->u8PHSS && - psPhsRule->u8PHSFLength); -} - -UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable, - IN B_UINT16 uiVcid, - struct bcm_phs_entry **ppstServiceFlowEntry) -{ - int i; - struct bcm_phs_entry *curr_sf_list; - - for (i = 0; i < MAX_SERVICEFLOWS; i++) { - curr_sf_list = &psServiceFlowTable->stSFList[i]; - if (curr_sf_list->bUsed && (curr_sf_list->uiVcid == uiVcid)) { - *ppstServiceFlowEntry = curr_sf_list; - return i; - } - } - - *ppstServiceFlowEntry = NULL; - return PHS_INVALID_TABLE_INDEX; -} - -static UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable, - IN B_UINT32 uiClsid, - enum bcm_phs_classifier_context eClsContext, - OUT struct bcm_phs_classifier_entry **ppstClassifierEntry) -{ - int i; - struct bcm_phs_classifier_entry *psClassifierRules = NULL; - - for (i = 0; i < MAX_PHSRULE_PER_SF; i++) { - - if (eClsContext == eActiveClassifierRuleContext) - psClassifierRules = - &pstClassifierTable->stActivePhsRulesList[i]; - else - psClassifierRules = - &pstClassifierTable->stOldPhsRulesList[i]; - - if (psClassifierRules->bUsed && - (psClassifierRules->uiClassifierRuleId == uiClsid)) { - *ppstClassifierEntry = psClassifierRules; - return i; - } - } - - *ppstClassifierEntry = NULL; - return PHS_INVALID_TABLE_INDEX; -} - -static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTable, - IN B_UINT32 uiPHSI, - enum bcm_phs_classifier_context eClsContext, - OUT struct bcm_phs_rule **ppstPhsRule) -{ - int i; - struct bcm_phs_classifier_entry *pstClassifierRule = NULL; - - for (i = 0; i < MAX_PHSRULE_PER_SF; i++) { - if (eClsContext == eActiveClassifierRuleContext) - pstClassifierRule = - &pstClassifierTable->stActivePhsRulesList[i]; - else - pstClassifierRule = - &pstClassifierTable->stOldPhsRulesList[i]; - - if (pstClassifierRule->bUsed && - (pstClassifierRule->u8PHSI == uiPHSI)) { - *ppstPhsRule = pstClassifierRule->pstPhsRule; - return i; - } - } - - *ppstPhsRule = NULL; - return PHS_INVALID_TABLE_INDEX; -} - -static UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId, - IN struct bcm_phs_table *psServiceFlowTable, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI) -{ - struct bcm_phs_classifier_table *psaClassifiertable = NULL; - UINT uiStatus = 0; - int iSfIndex; - bool bFreeEntryFound = false; - struct bcm_phs_entry *curr_list; - - /* Check for a free entry in SFID table */ - for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++) { - curr_list = &psServiceFlowTable->stSFList[iSfIndex]; - if (!curr_list->bUsed) { - bFreeEntryFound = TRUE; - break; - } - } - - if (!bFreeEntryFound) - return ERR_SFTABLE_FULL; - - psaClassifiertable = curr_list->pstClassifierTable; - uiStatus = CreateClassifierPHSRule(uiClsId, - psaClassifiertable, - psPhsRule, - eActiveClassifierRuleContext, - u8AssociatedPHSI); - if (uiStatus == PHS_SUCCESS) { - /* Add entry at free index to the SF */ - curr_list->bUsed = TRUE; - curr_list->uiVcid = uiVcid; - } - - return uiStatus; -} - -static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId, - IN struct bcm_phs_entry *pstServiceFlowEntry, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI) -{ - struct bcm_phs_classifier_entry *pstClassifierEntry = NULL; - UINT uiStatus = PHS_SUCCESS; - UINT nClassifierIndex = 0; - struct bcm_phs_classifier_table *psaClassifiertable = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - psaClassifiertable = pstServiceFlowEntry->pstClassifierTable; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "==>"); - - /* Check if the supplied Classifier already exists */ - nClassifierIndex = GetClassifierEntry( - pstServiceFlowEntry->pstClassifierTable, - uiClsId, - eActiveClassifierRuleContext, - &pstClassifierEntry); - - if (nClassifierIndex == PHS_INVALID_TABLE_INDEX) { - /* - * The Classifier doesn't exist. So its a new classifier being - * added. - * Add new entry to associate PHS Rule to the Classifier - */ - - uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable, - psPhsRule, - eActiveClassifierRuleContext, - u8AssociatedPHSI); - return uiStatus; - } - - /* - * The Classifier exists.The PHS Rule for this classifier - * is being modified - */ - - if (pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) { - if (pstClassifierEntry->pstPhsRule == NULL) - return ERR_PHS_INVALID_PHS_RULE; - - /* - * This rule already exists if any fields are changed for this - * PHS rule update them. - */ - /* If any part of PHSF is valid then we update PHSF */ - if (psPhsRule->u8PHSFLength) { - /* update PHSF */ - memcpy(pstClassifierEntry->pstPhsRule->u8PHSF, - psPhsRule->u8PHSF, - MAX_PHS_LENGTHS); - } - - if (psPhsRule->u8PHSFLength) { - /* update PHSFLen */ - pstClassifierEntry->pstPhsRule->u8PHSFLength = - psPhsRule->u8PHSFLength; - } - - if (psPhsRule->u8PHSMLength) { - /* update PHSM */ - memcpy(pstClassifierEntry->pstPhsRule->u8PHSM, - psPhsRule->u8PHSM, - MAX_PHS_LENGTHS); - } - - if (psPhsRule->u8PHSMLength) { - /* update PHSM Len */ - pstClassifierEntry->pstPhsRule->u8PHSMLength = - psPhsRule->u8PHSMLength; - } - - if (psPhsRule->u8PHSS) { - /* update PHSS */ - pstClassifierEntry->pstPhsRule->u8PHSS = - psPhsRule->u8PHSS; - } - - /* update PHSV */ - pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV; - } else { - /* A new rule is being set for this classifier. */ - uiStatus = UpdateClassifierPHSRule(uiClsId, - pstClassifierEntry, - psaClassifiertable, - psPhsRule, - u8AssociatedPHSI); - } - - return uiStatus; -} - -static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *psPhsRule, - enum bcm_phs_classifier_context eClsContext, - B_UINT8 u8AssociatedPHSI) -{ - UINT iClassifierIndex = 0; - bool bFreeEntryFound = false; - struct bcm_phs_classifier_entry *psClassifierRules = NULL; - UINT nStatus = PHS_SUCCESS; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "Inside CreateClassifierPHSRule"); - - if (psaClassifiertable == NULL) - return ERR_INVALID_CLASSIFIERTABLE_FOR_SF; - - if (eClsContext == eOldClassifierRuleContext) { - /* - * If An Old Entry for this classifier ID already exists in the - * old rules table replace it. - */ - - iClassifierIndex = GetClassifierEntry(psaClassifiertable, - uiClsId, - eClsContext, - &psClassifierRules); - - if (iClassifierIndex != PHS_INVALID_TABLE_INDEX) { - /* - * The Classifier already exists in the old rules table - * Lets replace the old classifier with the new one. - */ - bFreeEntryFound = TRUE; - } - } - - if (!bFreeEntryFound) { - /* Continue to search for a free location to add the rule */ - for (iClassifierIndex = 0; iClassifierIndex < - MAX_PHSRULE_PER_SF; iClassifierIndex++) { - if (eClsContext == eActiveClassifierRuleContext) - psClassifierRules = &psaClassifiertable->stActivePhsRulesList[iClassifierIndex]; - else - psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; - - if (!psClassifierRules->bUsed) { - bFreeEntryFound = TRUE; - break; - } - } - } - - if (!bFreeEntryFound) { - - if (eClsContext == eActiveClassifierRuleContext) - return ERR_CLSASSIFIER_TABLE_FULL; - else { - /* Lets replace the oldest rule if we are looking in - * old Rule table */ - if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF) - psaClassifiertable->uiOldestPhsRuleIndex = 0; - - iClassifierIndex = - psaClassifiertable->uiOldestPhsRuleIndex; - psClassifierRules = - &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; - - (psaClassifiertable->uiOldestPhsRuleIndex)++; - } - } - - if (eClsContext == eOldClassifierRuleContext) { - - if (psClassifierRules->pstPhsRule == NULL) { - - psClassifierRules->pstPhsRule = - kmalloc(sizeof(struct bcm_phs_rule), - GFP_KERNEL); - - if (NULL == psClassifierRules->pstPhsRule) - return ERR_PHSRULE_MEMALLOC_FAIL; - } - - psClassifierRules->bUsed = TRUE; - psClassifierRules->uiClassifierRuleId = uiClsId; - psClassifierRules->u8PHSI = psPhsRule->u8PHSI; - psClassifierRules->bUnclassifiedPHSRule = - psPhsRule->bUnclassifiedPHSRule; - - /* Update The PHS rule */ - memcpy(psClassifierRules->pstPhsRule, psPhsRule, - sizeof(struct bcm_phs_rule)); - } else - nStatus = UpdateClassifierPHSRule(uiClsId, - psClassifierRules, - psaClassifiertable, - psPhsRule, - u8AssociatedPHSI); - - return nStatus; -} - -static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, - IN struct bcm_phs_classifier_entry *pstClassifierEntry, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI) -{ - struct bcm_phs_rule *pstAddPhsRule = NULL; - UINT nPhsRuleIndex = 0; - bool bPHSRuleOrphaned = false; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - psPhsRule->u8RefCnt = 0; - - /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry */ - bPHSRuleOrphaned = DerefPhsRule(uiClsId, psaClassifiertable, - pstClassifierEntry->pstPhsRule); - - /* Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in - * Classifier table for this SF */ - nPhsRuleIndex = GetPhsRuleEntry(psaClassifiertable, u8AssociatedPHSI, - eActiveClassifierRuleContext, - &pstAddPhsRule); - if (PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) { - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, - "\nAdding New PHSRuleEntry For Classifier"); - - if (psPhsRule->u8PHSI == 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "\nError PHSI is Zero\n"); - return ERR_PHS_INVALID_PHS_RULE; - } - - /* Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for - * uiClsId */ - if (false == bPHSRuleOrphaned) { - - pstClassifierEntry->pstPhsRule = - kmalloc(sizeof(struct bcm_phs_rule), - GFP_KERNEL); - if (NULL == pstClassifierEntry->pstPhsRule) - return ERR_PHSRULE_MEMALLOC_FAIL; - } - memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, - sizeof(struct bcm_phs_rule)); - } else { - /* Step 2.b PHS Rule Exists Tie uiClsId with the existing - * PHS Rule */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, - "\nTying Classifier to Existing PHS Rule"); - if (bPHSRuleOrphaned) { - kfree(pstClassifierEntry->pstPhsRule); - pstClassifierEntry->pstPhsRule = NULL; - } - pstClassifierEntry->pstPhsRule = pstAddPhsRule; - } - - pstClassifierEntry->bUsed = TRUE; - pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI; - pstClassifierEntry->uiClassifierRuleId = uiClsId; - pstClassifierEntry->pstPhsRule->u8RefCnt++; - pstClassifierEntry->bUnclassifiedPHSRule = - pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule; - - return PHS_SUCCESS; -} - -static bool DerefPhsRule(IN B_UINT16 uiClsId, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *pstPhsRule) -{ - if (pstPhsRule == NULL) - return false; - - if (pstPhsRule->u8RefCnt) - pstPhsRule->u8RefCnt--; - - return (0 == pstPhsRule->u8RefCnt); -} - -static void dbg_print_st_cls_entry(struct bcm_mini_adapter *ad, - struct bcm_phs_entry *st_serv_flow_entry, - struct bcm_phs_classifier_entry *st_cls_entry) -{ - int k; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X", st_serv_flow_entry->uiVcid); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X", st_cls_entry->uiClassifierRuleId); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X", st_cls_entry->u8PHSI); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n"); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X", st_cls_entry->pstPhsRule->u8PHSI); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ", st_cls_entry->pstPhsRule->u8PHSFLength); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : "); - - for (k = 0 ; k < st_cls_entry->pstPhsRule->u8PHSFLength; k++) - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", st_cls_entry->pstPhsRule->u8PHSF[k]); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X", st_cls_entry->pstPhsRule->u8PHSMLength); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :"); - - for (k = 0; k < st_cls_entry->pstPhsRule->u8PHSMLength; k++) - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", st_cls_entry->pstPhsRule->u8PHSM[k]); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ", st_cls_entry->pstPhsRule->u8PHSS); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X", st_cls_entry->pstPhsRule->u8PHSV); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n"); -} - -static void phsrules_per_sf_dbg_print(struct bcm_mini_adapter *ad, - struct bcm_phs_entry *st_serv_flow_entry) -{ - int j, l; - struct bcm_phs_classifier_entry st_cls_entry; - - for (j = 0; j < MAX_PHSRULE_PER_SF; j++) { - - for (l = 0; l < 2; l++) { - - if (l == 0) { - st_cls_entry = st_serv_flow_entry->pstClassifierTable->stActivePhsRulesList[j]; - if (st_cls_entry.bUsed) - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, - DUMP_INFO, - (DBG_LVL_ALL | DBG_NO_FUNC_PRINT), - "\n Active PHS Rule :\n"); - } else { - st_cls_entry = st_serv_flow_entry->pstClassifierTable->stOldPhsRulesList[j]; - if (st_cls_entry.bUsed) - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, - DUMP_INFO, - (DBG_LVL_ALL | DBG_NO_FUNC_PRINT), - "\n Old PHS Rule :\n"); - } - - if (st_cls_entry.bUsed) { - dbg_print_st_cls_entry(ad, - st_serv_flow_entry, - &st_cls_entry); - } - } - } -} - -void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension) -{ - int i; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, - "\n Dumping PHS Rules :\n"); - - for (i = 0; i < MAX_SERVICEFLOWS; i++) { - - struct bcm_phs_entry stServFlowEntry = - pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i]; - - if (!stServFlowEntry.bUsed) - continue; - - phsrules_per_sf_dbg_print(Adapter, &stServFlowEntry); - } -} - -/* - * Procedure: phs_decompress - * - * Description: This routine restores the static fields within the packet. - * - * Arguments: - * in_buf - ptr to incoming packet buffer. - * out_buf - ptr to output buffer where the suppressed - * header is copied. - * decomp_phs_rules - ptr to PHS rule. - * header_size - ptr to field which holds the phss or - * phsf_length. - * - * Returns: - * size - The number of bytes of dynamic fields present with in the - * incoming packet header. - * 0 - If PHS rule is NULL.If PHSI is 0 indicateing packet as - * uncompressed. - */ -static int phs_decompress(unsigned char *in_buf, - unsigned char *out_buf, - struct bcm_phs_rule *decomp_phs_rules, - UINT *header_size) -{ - int phss, size = 0; - struct bcm_phs_rule *tmp_memb; - int bit, i = 0; - unsigned char *phsf, *phsm; - int in_buf_len = *header_size - 1; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - in_buf++; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, - "====>\n"); - *header_size = 0; - - if (decomp_phs_rules == NULL) - return 0; - - tmp_memb = decomp_phs_rules; - /* - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL, - * "\nDECOMP:In phs_decompress PHSI 1 %d",phsi)); - * header_size = tmp_memb->u8PHSFLength; - */ - phss = tmp_memb->u8PHSS; - phsf = tmp_memb->u8PHSF; - phsm = tmp_memb->u8PHSM; - - if (phss > MAX_PHS_LENGTHS) - phss = MAX_PHS_LENGTHS; - - /* - * 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)); - */ - while ((phss > 0) && (size < in_buf_len)) { - bit = ((*phsm << i) & SUPPRESS); - - if (bit == SUPPRESS) { - *out_buf = *phsf; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, - "\nDECOMP:In phss %d phsf %d output %d", - phss, *phsf, *out_buf); - } else { - *out_buf = *in_buf; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, - "\nDECOMP:In phss %d input %d output %d", - phss, *in_buf, *out_buf); - in_buf++; - size++; - } - out_buf++; - phsf++; - phss--; - i++; - *header_size = *header_size + 1; - - if (i > MAX_NO_BIT) { - i = 0; - phsm++; - } - } - - return size; -} - -/* - * Procedure: phs_compress - * - * Description: This routine suppresses the static fields within the packet. - * Before that it will verify the fields to be suppressed with the corresponding - * fields in the phsf. For verification it checks the phsv field of PHS rule. - * If set and verification succeeds it suppresses the field.If any one static - * field is found different none of the static fields are suppressed then the - * packet is sent as uncompressed packet with phsi=0. - * - * Arguments: - * phs_rule - ptr to PHS rule. - * in_buf - ptr to incoming packet buffer. - * out_buf - ptr to output buffer where the suppressed header is - * copied. - * header_size - ptr to field which holds the phss. - * - * Returns: - * size - The number of bytes copied into the output buffer i.e - * dynamic fields - * 0 - If PHS rule is NULL.If PHSV field is not set. If the - * verification fails. - */ -static int phs_compress(struct bcm_phs_rule *phs_rule, - unsigned char *in_buf, - unsigned char *out_buf, - UINT *header_size, - UINT *new_header_size) -{ - unsigned char *old_addr = out_buf; - int suppress = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (phs_rule == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nphs_compress(): phs_rule null!"); - *out_buf = ZERO_PHSI; - return STATUS_PHS_NOCOMPRESSION; - } - - if (phs_rule->u8PHSS <= *new_header_size) - *header_size = phs_rule->u8PHSS; - else - *header_size = *new_header_size; - - /* To copy PHSI */ - out_buf++; - suppress = verify_suppress_phsf(in_buf, out_buf, phs_rule->u8PHSF, - phs_rule->u8PHSM, phs_rule->u8PHSS, - phs_rule->u8PHSV, new_header_size); - - if (suppress == STATUS_PHS_COMPRESSED) { - *old_addr = (unsigned char)phs_rule->u8PHSI; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nCOMP:In phs_compress phsi %d", - phs_rule->u8PHSI); - } else { - *old_addr = ZERO_PHSI; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nCOMP:In phs_compress PHSV Verification failed"); - } - - return suppress; -} - -/* - * Procedure: verify_suppress_phsf - * - * Description: This routine verifies the fields of the packet and if all the - * static fields are equal it adds the phsi of that PHS rule.If any static - * field differs it woun't suppress any field. - * - * Arguments: - * rules_set - ptr to classifier_rules. - * in_buffer - ptr to incoming packet buffer. - * out_buffer - ptr to output buffer where the suppressed header is copied. - * phsf - ptr to phsf. - * phsm - ptr to phsm. - * phss - variable holding phss. - * - * Returns: - * size - The number of bytes copied into the output buffer i.e dynamic - * fields. - * 0 - Packet has failed the verification. - */ -static int verify_suppress_phsf(unsigned char *in_buffer, - unsigned char *out_buffer, - unsigned char *phsf, - unsigned char *phsm, - unsigned int phss, - unsigned int phsv, - UINT *new_header_size) -{ - unsigned int size = 0; - int bit, i = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nCOMP:In verify_phsf PHSM - 0x%X", *phsm); - - if (phss > (*new_header_size)) - phss = *new_header_size; - - while (phss > 0) { - bit = ((*phsm << i) & SUPPRESS); - if (bit == SUPPRESS) { - if (*in_buffer != *phsf) { - if (phsv == VERIFY) { - 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); - return STATUS_PHS_NOCOMPRESSION; - } - } else - 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); - } else { - *out_buffer = *in_buffer; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - PHS_SEND, - DBG_LVL_ALL, - "\nCOMP:In copying_header input %d out %d", - *in_buffer, - *out_buffer); - out_buffer++; - size++; - } - - in_buffer++; - phsf++; - phss--; - i++; - - if (i > MAX_NO_BIT) { - i = 0; - phsm++; - } - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nCOMP:In verify_phsf success"); - *new_header_size = size; - return STATUS_PHS_COMPRESSED; -} |