Skip to content

Commit d441d3c

Browse files
author
Nelson Escobar
committed
enic: added enic_wq.c and enic_wq.h
JIRA: https://issues.redhat.com/browse/RHEL-84863 commit e5f1bcd Author: Satish Kharat <satishkh@cisco.com> Date: Tue Mar 4 19:56:42 2025 -0500 enic: added enic_wq.c and enic_wq.h Moves wq related function to enic_wq.c. Prepares for a cleaup of enic wq code path. Co-developed-by: Nelson Escobar <neescoba@cisco.com> Signed-off-by: Nelson Escobar <neescoba@cisco.com> Co-developed-by: John Daley <johndale@cisco.com> Signed-off-by: John Daley <johndale@cisco.com> Signed-off-by: Satish Kharat <satishkh@cisco.com> Link: https://patch.msgid.link/20250304-enic_cleanup_and_ext_cq-v2-6-85804263dad8@cisco.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Nelson Escobar <nescobar@redhat.com>
1 parent c5e970e commit d441d3c

File tree

7 files changed

+138
-117
lines changed

7 files changed

+138
-117
lines changed

drivers/net/ethernet/cisco/enic/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ obj-$(CONFIG_ENIC) := enic.o
33

44
enic-y := enic_main.o vnic_cq.o vnic_intr.o vnic_wq.o \
55
enic_res.o enic_dev.o enic_pp.o vnic_dev.o vnic_rq.o vnic_vic.o \
6-
enic_ethtool.o enic_api.o enic_clsf.o enic_rq.o
6+
enic_ethtool.o enic_api.o enic_clsf.o enic_rq.o enic_wq.o
77

drivers/net/ethernet/cisco/enic/cq_desc.h

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,28 +43,4 @@ struct cq_desc {
4343
#define CQ_DESC_32_FI_MASK (BIT(0) | BIT(1))
4444
#define CQ_DESC_64_FI_MASK (BIT(0) | BIT(1))
4545

46-
static inline void cq_desc_dec(const struct cq_desc *desc_arg,
47-
u8 *type, u8 *color, u16 *q_number, u16 *completed_index)
48-
{
49-
const struct cq_desc *desc = desc_arg;
50-
const u8 type_color = desc->type_color;
51-
52-
*color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK;
53-
54-
/*
55-
* Make sure color bit is read from desc *before* other fields
56-
* are read from desc. Hardware guarantees color bit is last
57-
* bit (byte) written. Adding the rmb() prevents the compiler
58-
* and/or CPU from reordering the reads which would potentially
59-
* result in reading stale values.
60-
*/
61-
62-
rmb();
63-
64-
*type = type_color & CQ_DESC_TYPE_MASK;
65-
*q_number = le16_to_cpu(desc->q_number) & CQ_DESC_Q_NUM_MASK;
66-
*completed_index = le16_to_cpu(desc->completed_index) &
67-
CQ_DESC_COMP_NDX_MASK;
68-
}
69-
7046
#endif /* _CQ_DESC_H_ */

drivers/net/ethernet/cisco/enic/enic.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ struct enic_rx_coal {
8383
#define ENIC_SET_INSTANCE (1 << 3)
8484
#define ENIC_SET_HOST (1 << 4)
8585

86+
#define MAX_TSO BIT(16)
87+
#define WQ_ENET_MAX_DESC_LEN BIT(WQ_ENET_LEN_BITS)
88+
#define ENIC_DESC_MAX_SPLITS (MAX_TSO / WQ_ENET_MAX_DESC_LEN + 1)
89+
8690
struct enic_port_profile {
8791
u32 set;
8892
u8 request;

drivers/net/ethernet/cisco/enic/enic_main.c

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,9 @@
5959
#include "enic_pp.h"
6060
#include "enic_clsf.h"
6161
#include "enic_rq.h"
62+
#include "enic_wq.h"
6263

6364
#define ENIC_NOTIFY_TIMER_PERIOD (2 * HZ)
64-
#define WQ_ENET_MAX_DESC_LEN (1 << WQ_ENET_LEN_BITS)
65-
#define MAX_TSO (1 << 16)
66-
#define ENIC_DESC_MAX_SPLITS (MAX_TSO / WQ_ENET_MAX_DESC_LEN + 1)
6765

6866
#define PCI_DEVICE_ID_CISCO_VIC_ENET 0x0043 /* ethernet vnic */
6967
#define PCI_DEVICE_ID_CISCO_VIC_ENET_DYN 0x0044 /* enet dynamic vnic */
@@ -321,54 +319,6 @@ int enic_is_valid_vf(struct enic *enic, int vf)
321319
#endif
322320
}
323321

324-
static void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf)
325-
{
326-
struct enic *enic = vnic_dev_priv(wq->vdev);
327-
328-
if (buf->sop)
329-
dma_unmap_single(&enic->pdev->dev, buf->dma_addr, buf->len,
330-
DMA_TO_DEVICE);
331-
else
332-
dma_unmap_page(&enic->pdev->dev, buf->dma_addr, buf->len,
333-
DMA_TO_DEVICE);
334-
335-
if (buf->os_buf)
336-
dev_kfree_skb_any(buf->os_buf);
337-
}
338-
339-
static void enic_wq_free_buf(struct vnic_wq *wq,
340-
struct cq_desc *cq_desc, struct vnic_wq_buf *buf, void *opaque)
341-
{
342-
struct enic *enic = vnic_dev_priv(wq->vdev);
343-
344-
enic->wq[wq->index].stats.cq_work++;
345-
enic->wq[wq->index].stats.cq_bytes += buf->len;
346-
enic_free_wq_buf(wq, buf);
347-
}
348-
349-
static int enic_wq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc,
350-
u8 type, u16 q_number, u16 completed_index, void *opaque)
351-
{
352-
struct enic *enic = vnic_dev_priv(vdev);
353-
354-
spin_lock(&enic->wq[q_number].lock);
355-
356-
vnic_wq_service(&enic->wq[q_number].vwq, cq_desc,
357-
completed_index, enic_wq_free_buf,
358-
opaque);
359-
360-
if (netif_tx_queue_stopped(netdev_get_tx_queue(enic->netdev, q_number)) &&
361-
vnic_wq_desc_avail(&enic->wq[q_number].vwq) >=
362-
(MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS)) {
363-
netif_wake_subqueue(enic->netdev, q_number);
364-
enic->wq[q_number].stats.wake++;
365-
}
366-
367-
spin_unlock(&enic->wq[q_number].lock);
368-
369-
return 0;
370-
}
371-
372322
static bool enic_log_q_error(struct enic *enic)
373323
{
374324
unsigned int i;
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
// Copyright 2025 Cisco Systems, Inc. All rights reserved.
3+
4+
#include <net/netdev_queues.h>
5+
#include "enic_res.h"
6+
#include "enic.h"
7+
#include "enic_wq.h"
8+
9+
static void cq_desc_dec(const struct cq_desc *desc_arg, u8 *type, u8 *color,
10+
u16 *q_number, u16 *completed_index)
11+
{
12+
const struct cq_desc *desc = desc_arg;
13+
const u8 type_color = desc->type_color;
14+
15+
*color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK;
16+
17+
/*
18+
* Make sure color bit is read from desc *before* other fields
19+
* are read from desc. Hardware guarantees color bit is last
20+
* bit (byte) written. Adding the rmb() prevents the compiler
21+
* and/or CPU from reordering the reads which would potentially
22+
* result in reading stale values.
23+
*/
24+
rmb();
25+
26+
*type = type_color & CQ_DESC_TYPE_MASK;
27+
*q_number = le16_to_cpu(desc->q_number) & CQ_DESC_Q_NUM_MASK;
28+
*completed_index = le16_to_cpu(desc->completed_index) &
29+
CQ_DESC_COMP_NDX_MASK;
30+
}
31+
32+
unsigned int vnic_cq_service(struct vnic_cq *cq, unsigned int work_to_do,
33+
int (*q_service)(struct vnic_dev *vdev,
34+
struct cq_desc *cq_desc, u8 type,
35+
u16 q_number, u16 completed_index,
36+
void *opaque), void *opaque)
37+
{
38+
struct cq_desc *cq_desc;
39+
unsigned int work_done = 0;
40+
u16 q_number, completed_index;
41+
u8 type, color;
42+
43+
cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs +
44+
cq->ring.desc_size * cq->to_clean);
45+
cq_desc_dec(cq_desc, &type, &color,
46+
&q_number, &completed_index);
47+
48+
while (color != cq->last_color) {
49+
if ((*q_service)(cq->vdev, cq_desc, type, q_number,
50+
completed_index, opaque))
51+
break;
52+
53+
cq->to_clean++;
54+
if (cq->to_clean == cq->ring.desc_count) {
55+
cq->to_clean = 0;
56+
cq->last_color = cq->last_color ? 0 : 1;
57+
}
58+
59+
cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs +
60+
cq->ring.desc_size * cq->to_clean);
61+
cq_desc_dec(cq_desc, &type, &color,
62+
&q_number, &completed_index);
63+
64+
work_done++;
65+
if (work_done >= work_to_do)
66+
break;
67+
}
68+
69+
return work_done;
70+
}
71+
72+
void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf)
73+
{
74+
struct enic *enic = vnic_dev_priv(wq->vdev);
75+
76+
if (buf->sop)
77+
dma_unmap_single(&enic->pdev->dev, buf->dma_addr, buf->len,
78+
DMA_TO_DEVICE);
79+
else
80+
dma_unmap_page(&enic->pdev->dev, buf->dma_addr, buf->len,
81+
DMA_TO_DEVICE);
82+
83+
if (buf->os_buf)
84+
dev_kfree_skb_any(buf->os_buf);
85+
}
86+
87+
static void enic_wq_free_buf(struct vnic_wq *wq, struct cq_desc *cq_desc,
88+
struct vnic_wq_buf *buf, void *opaque)
89+
{
90+
struct enic *enic = vnic_dev_priv(wq->vdev);
91+
92+
enic->wq[wq->index].stats.cq_work++;
93+
enic->wq[wq->index].stats.cq_bytes += buf->len;
94+
enic_free_wq_buf(wq, buf);
95+
}
96+
97+
int enic_wq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, u8 type,
98+
u16 q_number, u16 completed_index, void *opaque)
99+
{
100+
struct enic *enic = vnic_dev_priv(vdev);
101+
102+
spin_lock(&enic->wq[q_number].lock);
103+
104+
vnic_wq_service(&enic->wq[q_number].vwq, cq_desc,
105+
completed_index, enic_wq_free_buf, opaque);
106+
107+
if (netif_tx_queue_stopped(netdev_get_tx_queue(enic->netdev, q_number))
108+
&& vnic_wq_desc_avail(&enic->wq[q_number].vwq) >=
109+
(MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS)) {
110+
netif_wake_subqueue(enic->netdev, q_number);
111+
enic->wq[q_number].stats.wake++;
112+
}
113+
114+
spin_unlock(&enic->wq[q_number].lock);
115+
116+
return 0;
117+
}
118+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only
2+
* Copyright 2025 Cisco Systems, Inc. All rights reserved.
3+
*/
4+
5+
unsigned int vnic_cq_service(struct vnic_cq *cq, unsigned int work_to_do,
6+
int (*q_service)(struct vnic_dev *vdev,
7+
struct cq_desc *cq_desc, u8 type,
8+
u16 q_number, u16 completed_index,
9+
void *opaque), void *opaque);
10+
11+
void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf);
12+
13+
int enic_wq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, u8 type,
14+
u16 q_number, u16 completed_index, void *opaque);

drivers/net/ethernet/cisco/enic/vnic_cq.h

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -56,47 +56,6 @@ struct vnic_cq {
5656
ktime_t prev_ts;
5757
};
5858

59-
static inline unsigned int vnic_cq_service(struct vnic_cq *cq,
60-
unsigned int work_to_do,
61-
int (*q_service)(struct vnic_dev *vdev, struct cq_desc *cq_desc,
62-
u8 type, u16 q_number, u16 completed_index, void *opaque),
63-
void *opaque)
64-
{
65-
struct cq_desc *cq_desc;
66-
unsigned int work_done = 0;
67-
u16 q_number, completed_index;
68-
u8 type, color;
69-
70-
cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs +
71-
cq->ring.desc_size * cq->to_clean);
72-
cq_desc_dec(cq_desc, &type, &color,
73-
&q_number, &completed_index);
74-
75-
while (color != cq->last_color) {
76-
77-
if ((*q_service)(cq->vdev, cq_desc, type,
78-
q_number, completed_index, opaque))
79-
break;
80-
81-
cq->to_clean++;
82-
if (cq->to_clean == cq->ring.desc_count) {
83-
cq->to_clean = 0;
84-
cq->last_color = cq->last_color ? 0 : 1;
85-
}
86-
87-
cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs +
88-
cq->ring.desc_size * cq->to_clean);
89-
cq_desc_dec(cq_desc, &type, &color,
90-
&q_number, &completed_index);
91-
92-
work_done++;
93-
if (work_done >= work_to_do)
94-
break;
95-
}
96-
97-
return work_done;
98-
}
99-
10059
static inline void *vnic_cq_to_clean(struct vnic_cq *cq)
10160
{
10261
return ((u8 *)cq->ring.descs + cq->ring.desc_size * cq->to_clean);

0 commit comments

Comments
 (0)