2010-09-08 15:46:36 -06:00
|
|
|
#include "headers.h"
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
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);
|
2010-11-01 10:24:00 -06:00
|
|
|
|
2014-07-15 01:43:08 -06:00
|
|
|
static bool ValidatePHSRuleComplete(const struct bcm_phs_rule *psPhsRule);
|
2010-11-01 10:24:00 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
static bool DerefPhsRule(B_UINT16 uiClsId,
|
|
|
|
struct bcm_phs_classifier_table *psaClassifiertable,
|
|
|
|
struct bcm_phs_rule *pstPhsRule);
|
2010-11-01 10:24:00 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
static UINT GetClassifierEntry(struct bcm_phs_classifier_table *pstClassifierTable,
|
|
|
|
B_UINT32 uiClsid,
|
|
|
|
enum bcm_phs_classifier_context eClsContext,
|
|
|
|
struct bcm_phs_classifier_entry **ppstClassifierEntry);
|
2010-11-01 10:24:00 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
static UINT GetPhsRuleEntry(struct bcm_phs_classifier_table *pstClassifierTable,
|
|
|
|
B_UINT32 uiPHSI,
|
|
|
|
enum bcm_phs_classifier_context eClsContext,
|
|
|
|
struct bcm_phs_rule **ppstPhsRule);
|
2010-11-01 10:24:00 -06:00
|
|
|
|
2012-12-19 22:31:29 -07:00
|
|
|
static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable);
|
2010-11-01 10:24:00 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
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);
|
2010-11-01 10:24:00 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
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);
|
2010-11-01 10:24:00 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
static int phs_decompress(unsigned char *in_buf,
|
|
|
|
unsigned char *out_buf,
|
|
|
|
struct bcm_phs_rule *phs_rules,
|
|
|
|
UINT *header_size);
|
2010-11-01 10:24:00 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
static ULONG PhsCompress(void *pvContext,
|
2014-07-15 01:42:54 -06:00
|
|
|
B_UINT16 uiVcid,
|
|
|
|
B_UINT16 uiClsId,
|
|
|
|
void *pvInputBuffer,
|
|
|
|
void *pvOutputBuffer,
|
|
|
|
UINT *pOldHeaderSize,
|
|
|
|
UINT *pNewHeaderSize);
|
2010-11-01 10:24:00 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
static ULONG PhsDeCompress(void *pvContext,
|
2014-07-15 01:42:54 -06:00
|
|
|
B_UINT16 uiVcid,
|
|
|
|
void *pvInputBuffer,
|
|
|
|
void *pvOutputBuffer,
|
|
|
|
UINT *pInHeaderSize,
|
|
|
|
UINT *pOutHeaderSize);
|
2010-11-01 10:24:00 -06:00
|
|
|
|
2010-09-08 15:46:36 -06:00
|
|
|
#define IN
|
|
|
|
#define OUT
|
|
|
|
|
|
|
|
/*
|
2013-02-20 21:25:29 -07:00
|
|
|
* 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.
|
|
|
|
*/
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2012-05-26 10:05:12 -06:00
|
|
|
int PHSTransmit(struct bcm_mini_adapter *Adapter,
|
2013-02-20 21:25:27 -07:00
|
|
|
struct sk_buff **pPacket,
|
|
|
|
USHORT Vcid,
|
|
|
|
B_UINT16 uiClassifierRuleID,
|
2013-10-28 02:35:59 -06:00
|
|
|
bool bHeaderSuppressionEnabled,
|
2013-02-20 21:25:27 -07:00
|
|
|
UINT *PacketLen,
|
|
|
|
UCHAR bEthCSSupport)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:29 -07:00
|
|
|
/* PHS Sepcific */
|
2013-02-20 21:25:27 -07:00
|
|
|
UINT unPHSPktHdrBytesCopied = 0;
|
|
|
|
UINT unPhsOldHdrSize = 0;
|
|
|
|
UINT unPHSNewPktHeaderLen = 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
/* Pointer to PHS IN Hdr Buffer */
|
2014-07-15 01:43:15 -06:00
|
|
|
PUCHAR pucPHSPktHdrInBuf =
|
|
|
|
Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf;
|
2010-09-08 15:46:36 -06:00
|
|
|
/* Pointer to PHS OUT Hdr Buffer */
|
2014-07-15 01:43:15 -06:00
|
|
|
PUCHAR pucPHSPktHdrOutBuf =
|
|
|
|
Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf;
|
2013-02-20 21:25:27 -07:00
|
|
|
UINT usPacketType;
|
|
|
|
UINT BytesToRemove = 0;
|
2013-10-28 02:35:59 -06:00
|
|
|
bool bPHSI = 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
LONG ulPhsStatus = 0;
|
2013-02-20 21:25:27 -07:00
|
|
|
UINT numBytesCompressed = 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
struct sk_buff *newPacket = NULL;
|
|
|
|
struct sk_buff *Packet = *pPacket;
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
|
|
|
|
"In PHSTransmit");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if (!bEthCSSupport)
|
|
|
|
BytesToRemove = ETH_HLEN;
|
2010-09-08 15:46:36 -06:00
|
|
|
/*
|
2013-02-20 21:25:29 -07:00
|
|
|
* Accumulate the header upto the size we support suppression
|
|
|
|
* from NDIS packet
|
|
|
|
*/
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
usPacketType = ((struct ethhdr *)(Packet->data))->h_proto;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
|
|
|
pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
|
2013-02-20 21:25:29 -07:00
|
|
|
/* considering data after ethernet header */
|
2013-02-20 21:25:27 -07:00
|
|
|
if ((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS)
|
2010-09-08 15:46:36 -06:00
|
|
|
unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove);
|
|
|
|
else
|
|
|
|
unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS;
|
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if ((unPHSPktHdrBytesCopied > 0) &&
|
2013-02-20 21:25:28 -07:00
|
|
|
(unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) {
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
2014-07-15 01:43:15 -06:00
|
|
|
* Step 2 Suppress Header using PHS and fill into intermediate
|
|
|
|
* ucaPHSPktHdrOutBuf.
|
|
|
|
* Suppress only if IP Header and PHS Enabled For the
|
|
|
|
* Service Flow
|
2013-02-20 21:25:29 -07:00
|
|
|
*/
|
2013-02-20 21:25:27 -07:00
|
|
|
if (((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
|
|
|
|
(usPacketType == ETHERNET_FRAMETYPE_IPV6)) &&
|
2013-02-20 21:25:28 -07:00
|
|
|
(bHeaderSuppressionEnabled)) {
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"\nTrying to PHS Compress Using Classifier rule 0x%X",
|
|
|
|
uiClassifierRuleID);
|
2013-02-20 21:25:27 -07:00
|
|
|
unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied;
|
|
|
|
ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext,
|
2014-07-15 01:42:54 -06:00
|
|
|
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);
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (unPHSNewPktHeaderLen == unPhsOldHdrSize) {
|
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if (ulPhsStatus == STATUS_PHS_COMPRESSED)
|
|
|
|
bPHSI = *pucPHSPktHdrOutBuf;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
ulPhsStatus = STATUS_PHS_NOCOMPRESSION;
|
|
|
|
}
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (ulPhsStatus == STATUS_PHS_COMPRESSED) {
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
|
|
|
|
PHS_SEND, DBG_LVL_ALL,
|
|
|
|
"PHS Sending packet Compressed");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (skb_cloned(Packet)) {
|
2014-07-15 01:43:15 -06:00
|
|
|
newPacket =
|
|
|
|
skb_copy(Packet, GFP_ATOMIC);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if (newPacket == NULL)
|
|
|
|
return STATUS_FAILURE;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
dev_kfree_skb(Packet);
|
|
|
|
*pPacket = Packet = newPacket;
|
2014-07-15 01:42:54 -06:00
|
|
|
pucPHSPktHdrInBuf =
|
|
|
|
Packet->data + BytesToRemove;
|
2013-02-20 21:25:27 -07:00
|
|
|
}
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
numBytesCompressed = unPhsOldHdrSize -
|
|
|
|
(unPHSNewPktHeaderLen + PHSI_LEN);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
memcpy(pucPHSPktHdrInBuf + numBytesCompressed,
|
|
|
|
pucPHSPktHdrOutBuf,
|
|
|
|
unPHSNewPktHeaderLen + PHSI_LEN);
|
|
|
|
memcpy(Packet->data + numBytesCompressed,
|
|
|
|
Packet->data, BytesToRemove);
|
2013-02-20 21:25:27 -07:00
|
|
|
skb_pull(Packet, numBytesCompressed);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
return STATUS_SUCCESS;
|
2013-02-20 21:25:28 -07:00
|
|
|
} else {
|
2014-07-15 01:42:54 -06:00
|
|
|
/* if one byte headroom is not available,
|
|
|
|
* increase it through skb_cow
|
|
|
|
*/
|
2013-02-20 21:25:28 -07:00
|
|
|
if (!(skb_headroom(Packet) > 0)) {
|
|
|
|
|
|
|
|
if (skb_cow(Packet, 1)) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter,
|
|
|
|
DBG_TYPE_PRINTK,
|
|
|
|
0, 0,
|
|
|
|
"SKB Cow Failed\n");
|
2013-02-20 21:25:27 -07:00
|
|
|
return STATUS_FAILURE;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
2013-02-20 21:25:27 -07:00
|
|
|
}
|
|
|
|
skb_push(Packet, 1);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* CAUTION: The MAC Header is getting corrupted
|
|
|
|
* here for IP CS - can be saved by copying 14
|
|
|
|
* Bytes. not needed .... hence corrupting it.
|
|
|
|
*/
|
2013-02-20 21:25:27 -07:00
|
|
|
*(Packet->data + BytesToRemove) = bPHSI;
|
|
|
|
return STATUS_SUCCESS;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
2013-02-20 21:25:28 -07:00
|
|
|
} else {
|
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if (!bHeaderSuppressionEnabled)
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
|
|
|
|
PHS_SEND, DBG_LVL_ALL,
|
|
|
|
"\nHeader Suppression Disabled For SF: No PHS\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 01:43:15 -06:00
|
|
|
/* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
|
|
|
|
* "PHSTransmit : Dumping data packet After PHS"); */
|
2010-09-08 15:46:36 -06:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-05-26 10:05:12 -06:00
|
|
|
int PHSReceive(struct bcm_mini_adapter *Adapter,
|
2014-07-15 01:42:54 -06:00
|
|
|
USHORT usVcid,
|
|
|
|
struct sk_buff *packet,
|
|
|
|
UINT *punPacketLen,
|
|
|
|
UCHAR *pucEthernetHdr,
|
|
|
|
UINT bHeaderSuppressionEnabled)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:27 -07:00
|
|
|
u32 nStandardPktHdrLen = 0;
|
|
|
|
u32 nTotalsuppressedPktHdrBytes = 0;
|
|
|
|
int ulPhsStatus = 0;
|
|
|
|
PUCHAR pucInBuff = NULL;
|
2010-09-08 15:46:36 -06:00
|
|
|
UINT TotalBytesAdded = 0;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (!bHeaderSuppressionEnabled) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"\nPhs Disabled for incoming packet");
|
2010-09-08 15:46:36 -06:00
|
|
|
return ulPhsStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
pucInBuff = packet->data;
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/* Restore PHS suppressed header */
|
2010-09-08 15:46:36 -06:00
|
|
|
nStandardPktHdrLen = packet->len;
|
|
|
|
ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext,
|
2014-07-15 01:42:54 -06:00
|
|
|
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",
|
2013-02-20 21:25:27 -07:00
|
|
|
nTotalsuppressedPktHdrBytes, nStandardPktHdrLen);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (ulPhsStatus != STATUS_PHS_COMPRESSED) {
|
2010-09-08 15:46:36 -06:00
|
|
|
skb_pull(packet, 1);
|
|
|
|
return STATUS_SUCCESS;
|
2013-02-20 21:25:28 -07:00
|
|
|
} else {
|
2014-07-15 01:42:54 -06:00
|
|
|
TotalBytesAdded = nStandardPktHdrLen -
|
|
|
|
nTotalsuppressedPktHdrBytes - PHSI_LEN;
|
2013-02-20 21:25:28 -07:00
|
|
|
|
|
|
|
if (TotalBytesAdded) {
|
2013-02-20 21:25:27 -07:00
|
|
|
if (skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded))
|
2010-09-08 15:46:36 -06:00
|
|
|
skb_push(packet, TotalBytesAdded);
|
2013-02-20 21:25:28 -07:00
|
|
|
else {
|
|
|
|
if (skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter,
|
|
|
|
DBG_TYPE_PRINTK, 0, 0,
|
|
|
|
"cow failed in receive\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
return STATUS_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
skb_push(packet, TotalBytesAdded);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf,
|
|
|
|
nStandardPktHdrLen);
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
void DumpFullPacket(UCHAR *pBuf, UINT nPktLen)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
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);
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* Procedure: phs_init
|
|
|
|
*
|
2014-07-15 01:43:15 -06:00
|
|
|
* Description: This routine is responsible for allocating memory for classifier
|
|
|
|
* and PHS rules.
|
2013-02-20 21:25:29 -07:00
|
|
|
*
|
|
|
|
* Arguments:
|
2014-07-15 01:43:15 -06:00
|
|
|
* pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules
|
|
|
|
* and PHS Rules , RX, TX buffer etc
|
2013-02-20 21:25:29 -07:00
|
|
|
*
|
|
|
|
* Returns:
|
2013-02-20 21:25:30 -07:00
|
|
|
* TRUE(1) -If allocation of memory was successful.
|
2013-02-20 21:25:29 -07:00
|
|
|
* FALSE -If allocation of memory fails.
|
|
|
|
*/
|
2014-07-15 01:42:54 -06:00
|
|
|
int phs_init(struct bcm_phs_extension *pPhsdeviceExtension,
|
|
|
|
struct bcm_mini_adapter *Adapter)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
|
|
|
int i;
|
2012-12-19 22:31:29 -07:00
|
|
|
struct bcm_phs_table *pstServiceFlowTable;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
|
|
|
|
"\nPHS:phs_init function");
|
2013-02-20 21:25:27 -07:00
|
|
|
|
|
|
|
if (pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
|
2010-09-08 15:46:36 -06:00
|
|
|
return -EINVAL;
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
pPhsdeviceExtension->pstServiceFlowPhsRulesTable =
|
|
|
|
kzalloc(sizeof(struct bcm_phs_table), GFP_KERNEL);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"\nAllocation ServiceFlowPhsRulesTable failed");
|
2010-09-08 15:46:36 -06:00
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable;
|
2013-02-20 21:25:28 -07:00
|
|
|
for (i = 0; i < MAX_SERVICEFLOWS; i++) {
|
2014-07-15 01:42:54 -06:00
|
|
|
struct bcm_phs_entry sServiceFlow =
|
|
|
|
pstServiceFlowTable->stSFList[i];
|
|
|
|
sServiceFlow.pstClassifierTable =
|
|
|
|
kzalloc(sizeof(struct bcm_phs_classifier_table),
|
|
|
|
GFP_KERNEL);
|
2013-02-20 21:25:28 -07:00
|
|
|
if (!sServiceFlow.pstClassifierTable) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
|
|
|
|
DBG_LVL_ALL, "\nAllocation failed");
|
2013-02-20 21:25:27 -07:00
|
|
|
free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
|
2010-09-08 15:46:36 -06:00
|
|
|
pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-01 07:35:21 -06:00
|
|
|
pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
|
2013-02-20 21:25:28 -07:00
|
|
|
if (pPhsdeviceExtension->CompressedTxBuffer == NULL) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
|
|
|
|
DBG_LVL_ALL, "\nAllocation failed");
|
2010-09-08 15:46:36 -06:00
|
|
|
free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
|
|
|
|
pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
pPhsdeviceExtension->UnCompressedRxBuffer =
|
|
|
|
kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
|
2013-02-20 21:25:28 -07:00
|
|
|
if (pPhsdeviceExtension->UnCompressedRxBuffer == NULL) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
|
|
|
|
DBG_LVL_ALL, "\nAllocation failed");
|
2010-11-01 07:35:21 -06:00
|
|
|
kfree(pPhsdeviceExtension->CompressedTxBuffer);
|
2010-09-08 15:46:36 -06:00
|
|
|
free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
|
|
|
|
pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
|
|
|
|
"\n phs_init Successful");
|
2010-09-08 15:46:36 -06:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-12-19 22:31:28 -07:00
|
|
|
int PhsCleanup(IN struct bcm_phs_extension *pPHSDeviceExt)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:28 -07:00
|
|
|
if (pPHSDeviceExt->pstServiceFlowPhsRulesTable) {
|
2010-09-08 15:46:36 -06:00
|
|
|
free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable);
|
|
|
|
pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
|
|
|
|
}
|
|
|
|
|
2010-11-01 07:35:21 -06:00
|
|
|
kfree(pPHSDeviceExt->CompressedTxBuffer);
|
|
|
|
pPHSDeviceExt->CompressedTxBuffer = NULL;
|
|
|
|
|
|
|
|
kfree(pPHSDeviceExt->UnCompressedRxBuffer);
|
|
|
|
pPHSDeviceExt->UnCompressedRxBuffer = NULL;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-02-20 21:25:27 -07:00
|
|
|
ULONG PhsUpdateClassifierRule(IN void *pvContext,
|
2014-07-15 01:42:54 -06:00
|
|
|
IN B_UINT16 uiVcid ,
|
|
|
|
IN B_UINT16 uiClsId ,
|
|
|
|
IN struct bcm_phs_rule *psPhsRule,
|
|
|
|
IN B_UINT8 u8AssociatedPHSI)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:27 -07:00
|
|
|
ULONG lStatus = 0;
|
|
|
|
UINT nSFIndex = 0;
|
2012-12-19 22:31:30 -07:00
|
|
|
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2014-07-15 01:43:15 -06:00
|
|
|
struct bcm_phs_extension *pDeviceExtension =
|
|
|
|
(struct bcm_phs_extension *)pvContext;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
|
|
|
|
"PHS With Corr2 Changes\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (pDeviceExtension == NULL) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
|
|
|
|
DBG_LVL_ALL, "Invalid Device Extension\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_PHS_INVALID_DEVICE_EXETENSION;
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if (u8AssociatedPHSI == 0)
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_PHS_INVALID_PHS_RULE;
|
|
|
|
|
|
|
|
/* Retrieve the SFID Entry Index for requested Service Flow */
|
|
|
|
nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
|
2014-07-15 01:42:54 -06:00
|
|
|
uiVcid, &pstServiceFlowEntry);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
|
2010-09-08 15:46:36 -06:00
|
|
|
/* This is a new SF. Create a mapping entry for this */
|
|
|
|
lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId,
|
2014-07-15 01:42:54 -06:00
|
|
|
pDeviceExtension->pstServiceFlowPhsRulesTable,
|
|
|
|
psPhsRule,
|
|
|
|
u8AssociatedPHSI);
|
2010-09-08 15:46:36 -06:00
|
|
|
return lStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* SF already Exists Add PHS Rule to existing SF */
|
2013-02-20 21:25:27 -07:00
|
|
|
lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId,
|
2014-07-15 01:42:54 -06:00
|
|
|
pstServiceFlowEntry,
|
|
|
|
psPhsRule,
|
|
|
|
u8AssociatedPHSI);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
return lStatus;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2014-07-15 01:42:54 -06:00
|
|
|
ULONG PhsDeletePHSRule(IN void *pvContext,
|
|
|
|
IN B_UINT16 uiVcid,
|
|
|
|
IN B_UINT8 u8PHSI)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:27 -07:00
|
|
|
UINT nSFIndex = 0, nClsidIndex = 0;
|
2012-12-19 22:31:30 -07:00
|
|
|
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
|
2012-12-19 22:31:31 -07:00
|
|
|
struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2013-02-20 21:25:27 -07:00
|
|
|
struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
|
2014-07-15 01:42:57 -06:00
|
|
|
struct bcm_phs_classifier_entry *curr_entry;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
|
|
|
|
"======>\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (pDeviceExtension) {
|
2013-02-20 21:25:29 -07:00
|
|
|
/* Retrieve the SFID Entry Index for requested Service Flow */
|
2014-07-15 01:42:54 -06:00
|
|
|
nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
|
|
|
|
uiVcid, &pstServiceFlowEntry);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
|
|
|
|
DBG_LVL_ALL, "SFID Match Failed\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_SF_MATCH_FAIL;
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable;
|
2013-02-20 21:25:28 -07:00
|
|
|
if (pstClassifierRulesTable) {
|
|
|
|
for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) {
|
2014-07-15 01:42:57 -06:00
|
|
|
curr_entry = &pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex];
|
2014-07-15 01:42:58 -06:00
|
|
|
if (curr_entry->bUsed &&
|
|
|
|
curr_entry->pstPhsRule &&
|
|
|
|
(curr_entry->pstPhsRule->u8PHSI == u8PHSI)) {
|
2013-02-20 21:25:28 -07:00
|
|
|
|
2014-07-15 01:42:58 -06:00
|
|
|
if (curr_entry->pstPhsRule->u8RefCnt)
|
|
|
|
curr_entry->pstPhsRule->u8RefCnt--;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:42:58 -06:00
|
|
|
if (0 == curr_entry->pstPhsRule->u8RefCnt)
|
|
|
|
kfree(curr_entry->pstPhsRule);
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:42:58 -06:00
|
|
|
memset(curr_entry,
|
|
|
|
0,
|
|
|
|
sizeof(struct bcm_phs_classifier_entry));
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-05-26 08:08:50 -06:00
|
|
|
return 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2014-07-15 01:43:15 -06:00
|
|
|
ULONG PhsDeleteClassifierRule(IN void *pvContext,
|
|
|
|
IN B_UINT16 uiVcid,
|
|
|
|
IN B_UINT16 uiClsId)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:27 -07:00
|
|
|
UINT nSFIndex = 0, nClsidIndex = 0;
|
2012-12-19 22:31:30 -07:00
|
|
|
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
|
2012-12-19 22:31:32 -07:00
|
|
|
struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2014-07-15 01:42:54 -06:00
|
|
|
struct bcm_phs_extension *pDeviceExtension =
|
|
|
|
(struct bcm_phs_extension *)pvContext;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:42:59 -06:00
|
|
|
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;
|
|
|
|
}
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:43:00 -06:00
|
|
|
nClsidIndex =
|
|
|
|
GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
|
|
|
|
uiClsId,
|
|
|
|
eActiveClassifierRuleContext,
|
|
|
|
&pstClassifierEntry);
|
|
|
|
|
|
|
|
if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) &&
|
|
|
|
(!pstClassifierEntry->bUnclassifiedPHSRule)) {
|
2014-07-15 01:42:59 -06:00
|
|
|
if (pstClassifierEntry->pstPhsRule) {
|
|
|
|
if (pstClassifierEntry->pstPhsRule->u8RefCnt)
|
|
|
|
pstClassifierEntry->pstPhsRule->u8RefCnt--;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:42:59 -06:00
|
|
|
if (0 == pstClassifierEntry->pstPhsRule->u8RefCnt)
|
|
|
|
kfree(pstClassifierEntry->pstPhsRule);
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
2014-07-15 01:42:59 -06:00
|
|
|
memset(pstClassifierEntry, 0,
|
|
|
|
sizeof(struct bcm_phs_classifier_entry));
|
|
|
|
}
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:43:00 -06:00
|
|
|
nClsidIndex =
|
|
|
|
GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
|
|
|
|
uiClsId,
|
|
|
|
eOldClassifierRuleContext,
|
|
|
|
&pstClassifierEntry);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:43:00 -06:00
|
|
|
if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) &&
|
|
|
|
(!pstClassifierEntry->bUnclassifiedPHSRule)) {
|
2014-07-15 01:42:59 -06:00
|
|
|
kfree(pstClassifierEntry->pstPhsRule);
|
|
|
|
memset(pstClassifierEntry, 0,
|
|
|
|
sizeof(struct bcm_phs_classifier_entry));
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
2014-07-15 01:42:59 -06:00
|
|
|
|
|
|
|
out:
|
2014-05-26 08:08:50 -06:00
|
|
|
return 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-02-20 21:25:27 -07:00
|
|
|
ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:27 -07:00
|
|
|
UINT nSFIndex = 0, nClsidIndex = 0;
|
2012-12-19 22:31:30 -07:00
|
|
|
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
|
2012-12-19 22:31:31 -07:00
|
|
|
struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2014-07-15 01:42:54 -06:00
|
|
|
struct bcm_phs_extension *pDeviceExtension =
|
|
|
|
(struct bcm_phs_extension *)pvContext;
|
2014-07-15 01:43:02 -06:00
|
|
|
struct bcm_phs_classifier_entry *curr_clsf_entry;
|
|
|
|
struct bcm_phs_classifier_entry *curr_rules_list;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
|
|
|
|
"====>\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:43:01 -06:00
|
|
|
if (!pDeviceExtension)
|
|
|
|
goto out;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:43:01 -06:00
|
|
|
/* 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;
|
|
|
|
}
|
2013-02-20 21:25:28 -07:00
|
|
|
|
2014-07-15 01:43:01 -06:00
|
|
|
pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable;
|
|
|
|
if (pstClassifierRulesTable) {
|
|
|
|
for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) {
|
2014-07-15 01:43:02 -06:00
|
|
|
curr_clsf_entry =
|
|
|
|
&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex];
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:02 -06:00
|
|
|
curr_rules_list =
|
|
|
|
&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex];
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:02 -06:00
|
|
|
if (curr_clsf_entry->pstPhsRule) {
|
2014-07-15 01:43:01 -06:00
|
|
|
|
2014-07-15 01:43:02 -06:00
|
|
|
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;
|
2014-07-15 01:43:01 -06:00
|
|
|
}
|
2014-07-15 01:43:02 -06:00
|
|
|
memset(curr_clsf_entry, 0,
|
|
|
|
sizeof(struct bcm_phs_classifier_entry));
|
|
|
|
if (curr_rules_list->pstPhsRule) {
|
2013-02-20 21:25:28 -07:00
|
|
|
|
2014-07-15 01:43:02 -06:00
|
|
|
if (curr_rules_list->pstPhsRule->u8RefCnt)
|
|
|
|
curr_rules_list->pstPhsRule->u8RefCnt--;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:02 -06:00
|
|
|
if (0 == curr_rules_list->pstPhsRule->u8RefCnt)
|
|
|
|
kfree(curr_rules_list->pstPhsRule);
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:02 -06:00
|
|
|
curr_rules_list->pstPhsRule = NULL;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
2014-07-15 01:43:02 -06:00
|
|
|
memset(curr_rules_list, 0,
|
|
|
|
sizeof(struct bcm_phs_classifier_entry));
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
}
|
2014-07-15 01:43:01 -06:00
|
|
|
pstServiceFlowEntry->bUsed = false;
|
|
|
|
pstServiceFlowEntry->uiVcid = 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:43:01 -06:00
|
|
|
out:
|
2014-05-26 08:08:50 -06:00
|
|
|
return 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* PhsCompress
|
|
|
|
*
|
|
|
|
* Routine Description:
|
|
|
|
* Exported function to compress the data using PHS.
|
|
|
|
*
|
|
|
|
* Arguments:
|
2014-07-15 01:43:15 -06:00
|
|
|
* 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
|
2013-02-20 21:25:29 -07:00
|
|
|
*
|
|
|
|
* Return Value:
|
|
|
|
*
|
|
|
|
* 0 if successful,
|
|
|
|
* >0 Error.
|
|
|
|
*/
|
2013-09-17 01:42:17 -06:00
|
|
|
static ULONG PhsCompress(IN void *pvContext,
|
2014-07-15 01:42:54 -06:00
|
|
|
IN B_UINT16 uiVcid,
|
|
|
|
IN B_UINT16 uiClsId,
|
|
|
|
IN void *pvInputBuffer,
|
|
|
|
OUT void *pvOutputBuffer,
|
|
|
|
OUT UINT *pOldHeaderSize,
|
|
|
|
OUT UINT *pNewHeaderSize)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:27 -07:00
|
|
|
UINT nSFIndex = 0, nClsidIndex = 0;
|
2012-12-19 22:31:30 -07:00
|
|
|
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
|
2012-12-19 22:31:32 -07:00
|
|
|
struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
|
2012-12-19 22:31:34 -07:00
|
|
|
struct bcm_phs_rule *pstPhsRule = NULL;
|
2013-02-20 21:25:27 -07:00
|
|
|
ULONG lStatus = 0;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2014-07-15 01:42:54 -06:00
|
|
|
struct bcm_phs_extension *pDeviceExtension =
|
|
|
|
(struct bcm_phs_extension *)pvContext;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (pDeviceExtension == NULL) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
|
|
|
|
"Invalid Device Extension\n");
|
2013-02-20 21:25:27 -07:00
|
|
|
lStatus = STATUS_PHS_NOCOMPRESSION;
|
2010-09-08 15:46:36 -06:00
|
|
|
return lStatus;
|
|
|
|
}
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
|
|
|
|
"Suppressing header\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/* Retrieve the SFID Entry Index for requested Service Flow */
|
2010-09-08 15:46:36 -06:00
|
|
|
nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
|
2014-07-15 01:43:03 -06:00
|
|
|
uiVcid, &pstServiceFlowEntry);
|
2013-02-20 21:25:28 -07:00
|
|
|
if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
|
|
|
|
"SFID Match Failed\n");
|
2013-02-20 21:25:27 -07:00
|
|
|
lStatus = STATUS_PHS_NOCOMPRESSION;
|
2010-09-08 15:46:36 -06:00
|
|
|
return lStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
|
2014-07-15 01:42:54 -06:00
|
|
|
uiClsId, eActiveClassifierRuleContext,
|
|
|
|
&pstClassifierEntry);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (nClsidIndex == PHS_INVALID_TABLE_INDEX) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
|
|
|
|
"No PHS Rule Defined For Classifier\n");
|
2013-02-20 21:25:27 -07:00
|
|
|
lStatus = STATUS_PHS_NOCOMPRESSION;
|
2010-09-08 15:46:36 -06:00
|
|
|
return lStatus;
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/* get rule from SF id,Cls ID pair and proceed */
|
2013-02-20 21:25:27 -07:00
|
|
|
pstPhsRule = pstClassifierEntry->pstPhsRule;
|
2013-02-20 21:25:28 -07:00
|
|
|
if (!ValidatePHSRuleComplete(pstPhsRule)) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
|
|
|
|
"PHS Rule Defined For Classifier But Not Complete\n");
|
2013-02-20 21:25:27 -07:00
|
|
|
lStatus = STATUS_PHS_NOCOMPRESSION;
|
2010-09-08 15:46:36 -06:00
|
|
|
return lStatus;
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/* Compress Packet */
|
2014-07-15 01:43:03 -06:00
|
|
|
lStatus = phs_compress(pstPhsRule,
|
|
|
|
(PUCHAR)pvInputBuffer,
|
|
|
|
(PUCHAR)pvOutputBuffer,
|
|
|
|
pOldHeaderSize,
|
|
|
|
pNewHeaderSize);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (lStatus == STATUS_PHS_COMPRESSED) {
|
2014-07-15 01:42:54 -06:00
|
|
|
pstPhsRule->PHSModifiedBytes +=
|
|
|
|
*pOldHeaderSize - *pNewHeaderSize - 1;
|
2010-09-08 15:46:36 -06:00
|
|
|
pstPhsRule->PHSModifiedNumPackets++;
|
2014-07-15 01:43:04 -06:00
|
|
|
} else {
|
2010-09-08 15:46:36 -06:00
|
|
|
pstPhsRule->PHSErrorNumPackets++;
|
2014-07-15 01:43:04 -06:00
|
|
|
}
|
2010-09-08 15:46:36 -06:00
|
|
|
|
|
|
|
return lStatus;
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* PhsDeCompress
|
|
|
|
*
|
|
|
|
* Routine Description:
|
|
|
|
* Exported function to restore the packet header in Rx path.
|
|
|
|
*
|
|
|
|
* Arguments:
|
2014-07-15 01:43:15 -06:00
|
|
|
* 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.
|
2013-02-20 21:25:29 -07:00
|
|
|
*
|
|
|
|
* Return Value:
|
|
|
|
*
|
|
|
|
* 0 if successful,
|
|
|
|
* >0 Error.
|
|
|
|
*/
|
2013-09-17 01:42:17 -06:00
|
|
|
static ULONG PhsDeCompress(IN void *pvContext,
|
2014-07-15 01:42:54 -06:00
|
|
|
IN B_UINT16 uiVcid,
|
|
|
|
IN void *pvInputBuffer,
|
|
|
|
OUT void *pvOutputBuffer,
|
|
|
|
OUT UINT *pInHeaderSize,
|
|
|
|
OUT UINT *pOutHeaderSize)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:27 -07:00
|
|
|
UINT nSFIndex = 0, nPhsRuleIndex = 0;
|
2012-12-19 22:31:30 -07:00
|
|
|
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
|
2012-12-19 22:31:34 -07:00
|
|
|
struct bcm_phs_rule *pstPhsRule = NULL;
|
2010-09-08 15:46:36 -06:00
|
|
|
UINT phsi;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2014-07-15 01:42:54 -06:00
|
|
|
struct bcm_phs_extension *pDeviceExtension =
|
|
|
|
(struct bcm_phs_extension *)pvContext;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
|
|
|
*pInHeaderSize = 0;
|
2013-02-20 21:25:28 -07:00
|
|
|
if (pDeviceExtension == NULL) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
|
|
|
|
DBG_LVL_ALL, "Invalid Device Extension\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_PHS_INVALID_DEVICE_EXETENSION;
|
|
|
|
}
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL,
|
|
|
|
"Restoring header\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
|
|
|
phsi = *((unsigned char *)(pvInputBuffer));
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL,
|
|
|
|
"PHSI To Be Used For restore : %x\n", phsi);
|
2013-02-20 21:25:27 -07:00
|
|
|
if (phsi == UNCOMPRESSED_PACKET)
|
2010-09-08 15:46:36 -06:00
|
|
|
return STATUS_PHS_NOCOMPRESSION;
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/* Retrieve the SFID Entry Index for requested Service Flow */
|
2010-09-08 15:46:36 -06:00
|
|
|
nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
|
2014-07-15 01:42:54 -06:00
|
|
|
uiVcid, &pstServiceFlowEntry);
|
2013-02-20 21:25:28 -07:00
|
|
|
if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"SFID Match Failed During Lookup\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_SF_MATCH_FAIL;
|
|
|
|
}
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
|
|
|
|
phsi,
|
|
|
|
eActiveClassifierRuleContext,
|
|
|
|
&pstPhsRule);
|
2013-02-20 21:25:28 -07:00
|
|
|
if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) {
|
2014-07-15 01:43:15 -06:00
|
|
|
/* Phs Rule does not exist in active rules table. Lets try
|
|
|
|
* in the old rules table. */
|
2010-09-08 15:46:36 -06:00
|
|
|
nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
|
2014-07-15 01:42:54 -06:00
|
|
|
phsi,
|
|
|
|
eOldClassifierRuleContext,
|
|
|
|
&pstPhsRule);
|
2013-02-20 21:25:27 -07:00
|
|
|
if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_PHSRULE_MATCH_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer,
|
2014-07-15 01:42:54 -06:00
|
|
|
(PUCHAR)pvOutputBuffer,
|
|
|
|
pstPhsRule,
|
|
|
|
pOutHeaderSize);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
|
|
|
pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1;
|
|
|
|
|
|
|
|
pstPhsRule->PHSModifiedNumPackets++;
|
|
|
|
return STATUS_PHS_COMPRESSED;
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* Procedure: free_phs_serviceflow_rules
|
|
|
|
*
|
2014-07-15 01:43:15 -06:00
|
|
|
* Description: This routine is responsible for freeing memory allocated for
|
|
|
|
* PHS rules.
|
2013-02-20 21:25:29 -07:00
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* rules - ptr to S_SERVICEFLOW_TABLE structure.
|
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
* Does not return any value.
|
|
|
|
*/
|
2012-12-19 22:31:29 -07:00
|
|
|
static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:27 -07:00
|
|
|
int i, j;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2014-07-15 01:43:05 -06:00
|
|
|
struct bcm_phs_classifier_entry *curr_act_rules_list;
|
|
|
|
struct bcm_phs_classifier_entry *curr_old_rules_list;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
|
|
|
|
"=======>\n");
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:06 -06:00
|
|
|
if (!psServiceFlowRulesTable)
|
|
|
|
goto out;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:43:06 -06:00
|
|
|
for (i = 0; i < MAX_SERVICEFLOWS; i++) {
|
|
|
|
struct bcm_phs_entry stServiceFlowEntry =
|
|
|
|
psServiceFlowRulesTable->stSFList[i];
|
|
|
|
struct bcm_phs_classifier_table *pstClassifierRulesTable =
|
|
|
|
stServiceFlowEntry.pstClassifierTable;
|
2013-02-20 21:25:28 -07:00
|
|
|
|
2014-07-15 01:43:06 -06:00
|
|
|
if (pstClassifierRulesTable) {
|
|
|
|
for (j = 0; j < MAX_PHSRULE_PER_SF; j++) {
|
|
|
|
curr_act_rules_list =
|
|
|
|
&pstClassifierRulesTable->stActivePhsRulesList[j];
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:06 -06:00
|
|
|
curr_old_rules_list =
|
|
|
|
&pstClassifierRulesTable->stOldPhsRulesList[j];
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:06 -06:00
|
|
|
if (curr_act_rules_list->pstPhsRule) {
|
2014-07-15 01:43:05 -06:00
|
|
|
|
2014-07-15 01:43:06 -06:00
|
|
|
if (curr_act_rules_list->pstPhsRule->u8RefCnt)
|
|
|
|
curr_act_rules_list->pstPhsRule->u8RefCnt--;
|
2014-07-15 01:43:05 -06:00
|
|
|
|
2014-07-15 01:43:06 -06:00
|
|
|
if (0 == curr_act_rules_list->pstPhsRule->u8RefCnt)
|
|
|
|
kfree(curr_act_rules_list->pstPhsRule);
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:06 -06:00
|
|
|
curr_act_rules_list->pstPhsRule = NULL;
|
|
|
|
}
|
2013-02-20 21:25:28 -07:00
|
|
|
|
2014-07-15 01:43:06 -06:00
|
|
|
if (curr_old_rules_list->pstPhsRule) {
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:06 -06:00
|
|
|
if (curr_old_rules_list->pstPhsRule->u8RefCnt)
|
|
|
|
curr_old_rules_list->pstPhsRule->u8RefCnt--;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:06 -06:00
|
|
|
if (0 == curr_old_rules_list->pstPhsRule->u8RefCnt)
|
|
|
|
kfree(curr_old_rules_list->pstPhsRule);
|
|
|
|
|
|
|
|
curr_old_rules_list->pstPhsRule = NULL;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
}
|
2014-07-15 01:43:06 -06:00
|
|
|
kfree(pstClassifierRulesTable);
|
|
|
|
stServiceFlowEntry.pstClassifierTable =
|
|
|
|
pstClassifierRulesTable = NULL;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 01:43:06 -06:00
|
|
|
out:
|
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
kfree(psServiceFlowRulesTable);
|
|
|
|
psServiceFlowRulesTable = NULL;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
2014-07-15 01:43:08 -06:00
|
|
|
static bool ValidatePHSRuleComplete(IN const struct bcm_phs_rule *psPhsRule)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2014-07-15 01:43:07 -06:00
|
|
|
return (psPhsRule &&
|
|
|
|
psPhsRule->u8PHSI &&
|
|
|
|
psPhsRule->u8PHSS &&
|
|
|
|
psPhsRule->u8PHSFLength);
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
2012-12-19 22:31:29 -07:00
|
|
|
UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable,
|
2014-07-15 01:42:54 -06:00
|
|
|
IN B_UINT16 uiVcid,
|
|
|
|
struct bcm_phs_entry **ppstServiceFlowEntry)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:27 -07:00
|
|
|
int i;
|
2014-07-15 01:43:09 -06:00
|
|
|
struct bcm_phs_entry *curr_sf_list;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
for (i = 0; i < MAX_SERVICEFLOWS; i++) {
|
2014-07-15 01:43:09 -06:00
|
|
|
curr_sf_list = &psServiceFlowTable->stSFList[i];
|
2014-07-15 01:43:10 -06:00
|
|
|
if (curr_sf_list->bUsed && (curr_sf_list->uiVcid == uiVcid)) {
|
|
|
|
*ppstServiceFlowEntry = curr_sf_list;
|
|
|
|
return i;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*ppstServiceFlowEntry = NULL;
|
|
|
|
return PHS_INVALID_TABLE_INDEX;
|
|
|
|
}
|
|
|
|
|
2013-09-17 01:42:17 -06:00
|
|
|
static UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
|
2014-07-15 01:42:54 -06:00
|
|
|
IN B_UINT32 uiClsid,
|
|
|
|
enum bcm_phs_classifier_context eClsContext,
|
|
|
|
OUT struct bcm_phs_classifier_entry **ppstClassifierEntry)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
|
|
|
int i;
|
2012-12-19 22:31:32 -07:00
|
|
|
struct bcm_phs_classifier_entry *psClassifierRules = NULL;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
for (i = 0; i < MAX_PHSRULE_PER_SF; i++) {
|
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if (eClsContext == eActiveClassifierRuleContext)
|
2014-07-15 01:42:54 -06:00
|
|
|
psClassifierRules =
|
|
|
|
&pstClassifierTable->stActivePhsRulesList[i];
|
2010-09-08 15:46:36 -06:00
|
|
|
else
|
2014-07-15 01:42:54 -06:00
|
|
|
psClassifierRules =
|
|
|
|
&pstClassifierTable->stOldPhsRulesList[i];
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:43:11 -06:00
|
|
|
if (psClassifierRules->bUsed &&
|
|
|
|
(psClassifierRules->uiClassifierRuleId == uiClsid)) {
|
|
|
|
*ppstClassifierEntry = psClassifierRules;
|
|
|
|
return i;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*ppstClassifierEntry = NULL;
|
|
|
|
return PHS_INVALID_TABLE_INDEX;
|
|
|
|
}
|
|
|
|
|
2012-12-19 22:31:31 -07:00
|
|
|
static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
|
2014-07-15 01:42:54 -06:00
|
|
|
IN B_UINT32 uiPHSI,
|
|
|
|
enum bcm_phs_classifier_context eClsContext,
|
|
|
|
OUT struct bcm_phs_rule **ppstPhsRule)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
|
|
|
int i;
|
2012-12-19 22:31:32 -07:00
|
|
|
struct bcm_phs_classifier_entry *pstClassifierRule = NULL;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
for (i = 0; i < MAX_PHSRULE_PER_SF; i++) {
|
2013-02-20 21:25:27 -07:00
|
|
|
if (eClsContext == eActiveClassifierRuleContext)
|
2014-07-15 01:42:54 -06:00
|
|
|
pstClassifierRule =
|
|
|
|
&pstClassifierTable->stActivePhsRulesList[i];
|
2010-09-08 15:46:36 -06:00
|
|
|
else
|
2014-07-15 01:42:54 -06:00
|
|
|
pstClassifierRule =
|
|
|
|
&pstClassifierTable->stOldPhsRulesList[i];
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:12 -06:00
|
|
|
if (pstClassifierRule->bUsed &&
|
|
|
|
(pstClassifierRule->u8PHSI == uiPHSI)) {
|
|
|
|
*ppstPhsRule = pstClassifierRule->pstPhsRule;
|
|
|
|
return i;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*ppstPhsRule = NULL;
|
|
|
|
return PHS_INVALID_TABLE_INDEX;
|
|
|
|
}
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
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)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2012-12-19 22:31:31 -07:00
|
|
|
struct bcm_phs_classifier_table *psaClassifiertable = NULL;
|
2010-09-08 15:46:36 -06:00
|
|
|
UINT uiStatus = 0;
|
|
|
|
int iSfIndex;
|
2013-10-28 02:36:19 -06:00
|
|
|
bool bFreeEntryFound = false;
|
2014-07-15 01:43:13 -06:00
|
|
|
struct bcm_phs_entry *curr_list;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/* Check for a free entry in SFID table */
|
2013-02-20 21:25:28 -07:00
|
|
|
for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++) {
|
2014-07-15 01:43:13 -06:00
|
|
|
curr_list = &psServiceFlowTable->stSFList[iSfIndex];
|
|
|
|
if (!curr_list->bUsed) {
|
2010-09-08 15:46:36 -06:00
|
|
|
bFreeEntryFound = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if (!bFreeEntryFound)
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_SFTABLE_FULL;
|
|
|
|
|
2014-07-15 01:43:13 -06:00
|
|
|
psaClassifiertable = curr_list->pstClassifierTable;
|
|
|
|
uiStatus = CreateClassifierPHSRule(uiClsId,
|
|
|
|
psaClassifiertable,
|
|
|
|
psPhsRule,
|
|
|
|
eActiveClassifierRuleContext,
|
|
|
|
u8AssociatedPHSI);
|
2013-02-20 21:25:28 -07:00
|
|
|
if (uiStatus == PHS_SUCCESS) {
|
2013-02-20 21:25:29 -07:00
|
|
|
/* Add entry at free index to the SF */
|
2014-07-15 01:43:13 -06:00
|
|
|
curr_list->bUsed = TRUE;
|
|
|
|
curr_list->uiVcid = uiVcid;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return uiStatus;
|
|
|
|
}
|
|
|
|
|
2013-09-17 01:42:17 -06:00
|
|
|
static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
|
2014-07-15 01:42:54 -06:00
|
|
|
IN B_UINT16 uiClsId,
|
|
|
|
IN struct bcm_phs_entry *pstServiceFlowEntry,
|
|
|
|
struct bcm_phs_rule *psPhsRule,
|
|
|
|
B_UINT8 u8AssociatedPHSI)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2012-12-19 22:31:32 -07:00
|
|
|
struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
|
2013-02-20 21:25:27 -07:00
|
|
|
UINT uiStatus = PHS_SUCCESS;
|
2010-09-08 15:46:36 -06:00
|
|
|
UINT nClassifierIndex = 0;
|
2012-12-19 22:31:31 -07:00
|
|
|
struct bcm_phs_classifier_table *psaClassifiertable = NULL;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
psaClassifiertable = pstServiceFlowEntry->pstClassifierTable;
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
|
|
|
|
"==>");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
|
|
|
/* Check if the supplied Classifier already exists */
|
2013-02-20 21:25:27 -07:00
|
|
|
nClassifierIndex = GetClassifierEntry(
|
|
|
|
pstServiceFlowEntry->pstClassifierTable,
|
|
|
|
uiClsId,
|
|
|
|
eActiveClassifierRuleContext,
|
|
|
|
&pstClassifierEntry);
|
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (nClassifierIndex == PHS_INVALID_TABLE_INDEX) {
|
2010-09-08 15:46:36 -06:00
|
|
|
/*
|
2014-07-15 01:43:15 -06:00
|
|
|
* The Classifier doesn't exist. So its a new classifier being
|
|
|
|
* added.
|
2013-02-20 21:25:29 -07:00
|
|
|
* Add new entry to associate PHS Rule to the Classifier
|
|
|
|
*/
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable,
|
2014-07-15 01:42:54 -06:00
|
|
|
psPhsRule,
|
|
|
|
eActiveClassifierRuleContext,
|
|
|
|
u8AssociatedPHSI);
|
2010-09-08 15:46:36 -06:00
|
|
|
return uiStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2013-02-20 21:25:29 -07:00
|
|
|
* The Classifier exists.The PHS Rule for this classifier
|
|
|
|
* is being modified
|
|
|
|
*/
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) {
|
2013-02-20 21:25:27 -07:00
|
|
|
if (pstClassifierEntry->pstPhsRule == NULL)
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_PHS_INVALID_PHS_RULE;
|
|
|
|
|
|
|
|
/*
|
2014-07-15 01:43:15 -06:00
|
|
|
* This rule already exists if any fields are changed for this
|
|
|
|
* PHS rule update them.
|
2013-02-20 21:25:29 -07:00
|
|
|
*/
|
2013-02-20 21:25:27 -07:00
|
|
|
/* If any part of PHSF is valid then we update PHSF */
|
2013-02-20 21:25:28 -07:00
|
|
|
if (psPhsRule->u8PHSFLength) {
|
2013-02-20 21:25:29 -07:00
|
|
|
/* update PHSF */
|
2010-11-01 07:35:21 -06:00
|
|
|
memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
|
2014-07-15 01:42:54 -06:00
|
|
|
psPhsRule->u8PHSF,
|
|
|
|
MAX_PHS_LENGTHS);
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (psPhsRule->u8PHSFLength) {
|
2013-02-20 21:25:29 -07:00
|
|
|
/* update PHSFLen */
|
2014-07-15 01:42:54 -06:00
|
|
|
pstClassifierEntry->pstPhsRule->u8PHSFLength =
|
|
|
|
psPhsRule->u8PHSFLength;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (psPhsRule->u8PHSMLength) {
|
2013-02-20 21:25:29 -07:00
|
|
|
/* update PHSM */
|
2010-11-01 07:35:21 -06:00
|
|
|
memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
|
2014-07-15 01:42:54 -06:00
|
|
|
psPhsRule->u8PHSM,
|
|
|
|
MAX_PHS_LENGTHS);
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (psPhsRule->u8PHSMLength) {
|
2013-02-20 21:25:29 -07:00
|
|
|
/* update PHSM Len */
|
2010-09-08 15:46:36 -06:00
|
|
|
pstClassifierEntry->pstPhsRule->u8PHSMLength =
|
2013-02-20 21:25:27 -07:00
|
|
|
psPhsRule->u8PHSMLength;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (psPhsRule->u8PHSS) {
|
2013-02-20 21:25:29 -07:00
|
|
|
/* update PHSS */
|
2014-07-15 01:42:54 -06:00
|
|
|
pstClassifierEntry->pstPhsRule->u8PHSS =
|
|
|
|
psPhsRule->u8PHSS;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/* update PHSV */
|
2010-09-08 15:46:36 -06:00
|
|
|
pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV;
|
2013-02-20 21:25:28 -07:00
|
|
|
} else {
|
2013-02-20 21:25:29 -07:00
|
|
|
/* A new rule is being set for this classifier. */
|
2014-07-15 01:42:54 -06:00
|
|
|
uiStatus = UpdateClassifierPHSRule(uiClsId,
|
|
|
|
pstClassifierEntry,
|
|
|
|
psaClassifiertable,
|
|
|
|
psPhsRule,
|
|
|
|
u8AssociatedPHSI);
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return uiStatus;
|
|
|
|
}
|
|
|
|
|
2010-11-01 10:24:00 -06:00
|
|
|
static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
|
2014-07-15 01:42:54 -06:00
|
|
|
struct bcm_phs_classifier_table *psaClassifiertable,
|
|
|
|
struct bcm_phs_rule *psPhsRule,
|
|
|
|
enum bcm_phs_classifier_context eClsContext,
|
|
|
|
B_UINT8 u8AssociatedPHSI)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
|
|
|
UINT iClassifierIndex = 0;
|
2013-10-28 02:36:19 -06:00
|
|
|
bool bFreeEntryFound = false;
|
2012-12-19 22:31:32 -07:00
|
|
|
struct bcm_phs_classifier_entry *psClassifierRules = NULL;
|
2010-09-08 15:46:36 -06:00
|
|
|
UINT nStatus = PHS_SUCCESS;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
|
|
|
|
"Inside CreateClassifierPHSRule");
|
2013-02-20 21:25:27 -07:00
|
|
|
|
|
|
|
if (psaClassifiertable == NULL)
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_INVALID_CLASSIFIERTABLE_FOR_SF;
|
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (eClsContext == eOldClassifierRuleContext) {
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* If An Old Entry for this classifier ID already exists in the
|
|
|
|
* old rules table replace it.
|
|
|
|
*/
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
iClassifierIndex = GetClassifierEntry(psaClassifiertable,
|
|
|
|
uiClsId,
|
|
|
|
eClsContext,
|
|
|
|
&psClassifierRules);
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (iClassifierIndex != PHS_INVALID_TABLE_INDEX) {
|
2010-09-08 15:46:36 -06:00
|
|
|
/*
|
2013-02-20 21:25:29 -07:00
|
|
|
* The Classifier already exists in the old rules table
|
|
|
|
* Lets replace the old classifier with the new one.
|
|
|
|
*/
|
2010-09-08 15:46:36 -06:00
|
|
|
bFreeEntryFound = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (!bFreeEntryFound) {
|
2013-02-20 21:25:29 -07:00
|
|
|
/* Continue to search for a free location to add the rule */
|
2013-02-20 21:25:27 -07:00
|
|
|
for (iClassifierIndex = 0; iClassifierIndex <
|
2013-02-20 21:25:28 -07:00
|
|
|
MAX_PHSRULE_PER_SF; iClassifierIndex++) {
|
2013-02-20 21:25:27 -07:00
|
|
|
if (eClsContext == eActiveClassifierRuleContext)
|
|
|
|
psClassifierRules = &psaClassifiertable->stActivePhsRulesList[iClassifierIndex];
|
2010-09-08 15:46:36 -06:00
|
|
|
else
|
2013-02-20 21:25:27 -07:00
|
|
|
psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (!psClassifierRules->bUsed) {
|
2010-09-08 15:46:36 -06:00
|
|
|
bFreeEntryFound = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (!bFreeEntryFound) {
|
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if (eClsContext == eActiveClassifierRuleContext)
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_CLSASSIFIER_TABLE_FULL;
|
2013-02-20 21:25:28 -07:00
|
|
|
else {
|
2014-07-15 01:43:15 -06:00
|
|
|
/* Lets replace the oldest rule if we are looking in
|
|
|
|
* old Rule table */
|
2013-02-20 21:25:27 -07:00
|
|
|
if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF)
|
|
|
|
psaClassifiertable->uiOldestPhsRuleIndex = 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
iClassifierIndex =
|
|
|
|
psaClassifiertable->uiOldestPhsRuleIndex;
|
|
|
|
psClassifierRules =
|
|
|
|
&psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
(psaClassifiertable->uiOldestPhsRuleIndex)++;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (eClsContext == eOldClassifierRuleContext) {
|
|
|
|
|
|
|
|
if (psClassifierRules->pstPhsRule == NULL) {
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
psClassifierRules->pstPhsRule =
|
|
|
|
kmalloc(sizeof(struct bcm_phs_rule),
|
|
|
|
GFP_KERNEL);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if (NULL == psClassifierRules->pstPhsRule)
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_PHSRULE_MEMALLOC_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
psClassifierRules->bUsed = TRUE;
|
|
|
|
psClassifierRules->uiClassifierRuleId = uiClsId;
|
|
|
|
psClassifierRules->u8PHSI = psPhsRule->u8PHSI;
|
2014-07-15 01:42:54 -06:00
|
|
|
psClassifierRules->bUnclassifiedPHSRule =
|
|
|
|
psPhsRule->bUnclassifiedPHSRule;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
/* Update The PHS rule */
|
2014-07-15 01:42:54 -06:00
|
|
|
memcpy(psClassifierRules->pstPhsRule, psPhsRule,
|
|
|
|
sizeof(struct bcm_phs_rule));
|
2013-02-20 21:25:28 -07:00
|
|
|
} else
|
2014-07-15 01:42:54 -06:00
|
|
|
nStatus = UpdateClassifierPHSRule(uiClsId,
|
|
|
|
psClassifierRules,
|
|
|
|
psaClassifiertable,
|
|
|
|
psPhsRule,
|
|
|
|
u8AssociatedPHSI);
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2010-09-08 15:46:36 -06:00
|
|
|
return nStatus;
|
|
|
|
}
|
|
|
|
|
2010-11-01 10:24:00 -06:00
|
|
|
static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
|
2014-07-15 01:42:54 -06:00
|
|
|
IN struct bcm_phs_classifier_entry *pstClassifierEntry,
|
|
|
|
struct bcm_phs_classifier_table *psaClassifiertable,
|
|
|
|
struct bcm_phs_rule *psPhsRule,
|
|
|
|
B_UINT8 u8AssociatedPHSI)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2012-12-19 22:31:34 -07:00
|
|
|
struct bcm_phs_rule *pstAddPhsRule = NULL;
|
2013-02-20 21:25:27 -07:00
|
|
|
UINT nPhsRuleIndex = 0;
|
2013-10-28 02:36:19 -06:00
|
|
|
bool bPHSRuleOrphaned = false;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2013-02-20 21:25:27 -07:00
|
|
|
|
|
|
|
psPhsRule->u8RefCnt = 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry */
|
2013-02-20 21:25:27 -07:00
|
|
|
bPHSRuleOrphaned = DerefPhsRule(uiClsId, psaClassifiertable,
|
|
|
|
pstClassifierEntry->pstPhsRule);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:43:15 -06:00
|
|
|
/* Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in
|
|
|
|
* Classifier table for this SF */
|
2013-02-20 21:25:27 -07:00
|
|
|
nPhsRuleIndex = GetPhsRuleEntry(psaClassifiertable, u8AssociatedPHSI,
|
2014-07-15 01:42:54 -06:00
|
|
|
eActiveClassifierRuleContext,
|
|
|
|
&pstAddPhsRule);
|
2013-02-20 21:25:28 -07:00
|
|
|
if (PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) {
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"\nAdding New PHSRuleEntry For Classifier");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (psPhsRule->u8PHSI == 0) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
|
|
|
|
DBG_LVL_ALL, "\nError PHSI is Zero\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_PHS_INVALID_PHS_RULE;
|
|
|
|
}
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:15 -06:00
|
|
|
/* Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for
|
|
|
|
* uiClsId */
|
2013-10-28 02:36:19 -06:00
|
|
|
if (false == bPHSRuleOrphaned) {
|
2013-02-20 21:25:28 -07:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
pstClassifierEntry->pstPhsRule =
|
|
|
|
kmalloc(sizeof(struct bcm_phs_rule),
|
|
|
|
GFP_KERNEL);
|
2013-02-20 21:25:27 -07:00
|
|
|
if (NULL == pstClassifierEntry->pstPhsRule)
|
2010-09-08 15:46:36 -06:00
|
|
|
return ERR_PHSRULE_MEMALLOC_FAIL;
|
|
|
|
}
|
2014-07-15 01:42:54 -06:00
|
|
|
memcpy(pstClassifierEntry->pstPhsRule, psPhsRule,
|
|
|
|
sizeof(struct bcm_phs_rule));
|
2013-02-20 21:25:28 -07:00
|
|
|
} else {
|
2014-07-15 01:43:15 -06:00
|
|
|
/* Step 2.b PHS Rule Exists Tie uiClsId with the existing
|
|
|
|
* PHS Rule */
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"\nTying Classifier to Existing PHS Rule");
|
2013-02-20 21:25:28 -07:00
|
|
|
if (bPHSRuleOrphaned) {
|
2010-11-01 07:35:21 -06:00
|
|
|
kfree(pstClassifierEntry->pstPhsRule);
|
2010-09-08 15:46:36 -06:00
|
|
|
pstClassifierEntry->pstPhsRule = NULL;
|
|
|
|
}
|
|
|
|
pstClassifierEntry->pstPhsRule = pstAddPhsRule;
|
|
|
|
}
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2010-09-08 15:46:36 -06:00
|
|
|
pstClassifierEntry->bUsed = TRUE;
|
|
|
|
pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI;
|
|
|
|
pstClassifierEntry->uiClassifierRuleId = uiClsId;
|
|
|
|
pstClassifierEntry->pstPhsRule->u8RefCnt++;
|
2014-07-15 01:42:54 -06:00
|
|
|
pstClassifierEntry->bUnclassifiedPHSRule =
|
|
|
|
pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
|
|
|
return PHS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
static bool DerefPhsRule(IN B_UINT16 uiClsId,
|
|
|
|
struct bcm_phs_classifier_table *psaClassifiertable,
|
|
|
|
struct bcm_phs_rule *pstPhsRule)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:27 -07:00
|
|
|
if (pstPhsRule == NULL)
|
2013-10-28 02:36:19 -06:00
|
|
|
return false;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
|
|
|
if (pstPhsRule->u8RefCnt)
|
2010-09-08 15:46:36 -06:00
|
|
|
pstPhsRule->u8RefCnt--;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:43:14 -06:00
|
|
|
return (0 == pstPhsRule->u8RefCnt);
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
2014-07-15 01:42:56 -06:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2014-07-15 01:42:55 -06:00
|
|
|
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) {
|
2014-07-15 01:42:56 -06:00
|
|
|
dbg_print_st_cls_entry(ad,
|
|
|
|
st_serv_flow_entry,
|
|
|
|
&st_cls_entry);
|
2014-07-15 01:42:55 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-19 22:31:28 -07:00
|
|
|
void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2014-07-15 01:42:55 -06:00
|
|
|
int i;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,
|
|
|
|
"\n Dumping PHS Rules :\n");
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
for (i = 0; i < MAX_SERVICEFLOWS; i++) {
|
|
|
|
|
2012-12-19 22:31:30 -07:00
|
|
|
struct bcm_phs_entry stServFlowEntry =
|
2013-02-20 21:25:27 -07:00
|
|
|
pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i];
|
|
|
|
|
2014-07-15 01:42:55 -06:00
|
|
|
if (!stServFlowEntry.bUsed)
|
|
|
|
continue;
|
2013-02-20 21:25:28 -07:00
|
|
|
|
2014-07-15 01:42:55 -06:00
|
|
|
phsrules_per_sf_dbg_print(Adapter, &stServFlowEntry);
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* Procedure: phs_decompress
|
|
|
|
*
|
|
|
|
* Description: This routine restores the static fields within the packet.
|
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* in_buf - ptr to incoming packet buffer.
|
2014-07-15 01:43:15 -06:00
|
|
|
* 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.
|
2013-02-20 21:25:29 -07:00
|
|
|
*
|
|
|
|
* Returns:
|
2014-07-15 01:43:15 -06:00
|
|
|
* 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.
|
2013-02-20 21:25:29 -07:00
|
|
|
*/
|
2013-09-17 01:42:17 -06:00
|
|
|
static int phs_decompress(unsigned char *in_buf,
|
2014-07-15 01:42:54 -06:00
|
|
|
unsigned char *out_buf,
|
|
|
|
struct bcm_phs_rule *decomp_phs_rules,
|
|
|
|
UINT *header_size)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:27 -07:00
|
|
|
int phss, size = 0;
|
2012-12-19 22:31:34 -07:00
|
|
|
struct bcm_phs_rule *tmp_memb;
|
2013-02-20 21:25:27 -07:00
|
|
|
int bit, i = 0;
|
|
|
|
unsigned char *phsf, *phsm;
|
|
|
|
int in_buf_len = *header_size - 1;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2010-09-08 15:46:36 -06:00
|
|
|
in_buf++;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL,
|
|
|
|
"====>\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
*header_size = 0;
|
|
|
|
|
2014-06-17 08:48:54 -06:00
|
|
|
if (decomp_phs_rules == NULL)
|
2010-09-08 15:46:36 -06:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
tmp_memb = decomp_phs_rules;
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
2014-07-15 01:43:15 -06:00
|
|
|
* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,
|
|
|
|
* "\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
|
2013-02-20 21:25:29 -07:00
|
|
|
* header_size = tmp_memb->u8PHSFLength;
|
|
|
|
*/
|
2013-02-20 21:25:27 -07:00
|
|
|
phss = tmp_memb->u8PHSS;
|
|
|
|
phsf = tmp_memb->u8PHSF;
|
|
|
|
phsm = tmp_memb->u8PHSM;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if (phss > MAX_PHS_LENGTHS)
|
2010-09-08 15:46:36 -06:00
|
|
|
phss = MAX_PHS_LENGTHS;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
2014-07-15 01:43:15 -06:00
|
|
|
* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,
|
|
|
|
* "\nDECOMP:
|
2013-02-20 21:25:29 -07:00
|
|
|
* In phs_decompress PHSI %d phss %d index %d",phsi,phss,index));
|
|
|
|
*/
|
2013-02-20 21:25:28 -07:00
|
|
|
while ((phss > 0) && (size < in_buf_len)) {
|
2013-02-20 21:25:27 -07:00
|
|
|
bit = ((*phsm << i) & SUPPRESS);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (bit == SUPPRESS) {
|
2010-09-08 15:46:36 -06:00
|
|
|
*out_buf = *phsf;
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"\nDECOMP:In phss %d phsf %d output %d",
|
2013-02-20 21:25:27 -07:00
|
|
|
phss, *phsf, *out_buf);
|
2013-02-20 21:25:28 -07:00
|
|
|
} else {
|
2010-09-08 15:46:36 -06:00
|
|
|
*out_buf = *in_buf;
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"\nDECOMP:In phss %d input %d output %d",
|
2013-02-20 21:25:27 -07:00
|
|
|
phss, *in_buf, *out_buf);
|
2010-09-08 15:46:36 -06:00
|
|
|
in_buf++;
|
|
|
|
size++;
|
|
|
|
}
|
|
|
|
out_buf++;
|
|
|
|
phsf++;
|
|
|
|
phss--;
|
|
|
|
i++;
|
2013-02-20 21:25:27 -07:00
|
|
|
*header_size = *header_size + 1;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (i > MAX_NO_BIT) {
|
2013-02-20 21:25:27 -07:00
|
|
|
i = 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
phsm++;
|
|
|
|
}
|
|
|
|
}
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2010-09-08 15:46:36 -06:00
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* Procedure: phs_compress
|
|
|
|
*
|
2014-07-15 01:43:15 -06:00
|
|
|
* 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.
|
2013-02-20 21:25:29 -07:00
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* phs_rule - ptr to PHS rule.
|
|
|
|
* in_buf - ptr to incoming packet buffer.
|
2014-07-15 01:43:15 -06:00
|
|
|
* out_buf - ptr to output buffer where the suppressed header is
|
|
|
|
* copied.
|
2013-02-20 21:25:29 -07:00
|
|
|
* header_size - ptr to field which holds the phss.
|
|
|
|
*
|
|
|
|
* Returns:
|
2014-07-15 01:43:15 -06:00
|
|
|
* 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.
|
2013-02-20 21:25:29 -07:00
|
|
|
*/
|
2013-02-20 21:25:27 -07:00
|
|
|
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)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
|
|
|
unsigned char *old_addr = out_buf;
|
2012-06-13 12:44:35 -06:00
|
|
|
int suppress = 0;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (phs_rule == NULL) {
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
|
|
|
|
"\nphs_compress(): phs_rule null!");
|
2010-09-08 15:46:36 -06:00
|
|
|
*out_buf = ZERO_PHSI;
|
|
|
|
return STATUS_PHS_NOCOMPRESSION;
|
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if (phs_rule->u8PHSS <= *new_header_size)
|
2010-09-08 15:46:36 -06:00
|
|
|
*header_size = phs_rule->u8PHSS;
|
|
|
|
else
|
|
|
|
*header_size = *new_header_size;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/* To copy PHSI */
|
2010-09-08 15:46:36 -06:00
|
|
|
out_buf++;
|
2013-02-20 21:25:27 -07:00
|
|
|
suppress = verify_suppress_phsf(in_buf, out_buf, phs_rule->u8PHSF,
|
|
|
|
phs_rule->u8PHSM, phs_rule->u8PHSS,
|
|
|
|
phs_rule->u8PHSV, new_header_size);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (suppress == STATUS_PHS_COMPRESSED) {
|
2010-09-08 15:46:36 -06:00
|
|
|
*old_addr = (unsigned char)phs_rule->u8PHSI;
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
|
|
|
|
"\nCOMP:In phs_compress phsi %d",
|
|
|
|
phs_rule->u8PHSI);
|
2013-02-20 21:25:28 -07:00
|
|
|
} else {
|
2010-09-08 15:46:36 -06:00
|
|
|
*old_addr = ZERO_PHSI;
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
|
|
|
|
"\nCOMP:In phs_compress PHSV Verification failed");
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2012-06-13 12:44:35 -06:00
|
|
|
return suppress;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
2013-02-20 21:25:29 -07:00
|
|
|
/*
|
|
|
|
* 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.
|
2014-07-15 01:43:15 -06:00
|
|
|
* phsf - ptr to phsf.
|
|
|
|
* phsm - ptr to phsm.
|
|
|
|
* phss - variable holding phss.
|
2013-02-20 21:25:29 -07:00
|
|
|
*
|
|
|
|
* Returns:
|
2014-07-15 01:43:15 -06:00
|
|
|
* size - The number of bytes copied into the output buffer i.e dynamic
|
|
|
|
* fields.
|
|
|
|
* 0 - Packet has failed the verification.
|
2013-02-20 21:25:29 -07:00
|
|
|
*/
|
2013-02-20 21:25:27 -07:00
|
|
|
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)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-02-20 21:25:27 -07:00
|
|
|
unsigned int size = 0;
|
|
|
|
int bit, i = 0;
|
2012-05-26 10:05:12 -06:00
|
|
|
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
|
|
|
|
"\nCOMP:In verify_phsf PHSM - 0x%X", *phsm);
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-02-20 21:25:27 -07:00
|
|
|
if (phss > (*new_header_size))
|
|
|
|
phss = *new_header_size;
|
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
while (phss > 0) {
|
2013-02-20 21:25:27 -07:00
|
|
|
bit = ((*phsm << i) & SUPPRESS);
|
2013-02-20 21:25:28 -07:00
|
|
|
if (bit == SUPPRESS) {
|
|
|
|
if (*in_buffer != *phsf) {
|
|
|
|
if (phsv == VERIFY) {
|
2013-02-20 21:25:27 -07:00
|
|
|
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);
|
2010-09-08 15:46:36 -06:00
|
|
|
return STATUS_PHS_NOCOMPRESSION;
|
|
|
|
}
|
2013-02-20 21:25:28 -07:00
|
|
|
} else
|
2013-02-20 21:25:27 -07:00
|
|
|
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);
|
2013-02-20 21:25:28 -07:00
|
|
|
} else {
|
2010-09-08 15:46:36 -06:00
|
|
|
*out_buffer = *in_buffer;
|
2013-02-20 21:25:27 -07:00
|
|
|
BCM_DEBUG_PRINT(Adapter,
|
|
|
|
DBG_TYPE_OTHERS,
|
|
|
|
PHS_SEND,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"\nCOMP:In copying_header input %d out %d",
|
|
|
|
*in_buffer,
|
|
|
|
*out_buffer);
|
2010-09-08 15:46:36 -06:00
|
|
|
out_buffer++;
|
|
|
|
size++;
|
|
|
|
}
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2010-09-08 15:46:36 -06:00
|
|
|
in_buffer++;
|
|
|
|
phsf++;
|
|
|
|
phss--;
|
|
|
|
i++;
|
2013-02-20 21:25:27 -07:00
|
|
|
|
2013-02-20 21:25:28 -07:00
|
|
|
if (i > MAX_NO_BIT) {
|
2013-02-20 21:25:27 -07:00
|
|
|
i = 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
phsm++;
|
|
|
|
}
|
|
|
|
}
|
2014-07-15 01:42:54 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
|
|
|
|
"\nCOMP:In verify_phsf success");
|
2010-09-08 15:46:36 -06:00
|
|
|
*new_header_size = size;
|
|
|
|
return STATUS_PHS_COMPRESSED;
|
|
|
|
}
|