Commit c0d92678 authored by Amit Cohen's avatar Amit Cohen Committed by David S. Miller

mlxsw: pci: Reorganize 'mlxsw_pci_queue' structure

The next patch will set the driver to use NAPI for event processing. Then
tasklet mechanism will be used only for EQ. Reorganize 'mlxsw_pci_queue'
to hold EQ and CQ attributes in a union. For now, add tasklet for both EQ
and CQ. This will be changed in the next patch, as 'tasklet_struct' will be
replaced with NAPI instance.
Signed-off-by: default avatarAmit Cohen <amcohen@nvidia.com>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5d01ed2e
...@@ -82,12 +82,17 @@ struct mlxsw_pci_queue { ...@@ -82,12 +82,17 @@ struct mlxsw_pci_queue {
u8 num; /* queue number */ u8 num; /* queue number */
u8 elem_size; /* size of one element */ u8 elem_size; /* size of one element */
enum mlxsw_pci_queue_type type; enum mlxsw_pci_queue_type type;
struct tasklet_struct tasklet; /* queue processing tasklet */
struct mlxsw_pci *pci; struct mlxsw_pci *pci;
struct { union {
enum mlxsw_pci_cqe_v v; struct {
struct mlxsw_pci_queue *dq; enum mlxsw_pci_cqe_v v;
} cq; struct mlxsw_pci_queue *dq;
struct tasklet_struct tasklet;
} cq;
struct {
struct tasklet_struct tasklet;
} eq;
} u;
}; };
struct mlxsw_pci_queue_type_group { struct mlxsw_pci_queue_type_group {
...@@ -163,11 +168,6 @@ static void mlxsw_pci_napi_devs_fini(struct mlxsw_pci *mlxsw_pci) ...@@ -163,11 +168,6 @@ static void mlxsw_pci_napi_devs_fini(struct mlxsw_pci *mlxsw_pci)
free_netdev(mlxsw_pci->napi_dev_tx); free_netdev(mlxsw_pci->napi_dev_tx);
} }
static void mlxsw_pci_queue_tasklet_schedule(struct mlxsw_pci_queue *q)
{
tasklet_schedule(&q->tasklet);
}
static char *__mlxsw_pci_queue_elem_get(struct mlxsw_pci_queue *q, static char *__mlxsw_pci_queue_elem_get(struct mlxsw_pci_queue *q,
size_t elem_size, int elem_index) size_t elem_size, int elem_index)
{ {
...@@ -324,7 +324,7 @@ static int mlxsw_pci_sdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -324,7 +324,7 @@ static int mlxsw_pci_sdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
return err; return err;
cq = mlxsw_pci_cq_get(mlxsw_pci, cq_num); cq = mlxsw_pci_cq_get(mlxsw_pci, cq_num);
cq->cq.dq = q; cq->u.cq.dq = q;
mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q); mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q);
return 0; return 0;
} }
...@@ -433,7 +433,7 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -433,7 +433,7 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
return err; return err;
cq = mlxsw_pci_cq_get(mlxsw_pci, cq_num); cq = mlxsw_pci_cq_get(mlxsw_pci, cq_num);
cq->cq.dq = q; cq->u.cq.dq = q;
mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q); mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q);
...@@ -455,7 +455,7 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -455,7 +455,7 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
elem_info = mlxsw_pci_queue_elem_info_get(q, i); elem_info = mlxsw_pci_queue_elem_info_get(q, i);
mlxsw_pci_rdq_skb_free(mlxsw_pci, elem_info); mlxsw_pci_rdq_skb_free(mlxsw_pci, elem_info);
} }
cq->cq.dq = NULL; cq->u.cq.dq = NULL;
mlxsw_cmd_hw2sw_rdq(mlxsw_pci->core, q->num); mlxsw_cmd_hw2sw_rdq(mlxsw_pci->core, q->num);
return err; return err;
...@@ -477,12 +477,12 @@ static void mlxsw_pci_rdq_fini(struct mlxsw_pci *mlxsw_pci, ...@@ -477,12 +477,12 @@ static void mlxsw_pci_rdq_fini(struct mlxsw_pci *mlxsw_pci,
static void mlxsw_pci_cq_pre_init(struct mlxsw_pci *mlxsw_pci, static void mlxsw_pci_cq_pre_init(struct mlxsw_pci *mlxsw_pci,
struct mlxsw_pci_queue *q) struct mlxsw_pci_queue *q)
{ {
q->cq.v = mlxsw_pci->max_cqe_ver; q->u.cq.v = mlxsw_pci->max_cqe_ver;
if (q->cq.v == MLXSW_PCI_CQE_V2 && if (q->u.cq.v == MLXSW_PCI_CQE_V2 &&
q->num < mlxsw_pci->num_sdqs && q->num < mlxsw_pci->num_sdqs &&
!mlxsw_core_sdq_supports_cqe_v2(mlxsw_pci->core)) !mlxsw_core_sdq_supports_cqe_v2(mlxsw_pci->core))
q->cq.v = MLXSW_PCI_CQE_V1; q->u.cq.v = MLXSW_PCI_CQE_V1;
} }
static unsigned int mlxsw_pci_read32_off(struct mlxsw_pci *mlxsw_pci, static unsigned int mlxsw_pci_read32_off(struct mlxsw_pci *mlxsw_pci,
...@@ -676,7 +676,7 @@ static char *mlxsw_pci_cq_sw_cqe_get(struct mlxsw_pci_queue *q) ...@@ -676,7 +676,7 @@ static char *mlxsw_pci_cq_sw_cqe_get(struct mlxsw_pci_queue *q)
elem_info = mlxsw_pci_queue_elem_info_consumer_get(q); elem_info = mlxsw_pci_queue_elem_info_consumer_get(q);
elem = elem_info->elem; elem = elem_info->elem;
owner_bit = mlxsw_pci_cqe_owner_get(q->cq.v, elem); owner_bit = mlxsw_pci_cqe_owner_get(q->u.cq.v, elem);
if (mlxsw_pci_elem_hw_owned(q, owner_bit)) if (mlxsw_pci_elem_hw_owned(q, owner_bit))
return NULL; return NULL;
q->consumer_counter++; q->consumer_counter++;
...@@ -688,16 +688,16 @@ static char *mlxsw_pci_cq_sw_cqe_get(struct mlxsw_pci_queue *q) ...@@ -688,16 +688,16 @@ static char *mlxsw_pci_cq_sw_cqe_get(struct mlxsw_pci_queue *q)
static void mlxsw_pci_cq_rx_tasklet(struct tasklet_struct *t) static void mlxsw_pci_cq_rx_tasklet(struct tasklet_struct *t)
{ {
struct mlxsw_pci_queue *q = from_tasklet(q, t, tasklet); struct mlxsw_pci_queue *q = from_tasklet(q, t, u.cq.tasklet);
struct mlxsw_pci_queue *rdq = q->cq.dq; struct mlxsw_pci_queue *rdq = q->u.cq.dq;
struct mlxsw_pci *mlxsw_pci = q->pci; struct mlxsw_pci *mlxsw_pci = q->pci;
int items = 0; int items = 0;
char *cqe; char *cqe;
while ((cqe = mlxsw_pci_cq_sw_cqe_get(q))) { while ((cqe = mlxsw_pci_cq_sw_cqe_get(q))) {
u16 wqe_counter = mlxsw_pci_cqe_wqe_counter_get(cqe); u16 wqe_counter = mlxsw_pci_cqe_wqe_counter_get(cqe);
u8 sendq = mlxsw_pci_cqe_sr_get(q->cq.v, cqe); u8 sendq = mlxsw_pci_cqe_sr_get(q->u.cq.v, cqe);
u8 dqn = mlxsw_pci_cqe_dqn_get(q->cq.v, cqe); u8 dqn = mlxsw_pci_cqe_dqn_get(q->u.cq.v, cqe);
if (unlikely(sendq)) { if (unlikely(sendq)) {
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
...@@ -710,7 +710,7 @@ static void mlxsw_pci_cq_rx_tasklet(struct tasklet_struct *t) ...@@ -710,7 +710,7 @@ static void mlxsw_pci_cq_rx_tasklet(struct tasklet_struct *t)
} }
mlxsw_pci_cqe_rdq_handle(mlxsw_pci, rdq, mlxsw_pci_cqe_rdq_handle(mlxsw_pci, rdq,
wqe_counter, q->cq.v, cqe); wqe_counter, q->u.cq.v, cqe);
if (++items == MLXSW_PCI_CQ_MAX_HANDLE) if (++items == MLXSW_PCI_CQ_MAX_HANDLE)
break; break;
...@@ -723,8 +723,8 @@ static void mlxsw_pci_cq_rx_tasklet(struct tasklet_struct *t) ...@@ -723,8 +723,8 @@ static void mlxsw_pci_cq_rx_tasklet(struct tasklet_struct *t)
static void mlxsw_pci_cq_tx_tasklet(struct tasklet_struct *t) static void mlxsw_pci_cq_tx_tasklet(struct tasklet_struct *t)
{ {
struct mlxsw_pci_queue *q = from_tasklet(q, t, tasklet); struct mlxsw_pci_queue *q = from_tasklet(q, t, u.cq.tasklet);
struct mlxsw_pci_queue *sdq = q->cq.dq; struct mlxsw_pci_queue *sdq = q->u.cq.dq;
struct mlxsw_pci *mlxsw_pci = q->pci; struct mlxsw_pci *mlxsw_pci = q->pci;
int credits = q->count >> 1; int credits = q->count >> 1;
int items = 0; int items = 0;
...@@ -732,8 +732,8 @@ static void mlxsw_pci_cq_tx_tasklet(struct tasklet_struct *t) ...@@ -732,8 +732,8 @@ static void mlxsw_pci_cq_tx_tasklet(struct tasklet_struct *t)
while ((cqe = mlxsw_pci_cq_sw_cqe_get(q))) { while ((cqe = mlxsw_pci_cq_sw_cqe_get(q))) {
u16 wqe_counter = mlxsw_pci_cqe_wqe_counter_get(cqe); u16 wqe_counter = mlxsw_pci_cqe_wqe_counter_get(cqe);
u8 sendq = mlxsw_pci_cqe_sr_get(q->cq.v, cqe); u8 sendq = mlxsw_pci_cqe_sr_get(q->u.cq.v, cqe);
u8 dqn = mlxsw_pci_cqe_dqn_get(q->cq.v, cqe); u8 dqn = mlxsw_pci_cqe_dqn_get(q->u.cq.v, cqe);
char ncqe[MLXSW_PCI_CQE_SIZE_MAX]; char ncqe[MLXSW_PCI_CQE_SIZE_MAX];
if (unlikely(!sendq)) { if (unlikely(!sendq)) {
...@@ -750,7 +750,7 @@ static void mlxsw_pci_cq_tx_tasklet(struct tasklet_struct *t) ...@@ -750,7 +750,7 @@ static void mlxsw_pci_cq_tx_tasklet(struct tasklet_struct *t)
mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q); mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q);
mlxsw_pci_cqe_sdq_handle(mlxsw_pci, sdq, mlxsw_pci_cqe_sdq_handle(mlxsw_pci, sdq,
wqe_counter, q->cq.v, ncqe); wqe_counter, q->u.cq.v, ncqe);
if (++items == credits) if (++items == credits)
break; break;
...@@ -777,10 +777,10 @@ static void mlxsw_pci_cq_tasklet_setup(struct mlxsw_pci_queue *q, ...@@ -777,10 +777,10 @@ static void mlxsw_pci_cq_tasklet_setup(struct mlxsw_pci_queue *q,
{ {
switch (cq_type) { switch (cq_type) {
case MLXSW_PCI_CQ_SDQ: case MLXSW_PCI_CQ_SDQ:
tasklet_setup(&q->tasklet, mlxsw_pci_cq_tx_tasklet); tasklet_setup(&q->u.cq.tasklet, mlxsw_pci_cq_tx_tasklet);
break; break;
case MLXSW_PCI_CQ_RDQ: case MLXSW_PCI_CQ_RDQ:
tasklet_setup(&q->tasklet, mlxsw_pci_cq_rx_tasklet); tasklet_setup(&q->u.cq.tasklet, mlxsw_pci_cq_rx_tasklet);
break; break;
} }
} }
...@@ -796,13 +796,13 @@ static int mlxsw_pci_cq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -796,13 +796,13 @@ static int mlxsw_pci_cq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
for (i = 0; i < q->count; i++) { for (i = 0; i < q->count; i++) {
char *elem = mlxsw_pci_queue_elem_get(q, i); char *elem = mlxsw_pci_queue_elem_get(q, i);
mlxsw_pci_cqe_owner_set(q->cq.v, elem, 1); mlxsw_pci_cqe_owner_set(q->u.cq.v, elem, 1);
} }
if (q->cq.v == MLXSW_PCI_CQE_V1) if (q->u.cq.v == MLXSW_PCI_CQE_V1)
mlxsw_cmd_mbox_sw2hw_cq_cqe_ver_set(mbox, mlxsw_cmd_mbox_sw2hw_cq_cqe_ver_set(mbox,
MLXSW_CMD_MBOX_SW2HW_CQ_CQE_VER_1); MLXSW_CMD_MBOX_SW2HW_CQ_CQE_VER_1);
else if (q->cq.v == MLXSW_PCI_CQE_V2) else if (q->u.cq.v == MLXSW_PCI_CQE_V2)
mlxsw_cmd_mbox_sw2hw_cq_cqe_ver_set(mbox, mlxsw_cmd_mbox_sw2hw_cq_cqe_ver_set(mbox,
MLXSW_CMD_MBOX_SW2HW_CQ_CQE_VER_2); MLXSW_CMD_MBOX_SW2HW_CQ_CQE_VER_2);
...@@ -831,13 +831,13 @@ static void mlxsw_pci_cq_fini(struct mlxsw_pci *mlxsw_pci, ...@@ -831,13 +831,13 @@ static void mlxsw_pci_cq_fini(struct mlxsw_pci *mlxsw_pci,
static u16 mlxsw_pci_cq_elem_count(const struct mlxsw_pci_queue *q) static u16 mlxsw_pci_cq_elem_count(const struct mlxsw_pci_queue *q)
{ {
return q->cq.v == MLXSW_PCI_CQE_V2 ? MLXSW_PCI_CQE2_COUNT : return q->u.cq.v == MLXSW_PCI_CQE_V2 ? MLXSW_PCI_CQE2_COUNT :
MLXSW_PCI_CQE01_COUNT; MLXSW_PCI_CQE01_COUNT;
} }
static u8 mlxsw_pci_cq_elem_size(const struct mlxsw_pci_queue *q) static u8 mlxsw_pci_cq_elem_size(const struct mlxsw_pci_queue *q)
{ {
return q->cq.v == MLXSW_PCI_CQE_V2 ? MLXSW_PCI_CQE2_SIZE : return q->u.cq.v == MLXSW_PCI_CQE_V2 ? MLXSW_PCI_CQE2_SIZE :
MLXSW_PCI_CQE01_SIZE; MLXSW_PCI_CQE01_SIZE;
} }
...@@ -860,7 +860,7 @@ static char *mlxsw_pci_eq_sw_eqe_get(struct mlxsw_pci_queue *q) ...@@ -860,7 +860,7 @@ static char *mlxsw_pci_eq_sw_eqe_get(struct mlxsw_pci_queue *q)
static void mlxsw_pci_eq_tasklet(struct tasklet_struct *t) static void mlxsw_pci_eq_tasklet(struct tasklet_struct *t)
{ {
unsigned long active_cqns[BITS_TO_LONGS(MLXSW_PCI_CQS_MAX)]; unsigned long active_cqns[BITS_TO_LONGS(MLXSW_PCI_CQS_MAX)];
struct mlxsw_pci_queue *q = from_tasklet(q, t, tasklet); struct mlxsw_pci_queue *q = from_tasklet(q, t, u.eq.tasklet);
struct mlxsw_pci *mlxsw_pci = q->pci; struct mlxsw_pci *mlxsw_pci = q->pci;
int credits = q->count >> 1; int credits = q->count >> 1;
u8 cqn, cq_count; u8 cqn, cq_count;
...@@ -886,7 +886,7 @@ static void mlxsw_pci_eq_tasklet(struct tasklet_struct *t) ...@@ -886,7 +886,7 @@ static void mlxsw_pci_eq_tasklet(struct tasklet_struct *t)
cq_count = mlxsw_pci->num_cqs; cq_count = mlxsw_pci->num_cqs;
for_each_set_bit(cqn, active_cqns, cq_count) { for_each_set_bit(cqn, active_cqns, cq_count) {
q = mlxsw_pci_cq_get(mlxsw_pci, cqn); q = mlxsw_pci_cq_get(mlxsw_pci, cqn);
mlxsw_pci_queue_tasklet_schedule(q); tasklet_schedule(&q->u.cq.tasklet);
} }
} }
...@@ -922,7 +922,7 @@ static int mlxsw_pci_eq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -922,7 +922,7 @@ static int mlxsw_pci_eq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
err = mlxsw_cmd_sw2hw_eq(mlxsw_pci->core, mbox, q->num); err = mlxsw_cmd_sw2hw_eq(mlxsw_pci->core, mbox, q->num);
if (err) if (err)
return err; return err;
tasklet_setup(&q->tasklet, mlxsw_pci_eq_tasklet); tasklet_setup(&q->u.eq.tasklet, mlxsw_pci_eq_tasklet);
mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q); mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q);
mlxsw_pci_queue_doorbell_arm_consumer_ring(mlxsw_pci, q); mlxsw_pci_queue_doorbell_arm_consumer_ring(mlxsw_pci, q);
return 0; return 0;
...@@ -1483,7 +1483,7 @@ static irqreturn_t mlxsw_pci_eq_irq_handler(int irq, void *dev_id) ...@@ -1483,7 +1483,7 @@ static irqreturn_t mlxsw_pci_eq_irq_handler(int irq, void *dev_id)
struct mlxsw_pci_queue *q; struct mlxsw_pci_queue *q;
q = mlxsw_pci_eq_get(mlxsw_pci); q = mlxsw_pci_eq_get(mlxsw_pci);
mlxsw_pci_queue_tasklet_schedule(q); tasklet_schedule(&q->u.eq.tasklet);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment