blob: d02ae95bcabf4eee5658cc0b8d6ca29ec93e7e76 [file] [log] [blame]
/*******************************************************************************
Copyright (C) Marvell International Ltd. and its affiliates
This software file (the "File") is owned and distributed by Marvell
International Ltd. and/or its affiliates ("Marvell") under the following
alternative licensing terms. Once you have made an election to distribute the
File under one of the following license alternatives, please (i) delete this
introductory statement regarding license alternatives, (ii) delete the two
license alternatives that you have not elected to use and (iii) preserve the
Marvell copyright notice above.
********************************************************************************
Marvell Commercial License Option
If you received this File from Marvell and you have entered into a commercial
license agreement (a "Commercial License") with Marvell, the File is licensed
to you under the terms of the applicable Commercial License.
********************************************************************************
Marvell GPL License Option
If you received this File from Marvell, you may opt to use, redistribute and/or
modify this File in accordance with the terms and conditions of the General
Public License Version 2, June 1991 (the "GPL License"), a copy of which is
available along with the File in the license.txt file or by writing to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
DISCLAIMED. The GPL License provides additional details about this warranty
disclaimer.
********************************************************************************
Marvell BSD License Option
If you received this File from Marvell, you may opt to use, redistribute and/or
modify this File under the following licensing terms.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Marvell nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __MV_PP2_GBE_H__
#define __MV_PP2_GBE_H__
#include "mvTypes.h"
#include "mvCommon.h"
#include "mv802_3.h"
#include "mvOs.h"
#include "mvPp2GbeRegs.h"
#include "bm/mvBm.h"
#include "gmac/mvEthGmacApi.h"
#include "common/mvPp2Common.h"
#include "prs/mvPp2PrsHw.h"
#define PP2_CPU_CODE_IS_RX_SPECIAL(cpu_code) ((cpu_code) & RI_CPU_CODE_RX_SPEC_VAL)
#define MV_AMPLIFY_FACTOR_MTU (3)
#define MV_BIT_NUM_OF_BYTE (8)
#define MV_WRR_WEIGHT_UNIT (256)
static inline int mvPp2IsRxSpecial(MV_U16 parser_info)
{
MV_U16 cpu_code = (parser_info & PP2_RX_CPU_CODE_MASK) >> PP2_RX_CPU_CODE_OFFS;
return PP2_CPU_CODE_IS_RX_SPECIAL(cpu_code);
}
static inline int mvPp2RxBmPoolId(PP2_RX_DESC *rxDesc)
{
return (rxDesc->status & PP2_RX_BM_POOL_ALL_MASK) >> PP2_RX_BM_POOL_ID_OFFS;
}
/************************** PPv2 HW Configuration ***********************/
typedef struct eth_pbuf {
void *osInfo;
MV_ULONG physAddr;
MV_U8 *pBuf;
MV_U16 bytes;
MV_U16 offset;
MV_U8 pool;
MV_U8 qset;
MV_U8 grntd;
MV_U8 reserved;
MV_U16 vlanId;
} MV_ETH_PKT;
/************************** Port + Queue Control Structures ******************************/
typedef struct {
char *pFirst;
int lastDesc;
int nextToProc;
int descSize;
MV_BUF_INFO descBuf;
} MV_PP2_QUEUE_CTRL;
#define MV_PP2_QUEUE_DESC_PTR(pQueueCtrl, descIdx) \
((pQueueCtrl)->pFirst + ((descIdx) * (pQueueCtrl)->descSize))
#define MV_PP2_QUEUE_NEXT_DESC(pQueueCtrl, descIdx) \
(((descIdx) < (pQueueCtrl)->lastDesc) ? ((descIdx) + 1) : 0)
#define MV_PP2_QUEUE_PREV_DESC(pQueueCtrl, descIdx) \
(((descIdx) > 0) ? ((descIdx) - 1) : (pQueueCtrl)->lastDesc)
/*-------------------------------------------------------------------------------*/
/* TXQ */
typedef struct {
MV_PP2_QUEUE_CTRL queueCtrl;
int txq;
} MV_PP2_PHYS_TXQ_CTRL;
typedef struct {
MV_PP2_QUEUE_CTRL queueCtrl;
int cpu;
} MV_PP2_AGGR_TXQ_CTRL;
/* physical TXQs */
extern MV_PP2_PHYS_TXQ_CTRL *mvPp2PhysTxqs;
/* aggregated TXQs */
extern MV_PP2_AGGR_TXQ_CTRL *mvPp2AggrTxqs;
/*-------------------------------------------------------------------------------*/
/* RXQ */
typedef struct {
MV_PP2_QUEUE_CTRL queueCtrl;
int rxq;
int port;
int logicRxq;
} MV_PP2_PHYS_RXQ_CTRL;
/* physical RXQs */
extern MV_PP2_PHYS_RXQ_CTRL *mvPp2PhysRxqs;
/*-------------------------------------------------------------------------------*/
/* Port */
typedef struct {
int portNo;
MV_PP2_PHYS_RXQ_CTRL **pRxQueue;
MV_PP2_PHYS_TXQ_CTRL **pTxQueue;
int rxqNum;
int txpNum;
int txqNum;
void *osHandle;
} MV_PP2_PORT_CTRL;
/* ports control */
extern MV_PP2_PORT_CTRL **mvPp2PortCtrl;
/*-------------------------------------------------------------------------------*/
/* HW data */
typedef struct {
MV_U32 maxPort;
MV_U32 maxTcont;
MV_U32 aggrTxqSize;
MV_U32 physTxqHwfSize;
MV_U32 maxCPUs;
MV_U32 portMask;
MV_U32 cpuMask;
MV_U32 pClk;
MV_U32 tClk;
MV_BOOL iocc;
MV_U16 ctrlModel; /* Controller Model */
MV_U8 ctrlRev; /* Controller Revision */
} MV_PP2_HAL_DATA;
extern MV_PP2_HAL_DATA mvPp2HalData;
/************************** RXQ: Physical - Logical Mapping ******************************/
static INLINE int mvPp2PhysRxqToPort(int prxq)
{
return mvPp2PhysRxqs[prxq].port;
}
static INLINE int mvPp2PhysRxqToLogicRxq(int prxq)
{
return mvPp2PhysRxqs[prxq].logicRxq;
}
static INLINE int mvPp2LogicRxqToPhysRxq(int port, int rxq)
{
if (mvPp2PortCtrl[port]->pRxQueue[rxq])
return mvPp2PortCtrl[port]->pRxQueue[rxq]->rxq;
return -1;
}
/************************** TXQ: Physical - Logical Mapping ******************************/
#ifdef MV_PP2_PON_EXIST
#define MV_PON_LOGIC_PORT_GET() (mvPp2HalData.maxPort - 1)
#define MV_PP2_IS_PON_PORT(p) ((p) == MV_PON_LOGIC_PORT_GET())
#define MV_PON_PHYS_PORT_GET() MV_PP2_PON_PORT_ID
#define MV_PON_PHYS_PORT(p) ((p) == MV_PP2_PON_PORT_ID)
#define MV_PP2_TOTAL_TXP_NUM (MV_PP2_MAX_TCONT + MV_ETH_MAX_PORTS - 1)
#define MV_PP2_TOTAL_PON_TXQ_NUM (MV_PP2_MAX_TCONT * MV_PP2_MAX_TXQ)
#define MV_PPV2_PORT_PHYS(port) ((MV_PP2_IS_PON_PORT(port)) ? MV_PON_PHYS_PORT_GET() : (port))
#define MV_PPV2_TXP_PHYS(port, txp) ((MV_PP2_IS_PON_PORT(port)) ? txp : (MV_PP2_MAX_TCONT + port))
#define MV_PPV2_TXQ_PHYS(port, txp, txq) ((MV_PP2_IS_PON_PORT(port)) ? txp * MV_PP2_MAX_TXQ + txq :\
MV_PP2_TOTAL_PON_TXQ_NUM + port * MV_PP2_MAX_TXQ + txq)
#define MV_PPV2_TXQ_LOGICAL_PORT(physTxq) ((physTxq < MV_PP2_TOTAL_PON_TXQ_NUM) ? MV_PON_LOGIC_PORT_ID_GET() :\
(physTxq - MV_PP2_TOTAL_PON_TXQ_NUM) / MV_PP2_MAX_TXQ)
#define MV_PPV2_TXQ_LOGICAL_TXP(physTxq) ((physTxq < MV_PP2_TOTAL_PON_TXQ_NUM) ? (physTxq / MV_PP2_MAX_TXQ) : 0)
#else /* Without PON */
#define MV_PP2_IS_PON_PORT(p) MV_FALSE
#define MV_PON_PHYS_PORT(p) MV_FALSE
#define MV_PP2_TOTAL_TXP_NUM (MV_ETH_MAX_PORTS)
#define MV_PPV2_PORT_PHYS(port) (port)
#define MV_PPV2_TXP_PHYS(port, txp) (port)
#define MV_PPV2_TXQ_PHYS(port, txp, txq) (port * MV_PP2_MAX_TXQ + txq)
#define MV_PPV2_TXQ_LOGICAL_PORT(physTxq) (physTxq / MV_PP2_MAX_TXQ)
#define MV_PPV2_TXQ_LOGICAL_TXP(physTxq) 0
#endif /* MV_PP2_PON_EXIST */
#define MV_PPV2_TXQ_LOGICAL_TXQ(physTxq) (physTxq % MV_PP2_MAX_TXQ)
#define MV_PP2_TXQ_TOTAL_NUM (MV_PP2_TOTAL_TXP_NUM * MV_PP2_MAX_TXQ)
/************************** Data Path functions ******************************/
/* Set TXQ descriptors fields relevant for CSUM calculation */
static INLINE MV_U32 mvPp2TxqDescCsum(int l3_offs, int l3_proto, int ip_hdr_len, int l4_proto)
{
MV_U32 command;
/* fields: L3_offset, IP_hdrlen, L3_type, G_IPv4_chk, G_L4_chk, L4_type */
/* required only for checksum calculation */
command = (l3_offs << PP2_TX_L3_OFFSET_OFFS);
command |= (ip_hdr_len << PP2_TX_IP_HLEN_OFFS);
command |= PP2_TX_IP_CSUM_DISABLE_MASK;
if (l3_proto == MV_16BIT_BE(MV_IP_TYPE)) {
command &= ~PP2_TX_IP_CSUM_DISABLE_MASK; /* enable IP CSUM */
command |= PP2_TX_L3_IP4;
} else
command |= PP2_TX_L3_IP6;
if (l4_proto == MV_IP_PROTO_TCP)
command |= (PP2_TX_L4_TCP | PP2_TX_L4_CSUM);
else if (l4_proto == MV_IP_PROTO_UDP)
command |= (PP2_TX_L4_UDP | PP2_TX_L4_CSUM);
else
command |= PP2_TX_L4_CSUM_NOT;
return command;
}
static INLINE MV_VOID mvPp2GbeCpuInterruptsDisable(int port, int cpuMask)
{
mvPp2WrReg(MV_PP2_ISR_ENABLE_REG(port), MV_PP2_ISR_DISABLE_INTERRUPT(cpuMask));
}
static INLINE MV_VOID mvPp2GbeCpuInterruptsEnable(int port, int cpuMask)
{
mvPp2WrReg(MV_PP2_ISR_ENABLE_REG(port), MV_PP2_ISR_ENABLE_INTERRUPT(cpuMask));
}
/* Get Giga port handler */
static INLINE MV_PP2_PORT_CTRL *mvPp2PortHndlGet(int port)
{
return mvPp2PortCtrl[port];
}
/* Get physical RX queue handler */
static INLINE MV_PP2_PHYS_RXQ_CTRL *mvPp2RxqHndlGet(int port, int rxq)
{
return mvPp2PortCtrl[port]->pRxQueue[rxq];
}
/* Get physical TX queue handler */
static INLINE MV_PP2_PHYS_TXQ_CTRL *mvPp2TxqHndlGet(int port, int txp, int txq)
{
MV_PP2_PORT_CTRL *pPortCtrl = mvPp2PortCtrl[port];
return pPortCtrl->pTxQueue[txp * pPortCtrl->txqNum + txq];
}
/* Get Aggregated TX queue handler */
static INLINE MV_PP2_AGGR_TXQ_CTRL *mvPp2AggrTxqHndlGet(int cpu)
{
return &mvPp2AggrTxqs[cpu];
}
/* Get pointer to next RX descriptor to be processed by SW */
static INLINE PP2_RX_DESC *mvPp2RxqNextDescGet(MV_PP2_PHYS_RXQ_CTRL *pRxq)
{
PP2_RX_DESC *pRxDesc;
int rxDesc = pRxq->queueCtrl.nextToProc;
pRxq->queueCtrl.nextToProc = MV_PP2_QUEUE_NEXT_DESC(&(pRxq->queueCtrl), rxDesc);
pRxDesc = ((PP2_RX_DESC *)pRxq->queueCtrl.pFirst) + rxDesc;
return pRxDesc;
}
static INLINE PP2_RX_DESC *mvPp2RxqDescGet(MV_PP2_PHYS_RXQ_CTRL *pRxq)
{
PP2_RX_DESC *pRxDesc;
pRxDesc = ((PP2_RX_DESC *)pRxq->queueCtrl.pFirst) + pRxq->queueCtrl.nextToProc;
return pRxDesc;
}
#if defined(MV_CPU_BE)
/* Swap RX descriptor to be BE */
static INLINE void mvPPv2RxqDescSwap(PP2_RX_DESC *pRxDesc)
{
pRxDesc->status = MV_BYTE_SWAP_32BIT(pRxDesc->status);
pRxDesc->parserInfo = MV_BYTE_SWAP_16BIT(pRxDesc->parserInfo);
pRxDesc->dataSize = MV_BYTE_SWAP_16BIT(pRxDesc->dataSize);
pRxDesc->bufPhysAddr = MV_BYTE_SWAP_32BIT(pRxDesc->bufPhysAddr);
pRxDesc->bufCookie = MV_BYTE_SWAP_32BIT(pRxDesc->bufCookie);
pRxDesc->gemPortIdPktColor = MV_BYTE_SWAP_16BIT(pRxDesc->gemPortIdPktColor);
pRxDesc->csumL4 = MV_BYTE_SWAP_16BIT(pRxDesc->csumL4);
pRxDesc->classifyInfo = MV_BYTE_SWAP_16BIT(pRxDesc->classifyInfo);
pRxDesc->flowId = MV_BYTE_SWAP_32BIT(pRxDesc->flowId);
}
/* Swap TX descriptor to be BE */
static INLINE void mvPPv2TxqDescSwap(PP2_TX_DESC *pTxDesc)
{
pTxDesc->command = MV_BYTE_SWAP_32BIT(pTxDesc->command);
pTxDesc->dataSize = MV_BYTE_SWAP_16BIT(pTxDesc->dataSize);
pTxDesc->bufPhysAddr = MV_BYTE_SWAP_32BIT(pTxDesc->bufPhysAddr);
pTxDesc->bufCookie = MV_BYTE_SWAP_32BIT(pTxDesc->bufCookie);
pTxDesc->hwCmd[0] = MV_BYTE_SWAP_32BIT(pTxDesc->hwCmd[0]);
pTxDesc->hwCmd[1] = MV_BYTE_SWAP_32BIT(pTxDesc->hwCmd[1]);
pTxDesc->hwCmd[2] = MV_BYTE_SWAP_32BIT(pTxDesc->hwCmd[2]);
}
#endif
/*-------------------------------------------------------------------------------*/
/* Get number of RX descriptors occupied by received packets */
static INLINE int mvPp2RxqBusyDescNumGet(int port, int rxq)
{
MV_U32 regVal;
int prxq = mvPp2LogicRxqToPhysRxq(port, rxq);
if (prxq < 0)
return 0;
regVal = mvPp2RdReg(MV_PP2_RXQ_STATUS_REG(prxq));
return (regVal & MV_PP2_RXQ_OCCUPIED_MASK) >> MV_PP2_RXQ_OCCUPIED_OFFSET;
}
/* Get number of free RX descriptors ready to received new packets */
static INLINE int mvPp2RxqFreeDescNumGet(int port, int rxq)
{
MV_U32 regVal;
int prxq = mvPp2LogicRxqToPhysRxq(port, rxq);
if (prxq < 0)
return 0;
regVal = mvPp2RdReg(MV_PP2_RXQ_STATUS_REG(prxq));
return (regVal & MV_PP2_RXQ_NON_OCCUPIED_MASK) >> MV_PP2_RXQ_NON_OCCUPIED_OFFSET;
}
/* Update HW with number of RX descriptors processed by SW:
* - decrement number of occupied descriptors
* - increment number of Non-occupied descriptors
*/
static INLINE void mvPp2RxqDescNumUpdate(int port, int rxq, int rx_done, int rx_filled)
{
MV_U32 regVal;
int prxq = mvPp2LogicRxqToPhysRxq(port, rxq);
regVal = (rx_done << MV_PP2_RXQ_NUM_PROCESSED_OFFSET) | (rx_filled << MV_PP2_RXQ_NUM_NEW_OFFSET);
mvPp2WrReg(MV_PP2_RXQ_STATUS_UPDATE_REG(prxq), regVal);
}
/* Add number of descriptors are ready to receive new packets */
static INLINE void mvPp2RxqNonOccupDescAdd(int port, int rxq, int rx_desc)
{
MV_U32 regVal;
int prxq = mvPp2LogicRxqToPhysRxq(port, rxq);
regVal = (rx_desc << MV_PP2_RXQ_NUM_NEW_OFFSET);
mvPp2WrReg(MV_PP2_RXQ_STATUS_UPDATE_REG(prxq), regVal);
}
/* Decrement number of processed descriptors */
static INLINE void mvPp2RxqOccupDescDec(int port, int rxq, int rx_done)
{
MV_U32 regVal;
int prxq = mvPp2LogicRxqToPhysRxq(port, rxq);
regVal = (rx_done << MV_PP2_RXQ_NUM_PROCESSED_OFFSET);
mvPp2WrReg(MV_PP2_RXQ_STATUS_UPDATE_REG(prxq), regVal);
}
/*-------------------------------------------------------------------------------*/
/*
PPv2 new feature MAS 3.16
reserved TXQ descriptorts allocation request
*/
static INLINE int mvPp2TxqAllocReservedDesc(int port, int txp, int txq, int num)
{
MV_U32 regVal, ptxq;
ptxq = MV_PPV2_TXQ_PHYS(port, txp, txq);
regVal = (ptxq << MV_PP2_TXQ_RSVD_REQ_Q_OFFSET) | (num << MV_PP2_TXQ_RSVD_REQ_DESC_OFFSET);
mvPp2WrReg(MV_PP2_TXQ_RSVD_REQ_REG, regVal);
regVal = mvPp2RdReg(MV_PP2_TXQ_RSVD_RSLT_REG);
return (regVal & MV_PP2_TXQ_RSVD_REQ_DESC_MASK) >> MV_PP2_TXQ_RSVD_RSLT_OFFSET;
}
/* Free all descriptors reserved */
static INLINE void mvPp2TxqFreeReservedDesc(int port, int txp, int txq)
{
MV_U32 regVal, ptxq;
ptxq = MV_PPV2_TXQ_PHYS(port, txp, txq);
regVal = (ptxq << MV_PP2_TXQ_RSVD_CLR_Q_OFFSET);
mvPp2WrReg(MV_PP2_TXQ_RSVD_CLR_REG, regVal);
}
/* Get number of TXQ descriptors waiting to be transmitted by HW */
static INLINE int mvPp2TxqPendDescNumGet(int port, int txp, int txq)
{
MV_U32 regVal, ptxq;
ptxq = MV_PPV2_TXQ_PHYS(port, txp, txq);
mvPp2WrReg(MV_PP2_TXQ_NUM_REG, ptxq);
regVal = mvPp2RdReg(MV_PP2_TXQ_PENDING_REG);
return (regVal & MV_PP2_TXQ_PENDING_MASK) >> MV_PP2_TXQ_PENDING_OFFSET;
}
/*
PPv2.1 new feature MAS 3.16
Get number of SWF reserved descriptors
*/
static INLINE int mvPp2TxqPendRsrvdDescNumGet(int port, int txp, int txq)
{
MV_U32 regVal, ptxq;
ptxq = MV_PPV2_TXQ_PHYS(port, txp, txq);
mvPp2WrReg(MV_PP2_TXQ_NUM_REG, ptxq);
regVal = mvPp2RdReg(MV_PP2_TXQ_PENDING_REG);
return (regVal & MV_PP2_TXQ_RSVD_DESC_OFFSET) >> MV_PP2_TXQ_RSVD_DESC_OFFSET;
}
/*
PPv2.1 field removed, MAS 3.16
Relevant only for ppv2.0
Get number of TXQ HWF descriptors waiting to be transmitted by HW
*/
static INLINE int mvPp2TxqPendHwfDescNumGet(int port, int txp, int txq)
{
MV_U32 regVal, ptxq;
ptxq = MV_PPV2_TXQ_PHYS(port, txp, txq);
mvPp2WrReg(MV_PP2_TXQ_NUM_REG, ptxq);
regVal = mvPp2RdReg(MV_PP2_TXQ_PENDING_REG);
return (regVal & MV_PP2_TXQ_HWF_PENDING_MASK) >> MV_PP2_TXQ_HWF_PENDING_OFFSET;
}
/* Get next aggregated TXQ descriptor */
static INLINE PP2_TX_DESC *mvPp2AggrTxqNextDescGet(MV_PP2_AGGR_TXQ_CTRL *pTxq)
{
PP2_TX_DESC *pTxDesc;
int txDesc = pTxq->queueCtrl.nextToProc;
pTxq->queueCtrl.nextToProc = MV_PP2_QUEUE_NEXT_DESC(&(pTxq->queueCtrl), txDesc);
pTxDesc = ((PP2_TX_DESC *)pTxq->queueCtrl.pFirst) + txDesc;
return pTxDesc;
}
/* Get pointer to previous aggregated TX descriptor for rollback when needed */
static INLINE PP2_TX_DESC *mvPp2AggrTxqPrevDescGet(MV_PP2_AGGR_TXQ_CTRL *pTxq)
{
int txDesc = pTxq->queueCtrl.nextToProc;
pTxq->queueCtrl.nextToProc = MV_PP2_QUEUE_PREV_DESC(&(pTxq->queueCtrl), txDesc);
return ((PP2_TX_DESC *) pTxq->queueCtrl.pFirst) + txDesc;
}
/* Get number of aggregated TXQ descriptors didn't send by HW to relevant physical TXQ */
static INLINE int mvPp2AggrTxqPendDescNumGet(int cpu)
{
MV_U32 regVal;
regVal = mvPp2RdReg(MV_PP2_AGGR_TXQ_STATUS_REG(cpu));
return (regVal & MV_PP2_AGGR_TXQ_PENDING_MASK) >> MV_PP2_AGGR_TXQ_PENDING_OFFSET;
}
/* Update HW with number of Aggr-TX descriptors to be sent - user responsible for writing TXQ in TX descriptor */
static INLINE void mvPp2AggrTxqPendDescAdd(int pending)
{
/* aggregated access - relevant TXQ number is written in TX descriptor */
mvPp2WrReg(MV_PP2_AGGR_TXQ_UPDATE_REG, pending);
}
/* Get number of sent descriptors and descrement counter.
Clear sent descriptor counter.
Number of sent descriptors is returned. */
static INLINE int mvPp2TxqSentDescProc(int port, int txp, int txq)
{
MV_U32 regVal, ptxq;
ptxq = MV_PPV2_TXQ_PHYS(port, txp, txq);
/* reading status reg also cause to reset transmitted counter */
regVal = mvPp2RdReg(MV_PP2_TXQ_SENT_REG(ptxq));
return (regVal & MV_PP2_TRANSMITTED_COUNT_MASK) >> MV_PP2_TRANSMITTED_COUNT_OFFSET;
}
/*-------------------------------------------------------------------------------*/
static INLINE MV_U32 mvPp2GbeIsrCauseRxTxGet(int port)
{
MV_U32 val;
if (MV_PP2_IS_PON_PORT(port)) {
val = mvPp2RdReg(MV_PP2_ISR_PON_RX_TX_CAUSE_REG);
val &= (MV_PP2_PON_CAUSE_RXQ_OCCUP_DESC_ALL_MASK |
MV_PP2_PON_CAUSE_TXP_OCCUP_DESC_ALL_MASK | MV_PP2_PON_CAUSE_MISC_SUM_MASK);
} else {
val = mvPp2RdReg(MV_PP2_ISR_RX_TX_CAUSE_REG(MV_PPV2_PORT_PHYS(port)));
val &= (MV_PP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK |
MV_PP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK | MV_PP2_CAUSE_MISC_SUM_MASK);
}
return val;
}
static INLINE MV_BOOL mvPp2GbeIsrCauseTxDoneIsSet(int port, MV_U32 causeRxTx)
{
if (MV_PP2_IS_PON_PORT(port))
return (causeRxTx & MV_PP2_PON_CAUSE_TXP_OCCUP_DESC_ALL_MASK);
return (causeRxTx & MV_PP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK);
}
static INLINE MV_U32 mvPp2GbeIsrCauseTxDoneOffset(int port, MV_U32 causeRxTx)
{
if (MV_PP2_IS_PON_PORT(port))
return (causeRxTx & MV_PP2_PON_CAUSE_TXP_OCCUP_DESC_ALL_MASK);
return (causeRxTx & MV_PP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK);
}
/************************** function declaration ******************************/
MV_STATUS mvPp2WinInit(MV_U32 dummy/*backward compability*/, MV_UNIT_WIN_INFO *addrWinMap);
MV_STATUS mvPp2WinWrite(MV_U32 dummy/*backward compability*/, MV_U32 winNum, MV_UNIT_WIN_INFO *pAddrDecWin);
MV_STATUS mvPp2WinRead(MV_U32 dummy/*backward compability*/, MV_U32 winNum, MV_UNIT_WIN_INFO *pAddrDecWin);
MV_STATUS mvPp2WinEnable(MV_U32 dummy/*backward compability*/, MV_U32 winNum, MV_BOOL enable);
int mvPp2MaxCheck(int value, int limit, char *name);
int mvPp2PortCheck(int port);
int mvPp2TxpCheck(int port, int txp);
int mvPp2CpuCheck(int cpu);
static INLINE MV_ULONG pp2DescVirtToPhys(MV_PP2_QUEUE_CTRL *pQueueCtrl, MV_U8 *pDesc)
{
return (pQueueCtrl->descBuf.bufPhysAddr + (pDesc - pQueueCtrl->descBuf.bufVirtPtr));
}
MV_U8 *mvPp2DescrMemoryAlloc(int descSize, MV_ULONG *pPhysAddr, MV_U32 *memHandle);
void mvPp2DescrMemoryFree(int descSize, MV_ULONG *pPhysAddr, MV_U8 *pVirt, MV_U32 *memHandle);
MV_STATUS mvPp2HalInit(MV_PP2_HAL_DATA *halData);
MV_VOID mvPp2HalDestroy(MV_VOID);
/* Add a mapping prxq <-> (port, lrxq) */
MV_STATUS mvPp2PhysRxqMapAdd(int prxq, int port, int lrxq);
/* Free the relevant physical rxq */
MV_STATUS mvPp2PhysRxqMapDel(int prxq);
MV_STATUS mvPp2PortLogicRxqMapDel(int port, int lrxq);
/* Allocate and initialize descriptors for RXQ */
MV_PP2_PHYS_RXQ_CTRL *mvPp2RxqInit(int port, int rxq, int descNum);
void mvPp2RxqDelete(int port, int queue);
void mvPp2RxqReset(int port, int queue);
/* Allocate and initialize all physical RXQs.
This function must be called before any use of RXQ */
MV_STATUS mvPp2PhysRxqsAlloc(MV_VOID);
/* Destroy all physical RXQs */
MV_STATUS mvPp2PhysRxqsDestroy(MV_VOID);
MV_STATUS mvPp2RxqOffsetSet(int port, int rxq, int offset);
MV_STATUS mvPp2RxqPktsCoalSet(int port, int rxq, MV_U32 pkts);
int mvPp2RxqPktsCoalGet(int port, int rxq);
void mvPp2RxReset(int port);
void mvPp2TxqHwfSizeSet(int port, int txp, int txq, int hwfNum);
/* Allocate and initialize descriptors for TXQ */
MV_PP2_PHYS_TXQ_CTRL *mvPp2TxqInit(int port, int txp, int txq, int descNum, int hwfNum);
MV_STATUS mvPp2TxqDelete(int port, int txp, int txq);
/* Allocate and initialize all physical TXQs.
This function must be called before any use of TXQ */
MV_STATUS mvPp2PhysTxqsAlloc(MV_VOID);
/* Destroy all physical TXQs */
MV_VOID mvPp2PhysTxqsDestroy(MV_VOID);
/* Allocate and initialize all aggregated TXQs.
This function must be called before any use of aggregated TXQ */
MV_STATUS mvPp2AggrTxqsAlloc(int cpuNum);
/* Destroy all aggregated TXQs */
MV_VOID mvPp2AggrTxqsDestroy(MV_VOID);
MV_VOID mvPp2AggrTxqDelete(int cpu);
/* Initialize aggregated TXQ */
MV_PP2_AGGR_TXQ_CTRL *mvPp2AggrTxqInit(int cpu, int descNum);
MV_STATUS mvPp2TxDonePktsCoalSet(int port, int txp, int txq, MV_U32 pkts);
int mvPp2TxDonePktsCoalGet(int port, int txp, int txq);
void mvPp2TxpReset(int port, int txp);
void mvPp2TxqReset(int port, int txp, int txq);
MV_STATUS mvPp2TxqTempInit(int descNum, int hwfNum);
MV_VOID mvPp2TxqTempDelete(MV_VOID);
/* Allocate and initialize port structure
Associate relevant TXQs for this port (predefined)
Associate <numRxqs> RXQs for Port number <port>, starting from RXQ number <firstRxq>
Note: mvPp2PortCtrl must be initialized, i.e. must call mvPp2HalInit before this function */
void *mvPp2PortInit(int port, int firstRxq, int numRxqs, void *osHandle);
void mvPp2PortDestroy(int port);
/* Low Level APIs */
MV_STATUS mvPp2RxqEnable(int port, int rxq, MV_BOOL en);
MV_STATUS mvPp2HwfTxqEnable(int port, int txp, int txq, MV_BOOL en);
MV_BOOL mvPp2DisableCmdInProgress(void);
MV_STATUS mvPp2TxqDrainSet(int port, int txp, int txq, MV_BOOL en);
MV_STATUS mvPp2TxPortFifoFlush(int port, MV_BOOL en);
MV_STATUS mvPp2TxpEnable(int port, int txp);
MV_STATUS mvPp2TxpDisable(int port, int txp);
MV_STATUS mvPp2PortEnable(int port, MV_BOOL en);
/* High Level APIs */
MV_STATUS mvPp2PortIngressEnable(int port, MV_BOOL en);
MV_STATUS mvPp2PortEgressEnable(int port, MV_BOOL en);
MV_STATUS mvPp2BmPoolBufSizeSet(int pool, int bufsize);
MV_STATUS mvPp2RxqBmShortPoolSet(int port, int rxq, int shortPool);
MV_STATUS mvPp2RxqBmLongPoolSet(int port, int rxq, int longPool);
MV_STATUS mvPp2TxqBmShortPoolSet(int port, int txp, int txq, int shortPool);
MV_STATUS mvPp2TxqBmLongPoolSet(int port, int txp, int txq, int longPool);
MV_STATUS mvPp2PortHwfBmPoolSet(int port, int shortPool, int longPool);
MV_STATUS mvPp2MhSet(int port, MV_TAG_TYPE mh);
MV_STATUS mvPp2RxFifoInit(int portNum);
MV_STATUS mvPp2TxpMaxTxSizeSet(int port, int txp, int maxTxSize);
MV_STATUS mvPp2TxpMaxRateSet(int port, int txp);
MV_STATUS mvPp2TxqMaxRateSet(int port, int txp, int txq);
MV_STATUS mvPp2TxpRateSet(int port, int txp, int rate);
MV_STATUS mvPp2TxpBurstSet(int port, int txp, int burst);
MV_STATUS mvPp2TxqRateSet(int port, int txp, int txq, int rate);
MV_STATUS mvPp2TxqBurstSet(int port, int txp, int txq, int burst);
MV_STATUS mvPp2TxqFixPrioSet(int port, int txp, int txq);
MV_STATUS mvPp2TxqWrrPrioSet(int port, int txp, int txq, int weight);
/* Function for swithcing SWF to HWF */
MV_STATUS mvPp2FwdSwitchCtrl(MV_U32 flowId, int txq, int rxq, int usec);
int mvPp2FwdSwitchStatus(int *hwState, int *usec);
void mvPp2FwdSwitchRegs(void);
/*****************************/
/* Interrupts API */
/*****************************/
MV_VOID mvPp2GbeCpuInterruptsDisable(int port, int cpuMask);
MV_VOID mvPp2GbeCpuInterruptsEnable(int port, int cpuMask);
MV_STATUS mvPp2RxqTimeCoalSet(int port, int rxq, MV_U32 uSec);
unsigned int mvPp2RxqTimeCoalGet(int port, int rxq);
MV_STATUS mvPp2GbeIsrRxqGroup(int port, int rxqNum);
/* unmask the current CPU's rx/tx interrupts *
* - rxq_mask: support rxq to cpu granularity *
* - isTxDoneIsr: if 0 then Tx Done interruptare not unmasked */
MV_STATUS mvPp2GbeIsrRxTxUnmask(int port, MV_U16 rxq_mask, int isTxDoneIsr);
/* mask the current CPU's rx/tx interrupts */
MV_STATUS mvPp2GbeIsrRxTxMask(int port);
/*****************************/
/*****************************/
/* Debug functions */
/*****************************/
MV_VOID mvPp2RxDmaRegsPrint(MV_VOID);
MV_VOID mvPp2DescMgrRegsRxPrint(MV_VOID);
MV_VOID mvPp2DescMgrRegsTxPrint(MV_VOID);
MV_VOID mvPp2AddressDecodeRegsPrint(MV_VOID);
void mvPp2IsrRegs(int port);
void mvPp2PhysRxqRegs(int rxq);
void mvPp2PortRxqRegs(int port, int rxq);
MV_VOID mvPp2RxqShow(int port, int rxq, int mode);
MV_VOID mvPp2TxqShow(int port, int txp, int txq, int mode);
MV_VOID mvPp2AggrTxqShow(int cpu, int mode);
void mvPp2PhysTxqRegs(int txq);
void mvPp2PortTxqRegs(int port, int txp, int txq);
void mvPp2AggrTxqRegs(int cpu);
void mvPp2TxRegs(void);
void mvPp2AddrDecodeRegs(void);
void mvPp2TxSchedRegs(int port, int txp);
void mvPp2BmPoolRegs(int pool);
void mvPp2V0DropCntrs(int port);
/* PPv2.1 MAS 3.20 - counters change */
void mvPp2V1DropCntrs(int port);
void mvPp2V1TxqDbgCntrs(int port, int txp, int txq);
void mvPp2V1RxqDbgCntrs(int port, int rxq);
void mvPp2RxFifoRegs(int port);
void mvPp2PortStatus(int port);
#endif /* MV_PP2_GBE_H */