Octeontx2-af: Broadcast XON on all channels

The NIX block receives traffic from multiple channels, including:

MAC block (RPM)
Loopback module (LBK)
CPT block

                     RPM
                      |
                -----------------
       LBK   --|     NIX         |
                -----------------
                     |
                    CPT

Due to a hardware errata,  CN10k and earlier Octeon silicon series,
the hardware may incorrectly assert XOFF on certain channels during
reset. As a workaround, a write operation to the NIX_AF_RX_CHANX_CFG
register can be performed to broadcast XON signals on the affected
channels

Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
Link: https://patch.msgid.link/20250820064625.1464361-1-hkelam@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Hariprasad Kelam 2025-08-20 12:16:25 +05:30 committed by Jakub Kicinski
parent 62d7f40503
commit a7bd721580
3 changed files with 20 additions and 0 deletions

View File

@ -1164,6 +1164,9 @@ static int rvu_setup_hw_resources(struct rvu *rvu)
rvu_program_channels(rvu);
cgx_start_linkup(rvu);
rvu_block_bcast_xon(rvu, BLKADDR_NIX0);
rvu_block_bcast_xon(rvu, BLKADDR_NIX1);
err = rvu_mcs_init(rvu);
if (err) {
dev_err(rvu->dev, "%s: Failed to initialize mcs\n", __func__);

View File

@ -1017,6 +1017,7 @@ int rvu_nix_mcast_update_mcam_entry(struct rvu *rvu, u16 pcifunc,
void rvu_nix_flr_free_bpids(struct rvu *rvu, u16 pcifunc);
int rvu_alloc_cint_qint_mem(struct rvu *rvu, struct rvu_pfvf *pfvf,
int blkaddr, int nixlf);
void rvu_block_bcast_xon(struct rvu *rvu, int blkaddr);
/* NPC APIs */
void rvu_npc_freemem(struct rvu *rvu);
int rvu_npc_get_pkind(struct rvu *rvu, u16 pf);

View File

@ -6616,3 +6616,19 @@ int rvu_mbox_handler_nix_mcast_grp_update(struct rvu *rvu,
return ret;
}
/* On CN10k and older series of silicons, hardware may incorrectly
* assert XOFF on certain channels. Issue a write on NIX_AF_RX_CHANX_CFG
* to broadcacst XON on the same.
*/
void rvu_block_bcast_xon(struct rvu *rvu, int blkaddr)
{
struct rvu_block *block = &rvu->hw->block[blkaddr];
u64 cfg;
if (!block->implemented || is_cn20k(rvu->pdev))
return;
cfg = rvu_read64(rvu, blkaddr, NIX_AF_RX_CHANX_CFG(0));
rvu_write64(rvu, blkaddr, NIX_AF_RX_CHANX_CFG(0), cfg);
}