Skip to content

Commit

Permalink
octeontx2-pf: Add representors for sdp MAC
Browse files Browse the repository at this point in the history
Hardware supports different types of MACs eg RPM, SDP, LBK.
LBK is for internal Tx->Rx HW loopback path. RPM and SDP MACs support
ingress/egress pkt IO on interfaces with different set of capabilities
like interface modes. At the time of netdev driver registration PF will
seek MAC related information from Admin function driver
'drivers/net/ethernet/marvell/octeontx2/af' and sets up ingress/egress
queues etc such that pkt IO on the channels of these different MACs is
possible. This patch add representors for SDP MAC.

Signed-off-by: Geetha sowjanya <gakula@marvell.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Geetha sowjanya authored and David S. Miller committed Nov 13, 2024
1 parent 3392f91 commit 2f7f33a
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 26 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ enum nix_scheduler {
#define NIC_HW_MIN_FRS 40
#define NIC_HW_MAX_FRS 9212
#define SDP_HW_MAX_FRS 65535
#define SDP_HW_MIN_FRS 16
#define CN10K_LMAC_LINK_MAX_FRS 16380 /* 16k - FCS */
#define CN10K_LBK_LINK_MAX_FRS 65535 /* 64k */

Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,9 @@ int rvu_mbox_handler_nix_bp_disable(struct rvu *rvu,
if (!is_pf_cgxmapped(rvu, pf) && type != NIX_INTF_TYPE_LBK)
return 0;

if (is_sdp_pfvf(pcifunc))
type = NIX_INTF_TYPE_SDP;

pfvf = rvu_get_pfvf(rvu, pcifunc);
err = nix_get_struct_ptrs(rvu, pcifunc, &nix_hw, &blkaddr);
if (err)
Expand Down Expand Up @@ -4687,7 +4690,7 @@ static void nix_link_config(struct rvu *rvu, int blkaddr,
if (hw->sdp_links) {
link = hw->cgx_links + hw->lbk_links;
rvu_write64(rvu, blkaddr, NIX_AF_RX_LINKX_CFG(link),
SDP_HW_MAX_FRS << 16 | NIC_HW_MIN_FRS);
SDP_HW_MAX_FRS << 16 | SDP_HW_MIN_FRS);
}

/* Get MCS external bypass status for CN10K-B */
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ int cn10k_lmtst_init(struct otx2_nic *pfvf)
}
EXPORT_SYMBOL(cn10k_lmtst_init);

int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura)
int cn10k_sq_aq_init(void *dev, u16 qidx, u8 chan_offset, u16 sqb_aura)
{
struct nix_cn10k_aq_enq_req *aq;
struct otx2_nic *pfvf = dev;
Expand All @@ -88,7 +88,7 @@ int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura)
aq->sq.ena = 1;
aq->sq.smq = otx2_get_smq_idx(pfvf, qidx);
aq->sq.smq_rr_weight = mtu_to_dwrr_weight(pfvf, pfvf->tx_max_pktlen);
aq->sq.default_chan = pfvf->hw.tx_chan_base;
aq->sq.default_chan = pfvf->hw.tx_chan_base + chan_offset;
aq->sq.sqe_stype = NIX_STYPE_STF; /* Cache SQB */
aq->sq.sqb_aura = sqb_aura;
aq->sq.sq_int_ena = NIX_SQINT_BITS;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/octeontx2/nic/cn10k.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static inline int mtu_to_dwrr_weight(struct otx2_nic *pfvf, int mtu)

int cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq);
void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx);
int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura);
int cn10k_sq_aq_init(void *dev, u16 qidx, u8 chan_offset, u16 sqb_aura);
int cn10k_lmtst_init(struct otx2_nic *pfvf);
int cn10k_free_all_ipolicers(struct otx2_nic *pfvf);
int cn10k_alloc_matchall_ipolicer(struct otx2_nic *pfvf);
Expand Down
50 changes: 39 additions & 11 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ int otx2_config_pause_frm(struct otx2_nic *pfvf)
struct cgx_pause_frm_cfg *req;
int err;

if (is_otx2_lbkvf(pfvf->pdev))
if (is_otx2_lbkvf(pfvf->pdev) || is_otx2_sdp_rep(pfvf->pdev))
return 0;

mutex_lock(&pfvf->mbox.lock);
Expand Down Expand Up @@ -647,20 +647,31 @@ int otx2_txschq_config(struct otx2_nic *pfvf, int lvl, int prio, bool txschq_for
req->reg[2] = NIX_AF_MDQX_SCHEDULE(schq);
req->regval[2] = dwrr_val;
} else if (lvl == NIX_TXSCH_LVL_TL4) {
int sdp_chan = hw->tx_chan_base + prio;

if (is_otx2_sdp_rep(pfvf->pdev))
prio = 0;
parent = schq_list[NIX_TXSCH_LVL_TL3][prio];
req->reg[0] = NIX_AF_TL4X_PARENT(schq);
req->regval[0] = (u64)parent << 16;
req->num_regs++;
req->reg[1] = NIX_AF_TL4X_SCHEDULE(schq);
req->regval[1] = dwrr_val;
if (is_otx2_sdp_rep(pfvf->pdev)) {
req->num_regs++;
req->reg[2] = NIX_AF_TL4X_SDP_LINK_CFG(schq);
req->regval[2] = BIT_ULL(12) | BIT_ULL(13) |
(sdp_chan & 0xff);
}
} else if (lvl == NIX_TXSCH_LVL_TL3) {
parent = schq_list[NIX_TXSCH_LVL_TL2][prio];
req->reg[0] = NIX_AF_TL3X_PARENT(schq);
req->regval[0] = (u64)parent << 16;
req->num_regs++;
req->reg[1] = NIX_AF_TL3X_SCHEDULE(schq);
req->regval[1] = dwrr_val;
if (lvl == hw->txschq_link_cfg_lvl) {
if (lvl == hw->txschq_link_cfg_lvl &&
!is_otx2_sdp_rep(pfvf->pdev)) {
req->num_regs++;
req->reg[2] = NIX_AF_TL3_TL2X_LINKX_CFG(schq, hw->tx_link);
/* Enable this queue and backpressure
Expand All @@ -677,7 +688,8 @@ int otx2_txschq_config(struct otx2_nic *pfvf, int lvl, int prio, bool txschq_for
req->reg[1] = NIX_AF_TL2X_SCHEDULE(schq);
req->regval[1] = (u64)hw->txschq_aggr_lvl_rr_prio << 24 | dwrr_val;

if (lvl == hw->txschq_link_cfg_lvl) {
if (lvl == hw->txschq_link_cfg_lvl &&
!is_otx2_sdp_rep(pfvf->pdev)) {
req->num_regs++;
req->reg[2] = NIX_AF_TL3_TL2X_LINKX_CFG(schq, hw->tx_link);
/* Enable this queue and backpressure
Expand Down Expand Up @@ -736,6 +748,7 @@ EXPORT_SYMBOL(otx2_smq_flush);

int otx2_txsch_alloc(struct otx2_nic *pfvf)
{
int chan_cnt = pfvf->hw.tx_chan_cnt;
struct nix_txsch_alloc_req *req;
struct nix_txsch_alloc_rsp *rsp;
int lvl, schq, rc;
Expand All @@ -748,6 +761,12 @@ int otx2_txsch_alloc(struct otx2_nic *pfvf)
/* Request one schq per level */
for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++)
req->schq[lvl] = 1;

if (is_otx2_sdp_rep(pfvf->pdev) && chan_cnt > 1) {
req->schq[NIX_TXSCH_LVL_SMQ] = chan_cnt;
req->schq[NIX_TXSCH_LVL_TL4] = chan_cnt;
}

rc = otx2_sync_mbox_msg(&pfvf->mbox);
if (rc)
return rc;
Expand All @@ -758,10 +777,12 @@ int otx2_txsch_alloc(struct otx2_nic *pfvf)
return PTR_ERR(rsp);

/* Setup transmit scheduler list */
for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++)
for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
pfvf->hw.txschq_cnt[lvl] = rsp->schq[lvl];
for (schq = 0; schq < rsp->schq[lvl]; schq++)
pfvf->hw.txschq_list[lvl][schq] =
rsp->schq_list[lvl][schq];
}

pfvf->hw.txschq_link_cfg_lvl = rsp->link_cfg_lvl;
pfvf->hw.txschq_aggr_lvl_rr_prio = rsp->aggr_lvl_rr_prio;
Expand Down Expand Up @@ -799,12 +820,15 @@ EXPORT_SYMBOL(otx2_txschq_free_one);

void otx2_txschq_stop(struct otx2_nic *pfvf)
{
int lvl, schq;
int lvl, schq, idx;

/* free non QOS TLx nodes */
for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++)
otx2_txschq_free_one(pfvf, lvl,
pfvf->hw.txschq_list[lvl][0]);
for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
for (idx = 0; idx < pfvf->hw.txschq_cnt[lvl]; idx++) {
otx2_txschq_free_one(pfvf, lvl,
pfvf->hw.txschq_list[lvl][idx]);
}
}

/* Clear the txschq list */
for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
Expand Down Expand Up @@ -884,7 +908,7 @@ static int otx2_rq_init(struct otx2_nic *pfvf, u16 qidx, u16 lpb_aura)
return otx2_sync_mbox_msg(&pfvf->mbox);
}

int otx2_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura)
int otx2_sq_aq_init(void *dev, u16 qidx, u8 chan_offset, u16 sqb_aura)
{
struct otx2_nic *pfvf = dev;
struct otx2_snd_queue *sq;
Expand All @@ -903,7 +927,7 @@ int otx2_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura)
aq->sq.ena = 1;
aq->sq.smq = otx2_get_smq_idx(pfvf, qidx);
aq->sq.smq_rr_quantum = mtu_to_dwrr_weight(pfvf, pfvf->tx_max_pktlen);
aq->sq.default_chan = pfvf->hw.tx_chan_base;
aq->sq.default_chan = pfvf->hw.tx_chan_base + chan_offset;
aq->sq.sqe_stype = NIX_STYPE_STF; /* Cache SQB */
aq->sq.sqb_aura = sqb_aura;
aq->sq.sq_int_ena = NIX_SQINT_BITS;
Expand All @@ -926,6 +950,7 @@ int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura)
struct otx2_qset *qset = &pfvf->qset;
struct otx2_snd_queue *sq;
struct otx2_pool *pool;
u8 chan_offset;
int err;

pool = &pfvf->qset.pool[sqb_aura];
Expand Down Expand Up @@ -972,7 +997,8 @@ int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura)
sq->stats.bytes = 0;
sq->stats.pkts = 0;

err = pfvf->hw_ops->sq_aq_init(pfvf, qidx, sqb_aura);
chan_offset = qidx % pfvf->hw.tx_chan_cnt;
err = pfvf->hw_ops->sq_aq_init(pfvf, qidx, chan_offset, sqb_aura);
if (err) {
kfree(sq->sg);
sq->sg = NULL;
Expand Down Expand Up @@ -1739,6 +1765,8 @@ void mbox_handler_nix_lf_alloc(struct otx2_nic *pfvf,
pfvf->hw.sqb_size = rsp->sqb_size;
pfvf->hw.rx_chan_base = rsp->rx_chan_base;
pfvf->hw.tx_chan_base = rsp->tx_chan_base;
pfvf->hw.rx_chan_cnt = rsp->rx_chan_cnt;
pfvf->hw.tx_chan_cnt = rsp->tx_chan_cnt;
pfvf->hw.lso_tsov4_idx = rsp->lso_tsov4_idx;
pfvf->hw.lso_tsov6_idx = rsp->lso_tsov6_idx;
pfvf->hw.cgx_links = rsp->cgx_links;
Expand Down
27 changes: 21 additions & 6 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#define PCI_SUBSYS_DEVID_96XX_RVU_PFVF 0xB200
#define PCI_SUBSYS_DEVID_CN10K_B_RVU_PFVF 0xBD00

#define PCI_DEVID_OCTEONTX2_SDP_REP 0xA0F7

/* PCI BAR nos */
#define PCI_CFG_REG_BAR_NUM 2
#define PCI_MBOX_BAR_NUM 4
Expand Down Expand Up @@ -198,6 +200,7 @@ struct otx2_hw {

/* NIX */
u8 txschq_link_cfg_lvl;
u8 txschq_cnt[NIX_TXSCH_LVL_CNT];
u8 txschq_aggr_lvl_rr_prio;
u16 txschq_list[NIX_TXSCH_LVL_CNT][MAX_TXSCHQ_PER_FUNC];
u16 matchall_ipolicer;
Expand All @@ -208,6 +211,8 @@ struct otx2_hw {
/* HW settings, coalescing etc */
u16 rx_chan_base;
u16 tx_chan_base;
u8 rx_chan_cnt;
u8 tx_chan_cnt;
u16 cq_qcount_wait;
u16 cq_ecount_wait;
u16 rq_skid;
Expand Down Expand Up @@ -342,7 +347,8 @@ struct otx2_flow_config {
};

struct dev_hw_ops {
int (*sq_aq_init)(void *dev, u16 qidx, u16 sqb_aura);
int (*sq_aq_init)(void *dev, u16 qidx, u8 chan_offset,
u16 sqb_aura);
void (*sqe_flush)(void *dev, struct otx2_snd_queue *sq,
int size, int qidx);
int (*refill_pool_ptrs)(void *dev, struct otx2_cq_queue *cq);
Expand Down Expand Up @@ -536,6 +542,11 @@ static inline bool is_96xx_B0(struct pci_dev *pdev)
(pdev->subsystem_device == PCI_SUBSYS_DEVID_96XX_RVU_PFVF);
}

static inline bool is_otx2_sdp_rep(struct pci_dev *pdev)
{
return pdev->device == PCI_DEVID_OCTEONTX2_SDP_REP;
}

/* REVID for PCIe devices.
* Bits 0..1: minor pass, bit 3..2: major pass
* bits 7..4: midr id
Expand Down Expand Up @@ -898,15 +909,19 @@ static inline void otx2_dma_unmap_page(struct otx2_nic *pfvf,
static inline u16 otx2_get_smq_idx(struct otx2_nic *pfvf, u16 qidx)
{
u16 smq;
int idx;

#ifdef CONFIG_DCB
if (qidx < NIX_PF_PFC_PRIO_MAX && pfvf->pfc_alloc_status[qidx])
return pfvf->pfc_schq_list[NIX_TXSCH_LVL_SMQ][qidx];
#endif
/* check if qidx falls under QOS queues */
if (qidx >= pfvf->hw.non_qos_queues)
if (qidx >= pfvf->hw.non_qos_queues) {
smq = pfvf->qos.qid_to_sqmap[qidx - pfvf->hw.non_qos_queues];
else
smq = pfvf->hw.txschq_list[NIX_TXSCH_LVL_SMQ][0];
} else {
idx = qidx % pfvf->hw.txschq_cnt[NIX_TXSCH_LVL_SMQ];
smq = pfvf->hw.txschq_list[NIX_TXSCH_LVL_SMQ][idx];
}

return smq;
}
Expand Down Expand Up @@ -973,8 +988,8 @@ int otx2_nix_config_bp(struct otx2_nic *pfvf, bool enable);
void otx2_cleanup_rx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq, int qidx);
void otx2_cleanup_tx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq);
int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura);
int otx2_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura);
int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura);
int otx2_sq_aq_init(void *dev, u16 qidx, u8 chan_offset, u16 sqb_aura);
int cn10k_sq_aq_init(void *dev, u16 qidx, u8 chan_offset, u16 sqb_aura);
int otx2_alloc_buffer(struct otx2_nic *pfvf, struct otx2_cq_queue *cq,
dma_addr_t *dma);
int otx2_pool_init(struct otx2_nic *pfvf, u16 pool_id,
Expand Down
13 changes: 9 additions & 4 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1591,10 +1591,15 @@ int otx2_init_hw_resources(struct otx2_nic *pf)
}

for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
err = otx2_txschq_config(pf, lvl, 0, false);
if (err) {
mutex_unlock(&mbox->lock);
goto err_free_nix_queues;
int idx;

for (idx = 0; idx < pf->hw.txschq_cnt[lvl]; idx++) {
err = otx2_txschq_config(pf, lvl, idx, false);
if (err) {
dev_err(pf->dev, "Failed to config TXSCH\n");
mutex_unlock(&mbox->lock);
goto err_free_nix_queues;
}
}
}

Expand Down
12 changes: 11 additions & 1 deletion drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
static const struct pci_device_id otx2_vf_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_RVU_AFVF) },
{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_RVU_VF) },
{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_SDP_REP) },
{ }
};

Expand Down Expand Up @@ -371,7 +372,7 @@ static int otx2vf_open(struct net_device *netdev)

/* LBKs do not receive link events so tell everyone we are up here */
vf = netdev_priv(netdev);
if (is_otx2_lbkvf(vf->pdev)) {
if (is_otx2_lbkvf(vf->pdev) || is_otx2_sdp_rep(vf->pdev)) {
pr_info("%s NIC Link is UP\n", netdev->name);
netif_carrier_on(netdev);
netif_tx_start_all_queues(netdev);
Expand Down Expand Up @@ -683,6 +684,15 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
snprintf(netdev->name, sizeof(netdev->name), "lbk%d", n);
}

if (is_otx2_sdp_rep(vf->pdev)) {
int n;

n = vf->pcifunc & RVU_PFVF_FUNC_MASK;
n -= 1;
snprintf(netdev->name, sizeof(netdev->name), "sdp%d-%d",
pdev->bus->number, n);
}

err = register_netdev(netdev);
if (err) {
dev_err(dev, "Failed to register netdevice\n");
Expand Down

0 comments on commit 2f7f33a

Please sign in to comment.