| From d0a546e89e828662c31863ea0553e6628318f086 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 18 Jan 2024 19:59:14 -0800 |
| Subject: net: mvpp2: clear BM pool before initialization |
| |
| From: Jenishkumar Maheshbhai Patel <jpatel2@marvell.com> |
| |
| [ Upstream commit 9f538b415db862e74b8c5d3abbccfc1b2b6caa38 ] |
| |
| Register value persist after booting the kernel using |
| kexec which results in kernel panic. Thus clear the |
| BM pool registers before initialisation to fix the issue. |
| |
| Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") |
| Signed-off-by: Jenishkumar Maheshbhai Patel <jpatel2@marvell.com> |
| Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com> |
| Link: https://lore.kernel.org/r/20240119035914.2595665-1-jpatel2@marvell.com |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 27 ++++++++++++++++++- |
| 1 file changed, 26 insertions(+), 1 deletion(-) |
| |
| diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c |
| index f936640cca4e..2f80ee84c7ec 100644 |
| --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c |
| +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c |
| @@ -614,12 +614,38 @@ static void mvpp23_bm_set_8pool_mode(struct mvpp2 *priv) |
| mvpp2_write(priv, MVPP22_BM_POOL_BASE_ADDR_HIGH_REG, val); |
| } |
| |
| +/* Cleanup pool before actual initialization in the OS */ |
| +static void mvpp2_bm_pool_cleanup(struct mvpp2 *priv, int pool_id) |
| +{ |
| + unsigned int thread = mvpp2_cpu_to_thread(priv, get_cpu()); |
| + u32 val; |
| + int i; |
| + |
| + /* Drain the BM from all possible residues left by firmware */ |
| + for (i = 0; i < MVPP2_BM_POOL_SIZE_MAX; i++) |
| + mvpp2_thread_read(priv, thread, MVPP2_BM_PHY_ALLOC_REG(pool_id)); |
| + |
| + put_cpu(); |
| + |
| + /* Stop the BM pool */ |
| + val = mvpp2_read(priv, MVPP2_BM_POOL_CTRL_REG(pool_id)); |
| + val |= MVPP2_BM_STOP_MASK; |
| + mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(pool_id), val); |
| +} |
| + |
| static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv) |
| { |
| enum dma_data_direction dma_dir = DMA_FROM_DEVICE; |
| int i, err, poolnum = MVPP2_BM_POOLS_NUM; |
| struct mvpp2_port *port; |
| |
| + if (priv->percpu_pools) |
| + poolnum = mvpp2_get_nrxqs(priv) * 2; |
| + |
| + /* Clean up the pool state in case it contains stale state */ |
| + for (i = 0; i < poolnum; i++) |
| + mvpp2_bm_pool_cleanup(priv, i); |
| + |
| if (priv->percpu_pools) { |
| for (i = 0; i < priv->port_count; i++) { |
| port = priv->port_list[i]; |
| @@ -629,7 +655,6 @@ static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv) |
| } |
| } |
| |
| - poolnum = mvpp2_get_nrxqs(priv) * 2; |
| for (i = 0; i < poolnum; i++) { |
| /* the pool in use */ |
| int pn = i / (poolnum / 2); |
| -- |
| 2.43.0 |
| |