Skip to content

Commit

Permalink
octeontx2-af: Set NIX link credits based on max LMAC
Browse files Browse the repository at this point in the history
When number of LMACs active on a CGX/RPM are 3, then
current NIX link credit config based on per lmac fifo
length which inturn  is calculated as
'lmac_fifo_len = total_fifo_len / 3', is incorrect. In HW
one of the LMAC gets half of the FIFO and rest gets 1/4th.

Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: Geetha Sowjanya <gakula@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Sunil Goutham authored and David S. Miller committed Jul 15, 2022
1 parent da92e03 commit 459f326
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 9 deletions.
27 changes: 27 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/cgx.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,32 @@ static u8 cgx_get_lmac_type(void *cgxd, int lmac_id)
return (cfg >> CGX_LMAC_TYPE_SHIFT) & CGX_LMAC_TYPE_MASK;
}

static u32 cgx_get_lmac_fifo_len(void *cgxd, int lmac_id)
{
struct cgx *cgx = cgxd;
u8 num_lmacs;
u32 fifo_len;

fifo_len = cgx->mac_ops->fifo_len;
num_lmacs = cgx->mac_ops->get_nr_lmacs(cgx);

switch (num_lmacs) {
case 1:
return fifo_len;
case 2:
return fifo_len / 2;
case 3:
/* LMAC0 gets half of the FIFO, reset 1/4th */
if (lmac_id == 0)
return fifo_len / 2;
return fifo_len / 4;
case 4:
default:
return fifo_len / 4;
}
return 0;
}

/* Configure CGX LMAC in internal loopback mode */
int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable)
{
Expand Down Expand Up @@ -1704,6 +1730,7 @@ static struct mac_ops cgx_mac_ops = {
.tx_stats_cnt = 18,
.get_nr_lmacs = cgx_get_nr_lmacs,
.get_lmac_type = cgx_get_lmac_type,
.lmac_fifo_len = cgx_get_lmac_fifo_len,
.mac_lmac_intl_lbk = cgx_lmac_internal_loopback,
.mac_get_rx_stats = cgx_get_rx_stats,
.mac_get_tx_stats = cgx_get_tx_stats,
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct mac_ops {
*/
int (*get_nr_lmacs)(void *cgx);
u8 (*get_lmac_type)(void *cgx, int lmac_id);
u32 (*lmac_fifo_len)(void *cgx, int lmac_id);
int (*mac_lmac_intl_lbk)(void *cgx, int lmac_id,
bool enable);
/* Register Stats related functions */
Expand Down
30 changes: 30 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ static struct mac_ops rpm_mac_ops = {
.tx_stats_cnt = 34,
.get_nr_lmacs = rpm_get_nr_lmacs,
.get_lmac_type = rpm_get_lmac_type,
.lmac_fifo_len = rpm_get_lmac_fifo_len,
.mac_lmac_intl_lbk = rpm_lmac_internal_loopback,
.mac_get_rx_stats = rpm_get_rx_stats,
.mac_get_tx_stats = rpm_get_tx_stats,
Expand Down Expand Up @@ -350,6 +351,35 @@ u8 rpm_get_lmac_type(void *rpmd, int lmac_id)
return err;
}

u32 rpm_get_lmac_fifo_len(void *rpmd, int lmac_id)
{
rpm_t *rpm = rpmd;
u64 hi_perf_lmac;
u8 num_lmacs;
u32 fifo_len;

fifo_len = rpm->mac_ops->fifo_len;
num_lmacs = rpm->mac_ops->get_nr_lmacs(rpm);

switch (num_lmacs) {
case 1:
return fifo_len;
case 2:
return fifo_len / 2;
case 3:
/* LMAC marked as hi_perf gets half of the FIFO and rest 1/4th */
hi_perf_lmac = rpm_read(rpm, 0, CGXX_CMRX_RX_LMACS);
hi_perf_lmac = (hi_perf_lmac >> 4) & 0x3ULL;
if (lmac_id == hi_perf_lmac)
return fifo_len / 2;
return fifo_len / 4;
case 4:
default:
return fifo_len / 4;
}
return 0;
}

int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable)
{
rpm_t *rpm = rpmd;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rpm.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
/* Function Declarations */
int rpm_get_nr_lmacs(void *rpmd);
u8 rpm_get_lmac_type(void *rpmd, int lmac_id);
u32 rpm_get_lmac_fifo_len(void *rpmd, int lmac_id);
int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable);
void rpm_lmac_enadis_rx_pause_fwding(void *rpmd, int lmac_id, bool enable);
int rpm_lmac_get_pause_frm_status(void *cgxd, int lmac_id, u8 *tx_pause,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/octeontx2/af/rvu.h
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable);
int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause,
u16 pfc_en);
int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause);

u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac);
int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf,
int type);
bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr,
Expand Down
16 changes: 16 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,22 @@ u32 rvu_cgx_get_fifolen(struct rvu *rvu)
return fifo_len;
}

u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac)
{
struct mac_ops *mac_ops;
void *cgxd;

cgxd = rvu_cgx_pdata(cgx, rvu);
if (!cgxd)
return 0;

mac_ops = get_mac_ops(cgxd);
if (!mac_ops->lmac_fifo_len)
return 0;

return mac_ops->lmac_fifo_len(cgxd, lmac);
}

static int rvu_cgx_config_intlbk(struct rvu *rvu, u16 pcifunc, bool en)
{
int pf = rvu_get_pf(pcifunc);
Expand Down
34 changes: 26 additions & 8 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
Original file line number Diff line number Diff line change
Expand Up @@ -4010,9 +4010,13 @@ int rvu_mbox_handler_nix_set_hw_frs(struct rvu *rvu, struct nix_frs_cfg *req,
return 0;

/* Update transmit credits for CGX links */
lmac_fifo_len =
rvu_cgx_get_fifolen(rvu) /
cgx_get_lmac_cnt(rvu_cgx_pdata(cgx, rvu));
lmac_fifo_len = rvu_cgx_get_lmac_fifolen(rvu, cgx, lmac);
if (!lmac_fifo_len) {
dev_err(rvu->dev,
"%s: Failed to get CGX/RPM%d:LMAC%d FIFO size\n",
__func__, cgx, lmac);
return 0;
}
return nix_config_link_credits(rvu, blkaddr, link, pcifunc,
(lmac_fifo_len - req->maxlen) / 16);
}
Expand Down Expand Up @@ -4064,7 +4068,10 @@ static void nix_link_config(struct rvu *rvu, int blkaddr,
struct rvu_hwinfo *hw = rvu->hw;
int cgx, lmac_cnt, slink, link;
u16 lbk_max_frs, lmac_max_frs;
unsigned long lmac_bmap;
u64 tx_credits, cfg;
u64 lmac_fifo_len;
int iter;

rvu_get_lbk_link_max_frs(rvu, &lbk_max_frs);
rvu_get_lmac_link_max_frs(rvu, &lmac_max_frs);
Expand Down Expand Up @@ -4098,12 +4105,23 @@ static void nix_link_config(struct rvu *rvu, int blkaddr,
/* Skip when cgx is not available or lmac cnt is zero */
if (lmac_cnt <= 0)
continue;
tx_credits = ((rvu_cgx_get_fifolen(rvu) / lmac_cnt) -
lmac_max_frs) / 16;
/* Enable credits and set credit pkt count to max allowed */
cfg = (tx_credits << 12) | (0x1FF << 2) | BIT_ULL(1);
slink = cgx * hw->lmac_per_cgx;
for (link = slink; link < (slink + lmac_cnt); link++) {

/* Get LMAC id's from bitmap */
lmac_bmap = cgx_get_lmac_bmap(rvu_cgx_pdata(cgx, rvu));
for_each_set_bit(iter, &lmac_bmap, MAX_LMAC_PER_CGX) {
lmac_fifo_len = rvu_cgx_get_lmac_fifolen(rvu, cgx, iter);
if (!lmac_fifo_len) {
dev_err(rvu->dev,
"%s: Failed to get CGX/RPM%d:LMAC%d FIFO size\n",
__func__, cgx, iter);
continue;
}
tx_credits = (lmac_fifo_len - lmac_max_frs) / 16;
/* Enable credits and set credit pkt count to max allowed */
cfg = (tx_credits << 12) | (0x1FF << 2) | BIT_ULL(1);

link = iter + slink;
nix_hw->tx_credits[link] = tx_credits;
rvu_write64(rvu, blkaddr,
NIX_AF_TX_LINKX_NORM_CREDIT(link), cfg);
Expand Down

0 comments on commit 459f326

Please sign in to comment.