Skip to content

Commit 27ba743

Browse files
author
Nelson Escobar
committed
enic: enable rq extended cq support
JIRA: https://issues.redhat.com/browse/RHEL-84863 commit bcb725c Author: Satish Kharat <satishkh@cisco.com> Date: Tue Mar 4 19:56:40 2025 -0500 enic: enable rq extended cq support Enables getting from hw all the supported rq cq sizes and uses the highest supported cq size. 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-4-85804263dad8@cisco.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Nelson Escobar <nescobar@redhat.com>
1 parent f758cf0 commit 27ba743

File tree

5 files changed

+150
-29
lines changed

5 files changed

+150
-29
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ struct cq_desc {
4040
#define CQ_DESC_COMP_NDX_BITS 12
4141
#define CQ_DESC_COMP_NDX_MASK ((1 << CQ_DESC_COMP_NDX_BITS) - 1)
4242

43+
#define CQ_DESC_32_FI_MASK (BIT(0) | BIT(1))
44+
#define CQ_DESC_64_FI_MASK (BIT(0) | BIT(1))
45+
4346
static inline void cq_desc_dec(const struct cq_desc *desc_arg,
4447
u8 *type, u8 *color, u16 *q_number, u16 *completed_index)
4548
{

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@
3131

3232
#define ENIC_AIC_LARGE_PKT_DIFF 3
3333

34+
enum ext_cq {
35+
ENIC_RQ_CQ_ENTRY_SIZE_16,
36+
ENIC_RQ_CQ_ENTRY_SIZE_32,
37+
ENIC_RQ_CQ_ENTRY_SIZE_64,
38+
ENIC_RQ_CQ_ENTRY_SIZE_MAX,
39+
};
40+
3441
struct enic_msix_entry {
3542
int requested;
3643
char devname[IFNAMSIZ + 8];
@@ -228,6 +235,7 @@ struct enic {
228235
struct enic_rfs_flw_tbl rfs_h;
229236
u8 rss_key[ENIC_RSS_LEN];
230237
struct vnic_gen_stats gen_stats;
238+
enum ext_cq ext_cq;
231239
};
232240

233241
static inline struct net_device *vnic_get_netdev(struct vnic_dev *vdev)
@@ -349,5 +357,6 @@ int enic_is_valid_vf(struct enic *enic, int vf);
349357
int enic_is_dynamic(struct enic *enic);
350358
void enic_set_ethtool_ops(struct net_device *netdev);
351359
int __enic_set_rsskey(struct enic *enic);
360+
void enic_ext_cq(struct enic *enic);
352361

353362
#endif /* _ENIC_H_ */

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2192,6 +2192,7 @@ static void enic_reset(struct work_struct *work)
21922192
enic_init_vnic_resources(enic);
21932193
enic_set_rss_nic_cfg(enic);
21942194
enic_dev_set_ig_vlan_rewrite_mode(enic);
2195+
enic_ext_cq(enic);
21952196
enic_open(enic->netdev);
21962197

21972198
/* Allow infiniband to fiddle with the device again */
@@ -2218,6 +2219,7 @@ static void enic_tx_hang_reset(struct work_struct *work)
22182219
enic_init_vnic_resources(enic);
22192220
enic_set_rss_nic_cfg(enic);
22202221
enic_dev_set_ig_vlan_rewrite_mode(enic);
2222+
enic_ext_cq(enic);
22212223
enic_open(enic->netdev);
22222224

22232225
/* Allow infiniband to fiddle with the device again */
@@ -2592,6 +2594,8 @@ static int enic_dev_init(struct enic *enic)
25922594

25932595
enic_get_res_counts(enic);
25942596

2597+
enic_ext_cq(enic);
2598+
25952599
err = enic_alloc_enic_resources(enic);
25962600
if (err) {
25972601
dev_err(dev, "Failed to allocate enic resources\n");

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

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ void enic_init_vnic_resources(struct enic *enic)
312312
int enic_alloc_vnic_resources(struct enic *enic)
313313
{
314314
enum vnic_dev_intr_mode intr_mode;
315+
int rq_cq_desc_size;
315316
unsigned int i;
316317
int err;
317318

@@ -326,6 +327,24 @@ int enic_alloc_vnic_resources(struct enic *enic)
326327
intr_mode == VNIC_DEV_INTR_MODE_MSIX ? "MSI-X" :
327328
"unknown");
328329

330+
switch (enic->ext_cq) {
331+
case ENIC_RQ_CQ_ENTRY_SIZE_16:
332+
rq_cq_desc_size = 16;
333+
break;
334+
case ENIC_RQ_CQ_ENTRY_SIZE_32:
335+
rq_cq_desc_size = 32;
336+
break;
337+
case ENIC_RQ_CQ_ENTRY_SIZE_64:
338+
rq_cq_desc_size = 64;
339+
break;
340+
default:
341+
dev_err(enic_get_dev(enic),
342+
"Unable to determine rq cq desc size: %d",
343+
enic->ext_cq);
344+
err = -ENODEV;
345+
goto err_out;
346+
}
347+
329348
/* Allocate queue resources
330349
*/
331350

@@ -348,8 +367,8 @@ int enic_alloc_vnic_resources(struct enic *enic)
348367
for (i = 0; i < enic->cq_count; i++) {
349368
if (i < enic->rq_count)
350369
err = vnic_cq_alloc(enic->vdev, &enic->cq[i], i,
351-
enic->config.rq_desc_count,
352-
sizeof(struct cq_enet_rq_desc));
370+
enic->config.rq_desc_count,
371+
rq_cq_desc_size);
353372
else
354373
err = vnic_cq_alloc(enic->vdev, &enic->cq[i], i,
355374
enic->config.wq_desc_count,
@@ -380,6 +399,39 @@ int enic_alloc_vnic_resources(struct enic *enic)
380399

381400
err_out_cleanup:
382401
enic_free_vnic_resources(enic);
383-
402+
err_out:
384403
return err;
385404
}
405+
406+
/*
407+
* CMD_CQ_ENTRY_SIZE_SET can fail on older hw generations that don't support
408+
* that command
409+
*/
410+
void enic_ext_cq(struct enic *enic)
411+
{
412+
u64 a0 = CMD_CQ_ENTRY_SIZE_SET, a1 = 0;
413+
int wait = 1000;
414+
int ret;
415+
416+
spin_lock_bh(&enic->devcmd_lock);
417+
ret = vnic_dev_cmd(enic->vdev, CMD_CAPABILITY, &a0, &a1, wait);
418+
if (ret || a0) {
419+
dev_info(&enic->pdev->dev,
420+
"CMD_CQ_ENTRY_SIZE_SET not supported.");
421+
enic->ext_cq = ENIC_RQ_CQ_ENTRY_SIZE_16;
422+
goto out;
423+
}
424+
a1 &= VNIC_RQ_CQ_ENTRY_SIZE_ALL_BIT;
425+
enic->ext_cq = fls(a1) - 1;
426+
a0 = VNIC_RQ_ALL;
427+
a1 = enic->ext_cq;
428+
ret = vnic_dev_cmd(enic->vdev, CMD_CQ_ENTRY_SIZE_SET, &a0, &a1, wait);
429+
if (ret) {
430+
dev_info(&enic->pdev->dev, "CMD_CQ_ENTRY_SIZE_SET failed.");
431+
enic->ext_cq = ENIC_RQ_CQ_ENTRY_SIZE_16;
432+
}
433+
out:
434+
spin_unlock_bh(&enic->devcmd_lock);
435+
dev_info(&enic->pdev->dev, "CQ entry size set to %d bytes",
436+
16 << enic->ext_cq);
437+
}

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

Lines changed: 79 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,76 @@ static void enic_intr_update_pkt_size(struct vnic_rx_bytes_counter *pkt_size,
2121
pkt_size->small_pkt_bytes_cnt += pkt_len;
2222
}
2323

24-
static void enic_rq_cq_desc_dec(struct cq_enet_rq_desc *desc, u8 *type,
24+
static void enic_rq_cq_desc_dec(void *cq_desc, u8 cq_desc_size, u8 *type,
2525
u8 *color, u16 *q_number, u16 *completed_index)
2626
{
2727
/* type_color is the last field for all cq structs */
28-
u8 type_color = desc->type_color;
28+
u8 type_color;
29+
30+
switch (cq_desc_size) {
31+
case VNIC_RQ_CQ_ENTRY_SIZE_16: {
32+
struct cq_enet_rq_desc *desc =
33+
(struct cq_enet_rq_desc *)cq_desc;
34+
type_color = desc->type_color;
35+
36+
/* Make sure color bit is read from desc *before* other fields
37+
* are read from desc. Hardware guarantees color bit is last
38+
* bit (byte) written. Adding the rmb() prevents the compiler
39+
* and/or CPU from reordering the reads which would potentially
40+
* result in reading stale values.
41+
*/
42+
rmb();
2943

30-
/* Make sure color bit is read from desc *before* other fields
31-
* are read from desc. Hardware guarantees color bit is last
32-
* bit (byte) written. Adding the rmb() prevents the compiler
33-
* and/or CPU from reordering the reads which would potentially
34-
* result in reading stale values.
35-
*/
36-
rmb();
44+
*q_number = le16_to_cpu(desc->q_number_rss_type_flags) &
45+
CQ_DESC_Q_NUM_MASK;
46+
*completed_index = le16_to_cpu(desc->completed_index_flags) &
47+
CQ_DESC_COMP_NDX_MASK;
48+
break;
49+
}
50+
case VNIC_RQ_CQ_ENTRY_SIZE_32: {
51+
struct cq_enet_rq_desc_32 *desc =
52+
(struct cq_enet_rq_desc_32 *)cq_desc;
53+
type_color = desc->type_color;
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+
rmb();
62+
63+
*q_number = le16_to_cpu(desc->q_number_rss_type_flags) &
64+
CQ_DESC_Q_NUM_MASK;
65+
*completed_index = le16_to_cpu(desc->completed_index_flags) &
66+
CQ_DESC_COMP_NDX_MASK;
67+
*completed_index |= (desc->fetch_index_flags & CQ_DESC_32_FI_MASK) <<
68+
CQ_DESC_COMP_NDX_BITS;
69+
break;
70+
}
71+
case VNIC_RQ_CQ_ENTRY_SIZE_64: {
72+
struct cq_enet_rq_desc_64 *desc =
73+
(struct cq_enet_rq_desc_64 *)cq_desc;
74+
type_color = desc->type_color;
75+
76+
/* Make sure color bit is read from desc *before* other fields
77+
* are read from desc. Hardware guarantees color bit is last
78+
* bit (byte) written. Adding the rmb() prevents the compiler
79+
* and/or CPU from reordering the reads which would potentially
80+
* result in reading stale values.
81+
*/
82+
rmb();
83+
84+
*q_number = le16_to_cpu(desc->q_number_rss_type_flags) &
85+
CQ_DESC_Q_NUM_MASK;
86+
*completed_index = le16_to_cpu(desc->completed_index_flags) &
87+
CQ_DESC_COMP_NDX_MASK;
88+
*completed_index |= (desc->fetch_index_flags & CQ_DESC_64_FI_MASK) <<
89+
CQ_DESC_COMP_NDX_BITS;
90+
break;
91+
}
92+
}
3793

38-
*q_number = le16_to_cpu(desc->q_number_rss_type_flags) &
39-
CQ_DESC_Q_NUM_MASK;
40-
*completed_index = le16_to_cpu(desc->completed_index_flags) &
41-
CQ_DESC_COMP_NDX_MASK;
4294
*color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK;
4395
*type = type_color & CQ_DESC_TYPE_MASK;
4496
}
@@ -113,6 +165,10 @@ static void enic_rq_set_skb_flags(struct vnic_rq *vrq, u8 type, u32 rss_hash,
113165
}
114166
}
115167

168+
/*
169+
* cq_enet_rq_desc accesses section uses only the 1st 15 bytes of the cq which
170+
* is identical for all type (16,32 and 64 byte) of cqs.
171+
*/
116172
static void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc, u8 *ingress_port,
117173
u8 *fcoe, u8 *eop, u8 *sop, u8 *rss_type,
118174
u8 *csum_not_calc, u32 *rss_hash,
@@ -258,9 +314,8 @@ void enic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf)
258314
}
259315

260316
static void enic_rq_indicate_buf(struct enic *enic, struct vnic_rq *rq,
261-
struct vnic_rq_buf *buf,
262-
struct cq_enet_rq_desc *cq_desc, u8 type,
263-
u16 q_number, u16 completed_index)
317+
struct vnic_rq_buf *buf, void *cq_desc,
318+
u8 type, u16 q_number, u16 completed_index)
264319
{
265320
struct sk_buff *skb;
266321
struct vnic_cq *cq = &enic->cq[enic_cq_rq(enic, rq->index)];
@@ -277,7 +332,7 @@ static void enic_rq_indicate_buf(struct enic *enic, struct vnic_rq *rq,
277332

278333
rqstats->packets++;
279334

280-
cq_enet_rq_desc_dec(cq_desc, &ingress_port,
335+
cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc, &ingress_port,
281336
&fcoe, &eop, &sop, &rss_type, &csum_not_calc,
282337
&rss_hash, &bytes_written, &packet_error,
283338
&vlan_stripped, &vlan_tci, &checksum, &fcoe_sof,
@@ -329,8 +384,8 @@ static void enic_rq_indicate_buf(struct enic *enic, struct vnic_rq *rq,
329384
}
330385
}
331386

332-
static void enic_rq_service(struct enic *enic, struct cq_enet_rq_desc *cq_desc,
333-
u8 type, u16 q_number, u16 completed_index)
387+
static void enic_rq_service(struct enic *enic, void *cq_desc, u8 type,
388+
u16 q_number, u16 completed_index)
334389
{
335390
struct enic_rq_stats *rqstats = &enic->rq[q_number].stats;
336391
struct vnic_rq *vrq = &enic->rq[q_number].vrq;
@@ -357,14 +412,12 @@ unsigned int enic_rq_cq_service(struct enic *enic, unsigned int cq_index,
357412
unsigned int work_to_do)
358413
{
359414
struct vnic_cq *cq = &enic->cq[cq_index];
360-
struct cq_enet_rq_desc *cq_desc;
415+
void *cq_desc = vnic_cq_to_clean(cq);
361416
u16 q_number, completed_index;
362417
unsigned int work_done = 0;
363418
u8 type, color;
364419

365-
cq_desc = (struct cq_enet_rq_desc *)vnic_cq_to_clean(cq);
366-
367-
enic_rq_cq_desc_dec(cq_desc, &type, &color, &q_number,
420+
enic_rq_cq_desc_dec(cq_desc, enic->ext_cq, &type, &color, &q_number,
368421
&completed_index);
369422

370423
while (color != cq->last_color) {
@@ -374,9 +427,9 @@ unsigned int enic_rq_cq_service(struct enic *enic, unsigned int cq_index,
374427
if (++work_done >= work_to_do)
375428
break;
376429

377-
cq_desc = (struct cq_enet_rq_desc *)vnic_cq_to_clean(cq);
378-
enic_rq_cq_desc_dec(cq_desc, &type, &color, &q_number,
379-
&completed_index);
430+
cq_desc = vnic_cq_to_clean(cq);
431+
enic_rq_cq_desc_dec(cq_desc, enic->ext_cq, &type, &color,
432+
&q_number, &completed_index);
380433
}
381434

382435
return work_done;

0 commit comments

Comments
 (0)