Commit 9270c565 authored by David S. Miller's avatar David S. Miller

Merge branch 'octeontx2-traffic-shaping'

Sunil Goutham says:

====================
Octeontx2: Traffic shaping and SDP link config support

This patch series adds support for traffic shaping configuration
on all silicons available after 96xx C0. And also adds SDP link
related configuration needed when Octeon is connected as an end-point
and traffic needs to flow from end-point to host and vice versa.

Series also has other changes like
- New mbox messages in admin function driver for PF/VF drivers
  to retrieve available HW resource count. HW resources like block LFs,
  bandwidth profiles etc are covered.
- Added PTP device ID for new CN10K and 95O silicons.
- etc
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fbcf8a34 66c312ea
......@@ -10,4 +10,5 @@ obj-$(CONFIG_OCTEONTX2_AF) += rvu_af.o
rvu_mbox-y := mbox.o rvu_trace.o
rvu_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \
rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o rvu_npc_fs.o \
rvu_cpt.o rvu_devlink.o rpm.o rvu_cn10k.o rvu_switch.o
rvu_cpt.o rvu_devlink.o rpm.o rvu_cn10k.o rvu_switch.o \
rvu_sdp.o
......@@ -185,13 +185,16 @@ enum nix_scheduler {
#define NIX_INTF_TYPE_CGX 0
#define NIX_INTF_TYPE_LBK 1
#define NIX_INTF_TYPE_SDP 2
#define MAX_LMAC_PKIND 12
#define NIX_LINK_CGX_LMAC(a, b) (0 + 4 * (a) + (b))
#define NIX_LINK_LBK(a) (12 + (a))
#define NIX_CHAN_CGX_LMAC_CHX(a, b, c) (0x800 + 0x100 * (a) + 0x10 * (b) + (c))
#define NIX_CHAN_LBK_CHX(a, b) (0 + 0x100 * (a) + (b))
#define NIX_CHAN_SDP_CH_START (0x700ull)
#define NIX_CHAN_SDP_CH_START (0x700ull)
#define NIX_CHAN_SDP_CHX(a) (NIX_CHAN_SDP_CH_START + (a))
#define NIX_CHAN_SDP_NUM_CHANS 256
/* The mask is to extract lower 10-bits of channel number
* which CPT will pass to X2P.
......
......@@ -87,7 +87,7 @@ struct mbox_msghdr {
#define OTX2_MBOX_REQ_SIG (0xdead)
#define OTX2_MBOX_RSP_SIG (0xbeef)
u16 sig; /* Signature, for validating corrupted msgs */
#define OTX2_MBOX_VERSION (0x0007)
#define OTX2_MBOX_VERSION (0x0009)
u16 ver; /* Version of msg's structure for this ID */
u16 next_msgoff; /* Offset of next msg within mailbox region */
int rc; /* Msg process'ed response code */
......@@ -130,6 +130,7 @@ static inline struct mbox_msghdr *otx2_mbox_alloc_msg(struct otx2_mbox *mbox,
M(READY, 0x001, ready, msg_req, ready_msg_rsp) \
M(ATTACH_RESOURCES, 0x002, attach_resources, rsrc_attach, msg_rsp) \
M(DETACH_RESOURCES, 0x003, detach_resources, rsrc_detach, msg_rsp) \
M(FREE_RSRC_CNT, 0x004, free_rsrc_cnt, msg_req, free_rsrcs_rsp) \
M(MSIX_OFFSET, 0x005, msix_offset, msg_req, msix_offset_rsp) \
M(VF_FLR, 0x006, vf_flr, msg_req, msg_rsp) \
M(PTP_OP, 0x007, ptp_op, ptp_req, ptp_rsp) \
......@@ -191,6 +192,9 @@ M(CPT_RD_WR_REGISTER, 0xA02, cpt_rd_wr_register, cpt_rd_wr_reg_msg, \
M(CPT_STATS, 0xA05, cpt_sts, cpt_sts_req, cpt_sts_rsp) \
M(CPT_RXC_TIME_CFG, 0xA06, cpt_rxc_time_cfg, cpt_rxc_time_cfg_req, \
msg_rsp) \
/* SDP mbox IDs (range 0x1000 - 0x11FF) */ \
M(SET_SDP_CHAN_INFO, 0x1000, set_sdp_chan_info, sdp_chan_info_msg, msg_rsp) \
M(GET_SDP_CHAN_INFO, 0x1001, get_sdp_chan_info, msg_req, sdp_get_chan_info_msg) \
/* NPC mbox IDs (range 0x6000 - 0x7FFF) */ \
M(NPC_MCAM_ALLOC_ENTRY, 0x6000, npc_mcam_alloc_entry, npc_mcam_alloc_entry_req,\
npc_mcam_alloc_entry_rsp) \
......@@ -243,7 +247,8 @@ M(NIX_HWCTX_DISABLE, 0x8003, nix_hwctx_disable, \
M(NIX_TXSCH_ALLOC, 0x8004, nix_txsch_alloc, \
nix_txsch_alloc_req, nix_txsch_alloc_rsp) \
M(NIX_TXSCH_FREE, 0x8005, nix_txsch_free, nix_txsch_free_req, msg_rsp) \
M(NIX_TXSCHQ_CFG, 0x8006, nix_txschq_cfg, nix_txschq_config, msg_rsp) \
M(NIX_TXSCHQ_CFG, 0x8006, nix_txschq_cfg, nix_txschq_config, \
nix_txschq_config) \
M(NIX_STATS_RST, 0x8007, nix_stats_rst, msg_req, msg_rsp) \
M(NIX_VTAG_CFG, 0x8008, nix_vtag_cfg, nix_vtag_config, \
nix_vtag_config_rsp) \
......@@ -274,7 +279,9 @@ M(NIX_GET_HW_INFO, 0x801c, nix_get_hw_info, msg_req, nix_hw_info) \
M(NIX_BANDPROF_ALLOC, 0x801d, nix_bandprof_alloc, nix_bandprof_alloc_req, \
nix_bandprof_alloc_rsp) \
M(NIX_BANDPROF_FREE, 0x801e, nix_bandprof_free, nix_bandprof_free_req, \
msg_rsp)
msg_rsp) \
M(NIX_BANDPROF_GET_HWINFO, 0x801f, nix_bandprof_get_hwinfo, msg_req, \
nix_bandprof_get_hwinfo_rsp)
/* Messages initiated by AF (range 0xC00 - 0xDFF) */
#define MBOX_UP_CGX_MESSAGES \
......@@ -363,6 +370,25 @@ struct rsrc_detach {
u8 cptlfs:1;
};
/* Number of resources available to the caller.
* In reply to MBOX_MSG_FREE_RSRC_CNT.
*/
struct free_rsrcs_rsp {
struct mbox_msghdr hdr;
u16 schq[NIX_TXSCH_LVL_CNT];
u16 sso;
u16 tim;
u16 ssow;
u16 cpt;
u8 npa;
u8 nix;
u16 schq_nix1[NIX_TXSCH_LVL_CNT];
u8 nix1;
u8 cpt1;
u8 ree0;
u8 ree1;
};
#define MSIX_VECTOR_INVALID 0xFFFF
#define MAX_RVU_BLKLF_CNT 256
......@@ -370,16 +396,20 @@ struct msix_offset_rsp {
struct mbox_msghdr hdr;
u16 npa_msixoff;
u16 nix_msixoff;
u8 sso;
u8 ssow;
u8 timlfs;
u8 cptlfs;
u16 sso;
u16 ssow;
u16 timlfs;
u16 cptlfs;
u16 sso_msixoff[MAX_RVU_BLKLF_CNT];
u16 ssow_msixoff[MAX_RVU_BLKLF_CNT];
u16 timlf_msixoff[MAX_RVU_BLKLF_CNT];
u16 cptlf_msixoff[MAX_RVU_BLKLF_CNT];
u8 cpt1_lfs;
u16 cpt1_lfs;
u16 ree0_lfs;
u16 ree1_lfs;
u16 cpt1_lf_msixoff[MAX_RVU_BLKLF_CNT];
u16 ree0_lf_msixoff[MAX_RVU_BLKLF_CNT];
u16 ree1_lf_msixoff[MAX_RVU_BLKLF_CNT];
};
struct get_hw_cap_rsp {
......@@ -699,6 +729,9 @@ struct nix_lf_alloc_req {
u16 sso_func;
u64 rx_cfg; /* See NIX_AF_LF(0..127)_RX_CFG */
u64 way_mask;
#define NIX_LF_RSS_TAG_LSB_AS_ADDER BIT_ULL(0)
#define NIX_LF_LBK_BLK_SEL BIT_ULL(1)
u64 flags;
};
struct nix_lf_alloc_rsp {
......@@ -718,6 +751,7 @@ struct nix_lf_alloc_rsp {
u8 cgx_links; /* No. of CGX links present in HW */
u8 lbk_links; /* No. of LBK links present in HW */
u8 sdp_links; /* No. of SDP links present in HW */
u8 tx_link; /* Transmit channel link number */
};
struct nix_lf_free_req {
......@@ -836,6 +870,7 @@ struct nix_txsch_free_req {
struct nix_txschq_config {
struct mbox_msghdr hdr;
u8 lvl; /* SMQ/MDQ/TL4/TL3/TL2/TL1 */
u8 read;
#define TXSCHQ_IDX_SHIFT 16
#define TXSCHQ_IDX_MASK (BIT_ULL(10) - 1)
#define TXSCHQ_IDX(reg, shift) (((reg) >> (shift)) & TXSCHQ_IDX_MASK)
......@@ -843,6 +878,8 @@ struct nix_txschq_config {
#define MAX_REGS_PER_MBOX_MSG 20
u64 reg[MAX_REGS_PER_MBOX_MSG];
u64 regval[MAX_REGS_PER_MBOX_MSG];
/* All 0's => overwrite with new value */
u64 regval_mask[MAX_REGS_PER_MBOX_MSG];
};
struct nix_vtag_config {
......@@ -1066,6 +1103,12 @@ struct nix_bandprof_free_req {
u16 prof_idx[BAND_PROF_NUM_LAYERS][MAX_BANDPROF_PER_PFFUNC];
};
struct nix_bandprof_get_hwinfo_rsp {
struct mbox_msghdr hdr;
u16 prof_count[BAND_PROF_NUM_LAYERS];
u32 policer_timeunit;
};
/* NPC mbox message structs */
#define NPC_MCAM_ENTRY_INVALID 0xFFFF
......@@ -1434,6 +1477,27 @@ struct cpt_rxc_time_cfg_req {
u16 active_limit;
};
struct sdp_node_info {
/* Node to which this PF belons to */
u8 node_id;
u8 max_vfs;
u8 num_pf_rings;
u8 pf_srn;
#define SDP_MAX_VFS 128
u8 vf_rings[SDP_MAX_VFS];
};
struct sdp_chan_info_msg {
struct mbox_msghdr hdr;
struct sdp_node_info info;
};
struct sdp_get_chan_info_msg {
struct mbox_msghdr hdr;
u16 chan_base;
u16 num_chan;
};
/* CGX mailbox error codes
* Range 1101 - 1200.
*/
......
......@@ -19,12 +19,11 @@
#define PCI_SUBSYS_DEVID_OCTX2_98xx_PTP 0xB100
#define PCI_SUBSYS_DEVID_OCTX2_96XX_PTP 0xB200
#define PCI_SUBSYS_DEVID_OCTX2_95XX_PTP 0xB300
#define PCI_SUBSYS_DEVID_OCTX2_LOKI_PTP 0xB400
#define PCI_SUBSYS_DEVID_OCTX2_95XXN_PTP 0xB400
#define PCI_SUBSYS_DEVID_OCTX2_95MM_PTP 0xB500
#define PCI_SUBSYS_DEVID_CN10K_A_PTP 0xB900
#define PCI_SUBSYS_DEVID_CNF10K_A_PTP 0xBA00
#define PCI_SUBSYS_DEVID_CNF10K_B_PTP 0xBC00
#define PCI_SUBSYS_DEVID_OCTX2_95XXO_PTP 0xB600
#define PCI_DEVID_OCTEONTX2_RST 0xA085
#define PCI_DEVID_CN10K_PTP 0xA09E
#define PCI_PTP_BAR_NO 0
#define PCI_RST_BAR_NO 0
......@@ -39,6 +38,9 @@
#define RST_MUL_BITS GENMASK_ULL(38, 33)
#define CLOCK_BASE_RATE 50000000ULL
static struct ptp *first_ptp_block;
static const struct pci_device_id ptp_id_table[];
static u64 get_clock_rate(void)
{
u64 cfg, ret = CLOCK_BASE_RATE * 16;
......@@ -74,23 +76,14 @@ static u64 get_clock_rate(void)
struct ptp *ptp_get(void)
{
struct pci_dev *pdev;
struct ptp *ptp;
struct ptp *ptp = first_ptp_block;
/* If the PTP pci device is found on the system and ptp
* driver is bound to it then the PTP pci device is returned
* to the caller(rvu driver).
*/
pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
PCI_DEVID_OCTEONTX2_PTP, NULL);
if (!pdev)
/* Check PTP block is present in hardware */
if (!pci_dev_present(ptp_id_table))
return ERR_PTR(-ENODEV);
ptp = pci_get_drvdata(pdev);
/* Check driver is bound to PTP block */
if (!ptp)
ptp = ERR_PTR(-EPROBE_DEFER);
if (IS_ERR(ptp))
pci_dev_put(pdev);
return ptp;
}
......@@ -190,6 +183,8 @@ static int ptp_probe(struct pci_dev *pdev,
writeq(clock_comp, ptp->reg_base + PTP_CLOCK_COMP);
pci_set_drvdata(pdev, ptp);
if (!first_ptp_block)
first_ptp_block = ptp;
return 0;
......@@ -204,6 +199,9 @@ static int ptp_probe(struct pci_dev *pdev,
* `dev->driver_data`.
*/
pci_set_drvdata(pdev, ERR_PTR(err));
if (!first_ptp_block)
first_ptp_block = ERR_PTR(err);
return 0;
}
......@@ -233,19 +231,14 @@ static const struct pci_device_id ptp_id_table[] = {
PCI_SUBSYS_DEVID_OCTX2_95XX_PTP) },
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_PTP,
PCI_VENDOR_ID_CAVIUM,
PCI_SUBSYS_DEVID_OCTX2_LOKI_PTP) },
PCI_SUBSYS_DEVID_OCTX2_95XXN_PTP) },
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_PTP,
PCI_VENDOR_ID_CAVIUM,
PCI_SUBSYS_DEVID_OCTX2_95MM_PTP) },
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_PTP,
PCI_VENDOR_ID_CAVIUM,
PCI_SUBSYS_DEVID_CN10K_A_PTP) },
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_PTP,
PCI_VENDOR_ID_CAVIUM,
PCI_SUBSYS_DEVID_CNF10K_A_PTP) },
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_PTP,
PCI_VENDOR_ID_CAVIUM,
PCI_SUBSYS_DEVID_CNF10K_B_PTP) },
PCI_SUBSYS_DEVID_OCTX2_95XXO_PTP) },
{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10K_PTP) },
{ 0, }
};
......
......@@ -70,18 +70,21 @@ static void rvu_setup_hw_capabilities(struct rvu *rvu)
hw->cap.nix_shaping = true;
hw->cap.nix_tx_link_bp = true;
hw->cap.nix_rx_multicast = true;
hw->cap.nix_shaper_toggle_wait = false;
hw->rvu = rvu;
if (is_rvu_96xx_B0(rvu)) {
if (is_rvu_pre_96xx_C0(rvu)) {
hw->cap.nix_fixed_txschq_mapping = true;
hw->cap.nix_txsch_per_cgx_lmac = 4;
hw->cap.nix_txsch_per_lbk_lmac = 132;
hw->cap.nix_txsch_per_sdp_lmac = 76;
hw->cap.nix_shaping = false;
hw->cap.nix_tx_link_bp = false;
if (is_rvu_96xx_A0(rvu))
if (is_rvu_96xx_A0(rvu) || is_rvu_95xx_A0(rvu))
hw->cap.nix_rx_multicast = false;
}
if (!is_rvu_pre_96xx_C0(rvu))
hw->cap.nix_shaper_toggle_wait = true;
if (!is_rvu_otx2(rvu))
hw->cap.per_pf_mbox_regs = true;
......@@ -1115,6 +1118,12 @@ static int rvu_setup_hw_resources(struct rvu *rvu)
goto nix_err;
}
err = rvu_sdp_init(rvu);
if (err) {
dev_err(rvu->dev, "%s: Failed to initialize sdp\n", __func__);
goto nix_err;
}
rvu_program_channels(rvu);
return 0;
......@@ -1367,9 +1376,10 @@ int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc)
int blkaddr = BLKADDR_NIX0, vf;
struct rvu_pfvf *pf;
pf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK);
/* All CGX mapped PFs are set with assigned NIX block during init */
if (is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc))) {
pf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK);
blkaddr = pf->nix_blkaddr;
} else if (is_afvf(pcifunc)) {
vf = pcifunc - 1;
......@@ -1382,6 +1392,10 @@ int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc)
blkaddr = BLKADDR_NIX0;
}
/* if SDP1 then the blkaddr is NIX1 */
if (is_sdp_pfvf(pcifunc) && pf->sdp_info->node_id == 1)
blkaddr = BLKADDR_NIX1;
switch (blkaddr) {
case BLKADDR_NIX1:
pfvf->nix_blkaddr = BLKADDR_NIX1;
......@@ -1782,6 +1796,99 @@ int rvu_mbox_handler_msix_offset(struct rvu *rvu, struct msg_req *req,
return 0;
}
int rvu_mbox_handler_free_rsrc_cnt(struct rvu *rvu, struct msg_req *req,
struct free_rsrcs_rsp *rsp)
{
struct rvu_hwinfo *hw = rvu->hw;
struct rvu_block *block;
struct nix_txsch *txsch;
struct nix_hw *nix_hw;
mutex_lock(&rvu->rsrc_lock);
block = &hw->block[BLKADDR_NPA];
rsp->npa = rvu_rsrc_free_count(&block->lf);
block = &hw->block[BLKADDR_NIX0];
rsp->nix = rvu_rsrc_free_count(&block->lf);
block = &hw->block[BLKADDR_NIX1];
rsp->nix1 = rvu_rsrc_free_count(&block->lf);
block = &hw->block[BLKADDR_SSO];
rsp->sso = rvu_rsrc_free_count(&block->lf);
block = &hw->block[BLKADDR_SSOW];
rsp->ssow = rvu_rsrc_free_count(&block->lf);
block = &hw->block[BLKADDR_TIM];
rsp->tim = rvu_rsrc_free_count(&block->lf);
block = &hw->block[BLKADDR_CPT0];
rsp->cpt = rvu_rsrc_free_count(&block->lf);
block = &hw->block[BLKADDR_CPT1];
rsp->cpt1 = rvu_rsrc_free_count(&block->lf);
if (rvu->hw->cap.nix_fixed_txschq_mapping) {
rsp->schq[NIX_TXSCH_LVL_SMQ] = 1;
rsp->schq[NIX_TXSCH_LVL_TL4] = 1;
rsp->schq[NIX_TXSCH_LVL_TL3] = 1;
rsp->schq[NIX_TXSCH_LVL_TL2] = 1;
/* NIX1 */
if (!is_block_implemented(rvu->hw, BLKADDR_NIX1))
goto out;
rsp->schq_nix1[NIX_TXSCH_LVL_SMQ] = 1;
rsp->schq_nix1[NIX_TXSCH_LVL_TL4] = 1;
rsp->schq_nix1[NIX_TXSCH_LVL_TL3] = 1;
rsp->schq_nix1[NIX_TXSCH_LVL_TL2] = 1;
} else {
nix_hw = get_nix_hw(hw, BLKADDR_NIX0);
txsch = &nix_hw->txsch[NIX_TXSCH_LVL_SMQ];
rsp->schq[NIX_TXSCH_LVL_SMQ] =
rvu_rsrc_free_count(&txsch->schq);
txsch = &nix_hw->txsch[NIX_TXSCH_LVL_TL4];
rsp->schq[NIX_TXSCH_LVL_TL4] =
rvu_rsrc_free_count(&txsch->schq);
txsch = &nix_hw->txsch[NIX_TXSCH_LVL_TL3];
rsp->schq[NIX_TXSCH_LVL_TL3] =
rvu_rsrc_free_count(&txsch->schq);
txsch = &nix_hw->txsch[NIX_TXSCH_LVL_TL2];
rsp->schq[NIX_TXSCH_LVL_TL2] =
rvu_rsrc_free_count(&txsch->schq);
if (!is_block_implemented(rvu->hw, BLKADDR_NIX1))
goto out;
nix_hw = get_nix_hw(hw, BLKADDR_NIX1);
txsch = &nix_hw->txsch[NIX_TXSCH_LVL_SMQ];
rsp->schq_nix1[NIX_TXSCH_LVL_SMQ] =
rvu_rsrc_free_count(&txsch->schq);
txsch = &nix_hw->txsch[NIX_TXSCH_LVL_TL4];
rsp->schq_nix1[NIX_TXSCH_LVL_TL4] =
rvu_rsrc_free_count(&txsch->schq);
txsch = &nix_hw->txsch[NIX_TXSCH_LVL_TL3];
rsp->schq_nix1[NIX_TXSCH_LVL_TL3] =
rvu_rsrc_free_count(&txsch->schq);
txsch = &nix_hw->txsch[NIX_TXSCH_LVL_TL2];
rsp->schq_nix1[NIX_TXSCH_LVL_TL2] =
rvu_rsrc_free_count(&txsch->schq);
}
rsp->schq_nix1[NIX_TXSCH_LVL_TL1] = 1;
out:
rsp->schq[NIX_TXSCH_LVL_TL1] = 1;
mutex_unlock(&rvu->rsrc_lock);
return 0;
}
int rvu_mbox_handler_vf_flr(struct rvu *rvu, struct msg_req *req,
struct msg_rsp *rsp)
{
......
......@@ -243,8 +243,10 @@ struct rvu_pfvf {
u8 nix_blkaddr; /* BLKADDR_NIX0/1 assigned to this PF */
u8 nix_rx_intf; /* NIX0_RX/NIX1_RX interface to NPC */
u8 nix_tx_intf; /* NIX0_TX/NIX1_TX interface to NPC */
u8 lbkid; /* NIX0/1 lbk link ID */
u64 lmt_base_addr; /* Preseving the pcifunc's lmtst base addr*/
unsigned long flags;
struct sdp_node_info *sdp_info;
};
enum rvu_pfvf_flags {
......@@ -328,6 +330,7 @@ struct hw_cap {
u16 nix_txsch_per_sdp_lmac; /* Max Q's transmitting to SDP LMAC */
bool nix_fixed_txschq_mapping; /* Schq mapping fixed or flexible */
bool nix_shaping; /* Is shaping and coloring supported */
bool nix_shaper_toggle_wait; /* Shaping toggle needs poll/wait */
bool nix_tx_link_bp; /* Can link backpressure TL queues ? */
bool nix_rx_multicast; /* Rx packet replication support */
bool nix_common_dwrr_mtu; /* Common DWRR MTU for quantum config */
......@@ -517,20 +520,34 @@ static inline u64 rvupf_read64(struct rvu *rvu, u64 offset)
}
/* Silicon revisions */
static inline bool is_rvu_pre_96xx_C0(struct rvu *rvu)
{
struct pci_dev *pdev = rvu->pdev;
/* 96XX A0/B0, 95XX A0/A1/B0 chips */
return ((pdev->revision == 0x00) || (pdev->revision == 0x01) ||
(pdev->revision == 0x10) || (pdev->revision == 0x11) ||
(pdev->revision == 0x14));
}
static inline bool is_rvu_96xx_A0(struct rvu *rvu)
{
struct pci_dev *pdev = rvu->pdev;
return (pdev->revision == 0x00) &&
(pdev->subsystem_device == PCI_SUBSYS_DEVID_96XX);
return (pdev->revision == 0x00);
}
static inline bool is_rvu_96xx_B0(struct rvu *rvu)
{
struct pci_dev *pdev = rvu->pdev;
return ((pdev->revision == 0x00) || (pdev->revision == 0x01)) &&
(pdev->subsystem_device == PCI_SUBSYS_DEVID_96XX);
return (pdev->revision == 0x00) || (pdev->revision == 0x01);
}
static inline bool is_rvu_95xx_A0(struct rvu *rvu)
{
struct pci_dev *pdev = rvu->pdev;
return (pdev->revision == 0x10) || (pdev->revision == 0x11);
}
/* REVID for PCIe devices.
......@@ -581,6 +598,16 @@ static inline u16 rvu_nix_chan_lbk(struct rvu *rvu, u8 lbkid,
return rvu->hw->lbk_chan_base + lbkid * lbk_chans + chan;
}
static inline u16 rvu_nix_chan_sdp(struct rvu *rvu, u8 chan)
{
struct rvu_hwinfo *hw = rvu->hw;
if (!hw->cap.programmable_chans)
return NIX_CHAN_SDP_CHX(chan);
return hw->sdp_chan_base + chan;
}
static inline u16 rvu_nix_chan_cpt(struct rvu *rvu, u8 chan)
{
return rvu->hw->cpt_chan_base + chan;
......@@ -643,10 +670,17 @@ int rvu_aq_alloc(struct rvu *rvu, struct admin_queue **ad_queue,
int qsize, int inst_size, int res_size);
void rvu_aq_free(struct rvu *rvu, struct admin_queue *aq);
/* SDP APIs */
int rvu_sdp_init(struct rvu *rvu);
bool is_sdp_pfvf(u16 pcifunc);
bool is_sdp_pf(u16 pcifunc);
bool is_sdp_vf(u16 pcifunc);
/* CGX APIs */
static inline bool is_pf_cgxmapped(struct rvu *rvu, u8 pf)
{
return (pf >= PF_CGXMAP_BASE && pf <= rvu->cgx_mapped_pfs);
return (pf >= PF_CGXMAP_BASE && pf <= rvu->cgx_mapped_pfs) &&
!is_sdp_pf(pf << RVU_PFVF_PF_SHIFT);
}
static inline void rvu_get_cgx_lmac_id(u8 map, u8 *cgx_id, u8 *lmac_id)
......@@ -750,7 +784,6 @@ bool is_npc_intf_tx(u8 intf);
bool is_npc_intf_rx(u8 intf);
bool is_npc_interface_valid(struct rvu *rvu, u8 intf);
int rvu_npc_get_tx_nibble_cfg(struct rvu *rvu, u64 nibble_ena);
int npc_mcam_verify_channel(struct rvu *rvu, u16 pcifunc, u8 intf, u16 channel);
int npc_flow_steering_init(struct rvu *rvu, int blkaddr);
const char *npc_get_field_name(u8 hdr);
int npc_get_bank(struct npc_mcam *mcam, int index);
......
......@@ -85,36 +85,6 @@ static int npc_mcam_verify_pf_func(struct rvu *rvu,
return 0;
}
int npc_mcam_verify_channel(struct rvu *rvu, u16 pcifunc, u8 intf, u16 channel)
{
int pf = rvu_get_pf(pcifunc);
u8 cgx_id, lmac_id;
int base = 0, end;
if (is_npc_intf_tx(intf))
return 0;
/* return in case of AF installed rules */
if (is_pffunc_af(pcifunc))
return 0;
if (is_afvf(pcifunc)) {
end = rvu_get_num_lbk_chans();
if (end < 0)
return -EINVAL;
} else {
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
base = rvu_nix_chan_cgx(rvu, cgx_id, lmac_id, 0x0);
/* CGX mapped functions has maximum of 16 channels */
end = rvu_nix_chan_cgx(rvu, cgx_id, lmac_id, 0xF);
}
if (channel < base || channel > end)
return -EINVAL;
return 0;
}
void rvu_npc_set_pkind(struct rvu *rvu, int pkind, struct rvu_pfvf *pfvf)
{
int blkaddr;
......@@ -634,8 +604,8 @@ void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,
struct nix_rx_action action;
int blkaddr, index;
/* AF's VFs work in promiscuous mode */
if (is_afvf(pcifunc))
/* AF's and SDP VFs work in promiscuous mode */
if (is_afvf(pcifunc) || is_sdp_vf(pcifunc))
return;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
......@@ -863,7 +833,7 @@ void rvu_npc_install_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf,
u16 vf_func;
/* Only CGX PF/VF can add allmulticast entry */
if (is_afvf(pcifunc))
if (is_afvf(pcifunc) && is_sdp_vf(pcifunc))
return;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
......@@ -2706,7 +2676,6 @@ int rvu_mbox_handler_npc_mcam_write_entry(struct rvu *rvu,
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
struct npc_mcam *mcam = &rvu->hw->mcam;
u16 pcifunc = req->hdr.pcifunc;
u16 channel, chan_mask;
int blkaddr, rc;
u8 nix_intf;
......@@ -2714,10 +2683,6 @@ int rvu_mbox_handler_npc_mcam_write_entry(struct rvu *rvu,
if (blkaddr < 0)
return NPC_MCAM_INVALID_REQ;
chan_mask = req->entry_data.kw_mask[0] & NPC_KEX_CHAN_MASK;
channel = req->entry_data.kw[0] & NPC_KEX_CHAN_MASK;
channel &= chan_mask;
mutex_lock(&mcam->lock);
rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry);
if (rc)
......@@ -2739,12 +2704,6 @@ int rvu_mbox_handler_npc_mcam_write_entry(struct rvu *rvu,
else
nix_intf = pfvf->nix_rx_intf;
if (!is_pffunc_af(pcifunc) &&
npc_mcam_verify_channel(rvu, pcifunc, req->intf, channel)) {
rc = NPC_MCAM_INVALID_REQ;
goto exit;
}
if (!is_pffunc_af(pcifunc) &&
npc_mcam_verify_pf_func(rvu, &req->entry_data, req->intf, pcifunc)) {
rc = NPC_MCAM_INVALID_REQ;
......@@ -3091,7 +3050,6 @@ int rvu_mbox_handler_npc_mcam_alloc_and_write_entry(struct rvu *rvu,
struct npc_mcam *mcam = &rvu->hw->mcam;
u16 entry = NPC_MCAM_ENTRY_INVALID;
u16 cntr = NPC_MCAM_ENTRY_INVALID;
u16 channel, chan_mask;
int blkaddr, rc;
u8 nix_intf;
......@@ -3102,13 +3060,6 @@ int rvu_mbox_handler_npc_mcam_alloc_and_write_entry(struct rvu *rvu,
if (!is_npc_interface_valid(rvu, req->intf))
return NPC_MCAM_INVALID_REQ;
chan_mask = req->entry_data.kw_mask[0] & NPC_KEX_CHAN_MASK;
channel = req->entry_data.kw[0] & NPC_KEX_CHAN_MASK;
channel &= chan_mask;
if (npc_mcam_verify_channel(rvu, req->hdr.pcifunc, req->intf, channel))
return NPC_MCAM_INVALID_REQ;
if (npc_mcam_verify_pf_func(rvu, &req->entry_data, req->intf,
req->hdr.pcifunc))
return NPC_MCAM_INVALID_REQ;
......
......@@ -1173,11 +1173,6 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu,
if (err)
return NPC_FLOW_NOT_SUPPORTED;
/* Skip channel validation if AF is installing */
if (!is_pffunc_af(req->hdr.pcifunc) &&
npc_mcam_verify_channel(rvu, target, req->intf, req->channel))
return NPC_FLOW_CHAN_INVALID;
pfvf = rvu_get_pfvf(rvu, target);
/* PF installing for its VF */
......
......@@ -33,8 +33,8 @@ static struct hw_reg_map txsch_reg_map[NIX_TXSCH_LVL_CNT] = {
{NIX_TXSCH_LVL_SMQ, 2, 0xFFFF, {{0x0700, 0x0708}, {0x1400, 0x14C8} } },
{NIX_TXSCH_LVL_TL4, 3, 0xFFFF, {{0x0B00, 0x0B08}, {0x0B10, 0x0B18},
{0x1200, 0x12E0} } },
{NIX_TXSCH_LVL_TL3, 3, 0xFFFF, {{0x1000, 0x10E0}, {0x1600, 0x1608},
{0x1610, 0x1618} } },
{NIX_TXSCH_LVL_TL3, 4, 0xFFFF, {{0x1000, 0x10E0}, {0x1600, 0x1608},
{0x1610, 0x1618}, {0x1700, 0x17B0} } },
{NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x17B0} } },
{NIX_TXSCH_LVL_TL1, 1, 0xFFFF, {{0x0C00, 0x0D98} } },
};
......
// SPDX-License-Identifier: GPL-2.0
/* Marvell OcteonTx2 RVU Admin Function driver
*
* Copyright (C) 2021 Marvell.
*
*/
#include <linux/pci.h>
#include "rvu.h"
/* SDP PF device id */
#define PCI_DEVID_OTX2_SDP_PF 0xA0F6
/* Maximum SDP blocks in a chip */
#define MAX_SDP 2
/* SDP PF number */
static int sdp_pf_num[MAX_SDP] = {-1, -1};
bool is_sdp_pfvf(u16 pcifunc)
{
u16 pf = rvu_get_pf(pcifunc);
u32 found = 0, i = 0;
while (i < MAX_SDP) {
if (pf == sdp_pf_num[i])
found = 1;
i++;
}
if (!found)
return false;
return true;
}
bool is_sdp_pf(u16 pcifunc)
{
return (is_sdp_pfvf(pcifunc) &&
!(pcifunc & RVU_PFVF_FUNC_MASK));
}
bool is_sdp_vf(u16 pcifunc)
{
return (is_sdp_pfvf(pcifunc) &&
!!(pcifunc & RVU_PFVF_FUNC_MASK));
}
int rvu_sdp_init(struct rvu *rvu)
{
struct pci_dev *pdev = NULL;
struct rvu_pfvf *pfvf;
u32 i = 0;
while ((i < MAX_SDP) && (pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
PCI_DEVID_OTX2_SDP_PF,
pdev)) != NULL) {
/* The RVU PF number is one less than bus number */
sdp_pf_num[i] = pdev->bus->number - 1;
pfvf = &rvu->pf[sdp_pf_num[i]];
pfvf->sdp_info = devm_kzalloc(rvu->dev,
sizeof(struct sdp_node_info),
GFP_KERNEL);
if (!pfvf->sdp_info)
return -ENOMEM;
dev_info(rvu->dev, "SDP PF number:%d\n", sdp_pf_num[i]);
put_device(&pdev->dev);
i++;
}
return 0;
}
int
rvu_mbox_handler_set_sdp_chan_info(struct rvu *rvu,
struct sdp_chan_info_msg *req,
struct msg_rsp *rsp)
{
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
memcpy(pfvf->sdp_info, &req->info, sizeof(struct sdp_node_info));
dev_info(rvu->dev, "AF: SDP%d max_vfs %d num_pf_rings %d pf_srn %d\n",
req->info.node_id, req->info.max_vfs, req->info.num_pf_rings,
req->info.pf_srn);
return 0;
}
int
rvu_mbox_handler_get_sdp_chan_info(struct rvu *rvu, struct msg_req *req,
struct sdp_get_chan_info_msg *rsp)
{
struct rvu_hwinfo *hw = rvu->hw;
int blkaddr;
if (!hw->cap.programmable_chans) {
rsp->chan_base = NIX_CHAN_SDP_CH_START;
rsp->num_chan = NIX_CHAN_SDP_NUM_CHANS;
} else {
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
rsp->chan_base = hw->sdp_chan_base;
rsp->num_chan = rvu_read64(rvu, blkaddr, NIX_AF_CONST1) & 0xFFFUL;
}
return 0;
}
......@@ -584,25 +584,6 @@ void otx2_get_mac_from_af(struct net_device *netdev)
}
EXPORT_SYMBOL(otx2_get_mac_from_af);
static int otx2_get_link(struct otx2_nic *pfvf)
{
int link = 0;
u16 map;
/* cgx lmac link */
if (pfvf->hw.tx_chan_base >= CGX_CHAN_BASE) {
map = pfvf->hw.tx_chan_base & 0x7FF;
link = 4 * ((map >> 8) & 0xF) + ((map >> 4) & 0xF);
}
/* LBK channel */
if (pfvf->hw.tx_chan_base < SDP_CHAN_BASE) {
map = pfvf->hw.tx_chan_base & 0x7FF;
link = pfvf->hw.cgx_links | ((map >> 8) & 0xF);
}
return link;
}
int otx2_txschq_config(struct otx2_nic *pfvf, int lvl)
{
struct otx2_hw *hw = &pfvf->hw;
......@@ -661,8 +642,7 @@ int otx2_txschq_config(struct otx2_nic *pfvf, int lvl)
req->regval[1] = TXSCH_TL1_DFLT_RR_PRIO << 24 | dwrr_val;
req->num_regs++;
req->reg[2] = NIX_AF_TL3_TL2X_LINKX_CFG(schq,
otx2_get_link(pfvf));
req->reg[2] = NIX_AF_TL3_TL2X_LINKX_CFG(schq, hw->tx_link);
/* Enable this queue and backpressure */
req->regval[2] = BIT_ULL(13) | BIT_ULL(12);
......@@ -1610,6 +1590,7 @@ void mbox_handler_nix_lf_alloc(struct otx2_nic *pfvf,
pfvf->hw.lso_tsov6_idx = rsp->lso_tsov6_idx;
pfvf->hw.cgx_links = rsp->cgx_links;
pfvf->hw.lbk_links = rsp->lbk_links;
pfvf->hw.tx_link = rsp->tx_link;
}
EXPORT_SYMBOL(mbox_handler_nix_lf_alloc);
......
......@@ -218,6 +218,7 @@ struct otx2_hw {
u64 cgx_fec_uncorr_blks;
u8 cgx_links; /* No. of CGX links present in HW */
u8 lbk_links; /* No. of LBK links present in HW */
u8 tx_link; /* Transmit channel link number */
#define HW_TSO 0
#define CN10K_MBOX 1
#define CN10K_LMTST 2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment