blob: f77e7fe65d02a30cfaa4739400aa3c3fec04ba4d [file] [log] [blame]
/* l2sec/mv_eth_l2sec.h */
#ifndef L2SEC_MV_ETH_L2SEC_H
#define L2SEC_MV_ETH_L2SEC_H
#include "mvOs.h"
#include "cesa/mvCesa.h"
#include "mv_neta/l2fw/mv_eth_l2fw.h"
#include "ctrlEnv/mvCtrlEnvLib.h"
#include "mv_neta/net_dev/mv_netdev.h"
/* Taken from mvNfpSec.h */
/* IPSec defines */
#define MV_NFP_SEC_MAX_PACKET 1540
#define MV_NFP_SEC_ENC_BLOCK_SIZE 16
#define MV_NFP_SEC_ESP_OFFSET 34
/* IPSec Enumerators */
typedef enum {
MV_NFP_SEC_TUNNEL = 0,
MV_NFP_SEC_TRANSPORT,
} MV_NFP_SEC_PROT;
typedef enum {
MV_NFP_SEC_ESP = 0,
MV_NFP_SEC_AH,
} MV_NFP_SEC_ENCAP;
typedef enum {
MV_NFP_SEC_ENCRYPT = 0,
MV_NFP_SEC_DECRYPT,
} MV_NFP_SEC_OP;
typedef struct _mv_nfp_sa_stats {
MV_U32 encrypt;
MV_U32 decrypt;
MV_U32 rejected; /* slow path */
MV_U32 dropped; /* packet drop */
MV_U32 bytes;
} MV_NFP_SA_STATS;
/* IPSec Structures */
typedef struct _mv_nfp_sec_tunnel_hdr {
MV_U32 sIp; /* BE */
MV_U32 dIp; /* BE */
/* dstMac should be 2 byte aligned */
MV_U8 dstMac[MV_MAC_ADDR_SIZE]; /* BE */
MV_U8 srcMac[MV_MAC_ADDR_SIZE]; /* BE */
MV_U8 outIfIndex;
} MV_NFP_SEC_TUNNEL_HDR;
typedef struct _mv_nfp_sec_sa_entry {
MV_U32 spi; /* BE */
MV_NFP_SEC_PROT tunProt;
MV_NFP_SEC_ENCAP encap;
MV_U16 sid;
MV_U32 seqNum; /* LE */
MV_NFP_SEC_TUNNEL_HDR tunnelHdr;
MV_U32 lifeTime;
MV_U8 ivSize;
MV_U8 cipherBlockSize;
MV_U8 digestSize;
MV_NFP_SEC_OP secOp;
MV_NFP_SA_STATS stats;
} MV_NFP_SEC_SA_ENTRY;
typedef struct _mv_nfp_sec_cesa_priv {
MV_NFP_SEC_SA_ENTRY *pSaEntry;
MV_PKT_INFO *pPktInfo;
MV_U8 orgDigest[MV_CESA_MAX_DIGEST_SIZE];
MV_CESA_COMMAND *pCesaCmd;
} MV_NFP_SEC_CESA_PRIV;
int cesaChanPort[CONFIG_MV_ETH_PORTS_NUM];
#define CESA_0 0
#define CESA_1 1
/* for future - handle by CPU */
#define CESA_NONE 2
#define MV_NFP_SEC_REQ_Q_SIZE 1000
#define CESA_DEF_REQ_SIZE (256*4)
int counterNoResources[4] = {0, 0, 0, 0};
spinlock_t cesa_lock[2];
extern u32 mv_crypto_virt_base_get(u8 chan);
static MV_PKT_INFO *pPktInfoNewArray_0;
static MV_PKT_INFO *pPktInfoNewArray_1;
static MV_BUF_INFO *pBufInfoArray_0;
static MV_BUF_INFO *pBufInfoArray_1;
MV_BUF_INFO cesaBufs_0[CESA_DEF_REQ_SIZE];
MV_BUF_INFO cesaBufs_1[CESA_DEF_REQ_SIZE];
static int cesaPrivIndx_0 = 0;
static int cesaPrivIndx_1 = 0;
static int cesaCmdIndx_0 = 0;
static int cesaCmdIndx_1 = 0;
typedef struct _mv_nfp_sec_cesa_priv_l2fw {
MV_NFP_SEC_SA_ENTRY *pSaEntry;
MV_PKT_INFO *pPktInfo;
MV_U8 orgDigest[MV_CESA_MAX_DIGEST_SIZE];
MV_CESA_COMMAND *pCesaCmd;
struct eth_pbuf *pPkt;
int ifout;
int ownerId;
int inPort;
} MV_NFP_SEC_CESA_PRIV_L2FW;
MV_NFP_SEC_CESA_PRIV_L2FW *cesaPrivArray_0;
MV_NFP_SEC_CESA_PRIV_L2FW *cesaPrivArray_1;
void *cesaOSHandle = NULL;
static MV_CESA_MBUF *cesaMbufArray_0;
static MV_CESA_MBUF *cesaMbufArray_1;
static MV_CESA_COMMAND *cesaCmdArray_0;
static MV_CESA_COMMAND *cesaCmdArray_1;
static MV_NFP_SEC_SA_ENTRY sa;
atomic_t req_count[2];
int l2fw_set_cesa_chan(int port, int cesaChan);
int cesa_init(void);
/* from mv_hal/eth/gbe/mvEthRegs.h */
/* Tx descriptor bits */
#define ETH_TX_ERROR_CODE_OFFSET 1
#define ETH_TX_ERROR_CODE_MASK (3<<ETH_TX_ERROR_CODE_OFFSET)
#define ETH_TX_LATE_COLLISION_ERROR (0<<ETH_TX_ERROR_CODE_OFFSET)
#define ETH_TX_UNDERRUN_ERROR (1<<ETH_TX_ERROR_CODE_OFFSET)
#define ETH_TX_EXCESSIVE_COLLISION_ERROR (2<<ETH_TX_ERROR_CODE_OFFSET)
#define ETH_TX_LLC_SNAP_FORMAT_BIT 9
#define ETH_TX_LLC_SNAP_FORMAT_MASK (1<<ETH_TX_LLC_SNAP_FORMAT_BIT)
#define ETH_TX_IP_FRAG_BIT 10
#define ETH_TX_IP_FRAG_MASK (1<<ETH_TX_IP_FRAG_BIT)
#define ETH_TX_IP_FRAG (0<<ETH_TX_IP_FRAG_BIT)
#define ETH_TX_IP_NO_FRAG (1<<ETH_TX_IP_FRAG_BIT)
#define ETH_TX_IP_HEADER_LEN_OFFSET 11
#define ETH_TX_IP_HEADER_LEN_ALL_MASK (0xF<<ETH_TX_IP_HEADER_LEN_OFFSET)
#define ETH_TX_IP_HEADER_LEN_MASK(len) ((len)<<ETH_TX_IP_HEADER_LEN_OFFSET)
#define ETH_TX_VLAN_TAGGED_FRAME_BIT 15
#define ETH_TX_VLAN_TAGGED_FRAME_MASK (1<<ETH_TX_VLAN_TAGGED_FRAME_BIT)
#define ETH_TX_L4_TYPE_BIT 16
#define ETH_TX_L4_TCP_TYPE (0<<ETH_TX_L4_TYPE_BIT)
#define ETH_TX_L4_UDP_TYPE (1<<ETH_TX_L4_TYPE_BIT)
#define ETH_TX_GENERATE_L4_CHKSUM_BIT 17
#define ETH_TX_GENERATE_L4_CHKSUM_MASK (1<<ETH_TX_GENERATE_L4_CHKSUM_BIT)
#define ETH_TX_GENERATE_IP_CHKSUM_BIT 18
#define ETH_TX_GENERATE_IP_CHKSUM_MASK (1<<ETH_TX_GENERATE_IP_CHKSUM_BIT)
#define ETH_TX_ZERO_PADDING_BIT 19
#define ETH_TX_ZERO_PADDING_MASK (1<<ETH_TX_ZERO_PADDING_BIT)
#define ETH_TX_LAST_DESC_BIT 20
#define ETH_TX_LAST_DESC_MASK (1<<ETH_TX_LAST_DESC_BIT)
#define ETH_TX_FIRST_DESC_BIT 21
#define ETH_TX_FIRST_DESC_MASK (1<<ETH_TX_FIRST_DESC_BIT)
#define ETH_TX_GENERATE_CRC_BIT 22
#define ETH_TX_GENERATE_CRC_MASK (1<<ETH_TX_GENERATE_CRC_BIT)
#define ETH_TX_ENABLE_INTERRUPT_BIT 23
#define ETH_TX_ENABLE_INTERRUPT_MASK (1<<ETH_TX_ENABLE_INTERRUPT_BIT)
#define ETH_TX_AUTO_MODE_BIT 30
#define ETH_TX_AUTO_MODE_MASK (1<<ETH_TX_AUTO_MODE_BIT)
inline MV_VOID mvNfpSecBuildIPTunnel(MV_PKT_INFO *pPktInfo, MV_NFP_SEC_SA_ENTRY *pSAEntry)
{
MV_IP_HEADER *pIpHdr, *pIntIpHdr;
MV_U16 newIpTotalLength;
newIpTotalLength = pPktInfo->pFrags[0].dataSize - sizeof(MV_802_3_HEADER);
pIpHdr = (MV_IP_HEADER *) (pPktInfo->pFrags[0].bufVirtPtr + sizeof(MV_802_3_HEADER));
pIntIpHdr = (MV_IP_HEADER *) ((MV_U8 *) (pIpHdr) + sizeof(MV_IP_HEADER) + sizeof(MV_ESP_HEADER) +
pSAEntry->ivSize);
/* TBD - review below settings in RFC */
pIpHdr->version = 0x45;
pIpHdr->tos = 0;
pIpHdr->checksum = 0;
pIpHdr->totalLength = MV_16BIT_BE(newIpTotalLength);
pIpHdr->identifier = 0;
pIpHdr->fragmentCtrl = 0;
pIpHdr->ttl = pIntIpHdr->ttl - 1;
pIpHdr->protocol = MV_IP_PROTO_ESP;
pIpHdr->srcIP = pSAEntry->tunnelHdr.sIp;
pIpHdr->dstIP = pSAEntry->tunnelHdr.dIp;
pPktInfo->status = ETH_TX_IP_NO_FRAG | ETH_TX_GENERATE_IP_CHKSUM_MASK | (0x5 << ETH_TX_IP_HEADER_LEN_OFFSET);
return;
}
/* Append sequence number and spi, save some space for IV */
inline MV_VOID mvNfpSecBuildEspHdr(MV_PKT_INFO *pPktInfo, MV_NFP_SEC_SA_ENTRY *pSAEntry)
{
MV_ESP_HEADER *pEspHdr;
pEspHdr = (MV_ESP_HEADER *) (pPktInfo->pFrags[0].bufVirtPtr + sizeof(MV_802_3_HEADER) + sizeof(MV_IP_HEADER));
pEspHdr->spi = pSAEntry->spi;
pSAEntry->seqNum = (pSAEntry->seqNum++);
pEspHdr->seqNum = MV_32BIT_BE(pSAEntry->seqNum);
}
inline MV_VOID mvNfpSecBuildMac(MV_PKT_INFO *pPktInfo, MV_NFP_SEC_SA_ENTRY *pSAEntry)
{
MV_802_3_HEADER *pMacHdr;
pMacHdr = (MV_802_3_HEADER *) ((MV_U8 *) (pPktInfo->pFrags[0].bufVirtPtr));
memcpy(pMacHdr, &pSAEntry->tunnelHdr.dstMac, 12);
pMacHdr->typeOrLen = 0x08; /* stands for IP protocol code 16bit swapped */
return;
}
inline MV_STATUS mvSecEspProcess_0(struct eth_pbuf *pPkt, MV_PKT_INFO *pPktInfo,
MV_NFP_SEC_SA_ENTRY *pSAEntry, struct eth_port *newpp,
MV_U8 channel, int inPort)
{
MV_CESA_COMMAND *pCesaCmd;
MV_CESA_MBUF *pCesaMbuf;
MV_NFP_SEC_CESA_PRIV_L2FW *pCesaPriv;
MV_STATUS status;
MV_IP_HEADER *pIpHdr;
MV_BUF_INFO *pBuf;
pCesaCmd = &cesaCmdArray_0[cesaCmdIndx_0];
pCesaMbuf = &cesaMbufArray_0[cesaCmdIndx_0];
cesaCmdIndx_0++;
cesaCmdIndx_0 %= CESA_DEF_REQ_SIZE;
pCesaPriv = &cesaPrivArray_0[cesaPrivIndx_0++];
cesaPrivIndx_0 = cesaPrivIndx_0%(CESA_DEF_REQ_SIZE + MV_NFP_SEC_REQ_Q_SIZE);
pCesaPriv->pPktInfo = pPktInfo;
pCesaPriv->pSaEntry = pSAEntry;
pCesaPriv->pCesaCmd = pCesaCmd;
pCesaPriv->pPkt = pPkt;
pCesaPriv->ifout = newpp->port;
pCesaPriv->inPort = inPort;
/*
* Fix, encrypt/decrypt the IP payload only, --BK 20091027
*/
pBuf = pPktInfo->pFrags;
pIpHdr = (MV_IP_HEADER *)(pBuf->bufVirtPtr + sizeof(MV_802_3_HEADER));
pBuf->dataSize = MV_16BIT_BE(pIpHdr->totalLength) + sizeof(MV_802_3_HEADER);
/* after next command, pBuf->bufVirtPtr will point to ESP */
pBuf->bufVirtPtr += MV_NFP_SEC_ESP_OFFSET;
pBuf->bufPhysAddr += MV_NFP_SEC_ESP_OFFSET;
pBuf->dataSize -= MV_NFP_SEC_ESP_OFFSET;
pBuf->bufAddrShift -= MV_NFP_SEC_ESP_OFFSET;
pCesaMbuf->pFrags = pPktInfo->pFrags;
pCesaMbuf->numFrags = 1;
pCesaMbuf->mbufSize = pBuf->dataSize;
pCesaMbuf->pFrags->bufSize = pBuf->dataSize;
pCesaCmd->pReqPrv = (MV_VOID *)pCesaPriv;
pCesaCmd->sessionId = pSAEntry->sid;
pCesaCmd->pSrc = pCesaMbuf;
pCesaCmd->pDst = pCesaMbuf;
pCesaCmd->skipFlush = MV_TRUE;
/* Assume ESP */
pCesaCmd->cryptoOffset = sizeof(MV_ESP_HEADER) + pSAEntry->ivSize;
pCesaCmd->cryptoLength = pBuf->dataSize - (sizeof(MV_ESP_HEADER)
+ pSAEntry->ivSize + pSAEntry->digestSize);
pCesaCmd->ivFromUser = 0; /* relevant for encode only */
pCesaCmd->ivOffset = sizeof(MV_ESP_HEADER);
pCesaCmd->macOffset = 0;
pCesaCmd->macLength = pBuf->dataSize - pSAEntry->digestSize;
if ((pCesaCmd->digestOffset != 0) && ((pCesaCmd->digestOffset%4))) {
printk(KERN_INFO "pBuf->dataSize=%d pSAEntry->digestSize=%d in %s\n",
pBuf->dataSize, pSAEntry->digestSize, __func__);
printk(KERN_INFO "pCesaCmd->digestOffset=%d in %s\n",
pCesaCmd->digestOffset, __func__);
}
pCesaCmd->digestOffset = pBuf->dataSize - pSAEntry->digestSize ;
disable_irq(CESA_IRQ(channel));
status = mvCesaAction(channel, pCesaCmd);
enable_irq(CESA_IRQ(channel));
if (status != MV_OK) {
pSAEntry->stats.rejected++;
mvOsPrintf("%s: mvCesaAction failed %d\n", __func__, status);
}
return status;
}
inline MV_STATUS mvSecEspProcess_1(struct eth_pbuf *pPkt, MV_PKT_INFO *pPktInfo,
MV_NFP_SEC_SA_ENTRY *pSAEntry, struct eth_port *newpp,
MV_U8 channel, int inPort)
{
MV_CESA_COMMAND *pCesaCmd;
MV_CESA_MBUF *pCesaMbuf;
MV_NFP_SEC_CESA_PRIV_L2FW *pCesaPriv;
MV_STATUS status;
MV_IP_HEADER *pIpHdr;
MV_BUF_INFO *pBuf;
pCesaCmd = &cesaCmdArray_1[cesaCmdIndx_1];
pCesaMbuf = &cesaMbufArray_1[cesaCmdIndx_1];
cesaCmdIndx_1++;
cesaCmdIndx_1 %= CESA_DEF_REQ_SIZE;
pCesaPriv = &cesaPrivArray_1[cesaPrivIndx_1++];
cesaPrivIndx_1 = cesaPrivIndx_1%(CESA_DEF_REQ_SIZE + MV_NFP_SEC_REQ_Q_SIZE);
pCesaPriv->pPktInfo = pPktInfo;
pCesaPriv->pSaEntry = pSAEntry;
pCesaPriv->pCesaCmd = pCesaCmd;
pCesaPriv->pPkt = pPkt;
pCesaPriv->ifout = newpp->port;
pCesaPriv->inPort = inPort;
/*
* Fix, encrypt/decrypt the IP payload only, --BK 20091027
*/
pBuf = pPktInfo->pFrags;
pIpHdr = (MV_IP_HEADER *)(pBuf->bufVirtPtr + sizeof(MV_802_3_HEADER));
pBuf->dataSize = MV_16BIT_BE(pIpHdr->totalLength) + sizeof(MV_802_3_HEADER);
/* after next command, pBuf->bufVirtPtr will point to ESP */
pBuf->bufVirtPtr += MV_NFP_SEC_ESP_OFFSET;
pBuf->bufPhysAddr += MV_NFP_SEC_ESP_OFFSET;
pBuf->dataSize -= MV_NFP_SEC_ESP_OFFSET;
pBuf->bufAddrShift -= MV_NFP_SEC_ESP_OFFSET;
pCesaMbuf->pFrags = pPktInfo->pFrags;
pCesaMbuf->numFrags = 1;
pCesaMbuf->mbufSize = pBuf->dataSize;
pCesaMbuf->pFrags->bufSize = pBuf->dataSize;
pCesaCmd->pReqPrv = (MV_VOID *)pCesaPriv;
pCesaCmd->sessionId = pSAEntry->sid;
pCesaCmd->pSrc = pCesaMbuf;
pCesaCmd->pDst = pCesaMbuf;
pCesaCmd->skipFlush = MV_TRUE;
/* Assume ESP */
pCesaCmd->cryptoOffset = sizeof(MV_ESP_HEADER) + pSAEntry->ivSize;
pCesaCmd->cryptoLength = pBuf->dataSize - (sizeof(MV_ESP_HEADER)
+ pSAEntry->ivSize + pSAEntry->digestSize);
pCesaCmd->ivFromUser = 0; /* relevant for encode only */
pCesaCmd->ivOffset = sizeof(MV_ESP_HEADER);
pCesaCmd->macOffset = 0;
pCesaCmd->macLength = pBuf->dataSize - pSAEntry->digestSize;
if ((pCesaCmd->digestOffset != 0) && ((pCesaCmd->digestOffset%4))) {
printk(KERN_INFO "pBuf->dataSize=%d pSAEntry->digestSize=%d in %s\n",
pBuf->dataSize, pSAEntry->digestSize, __func__);
printk(KERN_INFO "pCesaCmd->digestOffset=%d in %s\n",
pCesaCmd->digestOffset, __func__);
}
pCesaCmd->digestOffset = pBuf->dataSize - pSAEntry->digestSize ;
disable_irq(CESA_IRQ(channel));
status = mvCesaAction(channel, pCesaCmd);
enable_irq(CESA_IRQ(channel));
if (status != MV_OK) {
pSAEntry->stats.rejected++;
mvOsPrintf("%s: mvCesaAction failed %d\n", __func__, status);
}
return status;
}
inline MV_STATUS mvSecOutgoing(struct eth_pbuf *pkt, MV_PKT_INFO *pPktInfo,
MV_NFP_SEC_SA_ENTRY *pSAEntry, struct eth_port *new_pp,
int inPort, MV_U8 chan)
{
MV_U8 *pTmp;
MV_U32 cryptoSize, encBlockMod, dSize;
MV_BUF_INFO *pBuf = pPktInfo->pFrags;
/* CESA Q is full drop. */
if (cesaReqResources[chan] <= 1) {
counterNoResources[inPort]++;
return MV_DROPPED;
}
cryptoSize = pBuf->dataSize - sizeof(MV_802_3_HEADER);
/* Align buffer address to beginning of new packet - TBD handle VLAN tag, LLC */
dSize = pSAEntry->ivSize + sizeof(MV_ESP_HEADER) + sizeof(MV_IP_HEADER);
pBuf->bufVirtPtr -= dSize;
pBuf->bufPhysAddr -= dSize;
pBuf->dataSize += dSize;
pBuf->bufAddrShift += dSize;
encBlockMod = (cryptoSize % MV_NFP_SEC_ENC_BLOCK_SIZE);
/* leave space for padLen + Protocol */
if (encBlockMod > 14) {
encBlockMod = MV_NFP_SEC_ENC_BLOCK_SIZE - encBlockMod;
encBlockMod += MV_NFP_SEC_ENC_BLOCK_SIZE;
} else
encBlockMod = MV_NFP_SEC_ENC_BLOCK_SIZE - encBlockMod;
/* expected frame size */
dSize = pBuf->dataSize + encBlockMod + pSAEntry->digestSize;
pBuf->dataSize += encBlockMod;
pTmp = pBuf->bufVirtPtr + pBuf->dataSize;
memset(pTmp - encBlockMod, 0, encBlockMod - 2);
*((MV_U8 *)(pTmp-2)) = (MV_U8)(encBlockMod-2);
*((MV_U8 *)(pTmp-1)) = (MV_U8)4;
pBuf->dataSize += pSAEntry->digestSize;
mvNfpSecBuildEspHdr(pPktInfo, pSAEntry);
mvNfpSecBuildIPTunnel(pPktInfo, pSAEntry);
mvNfpSecBuildMac(pPktInfo, pSAEntry);
/* flush & invalidate new MAC, IP, & ESP headers + old ip*/
dSize = pBuf->bufAddrShift + sizeof(MV_IP_HEADER) + sizeof(MV_802_3_HEADER);
if (chan == 0)
return mvSecEspProcess_0(pkt, pPktInfo, pSAEntry, new_pp, chan, inPort);
else
return mvSecEspProcess_1(pkt, pPktInfo, pSAEntry, new_pp, chan, inPort);
}
inline MV_STATUS handleEsp(struct eth_pbuf *pkt, struct neta_rx_desc *rx_desc,
struct eth_port *new_pp, int inPort)
{
MV_STATUS res;
int chan = cesaChanPort[inPort];
spin_lock(&cesa_lock[chan]);
if (chan == 0) {
pBufInfoArray_0[cesaCmdIndx_0].bufAddrShift = 0;
pBufInfoArray_0[cesaCmdIndx_0].dataSize = pkt->bytes;
pBufInfoArray_0[cesaCmdIndx_0].bufSize = pkt->bytes;
pBufInfoArray_0[cesaCmdIndx_0].bufVirtPtr = pkt->pBuf + pkt->offset + MV_ETH_MH_SIZE;
pBufInfoArray_0[cesaCmdIndx_0].bufPhysAddr = mvOsIoVirtToPhy(NULL, pkt->pBuf + pkt->offset + MV_ETH_MH_SIZE);
pBufInfoArray_0[cesaCmdIndx_0].memHandle = 0;
pPktInfoNewArray_0[cesaCmdIndx_0].pFrags = &pBufInfoArray_0[cesaCmdIndx_0];
pPktInfoNewArray_0[cesaCmdIndx_0].numFrags = 1;
} else {
pBufInfoArray_1[cesaCmdIndx_1].bufAddrShift = 0;
pBufInfoArray_1[cesaCmdIndx_1].dataSize = pkt->bytes;
pBufInfoArray_1[cesaCmdIndx_1].bufSize = pkt->bytes;
pBufInfoArray_1[cesaCmdIndx_1].bufVirtPtr = pkt->pBuf + pkt->offset + MV_ETH_MH_SIZE;
pBufInfoArray_1[cesaCmdIndx_1].bufPhysAddr = mvOsIoVirtToPhy(NULL, pkt->pBuf + pkt->offset + MV_ETH_MH_SIZE);
pBufInfoArray_1[cesaCmdIndx_1].memHandle = 0;
pPktInfoNewArray_1[cesaCmdIndx_1].pFrags = &pBufInfoArray_1[cesaCmdIndx_1];
pPktInfoNewArray_1[cesaCmdIndx_1].numFrags = 1;
}
if (chan == 0)
res = mvSecOutgoing(pkt, &pPktInfoNewArray_0[cesaCmdIndx_0], &sa, new_pp, inPort, chan);
else
res = mvSecOutgoing(pkt, &pPktInfoNewArray_1[cesaCmdIndx_1], &sa, new_pp, inPort, chan);
spin_unlock(&cesa_lock[chan]);
return res;
}
void l2fw_stats(void)
{
int i;
for (i = 0; i < 4; i++) {
mvOsPrintf("number of Cesa No Resources error is port[%d]=%d \n", i, counterNoResources[i]);
counterNoResources[i] = 0;
}
}
#endif