Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2008-2017 Cisco Systems, Inc. All rights reserved.
3 : : * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 : : */
5 : :
6 : : #ifndef _ENIC_H_
7 : : #define _ENIC_H_
8 : :
9 : : #include <rte_vxlan.h>
10 : : #include <rte_ether.h>
11 : : #include "vnic_enet.h"
12 : : #include "vnic_dev.h"
13 : : #include "vnic_flowman.h"
14 : : #include "vnic_wq.h"
15 : : #include "vnic_rq.h"
16 : : #include "vnic_cq.h"
17 : : #include "vnic_intr.h"
18 : : #include "vnic_stats.h"
19 : : #include "vnic_nic.h"
20 : : #include "vnic_rss.h"
21 : : #include "enic_res.h"
22 : : #include "cq_enet_desc.h"
23 : : #include <stdbool.h>
24 : : #include <sys/queue.h>
25 : : #include <rte_spinlock.h>
26 : :
27 : : #define DRV_NAME "enic_pmd"
28 : : #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Poll-mode Driver"
29 : : #define DRV_COPYRIGHT "Copyright 2008-2015 Cisco Systems, Inc"
30 : :
31 : : #define VLAN_ETH_HLEN 18
32 : :
33 : : #define ENICPMD_SETTING(enic, f) ((enic->config.flags & VENETF_##f) ? 1 : 0)
34 : :
35 : : #define ENIC_CALC_IP_CKSUM 1
36 : : #define ENIC_CALC_TCP_UDP_CKSUM 2
37 : : #define ENIC_MAX_MTU 9000
38 : : #define ENIC_PAGE_SIZE 4096
39 : : #define PAGE_ROUND_UP(x) \
40 : : ((((unsigned long)(x)) + ENIC_PAGE_SIZE-1) & (~(ENIC_PAGE_SIZE-1)))
41 : :
42 : : #define ENICPMD_VFIO_PATH "/dev/vfio/vfio"
43 : : /*#define ENIC_DESC_COUNT_MAKE_ODD (x) do{if ((~(x)) & 1) { (x)--; } }while(0)*/
44 : :
45 : : #define PCI_DEVICE_ID_CISCO_VIC_ENET 0x0043 /* ethernet vnic */
46 : : #define PCI_DEVICE_ID_CISCO_VIC_ENET_VF 0x0071 /* enet SRIOV VF */
47 : : /* enet SRIOV Standalone vNic VF */
48 : : #define PCI_DEVICE_ID_CISCO_VIC_ENET_SN 0x02B7
49 : :
50 : : /* Special Filter id for non-specific packet flagging. Don't change value */
51 : : #define ENIC_MAGIC_FILTER_ID 0xffff
52 : :
53 : : /*
54 : : * Interrupt 0: LSC and errors
55 : : * Interrupt 1: rx queue 0
56 : : * Interrupt 2: rx queue 1
57 : : * ...
58 : : */
59 : : #define ENICPMD_LSC_INTR_OFFSET 0
60 : : #define ENICPMD_RXQ_INTR_OFFSET 1
61 : :
62 : : struct enic_soft_stats {
63 : : rte_atomic64_t rx_nombuf;
64 : : rte_atomic64_t rx_packet_errors;
65 : : rte_atomic64_t tx_oversized;
66 : : };
67 : :
68 : : struct enic_memzone_entry {
69 : : const struct rte_memzone *rz;
70 : : LIST_ENTRY(enic_memzone_entry) entries;
71 : : };
72 : :
73 : : /* Defined in enic_fm_flow.c */
74 : : struct enic_flowman;
75 : : struct enic_fm_flow;
76 : :
77 : : struct rte_flow {
78 : : LIST_ENTRY(rte_flow) next;
79 : : /* Data for filter API based flow (enic_flow.c) */
80 : : uint16_t enic_filter_id;
81 : : struct filter_v2 enic_filter;
82 : : /* Data for flow manager based flow (enic_fm_flow.c) */
83 : : struct enic_fm_flow *fm;
84 : : int internal;
85 : : };
86 : :
87 : : /* Per-instance private data structure */
88 : : struct enic {
89 : : struct rte_pci_device *pdev;
90 : : struct vnic_enet_config config;
91 : : struct vnic_dev_bar bar0;
92 : : struct vnic_dev *vdev;
93 : :
94 : : /*
95 : : * mbuf_initializer contains 64 bits of mbuf rearm_data, used by
96 : : * the avx2 handler at this time.
97 : : */
98 : : uint64_t mbuf_initializer;
99 : : unsigned int port_id;
100 : : bool overlay_offload;
101 : : struct rte_eth_dev *rte_dev;
102 : : struct rte_eth_dev_data *dev_data;
103 : : char bdf_name[PCI_PRI_STR_SIZE];
104 : : int dev_fd;
105 : : int iommu_group_fd;
106 : : int iommu_groupid;
107 : : int eventfd;
108 : : uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
109 : : pthread_t err_intr_thread;
110 : : int promisc;
111 : : int allmulti;
112 : : uint8_t ig_vlan_strip_en;
113 : : int link_status;
114 : : uint8_t hw_ip_checksum;
115 : : uint16_t max_mtu;
116 : : uint8_t adv_filters;
117 : : uint32_t flow_filter_mode;
118 : : uint8_t filter_actions; /* HW supported actions */
119 : : uint64_t cq_entry_sizes; /* supported CQ entry sizes */
120 : : bool geneve;
121 : : bool vxlan;
122 : : bool cq64; /* actually using 64B CQ entry */
123 : : bool cq64_request; /* devargs cq64=1 */
124 : : bool disable_overlay; /* devargs disable_overlay=1 */
125 : : uint8_t enable_avx2_rx; /* devargs enable-avx2-rx=1 */
126 : : uint8_t geneve_opt_request; /* devargs geneve-opt=1 */
127 : : bool nic_cfg_chk; /* NIC_CFG_CHK available */
128 : : bool udp_rss_weak; /* Bodega style UDP RSS */
129 : : uint8_t ig_vlan_rewrite_mode; /* devargs ig-vlan-rewrite */
130 : : uint16_t geneve_port; /* current geneve port pushed to NIC */
131 : : uint16_t vxlan_port; /* current vxlan port pushed to NIC */
132 : : int use_simple_tx_handler;
133 : : int use_noscatter_vec_rx_handler;
134 : :
135 : : unsigned int flags;
136 : : unsigned int priv_flags;
137 : :
138 : : /* work queue (len = conf_wq_count) */
139 : : struct vnic_wq *wq;
140 : : unsigned int wq_count; /* equals eth_dev nb_tx_queues */
141 : :
142 : : /* receive queue (len = conf_rq_count) */
143 : : struct vnic_rq *rq;
144 : : unsigned int rq_count; /* equals eth_dev nb_rx_queues */
145 : :
146 : : /* completion queue (len = conf_cq_count) */
147 : : struct vnic_cq *cq;
148 : : unsigned int cq_count; /* equals rq_count + wq_count */
149 : :
150 : : /* interrupt vectors (len = conf_intr_count) */
151 : : struct vnic_intr *intr;
152 : : unsigned int intr_count; /* equals enabled interrupts (lsc + rxqs) */
153 : :
154 : : /* software counters */
155 : : struct enic_soft_stats soft_stats;
156 : :
157 : : /* configured resources on vic */
158 : : unsigned int conf_rq_count;
159 : : unsigned int conf_wq_count;
160 : : unsigned int conf_cq_count;
161 : : unsigned int conf_intr_count;
162 : :
163 : : /* linked list storing memory allocations */
164 : : LIST_HEAD(enic_memzone_list, enic_memzone_entry) memzone_list;
165 : : rte_spinlock_t memzone_list_lock;
166 : : rte_spinlock_t mtu_lock;
167 : :
168 : : LIST_HEAD(enic_flows, rte_flow) flows;
169 : :
170 : : /* RSS */
171 : : uint16_t reta_size;
172 : : uint8_t hash_key_size;
173 : : uint64_t flow_type_rss_offloads; /* 0 indicates RSS not supported */
174 : : /*
175 : : * Keep a copy of current RSS config for queries, as we cannot retrieve
176 : : * it from the NIC.
177 : : */
178 : : uint8_t rss_hash_type; /* NIC_CFG_RSS_HASH_TYPE flags */
179 : : uint8_t rss_enable;
180 : : uint64_t rss_hf; /* RTE_ETH_RSS flags */
181 : : union vnic_rss_key rss_key;
182 : : union vnic_rss_cpu rss_cpu;
183 : :
184 : : uint64_t rx_offload_capa; /* DEV_RX_OFFLOAD flags */
185 : : uint64_t tx_offload_capa; /* DEV_TX_OFFLOAD flags */
186 : : uint64_t tx_queue_offload_capa; /* DEV_TX_OFFLOAD flags */
187 : : uint64_t tx_offload_mask; /* PKT_TX flags accepted */
188 : :
189 : : /* Multicast MAC addresses added to the NIC */
190 : : uint32_t mc_count;
191 : : struct rte_ether_addr mc_addrs[ENIC_MULTICAST_PERFECT_FILTERS];
192 : :
193 : : /* Flow manager API */
194 : : struct enic_flowman *fm;
195 : : uint64_t fm_vnic_handle;
196 : : uint32_t fm_vnic_uif;
197 : : /* switchdev */
198 : : uint8_t switchdev_mode;
199 : : uint16_t switch_domain_id;
200 : : uint16_t max_vf_id;
201 : : /* Number of queues needed for VF representor paths */
202 : : uint32_t vf_required_wq;
203 : : uint32_t vf_required_cq;
204 : : uint32_t vf_required_rq;
205 : : /*
206 : : * Lock to serialize devcmds from PF, VF representors as they all share
207 : : * the same PF devcmd instance in firmware.
208 : : */
209 : : rte_spinlock_t devcmd_lock;
210 : : };
211 : :
212 : : struct enic_vf_representor {
213 : : struct enic enic;
214 : : struct vnic_enet_config config;
215 : : struct rte_eth_dev *eth_dev;
216 : : struct rte_ether_addr mac_addr;
217 : : struct rte_pci_addr bdf;
218 : : struct enic *pf;
219 : : uint16_t switch_domain_id;
220 : : uint16_t vf_id;
221 : : int allmulti;
222 : : int promisc;
223 : : /* Representor path uses PF queues. These are reserved during init */
224 : : uint16_t pf_wq_idx; /* WQ dedicated to VF rep */
225 : : uint16_t pf_wq_cq_idx; /* CQ for WQ */
226 : : uint16_t pf_rq_sop_idx; /* SOP RQ dedicated to VF rep */
227 : : uint16_t pf_rq_data_idx; /* Data RQ */
228 : : /* Representor flows managed by flowman */
229 : : struct rte_flow *vf2rep_flow[2];
230 : : struct rte_flow *rep2vf_flow[2];
231 : : };
232 : :
233 : : #define VF_ENIC_TO_VF_REP(vf_enic) \
234 : : container_of(vf_enic, struct enic_vf_representor, enic)
235 : :
236 : : /* Compute ethdev's max packet size from MTU */
237 : : static inline uint32_t enic_mtu_to_max_rx_pktlen(uint32_t mtu)
238 : : {
239 : : /* ethdev max size includes eth whereas NIC MTU does not */
240 [ # # # # ]: 0 : return mtu + RTE_ETHER_HDR_LEN;
241 : : }
242 : :
243 : : /* Get the CQ index from a Start of Packet(SOP) RQ index */
244 : : static inline unsigned int enic_sop_rq_idx_to_cq_idx(unsigned int sop_idx)
245 : : {
246 : : return sop_idx;
247 : : }
248 : :
249 : : /* Get the RTE RQ index from a Start of Packet(SOP) RQ index */
250 : : static inline unsigned int enic_sop_rq_idx_to_rte_idx(unsigned int sop_idx)
251 : : {
252 : : return sop_idx;
253 : : }
254 : :
255 : : /* Get the Start of Packet(SOP) RQ index from a RTE RQ index */
256 : : static inline unsigned int enic_rte_rq_idx_to_sop_idx(unsigned int rte_idx)
257 : : {
258 : : return rte_idx;
259 : : }
260 : :
261 : : /* Get the Data RQ index from a RTE RQ index */
262 : : static inline unsigned int enic_rte_rq_idx_to_data_idx(unsigned int rte_idx,
263 : : struct enic *enic)
264 : : {
265 [ # # ]: 0 : return enic->rq_count + rte_idx;
266 : : }
267 : :
268 : : static inline unsigned int enic_vnic_rq_count(struct enic *enic)
269 : : {
270 [ # # # # : 0 : return enic->rq_count * 2;
# # ]
271 : : }
272 : :
273 : : static inline unsigned int enic_cq_rq(__rte_unused struct enic *enic, unsigned int rq)
274 : : {
275 : : return rq;
276 : : }
277 : :
278 : : static inline unsigned int enic_cq_wq(struct enic *enic, unsigned int wq)
279 : : {
280 : 0 : return enic->rq_count + wq;
281 : : }
282 : :
283 : : /*
284 : : * WQ, RQ, CQ allocation scheme. Firmware gives the driver an array of
285 : : * WQs, an array of RQs, and an array of CQs. Fow now, these are
286 : : * statically allocated between PF app send/receive queues and VF
287 : : * representor app send/receive queues. VF representor supports only 1
288 : : * send and 1 receive queue. The number of PF app queue is not known
289 : : * until the queue setup time.
290 : : *
291 : : * R = number of receive queues for PF app
292 : : * S = number of send queues for PF app
293 : : * V = number of VF representors
294 : : *
295 : : * wI = WQ for PF app send queue I
296 : : * rI = SOP RQ for PF app receive queue I
297 : : * dI = Data RQ for rI
298 : : * cwI = CQ for wI
299 : : * crI = CQ for rI
300 : : * vwI = WQ for VF representor send queue I
301 : : * vrI = SOP RQ for VF representor receive queue I
302 : : * vdI = Data RQ for vrI
303 : : * vcwI = CQ for vwI
304 : : * vcrI = CQ for vrI
305 : : *
306 : : * WQ array: | w0 |..| wS-1 |..| vwV-1 |..| vw0 |
307 : : * ^ ^ ^ ^
308 : : * index 0 S-1 W-V W-1 W=len(WQ array)
309 : : *
310 : : * RQ array: | r0 |..| rR-1 |d0 |..|dR-1| ..|vdV-1 |..| vd0 |vrV-1 |..|vr0 |
311 : : * ^ ^ ^ ^ ^ ^ ^ ^
312 : : * index 0 R-1 R 2R-1 X-2V X-(V+1) X-V X-1
313 : : * X=len(RQ array)
314 : : *
315 : : * CQ array: | cr0 |..| crR-1 |cw0|..|cwS-1|..|vcwV-1|..| vcw0|vcrV-1|..|vcr0|..
316 : : * ^ ^ ^ ^ ^ ^ ^ ^
317 : : * index 0 R-1 R R+S-1 X-2V X-(V+1) X-V X-1
318 : : * X is not a typo. It really is len(RQ array) to accommodate enic_cq_rq() used
319 : : * throughout RX handlers. The current scheme requires
320 : : * len(CQ array) >= len(RQ array).
321 : : */
322 : :
323 : : static inline unsigned int vf_wq_cq_idx(struct enic_vf_representor *vf)
324 : : {
325 : : /* rq is not a typo. index(vcwI) coincides with index(vdI) */
326 : 0 : return vf->pf->conf_rq_count - (vf->pf->max_vf_id + vf->vf_id + 2);
327 : : }
328 : :
329 : : static inline unsigned int vf_wq_idx(struct enic_vf_representor *vf)
330 : : {
331 : 0 : return vf->pf->conf_wq_count - vf->vf_id - 1;
332 : : }
333 : :
334 : : static inline unsigned int vf_rq_sop_idx(struct enic_vf_representor *vf)
335 : : {
336 : 0 : return vf->pf->conf_rq_count - vf->vf_id - 1;
337 : : }
338 : :
339 : : static inline unsigned int vf_rq_data_idx(struct enic_vf_representor *vf)
340 : : {
341 : : return vf->pf->conf_rq_count - (vf->pf->max_vf_id + vf->vf_id + 2);
342 : : }
343 : :
344 : : static inline struct enic *pmd_priv(struct rte_eth_dev *eth_dev)
345 : : {
346 [ # # # # : 0 : return eth_dev->data->dev_private;
# # ]
347 : : }
348 : :
349 : : static inline uint32_t
350 : : enic_ring_add(uint32_t n_descriptors, uint32_t i0, uint32_t i1)
351 : : {
352 : 0 : uint32_t d = i0 + i1;
353 [ # # # # : 0 : d -= (d >= n_descriptors) ? n_descriptors : 0;
# # ]
354 : : return d;
355 : : }
356 : :
357 : : static inline uint32_t
358 : : enic_ring_sub(uint32_t n_descriptors, uint32_t i0, uint32_t i1)
359 : : {
360 : 0 : int32_t d = i1 - i0;
361 [ # # ]: 0 : return (uint32_t)((d < 0) ? ((int32_t)n_descriptors + d) : d);
362 : : }
363 : :
364 : : static inline uint32_t
365 : : enic_ring_incr(uint32_t n_descriptors, uint32_t idx)
366 : : {
367 : 0 : idx++;
368 [ # # # # : 0 : if (unlikely(idx == n_descriptors))
# # # # ]
369 : : idx = 0;
370 : : return idx;
371 : : }
372 : :
373 : : int dev_is_enic(struct rte_eth_dev *dev);
374 : : void enic_free_wq(void *txq);
375 : : int enic_alloc_intr_resources(struct enic *enic);
376 : : int enic_setup_finish(struct enic *enic);
377 : : int enic_alloc_wq(struct enic *enic, uint16_t queue_idx,
378 : : unsigned int socket_id, uint16_t nb_desc);
379 : : void enic_start_wq(struct enic *enic, uint16_t queue_idx);
380 : : int enic_stop_wq(struct enic *enic, uint16_t queue_idx);
381 : : void enic_start_rq(struct enic *enic, uint16_t queue_idx);
382 : : int enic_stop_rq(struct enic *enic, uint16_t queue_idx);
383 : : void enic_free_rq(void *rxq);
384 : : int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
385 : : unsigned int socket_id, struct rte_mempool *mp,
386 : : uint16_t nb_desc, uint16_t free_thresh);
387 : : int enic_set_vnic_res(struct enic *enic);
388 : : int enic_init_rss_nic_cfg(struct enic *enic);
389 : : int enic_set_rss_conf(struct enic *enic,
390 : : struct rte_eth_rss_conf *rss_conf);
391 : : int enic_set_rss_reta(struct enic *enic, union vnic_rss_cpu *rss_cpu);
392 : : int enic_set_vlan_strip(struct enic *enic);
393 : : int enic_enable(struct enic *enic);
394 : : int enic_disable(struct enic *enic);
395 : : void enic_remove(struct enic *enic);
396 : : int enic_get_link_status(struct enic *enic);
397 : : int enic_dev_stats_get(struct enic *enic,
398 : : struct rte_eth_stats *r_stats);
399 : : int enic_dev_stats_clear(struct enic *enic);
400 : : int enic_add_packet_filter(struct enic *enic);
401 : : int enic_set_mac_address(struct enic *enic, uint8_t *mac_addr);
402 : : int enic_del_mac_address(struct enic *enic, int mac_index);
403 : : unsigned int enic_cleanup_wq(struct enic *enic, struct vnic_wq *wq);
404 : : void enic_send_pkt(struct enic *enic, struct vnic_wq *wq,
405 : : struct rte_mbuf *tx_pkt, unsigned short len,
406 : : uint8_t sop, uint8_t eop, uint8_t cq_entry,
407 : : uint16_t ol_flags, uint16_t vlan_tag);
408 : :
409 : : void enic_post_wq_index(struct vnic_wq *wq);
410 : : int enic_probe(struct enic *enic);
411 : : int enic_fm_init(struct enic *enic);
412 : : void enic_fm_destroy(struct enic *enic);
413 : : void *enic_alloc_consistent(void *priv, size_t size, dma_addr_t *dma_handle,
414 : : uint8_t *name);
415 : : void enic_free_consistent(void *priv, size_t size, void *vaddr,
416 : : dma_addr_t dma_handle);
417 : : uint16_t enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
418 : : uint16_t nb_pkts);
419 : : uint16_t enic_recv_pkts_64(void *rx_queue, struct rte_mbuf **rx_pkts,
420 : : uint16_t nb_pkts);
421 : : uint16_t enic_noscatter_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
422 : : uint16_t nb_pkts);
423 : : uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
424 : : uint16_t nb_pkts);
425 : : uint16_t enic_simple_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
426 : : uint16_t nb_pkts);
427 : : uint16_t enic_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
428 : : uint16_t nb_pkts);
429 : : int enic_set_mtu(struct enic *enic, uint16_t new_mtu);
430 : : int enic_link_update(struct rte_eth_dev *eth_dev);
431 : : bool enic_use_vector_rx_handler(struct rte_eth_dev *eth_dev);
432 : : void enic_pick_rx_handler(struct rte_eth_dev *eth_dev);
433 : : void enic_pick_tx_handler(struct rte_eth_dev *eth_dev);
434 : : int enic_vf_representor_init(struct rte_eth_dev *eth_dev, void *init_params);
435 : : int enic_vf_representor_uninit(struct rte_eth_dev *ethdev);
436 : : int enic_fm_allocate_switch_domain(struct enic *pf);
437 : : int enic_fm_add_rep2vf_flow(struct enic_vf_representor *vf);
438 : : int enic_fm_add_vf2rep_flow(struct enic_vf_representor *vf);
439 : : int enic_alloc_rx_queue_mbufs(struct enic *enic, struct vnic_rq *rq);
440 : : void enic_rxmbuf_queue_release(struct enic *enic, struct vnic_rq *rq);
441 : : void enic_free_wq_buf(struct rte_mbuf **buf);
442 : : void enic_free_rq_buf(struct rte_mbuf **mbuf);
443 : : extern const struct rte_flow_ops enic_flow_ops;
444 : : extern const struct rte_flow_ops enic_fm_flow_ops;
445 : :
446 : : #endif /* _ENIC_H_ */
|