mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
octeontx2-af: Set NIX link credits based on max LMAC
[ Upstream commit 459f326e99 ]
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>
Stable-dep-of: a0d9528f6daf ("octeontx2-af: Always configure NIX TX link credits based on max frame size")
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
6ef9a28e1b
commit
6bbbcff3c7
@@ -505,6 +505,32 @@ static u8 cgx_get_lmac_type(void *cgxd, int lmac_id)
|
|||||||
return (cfg >> CGX_LMAC_TYPE_SHIFT) & CGX_LMAC_TYPE_MASK;
|
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 */
|
/* Configure CGX LMAC in internal loopback mode */
|
||||||
int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable)
|
int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable)
|
||||||
{
|
{
|
||||||
@@ -1557,6 +1583,7 @@ static struct mac_ops cgx_mac_ops = {
|
|||||||
.tx_stats_cnt = 18,
|
.tx_stats_cnt = 18,
|
||||||
.get_nr_lmacs = cgx_get_nr_lmacs,
|
.get_nr_lmacs = cgx_get_nr_lmacs,
|
||||||
.get_lmac_type = cgx_get_lmac_type,
|
.get_lmac_type = cgx_get_lmac_type,
|
||||||
|
.lmac_fifo_len = cgx_get_lmac_fifo_len,
|
||||||
.mac_lmac_intl_lbk = cgx_lmac_internal_loopback,
|
.mac_lmac_intl_lbk = cgx_lmac_internal_loopback,
|
||||||
.mac_get_rx_stats = cgx_get_rx_stats,
|
.mac_get_rx_stats = cgx_get_rx_stats,
|
||||||
.mac_get_tx_stats = cgx_get_tx_stats,
|
.mac_get_tx_stats = cgx_get_tx_stats,
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ struct mac_ops {
|
|||||||
*/
|
*/
|
||||||
int (*get_nr_lmacs)(void *cgx);
|
int (*get_nr_lmacs)(void *cgx);
|
||||||
u8 (*get_lmac_type)(void *cgx, int lmac_id);
|
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,
|
int (*mac_lmac_intl_lbk)(void *cgx, int lmac_id,
|
||||||
bool enable);
|
bool enable);
|
||||||
/* Register Stats related functions */
|
/* Register Stats related functions */
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ static struct mac_ops rpm_mac_ops = {
|
|||||||
.tx_stats_cnt = 34,
|
.tx_stats_cnt = 34,
|
||||||
.get_nr_lmacs = rpm_get_nr_lmacs,
|
.get_nr_lmacs = rpm_get_nr_lmacs,
|
||||||
.get_lmac_type = rpm_get_lmac_type,
|
.get_lmac_type = rpm_get_lmac_type,
|
||||||
|
.lmac_fifo_len = rpm_get_lmac_fifo_len,
|
||||||
.mac_lmac_intl_lbk = rpm_lmac_internal_loopback,
|
.mac_lmac_intl_lbk = rpm_lmac_internal_loopback,
|
||||||
.mac_get_rx_stats = rpm_get_rx_stats,
|
.mac_get_rx_stats = rpm_get_rx_stats,
|
||||||
.mac_get_tx_stats = rpm_get_tx_stats,
|
.mac_get_tx_stats = rpm_get_tx_stats,
|
||||||
@@ -261,6 +262,35 @@ u8 rpm_get_lmac_type(void *rpmd, int lmac_id)
|
|||||||
return err;
|
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)
|
int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable)
|
||||||
{
|
{
|
||||||
rpm_t *rpm = rpmd;
|
rpm_t *rpm = rpmd;
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
/* Function Declarations */
|
/* Function Declarations */
|
||||||
int rpm_get_nr_lmacs(void *rpmd);
|
int rpm_get_nr_lmacs(void *rpmd);
|
||||||
u8 rpm_get_lmac_type(void *rpmd, int lmac_id);
|
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);
|
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);
|
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,
|
int rpm_lmac_get_pause_frm_status(void *cgxd, int lmac_id, u8 *tx_pause,
|
||||||
|
|||||||
@@ -813,7 +813,7 @@ u32 rvu_cgx_get_fifolen(struct rvu *rvu);
|
|||||||
void *rvu_first_cgx_pdata(struct rvu *rvu);
|
void *rvu_first_cgx_pdata(struct rvu *rvu);
|
||||||
int cgxlmac_to_pf(struct rvu *rvu, int cgx_id, int lmac_id);
|
int cgxlmac_to_pf(struct rvu *rvu, int cgx_id, int lmac_id);
|
||||||
int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable);
|
int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable);
|
||||||
|
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 npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf,
|
||||||
int type);
|
int type);
|
||||||
bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr,
|
bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr,
|
||||||
|
|||||||
@@ -831,6 +831,22 @@ u32 rvu_cgx_get_fifolen(struct rvu *rvu)
|
|||||||
return fifo_len;
|
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)
|
static int rvu_cgx_config_intlbk(struct rvu *rvu, u16 pcifunc, bool en)
|
||||||
{
|
{
|
||||||
int pf = rvu_get_pf(pcifunc);
|
int pf = rvu_get_pf(pcifunc);
|
||||||
|
|||||||
@@ -4036,9 +4036,13 @@ linkcfg:
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Update transmit credits for CGX links */
|
/* Update transmit credits for CGX links */
|
||||||
lmac_fifo_len =
|
lmac_fifo_len = rvu_cgx_get_lmac_fifolen(rvu, cgx, lmac);
|
||||||
rvu_cgx_get_fifolen(rvu) /
|
if (!lmac_fifo_len) {
|
||||||
cgx_get_lmac_cnt(rvu_cgx_pdata(cgx, rvu));
|
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,
|
return nix_config_link_credits(rvu, blkaddr, link, pcifunc,
|
||||||
(lmac_fifo_len - req->maxlen) / 16);
|
(lmac_fifo_len - req->maxlen) / 16);
|
||||||
}
|
}
|
||||||
@@ -4086,7 +4090,10 @@ static void nix_link_config(struct rvu *rvu, int blkaddr,
|
|||||||
struct rvu_hwinfo *hw = rvu->hw;
|
struct rvu_hwinfo *hw = rvu->hw;
|
||||||
int cgx, lmac_cnt, slink, link;
|
int cgx, lmac_cnt, slink, link;
|
||||||
u16 lbk_max_frs, lmac_max_frs;
|
u16 lbk_max_frs, lmac_max_frs;
|
||||||
|
unsigned long lmac_bmap;
|
||||||
u64 tx_credits, cfg;
|
u64 tx_credits, cfg;
|
||||||
|
u64 lmac_fifo_len;
|
||||||
|
int iter;
|
||||||
|
|
||||||
rvu_get_lbk_link_max_frs(rvu, &lbk_max_frs);
|
rvu_get_lbk_link_max_frs(rvu, &lbk_max_frs);
|
||||||
rvu_get_lmac_link_max_frs(rvu, &lmac_max_frs);
|
rvu_get_lmac_link_max_frs(rvu, &lmac_max_frs);
|
||||||
@@ -4120,12 +4127,23 @@ static void nix_link_config(struct rvu *rvu, int blkaddr,
|
|||||||
/* Skip when cgx is not available or lmac cnt is zero */
|
/* Skip when cgx is not available or lmac cnt is zero */
|
||||||
if (lmac_cnt <= 0)
|
if (lmac_cnt <= 0)
|
||||||
continue;
|
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;
|
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;
|
nix_hw->tx_credits[link] = tx_credits;
|
||||||
rvu_write64(rvu, blkaddr,
|
rvu_write64(rvu, blkaddr,
|
||||||
NIX_AF_TX_LINKX_NORM_CREDIT(link), cfg);
|
NIX_AF_TX_LINKX_NORM_CREDIT(link), cfg);
|
||||||
|
|||||||
Reference in New Issue
Block a user