octeontx2-af: Set NIX link credits based on max LMAC
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>
This commit is contained in:
parent
da92e03c7f
commit
459f326e99
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue