[PATCH net-next] mlxsw: pci: Le fix [xxx]
From: Petr Machata
Date: Wed Jul 22 2026 - 08:49:30 EST
Signed-off-by: Petr Machata <petrm@xxxxxxxxxx>
---
drivers/net/ethernet/mellanox/mlxsw/pci.c | 63 +++++++++++++++++++++--
1 file changed, 60 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index 0da85d36647d..30111ef16443 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -1063,7 +1063,6 @@ static int mlxsw_pci_cq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
if (err)
goto err_page_pool_init;
- napi_enable(&q->u.cq.napi);
mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q);
mlxsw_pci_queue_doorbell_arm_consumer_ring(mlxsw_pci, q);
return 0;
@@ -1078,12 +1077,23 @@ static void mlxsw_pci_cq_fini(struct mlxsw_pci *mlxsw_pci,
{
enum mlxsw_pci_cq_type cq_type = mlxsw_pci_cq_type(mlxsw_pci, q);
- napi_disable(&q->u.cq.napi);
mlxsw_pci_cq_page_pool_fini(q, cq_type);
mlxsw_pci_cq_napi_teardown(q);
mlxsw_cmd_hw2sw_cq(mlxsw_pci->core, q->num);
}
+static void mlxsw_pci_cq_start(struct mlxsw_pci *mlxsw_pci,
+ struct mlxsw_pci_queue *q)
+{
+ napi_enable(&q->u.cq.napi);
+}
+
+static void mlxsw_pci_cq_stop(struct mlxsw_pci *mlxsw_pci,
+ struct mlxsw_pci_queue *q)
+{
+ napi_disable(&q->u.cq.napi);
+}
+
static u16 mlxsw_pci_cq_elem_count(const struct mlxsw_pci_queue *q)
{
return q->u.cq.v == MLXSW_PCI_CQE_V2 ? MLXSW_PCI_CQE2_COUNT :
@@ -1177,7 +1187,6 @@ static int mlxsw_pci_eq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
err = mlxsw_cmd_sw2hw_eq(mlxsw_pci->core, mbox, q->num);
if (err)
return err;
- tasklet_setup(&q->u.eq.tasklet, mlxsw_pci_eq_tasklet);
mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q);
mlxsw_pci_queue_doorbell_arm_consumer_ring(mlxsw_pci, q);
return 0;
@@ -1189,6 +1198,18 @@ static void mlxsw_pci_eq_fini(struct mlxsw_pci *mlxsw_pci,
mlxsw_cmd_hw2sw_eq(mlxsw_pci->core, q->num);
}
+static void mlxsw_pci_eq_start(struct mlxsw_pci *mlxsw_pci,
+ struct mlxsw_pci_queue *q)
+{
+ tasklet_setup(&q->u.eq.tasklet, mlxsw_pci_eq_tasklet);
+}
+
+static void mlxsw_pci_eq_stop(struct mlxsw_pci *mlxsw_pci,
+ struct mlxsw_pci_queue *q)
+{
+ tasklet_kill(&q->u.eq.tasklet);
+}
+
struct mlxsw_pci_queue_ops {
const char *name;
enum mlxsw_pci_queue_type type;
@@ -1198,6 +1219,10 @@ struct mlxsw_pci_queue_ops {
struct mlxsw_pci_queue *q);
void (*fini)(struct mlxsw_pci *mlxsw_pci,
struct mlxsw_pci_queue *q);
+ void (*start)(struct mlxsw_pci *mlxsw_pci,
+ struct mlxsw_pci_queue *q);
+ void (*stop)(struct mlxsw_pci *mlxsw_pci,
+ struct mlxsw_pci_queue *q);
u16 (*elem_count_f)(const struct mlxsw_pci_queue *q);
u8 (*elem_size_f)(const struct mlxsw_pci_queue *q);
u16 elem_count;
@@ -1225,6 +1250,8 @@ static const struct mlxsw_pci_queue_ops mlxsw_pci_cq_ops = {
.pre_init = mlxsw_pci_cq_pre_init,
.init = mlxsw_pci_cq_init,
.fini = mlxsw_pci_cq_fini,
+ .start = mlxsw_pci_cq_start,
+ .stop = mlxsw_pci_cq_stop,
.elem_count_f = mlxsw_pci_cq_elem_count,
.elem_size_f = mlxsw_pci_cq_elem_size
};
@@ -1233,6 +1260,8 @@ static const struct mlxsw_pci_queue_ops mlxsw_pci_eq_ops = {
.type = MLXSW_PCI_QUEUE_TYPE_EQ,
.init = mlxsw_pci_eq_init,
.fini = mlxsw_pci_eq_fini,
+ .start = mlxsw_pci_eq_start,
+ .stop = mlxsw_pci_eq_stop,
.elem_count = MLXSW_PCI_EQE_COUNT,
.elem_size = MLXSW_PCI_EQE_SIZE
};
@@ -1349,6 +1378,28 @@ static void mlxsw_pci_queue_group_fini(struct mlxsw_pci *mlxsw_pci,
kfree(queue_group->q);
}
+static void mlxsw_pci_queue_group_start(struct mlxsw_pci *mlxsw_pci,
+ const struct mlxsw_pci_queue_ops *q_ops)
+{
+ struct mlxsw_pci_queue_type_group *queue_group;
+ int i;
+
+ queue_group = mlxsw_pci_queue_type_group_get(mlxsw_pci, q_ops->type);
+ for (i = 0; i < queue_group->count; i++)
+ q_ops->start(mlxsw_pci, &queue_group->q[i]);
+}
+
+static void mlxsw_pci_queue_group_stop(struct mlxsw_pci *mlxsw_pci,
+ const struct mlxsw_pci_queue_ops *q_ops)
+{
+ struct mlxsw_pci_queue_type_group *queue_group;
+ int i;
+
+ queue_group = mlxsw_pci_queue_type_group_get(mlxsw_pci, q_ops->type);
+ for (i = 0; i < queue_group->count; i++)
+ q_ops->stop(mlxsw_pci, &queue_group->q[i]);
+}
+
static int mlxsw_pci_aqs_init(struct mlxsw_pci *mlxsw_pci, char *mbox)
{
struct pci_dev *pdev = mlxsw_pci->pdev;
@@ -1426,6 +1477,9 @@ static int mlxsw_pci_aqs_init(struct mlxsw_pci *mlxsw_pci, char *mbox)
goto err_rdqs_init;
}
+ mlxsw_pci_queue_group_start(mlxsw_pci, &mlxsw_pci_cq_ops);
+ mlxsw_pci_queue_group_start(mlxsw_pci, &mlxsw_pci_eq_ops);
+
return 0;
err_rdqs_init:
@@ -1439,6 +1493,9 @@ static int mlxsw_pci_aqs_init(struct mlxsw_pci *mlxsw_pci, char *mbox)
static void mlxsw_pci_aqs_fini(struct mlxsw_pci *mlxsw_pci)
{
+ mlxsw_pci_queue_group_stop(mlxsw_pci, &mlxsw_pci_eq_ops);
+ mlxsw_pci_queue_group_stop(mlxsw_pci, &mlxsw_pci_cq_ops);
+
mlxsw_pci_queue_group_fini(mlxsw_pci, &mlxsw_pci_rdq_ops);
mlxsw_pci_queue_group_fini(mlxsw_pci, &mlxsw_pci_sdq_ops);
mlxsw_pci_queue_group_fini(mlxsw_pci, &mlxsw_pci_cq_ops);
--
2.54.0