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 b |