Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'enic-enable-32-64-byte-cqes-and-get-max-rx-tx-ring-size-from-hw'

Satish Kharat via says:

====================
enic: enable 32, 64 byte cqes and get max rx/tx ring size from hw

This series enables using the max rx and tx ring sizes read from hw.
For newer hw that can be up to 16k entries. This requires bigger
completion entries for rx queues. This series enables the use of the
32 and 64 byte completion queues entries for enic rx queues on
supported hw versions. This is in addition to the exiting (default)
16 byte rx cqes.

Signed-off-by: Satish Kharat <satishkh@cisco.com>
====================

Link: https://patch.msgid.link/20250304-enic_cleanup_and_ext_cq-v2-0-85804263dad8@cisco.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+545 -259
+1 -1
drivers/net/ethernet/cisco/enic/Makefile
··· 3 3 4 4 enic-y := enic_main.o vnic_cq.o vnic_intr.o vnic_wq.o \ 5 5 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 7 7
+2 -23
drivers/net/ethernet/cisco/enic/cq_desc.h
··· 40 40 #define CQ_DESC_COMP_NDX_BITS 12 41 41 #define CQ_DESC_COMP_NDX_MASK ((1 << CQ_DESC_COMP_NDX_BITS) - 1) 42 42 43 - static inline void cq_desc_dec(const struct cq_desc *desc_arg, 44 - u8 *type, u8 *color, u16 *q_number, u16 *completed_index) 45 - { 46 - const struct cq_desc *desc = desc_arg; 47 - const u8 type_color = desc->type_color; 48 - 49 - *color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK; 50 - 51 - /* 52 - * Make sure color bit is read from desc *before* other fields 53 - * are read from desc. Hardware guarantees color bit is last 54 - * bit (byte) written. Adding the rmb() prevents the compiler 55 - * and/or CPU from reordering the reads which would potentially 56 - * result in reading stale values. 57 - */ 58 - 59 - rmb(); 60 - 61 - *type = type_color & CQ_DESC_TYPE_MASK; 62 - *q_number = le16_to_cpu(desc->q_number) & CQ_DESC_Q_NUM_MASK; 63 - *completed_index = le16_to_cpu(desc->completed_index) & 64 - CQ_DESC_COMP_NDX_MASK; 65 - } 43 + #define CQ_DESC_32_FI_MASK (BIT(0) | BIT(1)) 44 + #define CQ_DESC_64_FI_MASK (BIT(0) | BIT(1)) 66 45 67 46 #endif /* _CQ_DESC_H_ */
+55 -87
drivers/net/ethernet/cisco/enic/cq_enet_desc.h
··· 17 17 u8 type_color; 18 18 }; 19 19 20 - static inline void cq_enet_wq_desc_dec(struct cq_enet_wq_desc *desc, 21 - u8 *type, u8 *color, u16 *q_number, u16 *completed_index) 22 - { 23 - cq_desc_dec((struct cq_desc *)desc, type, 24 - color, q_number, completed_index); 25 - } 20 + /* 21 + * Defines and Capabilities for CMD_CQ_ENTRY_SIZE_SET 22 + */ 23 + #define VNIC_RQ_ALL (~0ULL) 24 + 25 + #define VNIC_RQ_CQ_ENTRY_SIZE_16 0 26 + #define VNIC_RQ_CQ_ENTRY_SIZE_32 1 27 + #define VNIC_RQ_CQ_ENTRY_SIZE_64 2 28 + 29 + #define VNIC_RQ_CQ_ENTRY_SIZE_16_CAPABLE BIT(VNIC_RQ_CQ_ENTRY_SIZE_16) 30 + #define VNIC_RQ_CQ_ENTRY_SIZE_32_CAPABLE BIT(VNIC_RQ_CQ_ENTRY_SIZE_32) 31 + #define VNIC_RQ_CQ_ENTRY_SIZE_64_CAPABLE BIT(VNIC_RQ_CQ_ENTRY_SIZE_64) 32 + 33 + #define VNIC_RQ_CQ_ENTRY_SIZE_ALL_BIT (VNIC_RQ_CQ_ENTRY_SIZE_16_CAPABLE | \ 34 + VNIC_RQ_CQ_ENTRY_SIZE_32_CAPABLE | \ 35 + VNIC_RQ_CQ_ENTRY_SIZE_64_CAPABLE) 26 36 27 37 /* Completion queue descriptor: Ethernet receive queue, 16B */ 28 38 struct cq_enet_rq_desc { ··· 43 33 __le16 vlan; 44 34 __le16 checksum_fcoe; 45 35 u8 flags; 36 + u8 type_color; 37 + }; 38 + 39 + /* Completion queue descriptor: Ethernet receive queue, 32B */ 40 + struct cq_enet_rq_desc_32 { 41 + __le16 completed_index_flags; 42 + __le16 q_number_rss_type_flags; 43 + __le32 rss_hash; 44 + __le16 bytes_written_flags; 45 + __le16 vlan; 46 + __le16 checksum_fcoe; 47 + u8 flags; 48 + u8 fetch_index_flags; 49 + __le32 time_stamp; 50 + __le16 time_stamp2; 51 + __le16 pie_info; 52 + __le32 pie_info2; 53 + __le16 pie_info3; 54 + u8 pie_info4; 55 + u8 type_color; 56 + }; 57 + 58 + /* Completion queue descriptor: Ethernet receive queue, 64B */ 59 + struct cq_enet_rq_desc_64 { 60 + __le16 completed_index_flags; 61 + __le16 q_number_rss_type_flags; 62 + __le32 rss_hash; 63 + __le16 bytes_written_flags; 64 + __le16 vlan; 65 + __le16 checksum_fcoe; 66 + u8 flags; 67 + u8 fetch_index_flags; 68 + __le32 time_stamp; 69 + __le16 time_stamp2; 70 + __le16 pie_info; 71 + __le32 pie_info2; 72 + __le16 pie_info3; 73 + u8 pie_info4; 74 + u8 reserved[32]; 46 75 u8 type_color; 47 76 }; 48 77 ··· 136 87 #define CQ_ENET_RQ_DESC_FLAGS_IPV4 (0x1 << 5) 137 88 #define CQ_ENET_RQ_DESC_FLAGS_IPV4_FRAGMENT (0x1 << 6) 138 89 #define CQ_ENET_RQ_DESC_FLAGS_FCS_OK (0x1 << 7) 139 - 140 - static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc, 141 - u8 *type, u8 *color, u16 *q_number, u16 *completed_index, 142 - u8 *ingress_port, u8 *fcoe, u8 *eop, u8 *sop, u8 *rss_type, 143 - u8 *csum_not_calc, u32 *rss_hash, u16 *bytes_written, u8 *packet_error, 144 - u8 *vlan_stripped, u16 *vlan_tci, u16 *checksum, u8 *fcoe_sof, 145 - u8 *fcoe_fc_crc_ok, u8 *fcoe_enc_error, u8 *fcoe_eof, 146 - u8 *tcp_udp_csum_ok, u8 *udp, u8 *tcp, u8 *ipv4_csum_ok, 147 - u8 *ipv6, u8 *ipv4, u8 *ipv4_fragment, u8 *fcs_ok) 148 - { 149 - u16 completed_index_flags; 150 - u16 q_number_rss_type_flags; 151 - u16 bytes_written_flags; 152 - 153 - cq_desc_dec((struct cq_desc *)desc, type, 154 - color, q_number, completed_index); 155 - 156 - completed_index_flags = le16_to_cpu(desc->completed_index_flags); 157 - q_number_rss_type_flags = 158 - le16_to_cpu(desc->q_number_rss_type_flags); 159 - bytes_written_flags = le16_to_cpu(desc->bytes_written_flags); 160 - 161 - *ingress_port = (completed_index_flags & 162 - CQ_ENET_RQ_DESC_FLAGS_INGRESS_PORT) ? 1 : 0; 163 - *fcoe = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_FCOE) ? 164 - 1 : 0; 165 - *eop = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_EOP) ? 166 - 1 : 0; 167 - *sop = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_SOP) ? 168 - 1 : 0; 169 - 170 - *rss_type = (u8)((q_number_rss_type_flags >> CQ_DESC_Q_NUM_BITS) & 171 - CQ_ENET_RQ_DESC_RSS_TYPE_MASK); 172 - *csum_not_calc = (q_number_rss_type_flags & 173 - CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC) ? 1 : 0; 174 - 175 - *rss_hash = le32_to_cpu(desc->rss_hash); 176 - 177 - *bytes_written = bytes_written_flags & 178 - CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK; 179 - *packet_error = (bytes_written_flags & 180 - CQ_ENET_RQ_DESC_FLAGS_TRUNCATED) ? 1 : 0; 181 - *vlan_stripped = (bytes_written_flags & 182 - CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED) ? 1 : 0; 183 - 184 - /* 185 - * Tag Control Information(16) = user_priority(3) + cfi(1) + vlan(12) 186 - */ 187 - *vlan_tci = le16_to_cpu(desc->vlan); 188 - 189 - if (*fcoe) { 190 - *fcoe_sof = (u8)(le16_to_cpu(desc->checksum_fcoe) & 191 - CQ_ENET_RQ_DESC_FCOE_SOF_MASK); 192 - *fcoe_fc_crc_ok = (desc->flags & 193 - CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK) ? 1 : 0; 194 - *fcoe_enc_error = (desc->flags & 195 - CQ_ENET_RQ_DESC_FCOE_ENC_ERROR) ? 1 : 0; 196 - *fcoe_eof = (u8)((le16_to_cpu(desc->checksum_fcoe) >> 197 - CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT) & 198 - CQ_ENET_RQ_DESC_FCOE_EOF_MASK); 199 - *checksum = 0; 200 - } else { 201 - *fcoe_sof = 0; 202 - *fcoe_fc_crc_ok = 0; 203 - *fcoe_enc_error = 0; 204 - *fcoe_eof = 0; 205 - *checksum = le16_to_cpu(desc->checksum_fcoe); 206 - } 207 - 208 - *tcp_udp_csum_ok = 209 - (desc->flags & CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK) ? 1 : 0; 210 - *udp = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_UDP) ? 1 : 0; 211 - *tcp = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_TCP) ? 1 : 0; 212 - *ipv4_csum_ok = 213 - (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK) ? 1 : 0; 214 - *ipv6 = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV6) ? 1 : 0; 215 - *ipv4 = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4) ? 1 : 0; 216 - *ipv4_fragment = 217 - (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4_FRAGMENT) ? 1 : 0; 218 - *fcs_ok = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_FCS_OK) ? 1 : 0; 219 - } 220 90 221 91 #endif /* _CQ_ENET_DESC_H_ */
+13
drivers/net/ethernet/cisco/enic/enic.h
··· 31 31 32 32 #define ENIC_AIC_LARGE_PKT_DIFF 3 33 33 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 + 34 41 struct enic_msix_entry { 35 42 int requested; 36 43 char devname[IFNAMSIZ + 8]; ··· 82 75 #define ENIC_SET_NAME (1 << 2) 83 76 #define ENIC_SET_INSTANCE (1 << 3) 84 77 #define ENIC_SET_HOST (1 << 4) 78 + 79 + #define MAX_TSO BIT(16) 80 + #define WQ_ENET_MAX_DESC_LEN BIT(WQ_ENET_LEN_BITS) 81 + #define ENIC_DESC_MAX_SPLITS (MAX_TSO / WQ_ENET_MAX_DESC_LEN + 1) 85 82 86 83 struct enic_port_profile { 87 84 u32 set; ··· 239 228 struct enic_rfs_flw_tbl rfs_h; 240 229 u8 rss_key[ENIC_RSS_LEN]; 241 230 struct vnic_gen_stats gen_stats; 231 + enum ext_cq ext_cq; 242 232 }; 243 233 244 234 static inline struct net_device *vnic_get_netdev(struct vnic_dev *vdev) ··· 361 349 int enic_is_dynamic(struct enic *enic); 362 350 void enic_set_ethtool_ops(struct net_device *netdev); 363 351 int __enic_set_rsskey(struct enic *enic); 352 + void enic_ext_cq(struct enic *enic); 364 353 365 354 #endif /* _ENIC_H_ */
+6 -6
drivers/net/ethernet/cisco/enic/enic_ethtool.c
··· 222 222 struct enic *enic = netdev_priv(netdev); 223 223 struct vnic_enet_config *c = &enic->config; 224 224 225 - ring->rx_max_pending = ENIC_MAX_RQ_DESCS; 225 + ring->rx_max_pending = c->max_rq_ring; 226 226 ring->rx_pending = c->rq_desc_count; 227 - ring->tx_max_pending = ENIC_MAX_WQ_DESCS; 227 + ring->tx_max_pending = c->max_wq_ring; 228 228 ring->tx_pending = c->wq_desc_count; 229 229 } 230 230 ··· 252 252 } 253 253 rx_pending = c->rq_desc_count; 254 254 tx_pending = c->wq_desc_count; 255 - if (ring->rx_pending > ENIC_MAX_RQ_DESCS || 255 + if (ring->rx_pending > c->max_rq_ring || 256 256 ring->rx_pending < ENIC_MIN_RQ_DESCS) { 257 257 netdev_info(netdev, "rx pending (%u) not in range [%u,%u]", 258 258 ring->rx_pending, ENIC_MIN_RQ_DESCS, 259 - ENIC_MAX_RQ_DESCS); 259 + c->max_rq_ring); 260 260 return -EINVAL; 261 261 } 262 - if (ring->tx_pending > ENIC_MAX_WQ_DESCS || 262 + if (ring->tx_pending > c->max_wq_ring || 263 263 ring->tx_pending < ENIC_MIN_WQ_DESCS) { 264 264 netdev_info(netdev, "tx pending (%u) not in range [%u,%u]", 265 265 ring->tx_pending, ENIC_MIN_WQ_DESCS, 266 - ENIC_MAX_WQ_DESCS); 266 + c->max_wq_ring); 267 267 return -EINVAL; 268 268 } 269 269 if (running)
+10 -59
drivers/net/ethernet/cisco/enic/enic_main.c
··· 59 59 #include "enic_pp.h" 60 60 #include "enic_clsf.h" 61 61 #include "enic_rq.h" 62 + #include "enic_wq.h" 62 63 63 64 #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) 67 65 68 66 #define PCI_DEVICE_ID_CISCO_VIC_ENET 0x0043 /* ethernet vnic */ 69 67 #define PCI_DEVICE_ID_CISCO_VIC_ENET_DYN 0x0044 /* enet dynamic vnic */ ··· 317 319 #else 318 320 return 0; 319 321 #endif 320 - } 321 - 322 - static void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf) 323 - { 324 - struct enic *enic = vnic_dev_priv(wq->vdev); 325 - 326 - if (buf->sop) 327 - dma_unmap_single(&enic->pdev->dev, buf->dma_addr, buf->len, 328 - DMA_TO_DEVICE); 329 - else 330 - dma_unmap_page(&enic->pdev->dev, buf->dma_addr, buf->len, 331 - DMA_TO_DEVICE); 332 - 333 - if (buf->os_buf) 334 - dev_kfree_skb_any(buf->os_buf); 335 - } 336 - 337 - static void enic_wq_free_buf(struct vnic_wq *wq, 338 - struct cq_desc *cq_desc, struct vnic_wq_buf *buf, void *opaque) 339 - { 340 - struct enic *enic = vnic_dev_priv(wq->vdev); 341 - 342 - enic->wq[wq->index].stats.cq_work++; 343 - enic->wq[wq->index].stats.cq_bytes += buf->len; 344 - enic_free_wq_buf(wq, buf); 345 - } 346 - 347 - static int enic_wq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, 348 - u8 type, u16 q_number, u16 completed_index, void *opaque) 349 - { 350 - struct enic *enic = vnic_dev_priv(vdev); 351 - 352 - spin_lock(&enic->wq[q_number].lock); 353 - 354 - vnic_wq_service(&enic->wq[q_number].vwq, cq_desc, 355 - completed_index, enic_wq_free_buf, 356 - opaque); 357 - 358 - if (netif_tx_queue_stopped(netdev_get_tx_queue(enic->netdev, q_number)) && 359 - vnic_wq_desc_avail(&enic->wq[q_number].vwq) >= 360 - (MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS)) { 361 - netif_wake_subqueue(enic->netdev, q_number); 362 - enic->wq[q_number].stats.wake++; 363 - } 364 - 365 - spin_unlock(&enic->wq[q_number].lock); 366 - 367 - return 0; 368 322 } 369 323 370 324 static bool enic_log_q_error(struct enic *enic) ··· 1332 1382 unsigned int work_done, rq_work_done = 0, wq_work_done; 1333 1383 int err; 1334 1384 1335 - wq_work_done = vnic_cq_service(&enic->cq[cq_wq], wq_work_to_do, 1336 - enic_wq_service, NULL); 1385 + wq_work_done = enic_wq_cq_service(enic, cq_wq, wq_work_to_do); 1337 1386 1338 1387 if (budget > 0) 1339 - rq_work_done = vnic_cq_service(&enic->cq[cq_rq], 1340 - rq_work_to_do, enic_rq_service, NULL); 1388 + rq_work_done = enic_rq_cq_service(enic, cq_rq, rq_work_to_do); 1341 1389 1342 1390 /* Accumulate intr event credits for this polling 1343 1391 * cycle. An intr event is the completion of a ··· 1434 1486 wq_irq = wq->index; 1435 1487 cq = enic_cq_wq(enic, wq_irq); 1436 1488 intr = enic_msix_wq_intr(enic, wq_irq); 1437 - wq_work_done = vnic_cq_service(&enic->cq[cq], wq_work_to_do, 1438 - enic_wq_service, NULL); 1489 + 1490 + wq_work_done = enic_wq_cq_service(enic, cq, wq_work_to_do); 1439 1491 1440 1492 vnic_intr_return_credits(&enic->intr[intr], wq_work_done, 1441 1493 0 /* don't unmask intr */, ··· 1464 1516 */ 1465 1517 1466 1518 if (budget > 0) 1467 - work_done = vnic_cq_service(&enic->cq[cq], 1468 - work_to_do, enic_rq_service, NULL); 1519 + work_done = enic_rq_cq_service(enic, cq, work_to_do); 1469 1520 1470 1521 /* Return intr event credits for this polling 1471 1522 * cycle. An intr event is the completion of a ··· 2141 2194 enic_init_vnic_resources(enic); 2142 2195 enic_set_rss_nic_cfg(enic); 2143 2196 enic_dev_set_ig_vlan_rewrite_mode(enic); 2197 + enic_ext_cq(enic); 2144 2198 enic_open(enic->netdev); 2145 2199 2146 2200 /* Allow infiniband to fiddle with the device again */ ··· 2168 2220 enic_init_vnic_resources(enic); 2169 2221 enic_set_rss_nic_cfg(enic); 2170 2222 enic_dev_set_ig_vlan_rewrite_mode(enic); 2223 + enic_ext_cq(enic); 2171 2224 enic_open(enic->netdev); 2172 2225 2173 2226 /* Allow infiniband to fiddle with the device again */ ··· 2542 2593 */ 2543 2594 2544 2595 enic_get_res_counts(enic); 2596 + 2597 + enic_ext_cq(enic); 2545 2598 2546 2599 err = enic_alloc_enic_resources(enic); 2547 2600 if (err) {
+73 -14
drivers/net/ethernet/cisco/enic/enic_res.c
··· 59 59 GET_CONFIG(intr_timer_usec); 60 60 GET_CONFIG(loop_tag); 61 61 GET_CONFIG(num_arfs); 62 + GET_CONFIG(max_rq_ring); 63 + GET_CONFIG(max_wq_ring); 64 + GET_CONFIG(max_cq_ring); 65 + 66 + if (!c->max_wq_ring) 67 + c->max_wq_ring = ENIC_MAX_WQ_DESCS_DEFAULT; 68 + if (!c->max_rq_ring) 69 + c->max_rq_ring = ENIC_MAX_RQ_DESCS_DEFAULT; 70 + if (!c->max_cq_ring) 71 + c->max_cq_ring = ENIC_MAX_CQ_DESCS_DEFAULT; 62 72 63 73 c->wq_desc_count = 64 - min_t(u32, ENIC_MAX_WQ_DESCS, 65 - max_t(u32, ENIC_MIN_WQ_DESCS, 66 - c->wq_desc_count)); 74 + min_t(u32, c->max_wq_ring, 75 + max_t(u32, ENIC_MIN_WQ_DESCS, c->wq_desc_count)); 67 76 c->wq_desc_count &= 0xffffffe0; /* must be aligned to groups of 32 */ 68 77 69 78 c->rq_desc_count = 70 - min_t(u32, ENIC_MAX_RQ_DESCS, 71 - max_t(u32, ENIC_MIN_RQ_DESCS, 72 - c->rq_desc_count)); 79 + min_t(u32, c->max_rq_ring, 80 + max_t(u32, ENIC_MIN_RQ_DESCS, c->rq_desc_count)); 73 81 c->rq_desc_count &= 0xffffffe0; /* must be aligned to groups of 32 */ 74 82 75 83 if (c->mtu == 0) 76 84 c->mtu = 1500; 77 - c->mtu = min_t(u16, ENIC_MAX_MTU, 78 - max_t(u16, ENIC_MIN_MTU, 79 - c->mtu)); 85 + c->mtu = min_t(u16, ENIC_MAX_MTU, max_t(u16, ENIC_MIN_MTU, c->mtu)); 80 86 81 87 c->intr_timer_usec = min_t(u32, c->intr_timer_usec, 82 88 vnic_dev_get_intr_coal_timer_max(enic->vdev)); 83 89 84 90 dev_info(enic_get_dev(enic), 85 - "vNIC MAC addr %pM wq/rq %d/%d mtu %d\n", 86 - enic->mac_addr, c->wq_desc_count, c->rq_desc_count, c->mtu); 91 + "vNIC MAC addr %pM wq/rq %d/%d max wq/rq/cq %d/%d/%d mtu %d\n", 92 + enic->mac_addr, c->wq_desc_count, c->rq_desc_count, 93 + c->max_wq_ring, c->max_rq_ring, c->max_cq_ring, c->mtu); 87 94 88 95 dev_info(enic_get_dev(enic), "vNIC csum tx/rx %s/%s " 89 96 "tso/lro %s/%s rss %s intr mode %s type %s timer %d usec " ··· 319 312 int enic_alloc_vnic_resources(struct enic *enic) 320 313 { 321 314 enum vnic_dev_intr_mode intr_mode; 315 + int rq_cq_desc_size; 322 316 unsigned int i; 323 317 int err; 324 318 ··· 333 325 intr_mode == VNIC_DEV_INTR_MODE_MSI ? "MSI" : 334 326 intr_mode == VNIC_DEV_INTR_MODE_MSIX ? "MSI-X" : 335 327 "unknown"); 328 + 329 + switch (enic->ext_cq) { 330 + case ENIC_RQ_CQ_ENTRY_SIZE_16: 331 + rq_cq_desc_size = 16; 332 + break; 333 + case ENIC_RQ_CQ_ENTRY_SIZE_32: 334 + rq_cq_desc_size = 32; 335 + break; 336 + case ENIC_RQ_CQ_ENTRY_SIZE_64: 337 + rq_cq_desc_size = 64; 338 + break; 339 + default: 340 + dev_err(enic_get_dev(enic), 341 + "Unable to determine rq cq desc size: %d", 342 + enic->ext_cq); 343 + err = -ENODEV; 344 + goto err_out; 345 + } 336 346 337 347 /* Allocate queue resources 338 348 */ ··· 374 348 for (i = 0; i < enic->cq_count; i++) { 375 349 if (i < enic->rq_count) 376 350 err = vnic_cq_alloc(enic->vdev, &enic->cq[i], i, 377 - enic->config.rq_desc_count, 378 - sizeof(struct cq_enet_rq_desc)); 351 + enic->config.rq_desc_count, 352 + rq_cq_desc_size); 379 353 else 380 354 err = vnic_cq_alloc(enic->vdev, &enic->cq[i], i, 381 355 enic->config.wq_desc_count, ··· 406 380 407 381 err_out_cleanup: 408 382 enic_free_vnic_resources(enic); 409 - 383 + err_out: 410 384 return err; 385 + } 386 + 387 + /* 388 + * CMD_CQ_ENTRY_SIZE_SET can fail on older hw generations that don't support 389 + * that command 390 + */ 391 + void enic_ext_cq(struct enic *enic) 392 + { 393 + u64 a0 = CMD_CQ_ENTRY_SIZE_SET, a1 = 0; 394 + int wait = 1000; 395 + int ret; 396 + 397 + spin_lock_bh(&enic->devcmd_lock); 398 + ret = vnic_dev_cmd(enic->vdev, CMD_CAPABILITY, &a0, &a1, wait); 399 + if (ret || a0) { 400 + dev_info(&enic->pdev->dev, 401 + "CMD_CQ_ENTRY_SIZE_SET not supported."); 402 + enic->ext_cq = ENIC_RQ_CQ_ENTRY_SIZE_16; 403 + goto out; 404 + } 405 + a1 &= VNIC_RQ_CQ_ENTRY_SIZE_ALL_BIT; 406 + enic->ext_cq = fls(a1) - 1; 407 + a0 = VNIC_RQ_ALL; 408 + a1 = enic->ext_cq; 409 + ret = vnic_dev_cmd(enic->vdev, CMD_CQ_ENTRY_SIZE_SET, &a0, &a1, wait); 410 + if (ret) { 411 + dev_info(&enic->pdev->dev, "CMD_CQ_ENTRY_SIZE_SET failed."); 412 + enic->ext_cq = ENIC_RQ_CQ_ENTRY_SIZE_16; 413 + } 414 + out: 415 + spin_unlock_bh(&enic->devcmd_lock); 416 + dev_info(&enic->pdev->dev, "CQ entry size set to %d bytes", 417 + 16 << enic->ext_cq); 411 418 }
+7 -4
drivers/net/ethernet/cisco/enic/enic_res.h
··· 12 12 #include "vnic_wq.h" 13 13 #include "vnic_rq.h" 14 14 15 - #define ENIC_MIN_WQ_DESCS 64 16 - #define ENIC_MAX_WQ_DESCS 4096 17 - #define ENIC_MIN_RQ_DESCS 64 18 - #define ENIC_MAX_RQ_DESCS 4096 15 + #define ENIC_MIN_WQ_DESCS 64 16 + #define ENIC_MAX_WQ_DESCS_DEFAULT 4096 17 + #define ENIC_MAX_WQ_DESCS 16384 18 + #define ENIC_MIN_RQ_DESCS 64 19 + #define ENIC_MAX_RQ_DESCS 16384 20 + #define ENIC_MAX_RQ_DESCS_DEFAULT 4096 21 + #define ENIC_MAX_CQ_DESCS_DEFAULT (64 * 1024) 19 22 20 23 #define ENIC_MIN_MTU ETH_MIN_MTU 21 24 #define ENIC_MAX_MTU 9000
+217 -23
drivers/net/ethernet/cisco/enic/enic_rq.c
··· 21 21 pkt_size->small_pkt_bytes_cnt += pkt_len; 22 22 } 23 23 24 - int enic_rq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, u8 type, 25 - u16 q_number, u16 completed_index, void *opaque) 24 + static void enic_rq_cq_desc_dec(void *cq_desc, u8 cq_desc_size, u8 *type, 25 + u8 *color, u16 *q_number, u16 *completed_index) 26 26 { 27 - struct enic *enic = vnic_dev_priv(vdev); 27 + /* type_color is the last field for all cq structs */ 28 + u8 type_color; 28 29 29 - vnic_rq_service(&enic->rq[q_number].vrq, cq_desc, completed_index, 30 - VNIC_RQ_RETURN_DESC, enic_rq_indicate_buf, opaque); 31 - return 0; 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(); 43 + 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 + } 93 + 94 + *color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK; 95 + *type = type_color & CQ_DESC_TYPE_MASK; 32 96 } 33 97 34 98 static void enic_rq_set_skb_flags(struct vnic_rq *vrq, u8 type, u32 rss_hash, ··· 165 101 } 166 102 } 167 103 104 + /* 105 + * cq_enet_rq_desc accesses section uses only the 1st 15 bytes of the cq which 106 + * is identical for all type (16,32 and 64 byte) of cqs. 107 + */ 108 + static void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc, u8 *ingress_port, 109 + u8 *fcoe, u8 *eop, u8 *sop, u8 *rss_type, 110 + u8 *csum_not_calc, u32 *rss_hash, 111 + u16 *bytes_written, u8 *packet_error, 112 + u8 *vlan_stripped, u16 *vlan_tci, 113 + u16 *checksum, u8 *fcoe_sof, 114 + u8 *fcoe_fc_crc_ok, u8 *fcoe_enc_error, 115 + u8 *fcoe_eof, u8 *tcp_udp_csum_ok, u8 *udp, 116 + u8 *tcp, u8 *ipv4_csum_ok, u8 *ipv6, u8 *ipv4, 117 + u8 *ipv4_fragment, u8 *fcs_ok) 118 + { 119 + u16 completed_index_flags; 120 + u16 q_number_rss_type_flags; 121 + u16 bytes_written_flags; 122 + 123 + completed_index_flags = le16_to_cpu(desc->completed_index_flags); 124 + q_number_rss_type_flags = 125 + le16_to_cpu(desc->q_number_rss_type_flags); 126 + bytes_written_flags = le16_to_cpu(desc->bytes_written_flags); 127 + 128 + *ingress_port = (completed_index_flags & 129 + CQ_ENET_RQ_DESC_FLAGS_INGRESS_PORT) ? 1 : 0; 130 + *fcoe = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_FCOE) ? 131 + 1 : 0; 132 + *eop = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_EOP) ? 133 + 1 : 0; 134 + *sop = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_SOP) ? 135 + 1 : 0; 136 + 137 + *rss_type = (u8)((q_number_rss_type_flags >> CQ_DESC_Q_NUM_BITS) & 138 + CQ_ENET_RQ_DESC_RSS_TYPE_MASK); 139 + *csum_not_calc = (q_number_rss_type_flags & 140 + CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC) ? 1 : 0; 141 + 142 + *rss_hash = le32_to_cpu(desc->rss_hash); 143 + 144 + *bytes_written = bytes_written_flags & 145 + CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK; 146 + *packet_error = (bytes_written_flags & 147 + CQ_ENET_RQ_DESC_FLAGS_TRUNCATED) ? 1 : 0; 148 + *vlan_stripped = (bytes_written_flags & 149 + CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED) ? 1 : 0; 150 + 151 + /* 152 + * Tag Control Information(16) = user_priority(3) + cfi(1) + vlan(12) 153 + */ 154 + *vlan_tci = le16_to_cpu(desc->vlan); 155 + 156 + if (*fcoe) { 157 + *fcoe_sof = (u8)(le16_to_cpu(desc->checksum_fcoe) & 158 + CQ_ENET_RQ_DESC_FCOE_SOF_MASK); 159 + *fcoe_fc_crc_ok = (desc->flags & 160 + CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK) ? 1 : 0; 161 + *fcoe_enc_error = (desc->flags & 162 + CQ_ENET_RQ_DESC_FCOE_ENC_ERROR) ? 1 : 0; 163 + *fcoe_eof = (u8)((le16_to_cpu(desc->checksum_fcoe) >> 164 + CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT) & 165 + CQ_ENET_RQ_DESC_FCOE_EOF_MASK); 166 + *checksum = 0; 167 + } else { 168 + *fcoe_sof = 0; 169 + *fcoe_fc_crc_ok = 0; 170 + *fcoe_enc_error = 0; 171 + *fcoe_eof = 0; 172 + *checksum = le16_to_cpu(desc->checksum_fcoe); 173 + } 174 + 175 + *tcp_udp_csum_ok = 176 + (desc->flags & CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK) ? 1 : 0; 177 + *udp = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_UDP) ? 1 : 0; 178 + *tcp = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_TCP) ? 1 : 0; 179 + *ipv4_csum_ok = 180 + (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK) ? 1 : 0; 181 + *ipv6 = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV6) ? 1 : 0; 182 + *ipv4 = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4) ? 1 : 0; 183 + *ipv4_fragment = 184 + (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4_FRAGMENT) ? 1 : 0; 185 + *fcs_ok = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_FCS_OK) ? 1 : 0; 186 + } 187 + 168 188 static bool enic_rq_pkt_error(struct vnic_rq *vrq, u8 packet_error, u8 fcs_ok, 169 189 u16 bytes_written) 170 190 { ··· 313 165 buf->os_buf = NULL; 314 166 } 315 167 316 - void enic_rq_indicate_buf(struct vnic_rq *rq, struct cq_desc *cq_desc, 317 - struct vnic_rq_buf *buf, int skipped, void *opaque) 168 + static void enic_rq_indicate_buf(struct enic *enic, struct vnic_rq *rq, 169 + struct vnic_rq_buf *buf, void *cq_desc, 170 + u8 type, u16 q_number, u16 completed_index) 318 171 { 319 - struct enic *enic = vnic_dev_priv(rq->vdev); 320 172 struct sk_buff *skb; 321 173 struct vnic_cq *cq = &enic->cq[enic_cq_rq(enic, rq->index)]; 322 174 struct enic_rq_stats *rqstats = &enic->rq[rq->index].stats; 323 175 struct napi_struct *napi; 324 176 325 - u8 type, color, eop, sop, ingress_port, vlan_stripped; 177 + u8 eop, sop, ingress_port, vlan_stripped; 326 178 u8 fcoe, fcoe_sof, fcoe_fc_crc_ok, fcoe_enc_error, fcoe_eof; 327 179 u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok; 328 180 u8 ipv6, ipv4, ipv4_fragment, fcs_ok, rss_type, csum_not_calc; 329 181 u8 packet_error; 330 - u16 q_number, completed_index, bytes_written, vlan_tci, checksum; 182 + u16 bytes_written, vlan_tci, checksum; 331 183 u32 rss_hash; 332 184 333 185 rqstats->packets++; 334 - if (skipped) { 335 - rqstats->desc_skip++; 336 - return; 337 - } 338 186 339 - cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc, &type, &color, 340 - &q_number, &completed_index, &ingress_port, &fcoe, 341 - &eop, &sop, &rss_type, &csum_not_calc, &rss_hash, 342 - &bytes_written, &packet_error, &vlan_stripped, 343 - &vlan_tci, &checksum, &fcoe_sof, &fcoe_fc_crc_ok, 344 - &fcoe_enc_error, &fcoe_eof, &tcp_udp_csum_ok, &udp, 345 - &tcp, &ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment, 346 - &fcs_ok); 187 + cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc, &ingress_port, 188 + &fcoe, &eop, &sop, &rss_type, &csum_not_calc, 189 + &rss_hash, &bytes_written, &packet_error, 190 + &vlan_stripped, &vlan_tci, &checksum, &fcoe_sof, 191 + &fcoe_fc_crc_ok, &fcoe_enc_error, &fcoe_eof, 192 + &tcp_udp_csum_ok, &udp, &tcp, &ipv4_csum_ok, &ipv6, 193 + &ipv4, &ipv4_fragment, &fcs_ok); 347 194 348 195 if (enic_rq_pkt_error(rq, packet_error, fcs_ok, bytes_written)) 349 196 return; ··· 382 239 */ 383 240 rqstats->pkt_truncated++; 384 241 } 242 + } 243 + 244 + static void enic_rq_service(struct enic *enic, void *cq_desc, u8 type, 245 + u16 q_number, u16 completed_index) 246 + { 247 + struct enic_rq_stats *rqstats = &enic->rq[q_number].stats; 248 + struct vnic_rq *vrq = &enic->rq[q_number].vrq; 249 + struct vnic_rq_buf *vrq_buf = vrq->to_clean; 250 + int skipped; 251 + 252 + while (1) { 253 + skipped = (vrq_buf->index != completed_index); 254 + if (!skipped) 255 + enic_rq_indicate_buf(enic, vrq, vrq_buf, cq_desc, type, 256 + q_number, completed_index); 257 + else 258 + rqstats->desc_skip++; 259 + 260 + vrq->ring.desc_avail++; 261 + vrq->to_clean = vrq_buf->next; 262 + vrq_buf = vrq_buf->next; 263 + if (!skipped) 264 + break; 265 + } 266 + } 267 + 268 + unsigned int enic_rq_cq_service(struct enic *enic, unsigned int cq_index, 269 + unsigned int work_to_do) 270 + { 271 + struct vnic_cq *cq = &enic->cq[cq_index]; 272 + void *cq_desc = vnic_cq_to_clean(cq); 273 + u16 q_number, completed_index; 274 + unsigned int work_done = 0; 275 + u8 type, color; 276 + 277 + enic_rq_cq_desc_dec(cq_desc, enic->ext_cq, &type, &color, &q_number, 278 + &completed_index); 279 + 280 + while (color != cq->last_color) { 281 + enic_rq_service(enic, cq_desc, type, q_number, completed_index); 282 + vnic_cq_inc_to_clean(cq); 283 + 284 + if (++work_done >= work_to_do) 285 + break; 286 + 287 + cq_desc = vnic_cq_to_clean(cq); 288 + enic_rq_cq_desc_dec(cq_desc, enic->ext_cq, &type, &color, 289 + &q_number, &completed_index); 290 + } 291 + 292 + return work_done; 385 293 }
+2 -4
drivers/net/ethernet/cisco/enic/enic_rq.h
··· 2 2 * Copyright 2024 Cisco Systems, Inc. All rights reserved. 3 3 */ 4 4 5 - int enic_rq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, u8 type, 6 - u16 q_number, u16 completed_index, void *opaque); 7 - void enic_rq_indicate_buf(struct vnic_rq *rq, struct cq_desc *cq_desc, 8 - struct vnic_rq_buf *buf, int skipped, void *opaque); 5 + unsigned int enic_rq_cq_service(struct enic *enic, unsigned int cq_index, 6 + unsigned int work_to_do); 9 7 int enic_rq_alloc_buf(struct vnic_rq *rq); 10 8 void enic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf);
+117
drivers/net/ethernet/cisco/enic/enic_wq.c
··· 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 + #define ENET_CQ_DESC_COMP_NDX_BITS 14 10 + #define ENET_CQ_DESC_COMP_NDX_MASK GENMASK(ENET_CQ_DESC_COMP_NDX_BITS - 1, 0) 11 + 12 + static void enic_wq_cq_desc_dec(const struct cq_desc *desc_arg, bool ext_wq, 13 + u8 *type, u8 *color, u16 *q_number, 14 + u16 *completed_index) 15 + { 16 + const struct cq_desc *desc = desc_arg; 17 + const u8 type_color = desc->type_color; 18 + 19 + *color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK; 20 + 21 + /* 22 + * Make sure color bit is read from desc *before* other fields 23 + * are read from desc. Hardware guarantees color bit is last 24 + * bit (byte) written. Adding the rmb() prevents the compiler 25 + * and/or CPU from reordering the reads which would potentially 26 + * result in reading stale values. 27 + */ 28 + rmb(); 29 + 30 + *type = type_color & CQ_DESC_TYPE_MASK; 31 + *q_number = le16_to_cpu(desc->q_number) & CQ_DESC_Q_NUM_MASK; 32 + 33 + if (ext_wq) 34 + *completed_index = le16_to_cpu(desc->completed_index) & 35 + ENET_CQ_DESC_COMP_NDX_MASK; 36 + else 37 + *completed_index = le16_to_cpu(desc->completed_index) & 38 + CQ_DESC_COMP_NDX_MASK; 39 + } 40 + 41 + void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf) 42 + { 43 + struct enic *enic = vnic_dev_priv(wq->vdev); 44 + 45 + if (buf->sop) 46 + dma_unmap_single(&enic->pdev->dev, buf->dma_addr, buf->len, 47 + DMA_TO_DEVICE); 48 + else 49 + dma_unmap_page(&enic->pdev->dev, buf->dma_addr, buf->len, 50 + DMA_TO_DEVICE); 51 + 52 + if (buf->os_buf) 53 + dev_kfree_skb_any(buf->os_buf); 54 + } 55 + 56 + static void enic_wq_free_buf(struct vnic_wq *wq, struct cq_desc *cq_desc, 57 + struct vnic_wq_buf *buf, void *opaque) 58 + { 59 + struct enic *enic = vnic_dev_priv(wq->vdev); 60 + 61 + enic->wq[wq->index].stats.cq_work++; 62 + enic->wq[wq->index].stats.cq_bytes += buf->len; 63 + enic_free_wq_buf(wq, buf); 64 + } 65 + 66 + static void enic_wq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, 67 + u8 type, u16 q_number, u16 completed_index) 68 + { 69 + struct enic *enic = vnic_dev_priv(vdev); 70 + 71 + spin_lock(&enic->wq[q_number].lock); 72 + 73 + vnic_wq_service(&enic->wq[q_number].vwq, cq_desc, 74 + completed_index, enic_wq_free_buf, NULL); 75 + 76 + if (netif_tx_queue_stopped(netdev_get_tx_queue(enic->netdev, q_number)) 77 + && vnic_wq_desc_avail(&enic->wq[q_number].vwq) >= 78 + (MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS)) { 79 + netif_wake_subqueue(enic->netdev, q_number); 80 + enic->wq[q_number].stats.wake++; 81 + } 82 + 83 + spin_unlock(&enic->wq[q_number].lock); 84 + } 85 + 86 + unsigned int enic_wq_cq_service(struct enic *enic, unsigned int cq_index, 87 + unsigned int work_to_do) 88 + { 89 + struct vnic_cq *cq = &enic->cq[cq_index]; 90 + u16 q_number, completed_index; 91 + unsigned int work_done = 0; 92 + struct cq_desc *cq_desc; 93 + u8 type, color; 94 + bool ext_wq; 95 + 96 + ext_wq = cq->ring.size > ENIC_MAX_WQ_DESCS_DEFAULT; 97 + 98 + cq_desc = (struct cq_desc *)vnic_cq_to_clean(cq); 99 + enic_wq_cq_desc_dec(cq_desc, ext_wq, &type, &color, 100 + &q_number, &completed_index); 101 + 102 + while (color != cq->last_color) { 103 + enic_wq_service(cq->vdev, cq_desc, type, q_number, 104 + completed_index); 105 + 106 + vnic_cq_inc_to_clean(cq); 107 + 108 + if (++work_done >= work_to_do) 109 + break; 110 + 111 + cq_desc = (struct cq_desc *)vnic_cq_to_clean(cq); 112 + enic_wq_cq_desc_dec(cq_desc, ext_wq, &type, &color, 113 + &q_number, &completed_index); 114 + } 115 + 116 + return work_done; 117 + }
+7
drivers/net/ethernet/cisco/enic/enic_wq.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only 2 + * Copyright 2025 Cisco Systems, Inc. All rights reserved. 3 + */ 4 + 5 + void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf); 6 + unsigned int enic_wq_cq_service(struct enic *enic, unsigned int cq_index, 7 + unsigned int work_to_do);
+9 -36
drivers/net/ethernet/cisco/enic/vnic_cq.h
··· 56 56 ktime_t prev_ts; 57 57 }; 58 58 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) 59 + static inline void *vnic_cq_to_clean(struct vnic_cq *cq) 64 60 { 65 - struct cq_desc *cq_desc; 66 - unsigned int work_done = 0; 67 - u16 q_number, completed_index; 68 - u8 type, color; 61 + return ((u8 *)cq->ring.descs + cq->ring.desc_size * cq->to_clean); 62 + } 69 63 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; 64 + static inline void vnic_cq_inc_to_clean(struct vnic_cq *cq) 65 + { 66 + cq->to_clean++; 67 + if (cq->to_clean == cq->ring.desc_count) { 68 + cq->to_clean = 0; 69 + cq->last_color = cq->last_color ? 0 : 1; 95 70 } 96 - 97 - return work_done; 98 71 } 99 72 100 73 void vnic_cq_free(struct vnic_cq *cq);
+19
drivers/net/ethernet/cisco/enic/vnic_devcmd.h
··· 436 436 * in: (u16) a2 = unsigned short int port information 437 437 */ 438 438 CMD_OVERLAY_OFFLOAD_CFG = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 73), 439 + 440 + /* 441 + * Set extended CQ field in MREGS of RQ (or all RQs) 442 + * for given vNIC 443 + * in: (u64) a0 = RQ selection (VNIC_RQ_ALL for all RQs) 444 + * (u32) a1 = CQ entry size 445 + * VNIC_RQ_CQ_ENTRY_SIZE_16 --> 16 bytes 446 + * VNIC_RQ_CQ_ENTRY_SIZE_32 --> 32 bytes 447 + * VNIC_RQ_CQ_ENTRY_SIZE_64 --> 64 bytes 448 + * 449 + * Capability query: 450 + * out: (u32) a0 = errno, 0:valid cmd 451 + * (u32) a1 = value consisting of supported entries 452 + * bit 0: 16 bytes 453 + * bit 1: 32 bytes 454 + * bit 2: 64 bytes 455 + */ 456 + CMD_CQ_ENTRY_SIZE_SET = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 90), 457 + 439 458 }; 440 459 441 460 /* CMD_ENABLE2 flags */
+5
drivers/net/ethernet/cisco/enic/vnic_enet.h
··· 21 21 u16 loop_tag; 22 22 u16 vf_rq_count; 23 23 u16 num_arfs; 24 + u8 reserved[66]; 25 + u32 max_rq_ring; // MAX RQ ring size 26 + u32 max_wq_ring; // MAX WQ ring size 27 + u32 max_cq_ring; // MAX CQ ring size 28 + u32 rdma_rsvd_lkey; // Reserved (privileged) LKey 24 29 }; 25 30 26 31 #define VENETF_TSO 0x1 /* TSO enabled */
+1 -1
drivers/net/ethernet/cisco/enic/vnic_rq.h
··· 50 50 (VNIC_RQ_BUF_BLK_ENTRIES(entries) * sizeof(struct vnic_rq_buf)) 51 51 #define VNIC_RQ_BUF_BLKS_NEEDED(entries) \ 52 52 DIV_ROUND_UP(entries, VNIC_RQ_BUF_BLK_ENTRIES(entries)) 53 - #define VNIC_RQ_BUF_BLKS_MAX VNIC_RQ_BUF_BLKS_NEEDED(4096) 53 + #define VNIC_RQ_BUF_BLKS_MAX VNIC_RQ_BUF_BLKS_NEEDED(16384) 54 54 55 55 struct vnic_rq_buf { 56 56 struct vnic_rq_buf *next;
+1 -1
drivers/net/ethernet/cisco/enic/vnic_wq.h
··· 62 62 (VNIC_WQ_BUF_BLK_ENTRIES(entries) * sizeof(struct vnic_wq_buf)) 63 63 #define VNIC_WQ_BUF_BLKS_NEEDED(entries) \ 64 64 DIV_ROUND_UP(entries, VNIC_WQ_BUF_BLK_ENTRIES(entries)) 65 - #define VNIC_WQ_BUF_BLKS_MAX VNIC_WQ_BUF_BLKS_NEEDED(4096) 65 + #define VNIC_WQ_BUF_BLKS_MAX VNIC_WQ_BUF_BLKS_NEEDED(16384) 66 66 67 67 struct vnic_wq { 68 68 unsigned int index;