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 : : static inline int enic_is_vf_rep(struct enic *enic)
237 : : {
238 [ # # # # : 0 : return !!(enic->rte_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR);
# # # # #
# # # ]
239 : : }
240 : :
241 : : /* Compute ethdev's max packet size from MTU */
242 : : static inline uint32_t enic_mtu_to_max_rx_pktlen(uint32_t mtu)
243 : : {
244 : : /* ethdev max size includes eth whereas NIC MTU does not */
245 [ # # # # ]: 0 : return mtu + RTE_ETHER_HDR_LEN;
246 : : }
247 : :
248 : : /* Get the CQ index from a Start of Packet(SOP) RQ index */
249 : : static inline unsigned int enic_sop_rq_idx_to_cq_idx(unsigned int sop_idx)
250 : : {
251 : : return sop_idx;
252 : : }
253 : :
254 : : /* Get the RTE RQ index from a Start of Packet(SOP) RQ index */
255 : : static inline unsigned int enic_sop_rq_idx_to_rte_idx(unsigned int sop_idx)
256 : : {
257 : : return sop_idx;
258 : : }
259 : :
260 : : /* Get the Start of Packet(SOP) RQ index from a RTE RQ index */
261 : : static inline unsigned int enic_rte_rq_idx_to_sop_idx(unsigned int rte_idx)
262 : : {
263 : : return rte_idx;
264 : : }
265 : :
266 : : /* Get the Data RQ index from a RTE RQ index */
267 : : static inline unsigned int enic_rte_rq_idx_to_data_idx(unsigned int rte_idx,
268 : : struct enic *enic)
269 : : {
270 [ # # ]: 0 : return enic->rq_count + rte_idx;
271 : : }
272 : :
273 : : static inline unsigned int enic_vnic_rq_count(struct enic *enic)
274 : : {
275 [ # # # # : 0 : return enic->rq_count * 2;
# # ]
276 : : }
277 : :
278 : : static inline unsigned int enic_cq_rq(__rte_unused struct enic *enic, unsigned int rq)
279 : : {
280 : : return rq;
281 : : }
282 : :
283 : : static inline unsigned int enic_cq_wq(struct enic *enic, unsigned int wq)
284 : : {
285 : 0 : return enic->rq_count + wq;
286 : : }
287 : :
288 : : /*
289 : : * WQ, RQ, CQ allocation scheme. Firmware gives the driver an array of
290 : : * WQs, an array of RQs, and an array of CQs. Fow now, these are
291 : : * statically allocated between PF app send/receive queues and VF
292 : : * representor app send/receive queues. VF representor supports only 1
293 : : * send and 1 receive queue. The number of PF app queue is not known
294 : : * until the queue setup time.
295 : : *
296 : : * R = number of receive queues for PF app
297 : : * S = number of send queues for PF app
298 : : * V = number of VF representors
299 : : *
300 : : * wI = WQ for PF app send queue I
301 : : * rI = SOP RQ for PF app receive queue I
302 : : * dI = Data RQ for rI
303 : : * cwI = CQ for wI
304 : : * crI = CQ for rI
305 : : * vwI = WQ for VF representor send queue I
306 : : * vrI = SOP RQ for VF representor receive queue I
307 : : * vdI = Data RQ for vrI
308 : : * vcwI = CQ for vwI
309 : : * vcrI = CQ for vrI
310 : : *
311 : : * WQ array: | w0 |..| wS-1 |..| vwV-1 |..| vw0 |
312 : : * ^ ^ ^ ^
313 : : * index 0 S-1 W-V W-1 W=len(WQ array)
314 : : *
315 : : * RQ array: | r0 |..| rR-1 |d0 |..|dR-1| ..|vdV-1 |..| vd0 |vrV-1 |..|vr0 |
316 : : * ^ ^ ^ ^ ^ ^ ^ ^
317 : : * index 0 R-1 R 2R-1 X-2V X-(V+1) X-V X-1
318 : : * X=len(RQ array)
319 : : *
320 : : * CQ array: | cr0 |..| crR-1 |cw0|..|cwS-1|..|vcwV-1|..| vcw0|vcrV-1|..|vcr0|..
321 : : * ^ ^ ^ ^ ^ ^ ^ ^
322 : : * index 0 R-1 R R+S-1 X-2V X-(V+1) X-V X-1
323 : : * X is not a typo. It really is len(RQ array) to accommodate enic_cq_rq() used
324 : : * throughout RX handlers. The current scheme requires
325 : : * len(CQ array) >= len(RQ array).
326 : : */
327 : :
328 : : static inline unsigned int vf_wq_cq_idx(struct enic_vf_representor *vf)
329 : : {
330 : : /* rq is not a typo. index(vcwI) coincides with index(vdI) */
331 : 0 : return vf->pf->conf_rq_count - (vf->pf->max_vf_id + vf->vf_id + 2);
332 : : }
333 : :
334 : : static inline unsigned int vf_wq_idx(struct enic_vf_representor *vf)
335 : : {
336 : 0 : return vf->pf->conf_wq_count - vf->vf_id - 1;
337 : : }
338 : :
339 : : static inline unsigned int vf_rq_sop_idx(struct enic_vf_representor *vf)
340 : : {
341 : 0 : return vf->pf->conf_rq_count - vf->vf_id - 1;
342 : : }
343 : :
344 : : static inline unsigned int vf_rq_data_idx(struct enic_vf_representor *vf)
345 : : {
346 : : return vf->pf->conf_rq_count - (vf->pf->max_vf_id + vf->vf_id + 2);
347 : : }
348 : :
349 : : static inline struct enic *pmd_priv(struct rte_eth_dev *eth_dev)
350 : : {
351 [ # # # # : 0 : return eth_dev->data->dev_private;
# # ]
352 : : }
353 : :
354 : : static inline uint32_t
355 : : enic_ring_add(uint32_t n_descriptors, uint32_t i0, uint32_t i1)
356 : : {
357 : 0 : uint32_t d = i0 + i1;
358 [ # # # # : 0 : d -= (d >= n_descriptors) ? n_descriptors : 0;
# # ]
359 : : return d;
360 : : }
361 : :
362 : : static inline uint32_t
363 : : enic_ring_sub(uint32_t n_descriptors, uint32_t i0, uint32_t i1)
364 : : {
365 : 0 : int32_t d = i1 - i0;
366 [ # # ]: 0 : return (uint32_t)((d < 0) ? ((int32_t)n_descriptors + d) : d);
367 : : }
368 : :
369 : : static inline uint32_t
370 : : enic_ring_incr(uint32_t n_descriptors, uint32_t idx)
371 : : {
372 : 0 : idx++;
373 [ # # # # : 0 : if (unlikely(idx == n_descriptors))
# # # # ]
374 : : idx = 0;
375 : : return idx;
376 : : }
377 : :
378 : : int dev_is_enic(struct rte_eth_dev *dev);
379 : : void enic_free_wq(void *txq);
380 : : int enic_alloc_intr_resources(struct enic *enic);
381 : : int enic_setup_finish(struct enic *enic);
382 : : int enic_alloc_wq(struct enic *enic, uint16_t queue_idx,
383 : : unsigned int socket_id, uint16_t nb_desc);
384 : : void enic_start_wq(struct enic *enic, uint16_t queue_idx);
385 : : int enic_stop_wq(struct enic *enic, uint16_t queue_idx);
386 : : void enic_start_rq(struct enic *enic, uint16_t queue_idx);
387 : : int enic_stop_rq(struct enic *enic, uint16_t queue_idx);
388 : : void enic_free_rq(void *rxq);
389 : : int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
390 : : unsigned int socket_id, struct rte_mempool *mp,
391 : : uint16_t nb_desc, uint16_t free_thresh);
392 : : int enic_set_vnic_res(struct enic *enic);
393 : : int enic_init_rss_nic_cfg(struct enic *enic);
394 : : int enic_set_rss_conf(struct enic *enic,
395 : : struct rte_eth_rss_conf *rss_conf);
396 : : int enic_set_rss_reta(struct enic *enic, union vnic_rss_cpu *rss_cpu);
397 : : int enic_set_vlan_strip(struct enic *enic);
398 : : int enic_enable(struct enic *enic);
399 : : int enic_disable(struct enic *enic);
400 : : void enic_remove(struct enic *enic);
401 : : int enic_get_link_status(struct enic *enic);
402 : : int enic_dev_stats_get(struct enic *enic,
403 : : struct rte_eth_stats *r_stats);
404 : : int enic_dev_stats_clear(struct enic *enic);
405 : : int enic_add_packet_filter(struct enic *enic);
406 : : int enic_set_mac_address(struct enic *enic, uint8_t *mac_addr);
407 : : int enic_del_mac_address(struct enic *enic, int mac_index);
408 : : unsigned int enic_cleanup_wq(struct enic *enic, struct vnic_wq *wq);
409 : : void enic_send_pkt(struct enic *enic, struct vnic_wq *wq,
410 : : struct rte_mbuf *tx_pkt, unsigned short len,
411 : : uint8_t sop, uint8_t eop, uint8_t cq_entry,
412 : : uint16_t ol_flags, uint16_t vlan_tag);
413 : :
414 : : void enic_post_wq_index(struct vnic_wq *wq);
415 : : int enic_probe(struct enic *enic);
416 : : int enic_fm_init(struct enic *enic);
417 : : void enic_fm_destroy(struct enic *enic);
418 : : void *enic_alloc_consistent(void *priv, size_t size, dma_addr_t *dma_handle,
419 : : uint8_t *name);
420 : : void enic_free_consistent(void *priv, size_t size, void *vaddr,
421 : : dma_addr_t dma_handle);
422 : : uint16_t enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
423 : : uint16_t nb_pkts);
424 : : uint16_t enic_recv_pkts_64(void *rx_queue, struct rte_mbuf **rx_pkts,
425 : : uint16_t nb_pkts);
426 : : uint16_t enic_noscatter_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
427 : : uint16_t nb_pkts);
428 : : uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
429 : : uint16_t nb_pkts);
430 : : uint16_t enic_simple_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
431 : : uint16_t nb_pkts);
432 : : uint16_t enic_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
433 : : uint16_t nb_pkts);
434 : : int enic_set_mtu(struct enic *enic, uint16_t new_mtu);
435 : : int enic_link_update(struct rte_eth_dev *eth_dev);
436 : : bool enic_use_vector_rx_handler(struct rte_eth_dev *eth_dev);
437 : : void enic_pick_rx_handler(struct rte_eth_dev *eth_dev);
438 : : void enic_pick_tx_handler(struct rte_eth_dev *eth_dev);
439 : : int enic_vf_representor_init(struct rte_eth_dev *eth_dev, void *init_params);
440 : : int enic_vf_representor_uninit(struct rte_eth_dev *ethdev);
441 : : int enic_fm_allocate_switch_domain(struct enic *pf);
442 : : int enic_fm_add_rep2vf_flow(struct enic_vf_representor *vf);
443 : : int enic_fm_add_vf2rep_flow(struct enic_vf_representor *vf);
444 : : int enic_alloc_rx_queue_mbufs(struct enic *enic, struct vnic_rq *rq);
445 : : void enic_rxmbuf_queue_release(struct enic *enic, struct vnic_rq *rq);
446 : : void enic_free_wq_buf(struct rte_mbuf **buf);
447 : : void enic_free_rq_buf(struct rte_mbuf **mbuf);
448 : : extern const struct rte_flow_ops enic_flow_ops;
449 : : extern const struct rte_flow_ops enic_fm_flow_ops;
450 : :
451 : : #endif /* _ENIC_H_ */
|