7a67e168959212f37c6714fc59c382ff20271f76
[dpdk.git] / drivers / net / failsafe / failsafe_ops.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2017 6WIND S.A.
3  * Copyright 2017 Mellanox.
4  */
5
6 #include <stdbool.h>
7 #include <stdint.h>
8 #include <unistd.h>
9
10 #include <rte_debug.h>
11 #include <rte_atomic.h>
12 #include <rte_ethdev_driver.h>
13 #include <rte_malloc.h>
14 #include <rte_flow.h>
15 #include <rte_cycles.h>
16
17 #include "failsafe_private.h"
18
19 static struct rte_eth_dev_info default_infos = {
20         /* Max possible number of elements */
21         .max_rx_pktlen = UINT32_MAX,
22         .max_rx_queues = RTE_MAX_QUEUES_PER_PORT,
23         .max_tx_queues = RTE_MAX_QUEUES_PER_PORT,
24         .max_mac_addrs = FAILSAFE_MAX_ETHADDR,
25         .max_hash_mac_addrs = UINT32_MAX,
26         .max_vfs = UINT16_MAX,
27         .max_vmdq_pools = UINT16_MAX,
28         .rx_desc_lim = {
29                 .nb_max = UINT16_MAX,
30                 .nb_min = 0,
31                 .nb_align = 1,
32                 .nb_seg_max = UINT16_MAX,
33                 .nb_mtu_seg_max = UINT16_MAX,
34         },
35         .tx_desc_lim = {
36                 .nb_max = UINT16_MAX,
37                 .nb_min = 0,
38                 .nb_align = 1,
39                 .nb_seg_max = UINT16_MAX,
40                 .nb_mtu_seg_max = UINT16_MAX,
41         },
42         /*
43          * Set of capabilities that can be verified upon
44          * configuring a sub-device.
45          */
46         .rx_offload_capa =
47                 DEV_RX_OFFLOAD_VLAN_STRIP |
48                 DEV_RX_OFFLOAD_IPV4_CKSUM |
49                 DEV_RX_OFFLOAD_UDP_CKSUM |
50                 DEV_RX_OFFLOAD_TCP_CKSUM |
51                 DEV_RX_OFFLOAD_TCP_LRO |
52                 DEV_RX_OFFLOAD_QINQ_STRIP |
53                 DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
54                 DEV_RX_OFFLOAD_MACSEC_STRIP |
55                 DEV_RX_OFFLOAD_HEADER_SPLIT |
56                 DEV_RX_OFFLOAD_VLAN_FILTER |
57                 DEV_RX_OFFLOAD_VLAN_EXTEND |
58                 DEV_RX_OFFLOAD_JUMBO_FRAME |
59                 DEV_RX_OFFLOAD_CRC_STRIP |
60                 DEV_RX_OFFLOAD_SCATTER |
61                 DEV_RX_OFFLOAD_TIMESTAMP |
62                 DEV_RX_OFFLOAD_SECURITY,
63         .rx_queue_offload_capa =
64                 DEV_RX_OFFLOAD_VLAN_STRIP |
65                 DEV_RX_OFFLOAD_IPV4_CKSUM |
66                 DEV_RX_OFFLOAD_UDP_CKSUM |
67                 DEV_RX_OFFLOAD_TCP_CKSUM |
68                 DEV_RX_OFFLOAD_TCP_LRO |
69                 DEV_RX_OFFLOAD_QINQ_STRIP |
70                 DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
71                 DEV_RX_OFFLOAD_MACSEC_STRIP |
72                 DEV_RX_OFFLOAD_HEADER_SPLIT |
73                 DEV_RX_OFFLOAD_VLAN_FILTER |
74                 DEV_RX_OFFLOAD_VLAN_EXTEND |
75                 DEV_RX_OFFLOAD_JUMBO_FRAME |
76                 DEV_RX_OFFLOAD_CRC_STRIP |
77                 DEV_RX_OFFLOAD_SCATTER |
78                 DEV_RX_OFFLOAD_TIMESTAMP |
79                 DEV_RX_OFFLOAD_SECURITY,
80         .tx_offload_capa =
81                 DEV_TX_OFFLOAD_MULTI_SEGS |
82                 DEV_TX_OFFLOAD_IPV4_CKSUM |
83                 DEV_TX_OFFLOAD_UDP_CKSUM |
84                 DEV_TX_OFFLOAD_TCP_CKSUM,
85         .flow_type_rss_offloads = 0x0,
86 };
87
88 static int
89 fs_dev_configure(struct rte_eth_dev *dev)
90 {
91         struct sub_device *sdev;
92         uint64_t supp_tx_offloads;
93         uint64_t tx_offloads;
94         uint8_t i;
95         int ret;
96
97         supp_tx_offloads = PRIV(dev)->infos.tx_offload_capa;
98         tx_offloads = dev->data->dev_conf.txmode.offloads;
99         if ((tx_offloads & supp_tx_offloads) != tx_offloads) {
100                 rte_errno = ENOTSUP;
101                 ERROR("Some Tx offloads are not supported, "
102                       "requested 0x%" PRIx64 " supported 0x%" PRIx64,
103                       tx_offloads, supp_tx_offloads);
104                 return -rte_errno;
105         }
106         FOREACH_SUBDEV(sdev, i, dev) {
107                 int rmv_interrupt = 0;
108                 int lsc_interrupt = 0;
109                 int lsc_enabled;
110
111                 if (sdev->state != DEV_PROBED)
112                         continue;
113
114                 rmv_interrupt = ETH(sdev)->data->dev_flags &
115                                 RTE_ETH_DEV_INTR_RMV;
116                 if (rmv_interrupt) {
117                         DEBUG("Enabling RMV interrupts for sub_device %d", i);
118                         dev->data->dev_conf.intr_conf.rmv = 1;
119                 } else {
120                         DEBUG("sub_device %d does not support RMV event", i);
121                 }
122                 lsc_enabled = dev->data->dev_conf.intr_conf.lsc;
123                 lsc_interrupt = lsc_enabled &&
124                                 (ETH(sdev)->data->dev_flags &
125                                  RTE_ETH_DEV_INTR_LSC);
126                 if (lsc_interrupt) {
127                         DEBUG("Enabling LSC interrupts for sub_device %d", i);
128                         dev->data->dev_conf.intr_conf.lsc = 1;
129                 } else if (lsc_enabled && !lsc_interrupt) {
130                         DEBUG("Disabling LSC interrupts for sub_device %d", i);
131                         dev->data->dev_conf.intr_conf.lsc = 0;
132                 }
133                 DEBUG("Configuring sub-device %d", i);
134                 sdev->remove = 0;
135                 ret = rte_eth_dev_configure(PORT_ID(sdev),
136                                         dev->data->nb_rx_queues,
137                                         dev->data->nb_tx_queues,
138                                         &dev->data->dev_conf);
139                 if (ret) {
140                         if (!fs_err(sdev, ret))
141                                 continue;
142                         ERROR("Could not configure sub_device %d", i);
143                         return ret;
144                 }
145                 if (rmv_interrupt) {
146                         ret = rte_eth_dev_callback_register(PORT_ID(sdev),
147                                         RTE_ETH_EVENT_INTR_RMV,
148                                         failsafe_eth_rmv_event_callback,
149                                         sdev);
150                         if (ret)
151                                 WARN("Failed to register RMV callback for sub_device %d",
152                                      SUB_ID(sdev));
153                 }
154                 dev->data->dev_conf.intr_conf.rmv = 0;
155                 if (lsc_interrupt) {
156                         ret = rte_eth_dev_callback_register(PORT_ID(sdev),
157                                                 RTE_ETH_EVENT_INTR_LSC,
158                                                 failsafe_eth_lsc_event_callback,
159                                                 dev);
160                         if (ret)
161                                 WARN("Failed to register LSC callback for sub_device %d",
162                                      SUB_ID(sdev));
163                 }
164                 dev->data->dev_conf.intr_conf.lsc = lsc_enabled;
165                 sdev->state = DEV_ACTIVE;
166         }
167         if (PRIV(dev)->state < DEV_ACTIVE)
168                 PRIV(dev)->state = DEV_ACTIVE;
169         return 0;
170 }
171
172 static int
173 fs_dev_start(struct rte_eth_dev *dev)
174 {
175         struct sub_device *sdev;
176         uint8_t i;
177         int ret;
178
179         ret = failsafe_rx_intr_install(dev);
180         if (ret)
181                 return ret;
182         FOREACH_SUBDEV(sdev, i, dev) {
183                 if (sdev->state != DEV_ACTIVE)
184                         continue;
185                 DEBUG("Starting sub_device %d", i);
186                 ret = rte_eth_dev_start(PORT_ID(sdev));
187                 if (ret) {
188                         if (!fs_err(sdev, ret))
189                                 continue;
190                         return ret;
191                 }
192                 ret = failsafe_rx_intr_install_subdevice(sdev);
193                 if (ret) {
194                         if (!fs_err(sdev, ret))
195                                 continue;
196                         rte_eth_dev_stop(PORT_ID(sdev));
197                         return ret;
198                 }
199                 sdev->state = DEV_STARTED;
200         }
201         if (PRIV(dev)->state < DEV_STARTED)
202                 PRIV(dev)->state = DEV_STARTED;
203         fs_switch_dev(dev, NULL);
204         return 0;
205 }
206
207 static void
208 fs_dev_stop(struct rte_eth_dev *dev)
209 {
210         struct sub_device *sdev;
211         uint8_t i;
212
213         PRIV(dev)->state = DEV_STARTED - 1;
214         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_STARTED) {
215                 rte_eth_dev_stop(PORT_ID(sdev));
216                 failsafe_rx_intr_uninstall_subdevice(sdev);
217                 sdev->state = DEV_STARTED - 1;
218         }
219         failsafe_rx_intr_uninstall(dev);
220 }
221
222 static int
223 fs_dev_set_link_up(struct rte_eth_dev *dev)
224 {
225         struct sub_device *sdev;
226         uint8_t i;
227         int ret;
228
229         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
230                 DEBUG("Calling rte_eth_dev_set_link_up on sub_device %d", i);
231                 ret = rte_eth_dev_set_link_up(PORT_ID(sdev));
232                 if ((ret = fs_err(sdev, ret))) {
233                         ERROR("Operation rte_eth_dev_set_link_up failed for sub_device %d"
234                               " with error %d", i, ret);
235                         return ret;
236                 }
237         }
238         return 0;
239 }
240
241 static int
242 fs_dev_set_link_down(struct rte_eth_dev *dev)
243 {
244         struct sub_device *sdev;
245         uint8_t i;
246         int ret;
247
248         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
249                 DEBUG("Calling rte_eth_dev_set_link_down on sub_device %d", i);
250                 ret = rte_eth_dev_set_link_down(PORT_ID(sdev));
251                 if ((ret = fs_err(sdev, ret))) {
252                         ERROR("Operation rte_eth_dev_set_link_down failed for sub_device %d"
253                               " with error %d", i, ret);
254                         return ret;
255                 }
256         }
257         return 0;
258 }
259
260 static void fs_dev_free_queues(struct rte_eth_dev *dev);
261 static void
262 fs_dev_close(struct rte_eth_dev *dev)
263 {
264         struct sub_device *sdev;
265         uint8_t i;
266
267         failsafe_hotplug_alarm_cancel(dev);
268         if (PRIV(dev)->state == DEV_STARTED)
269                 dev->dev_ops->dev_stop(dev);
270         PRIV(dev)->state = DEV_ACTIVE - 1;
271         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
272                 DEBUG("Closing sub_device %d", i);
273                 rte_eth_dev_close(PORT_ID(sdev));
274                 sdev->state = DEV_ACTIVE - 1;
275         }
276         fs_dev_free_queues(dev);
277 }
278
279 static bool
280 fs_rxq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
281 {
282         uint64_t port_offloads;
283         uint64_t queue_supp_offloads;
284         uint64_t port_supp_offloads;
285
286         port_offloads = dev->data->dev_conf.rxmode.offloads;
287         queue_supp_offloads = PRIV(dev)->infos.rx_queue_offload_capa;
288         port_supp_offloads = PRIV(dev)->infos.rx_offload_capa;
289         if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
290              offloads)
291                 return false;
292         /* Verify we have no conflict with port offloads */
293         if ((port_offloads ^ offloads) & port_supp_offloads)
294                 return false;
295         return true;
296 }
297
298 static void
299 fs_rx_queue_release(void *queue)
300 {
301         struct rte_eth_dev *dev;
302         struct sub_device *sdev;
303         uint8_t i;
304         struct rxq *rxq;
305
306         if (queue == NULL)
307                 return;
308         rxq = queue;
309         if (rxq->event_fd > 0)
310                 close(rxq->event_fd);
311         dev = rxq->priv->dev;
312         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
313                 SUBOPS(sdev, rx_queue_release)
314                         (ETH(sdev)->data->rx_queues[rxq->qid]);
315         dev->data->rx_queues[rxq->qid] = NULL;
316         rte_free(rxq);
317 }
318
319 static int
320 fs_rx_queue_setup(struct rte_eth_dev *dev,
321                 uint16_t rx_queue_id,
322                 uint16_t nb_rx_desc,
323                 unsigned int socket_id,
324                 const struct rte_eth_rxconf *rx_conf,
325                 struct rte_mempool *mb_pool)
326 {
327         /*
328          * FIXME: Add a proper interface in rte_eal_interrupts for
329          * allocating eventfd as an interrupt vector.
330          * For the time being, fake as if we are using MSIX interrupts,
331          * this will cause rte_intr_efd_enable to allocate an eventfd for us.
332          */
333         struct rte_intr_handle intr_handle = {
334                 .type = RTE_INTR_HANDLE_VFIO_MSIX,
335                 .efds = { -1, },
336         };
337         struct sub_device *sdev;
338         struct rxq *rxq;
339         uint8_t i;
340         int ret;
341
342         rxq = dev->data->rx_queues[rx_queue_id];
343         if (rxq != NULL) {
344                 fs_rx_queue_release(rxq);
345                 dev->data->rx_queues[rx_queue_id] = NULL;
346         }
347         /* Verify application offloads are valid for our port and queue. */
348         if (fs_rxq_offloads_valid(dev, rx_conf->offloads) == false) {
349                 rte_errno = ENOTSUP;
350                 ERROR("Rx queue offloads 0x%" PRIx64
351                       " don't match port offloads 0x%" PRIx64
352                       " or supported offloads 0x%" PRIx64,
353                       rx_conf->offloads,
354                       dev->data->dev_conf.rxmode.offloads,
355                       PRIV(dev)->infos.rx_offload_capa |
356                       PRIV(dev)->infos.rx_queue_offload_capa);
357                 return -rte_errno;
358         }
359         rxq = rte_zmalloc(NULL,
360                           sizeof(*rxq) +
361                           sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
362                           RTE_CACHE_LINE_SIZE);
363         if (rxq == NULL)
364                 return -ENOMEM;
365         FOREACH_SUBDEV(sdev, i, dev)
366                 rte_atomic64_init(&rxq->refcnt[i]);
367         rxq->qid = rx_queue_id;
368         rxq->socket_id = socket_id;
369         rxq->info.mp = mb_pool;
370         rxq->info.conf = *rx_conf;
371         rxq->info.nb_desc = nb_rx_desc;
372         rxq->priv = PRIV(dev);
373         rxq->sdev = PRIV(dev)->subs;
374         ret = rte_intr_efd_enable(&intr_handle, 1);
375         if (ret < 0)
376                 return ret;
377         rxq->event_fd = intr_handle.efds[0];
378         dev->data->rx_queues[rx_queue_id] = rxq;
379         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
380                 ret = rte_eth_rx_queue_setup(PORT_ID(sdev),
381                                 rx_queue_id,
382                                 nb_rx_desc, socket_id,
383                                 rx_conf, mb_pool);
384                 if ((ret = fs_err(sdev, ret))) {
385                         ERROR("RX queue setup failed for sub_device %d", i);
386                         goto free_rxq;
387                 }
388         }
389         return 0;
390 free_rxq:
391         fs_rx_queue_release(rxq);
392         return ret;
393 }
394
395 static int
396 fs_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx)
397 {
398         struct rxq *rxq;
399         struct sub_device *sdev;
400         uint8_t i;
401         int ret;
402         int rc = 0;
403
404         if (idx >= dev->data->nb_rx_queues) {
405                 rte_errno = EINVAL;
406                 return -rte_errno;
407         }
408         rxq = dev->data->rx_queues[idx];
409         if (rxq == NULL || rxq->event_fd <= 0) {
410                 rte_errno = EINVAL;
411                 return -rte_errno;
412         }
413         /* Fail if proxy service is nor running. */
414         if (PRIV(dev)->rxp.sstate != SS_RUNNING) {
415                 ERROR("failsafe interrupt services are not running");
416                 rte_errno = EAGAIN;
417                 return -rte_errno;
418         }
419         rxq->enable_events = 1;
420         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
421                 ret = rte_eth_dev_rx_intr_enable(PORT_ID(sdev), idx);
422                 ret = fs_err(sdev, ret);
423                 if (ret)
424                         rc = ret;
425         }
426         if (rc)
427                 rte_errno = -rc;
428         return rc;
429 }
430
431 static int
432 fs_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
433 {
434         struct rxq *rxq;
435         struct sub_device *sdev;
436         uint64_t u64;
437         uint8_t i;
438         int rc = 0;
439         int ret;
440
441         if (idx >= dev->data->nb_rx_queues) {
442                 rte_errno = EINVAL;
443                 return -rte_errno;
444         }
445         rxq = dev->data->rx_queues[idx];
446         if (rxq == NULL || rxq->event_fd <= 0) {
447                 rte_errno = EINVAL;
448                 return -rte_errno;
449         }
450         rxq->enable_events = 0;
451         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
452                 ret = rte_eth_dev_rx_intr_disable(PORT_ID(sdev), idx);
453                 ret = fs_err(sdev, ret);
454                 if (ret)
455                         rc = ret;
456         }
457         /* Clear pending events */
458         while (read(rxq->event_fd, &u64, sizeof(uint64_t)) >  0)
459                 ;
460         if (rc)
461                 rte_errno = -rc;
462         return rc;
463 }
464
465 static bool
466 fs_txq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads)
467 {
468         uint64_t port_offloads;
469         uint64_t queue_supp_offloads;
470         uint64_t port_supp_offloads;
471
472         port_offloads = dev->data->dev_conf.txmode.offloads;
473         queue_supp_offloads = PRIV(dev)->infos.tx_queue_offload_capa;
474         port_supp_offloads = PRIV(dev)->infos.tx_offload_capa;
475         if ((offloads & (queue_supp_offloads | port_supp_offloads)) !=
476              offloads)
477                 return false;
478         /* Verify we have no conflict with port offloads */
479         if ((port_offloads ^ offloads) & port_supp_offloads)
480                 return false;
481         return true;
482 }
483
484 static void
485 fs_tx_queue_release(void *queue)
486 {
487         struct rte_eth_dev *dev;
488         struct sub_device *sdev;
489         uint8_t i;
490         struct txq *txq;
491
492         if (queue == NULL)
493                 return;
494         txq = queue;
495         dev = txq->priv->dev;
496         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
497                 SUBOPS(sdev, tx_queue_release)
498                         (ETH(sdev)->data->tx_queues[txq->qid]);
499         dev->data->tx_queues[txq->qid] = NULL;
500         rte_free(txq);
501 }
502
503 static int
504 fs_tx_queue_setup(struct rte_eth_dev *dev,
505                 uint16_t tx_queue_id,
506                 uint16_t nb_tx_desc,
507                 unsigned int socket_id,
508                 const struct rte_eth_txconf *tx_conf)
509 {
510         struct sub_device *sdev;
511         struct txq *txq;
512         uint8_t i;
513         int ret;
514
515         txq = dev->data->tx_queues[tx_queue_id];
516         if (txq != NULL) {
517                 fs_tx_queue_release(txq);
518                 dev->data->tx_queues[tx_queue_id] = NULL;
519         }
520         /*
521          * Don't verify queue offloads for applications which
522          * use the old API.
523          */
524         if (tx_conf != NULL &&
525             (tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) &&
526             fs_txq_offloads_valid(dev, tx_conf->offloads) == false) {
527                 rte_errno = ENOTSUP;
528                 ERROR("Tx queue offloads 0x%" PRIx64
529                       " don't match port offloads 0x%" PRIx64
530                       " or supported offloads 0x%" PRIx64,
531                       tx_conf->offloads,
532                       dev->data->dev_conf.txmode.offloads,
533                       PRIV(dev)->infos.tx_offload_capa |
534                       PRIV(dev)->infos.tx_queue_offload_capa);
535                 return -rte_errno;
536         }
537         txq = rte_zmalloc("ethdev TX queue",
538                           sizeof(*txq) +
539                           sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
540                           RTE_CACHE_LINE_SIZE);
541         if (txq == NULL)
542                 return -ENOMEM;
543         FOREACH_SUBDEV(sdev, i, dev)
544                 rte_atomic64_init(&txq->refcnt[i]);
545         txq->qid = tx_queue_id;
546         txq->socket_id = socket_id;
547         txq->info.conf = *tx_conf;
548         txq->info.nb_desc = nb_tx_desc;
549         txq->priv = PRIV(dev);
550         dev->data->tx_queues[tx_queue_id] = txq;
551         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
552                 ret = rte_eth_tx_queue_setup(PORT_ID(sdev),
553                                 tx_queue_id,
554                                 nb_tx_desc, socket_id,
555                                 tx_conf);
556                 if ((ret = fs_err(sdev, ret))) {
557                         ERROR("TX queue setup failed for sub_device %d", i);
558                         goto free_txq;
559                 }
560         }
561         return 0;
562 free_txq:
563         fs_tx_queue_release(txq);
564         return ret;
565 }
566
567 static void
568 fs_dev_free_queues(struct rte_eth_dev *dev)
569 {
570         uint16_t i;
571
572         for (i = 0; i < dev->data->nb_rx_queues; i++) {
573                 fs_rx_queue_release(dev->data->rx_queues[i]);
574                 dev->data->rx_queues[i] = NULL;
575         }
576         dev->data->nb_rx_queues = 0;
577         for (i = 0; i < dev->data->nb_tx_queues; i++) {
578                 fs_tx_queue_release(dev->data->tx_queues[i]);
579                 dev->data->tx_queues[i] = NULL;
580         }
581         dev->data->nb_tx_queues = 0;
582 }
583
584 static void
585 fs_promiscuous_enable(struct rte_eth_dev *dev)
586 {
587         struct sub_device *sdev;
588         uint8_t i;
589
590         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
591                 rte_eth_promiscuous_enable(PORT_ID(sdev));
592 }
593
594 static void
595 fs_promiscuous_disable(struct rte_eth_dev *dev)
596 {
597         struct sub_device *sdev;
598         uint8_t i;
599
600         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
601                 rte_eth_promiscuous_disable(PORT_ID(sdev));
602 }
603
604 static void
605 fs_allmulticast_enable(struct rte_eth_dev *dev)
606 {
607         struct sub_device *sdev;
608         uint8_t i;
609
610         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
611                 rte_eth_allmulticast_enable(PORT_ID(sdev));
612 }
613
614 static void
615 fs_allmulticast_disable(struct rte_eth_dev *dev)
616 {
617         struct sub_device *sdev;
618         uint8_t i;
619
620         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
621                 rte_eth_allmulticast_disable(PORT_ID(sdev));
622 }
623
624 static int
625 fs_link_update(struct rte_eth_dev *dev,
626                 int wait_to_complete)
627 {
628         struct sub_device *sdev;
629         uint8_t i;
630         int ret;
631
632         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
633                 DEBUG("Calling link_update on sub_device %d", i);
634                 ret = (SUBOPS(sdev, link_update))(ETH(sdev), wait_to_complete);
635                 if (ret && ret != -1 && sdev->remove == 0 &&
636                     rte_eth_dev_is_removed(PORT_ID(sdev)) == 0) {
637                         ERROR("Link update failed for sub_device %d with error %d",
638                               i, ret);
639                         return ret;
640                 }
641         }
642         if (TX_SUBDEV(dev)) {
643                 struct rte_eth_link *l1;
644                 struct rte_eth_link *l2;
645
646                 l1 = &dev->data->dev_link;
647                 l2 = &ETH(TX_SUBDEV(dev))->data->dev_link;
648                 if (memcmp(l1, l2, sizeof(*l1))) {
649                         *l1 = *l2;
650                         return 0;
651                 }
652         }
653         return -1;
654 }
655
656 static int
657 fs_stats_get(struct rte_eth_dev *dev,
658              struct rte_eth_stats *stats)
659 {
660         struct rte_eth_stats backup;
661         struct sub_device *sdev;
662         uint8_t i;
663         int ret;
664
665         rte_memcpy(stats, &PRIV(dev)->stats_accumulator, sizeof(*stats));
666         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
667                 struct rte_eth_stats *snapshot = &sdev->stats_snapshot.stats;
668                 uint64_t *timestamp = &sdev->stats_snapshot.timestamp;
669
670                 rte_memcpy(&backup, snapshot, sizeof(backup));
671                 ret = rte_eth_stats_get(PORT_ID(sdev), snapshot);
672                 if (ret) {
673                         if (!fs_err(sdev, ret)) {
674                                 rte_memcpy(snapshot, &backup, sizeof(backup));
675                                 goto inc;
676                         }
677                         ERROR("Operation rte_eth_stats_get failed for sub_device %d with error %d",
678                                   i, ret);
679                         *timestamp = 0;
680                         return ret;
681                 }
682                 *timestamp = rte_rdtsc();
683 inc:
684                 failsafe_stats_increment(stats, snapshot);
685         }
686         return 0;
687 }
688
689 static void
690 fs_stats_reset(struct rte_eth_dev *dev)
691 {
692         struct sub_device *sdev;
693         uint8_t i;
694
695         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
696                 rte_eth_stats_reset(PORT_ID(sdev));
697                 memset(&sdev->stats_snapshot, 0, sizeof(struct rte_eth_stats));
698         }
699         memset(&PRIV(dev)->stats_accumulator, 0, sizeof(struct rte_eth_stats));
700 }
701
702 /**
703  * Fail-safe dev_infos_get rules:
704  *
705  * No sub_device:
706  *   Numerables:
707  *      Use the maximum possible values for any field, so as not
708  *      to impede any further configuration effort.
709  *   Capabilities:
710  *      Limits capabilities to those that are understood by the
711  *      fail-safe PMD. This understanding stems from the fail-safe
712  *      being capable of verifying that the related capability is
713  *      expressed within the device configuration (struct rte_eth_conf).
714  *
715  * At least one probed sub_device:
716  *   Numerables:
717  *      Uses values from the active probed sub_device
718  *      The rationale here is that if any sub_device is less capable
719  *      (for example concerning the number of queues) than the active
720  *      sub_device, then its subsequent configuration will fail.
721  *      It is impossible to foresee this failure when the failing sub_device
722  *      is supposed to be plugged-in later on, so the configuration process
723  *      is the single point of failure and error reporting.
724  *   Capabilities:
725  *      Uses a logical AND of RX capabilities among
726  *      all sub_devices and the default capabilities.
727  *      Uses a logical AND of TX capabilities among
728  *      the active probed sub_device and the default capabilities.
729  *
730  */
731 static void
732 fs_dev_infos_get(struct rte_eth_dev *dev,
733                   struct rte_eth_dev_info *infos)
734 {
735         struct sub_device *sdev;
736         uint8_t i;
737
738         sdev = TX_SUBDEV(dev);
739         if (sdev == NULL) {
740                 DEBUG("No probed device, using default infos");
741                 rte_memcpy(&PRIV(dev)->infos, &default_infos,
742                            sizeof(default_infos));
743         } else {
744                 uint64_t rx_offload_capa;
745                 uint64_t rxq_offload_capa;
746
747                 rx_offload_capa = default_infos.rx_offload_capa;
748                 rxq_offload_capa = default_infos.rx_queue_offload_capa;
749                 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_PROBED) {
750                         rte_eth_dev_info_get(PORT_ID(sdev),
751                                         &PRIV(dev)->infos);
752                         rx_offload_capa &= PRIV(dev)->infos.rx_offload_capa;
753                         rxq_offload_capa &=
754                                         PRIV(dev)->infos.rx_queue_offload_capa;
755                 }
756                 sdev = TX_SUBDEV(dev);
757                 rte_eth_dev_info_get(PORT_ID(sdev), &PRIV(dev)->infos);
758                 PRIV(dev)->infos.rx_offload_capa = rx_offload_capa;
759                 PRIV(dev)->infos.rx_queue_offload_capa = rxq_offload_capa;
760                 PRIV(dev)->infos.tx_offload_capa &=
761                                         default_infos.tx_offload_capa;
762                 PRIV(dev)->infos.tx_queue_offload_capa &=
763                                         default_infos.tx_queue_offload_capa;
764                 PRIV(dev)->infos.flow_type_rss_offloads &=
765                                         default_infos.flow_type_rss_offloads;
766         }
767         rte_memcpy(infos, &PRIV(dev)->infos, sizeof(*infos));
768 }
769
770 static const uint32_t *
771 fs_dev_supported_ptypes_get(struct rte_eth_dev *dev)
772 {
773         struct sub_device *sdev;
774         struct rte_eth_dev *edev;
775
776         sdev = TX_SUBDEV(dev);
777         if (sdev == NULL)
778                 return NULL;
779         edev = ETH(sdev);
780         /* ENOTSUP: counts as no supported ptypes */
781         if (SUBOPS(sdev, dev_supported_ptypes_get) == NULL)
782                 return NULL;
783         /*
784          * The API does not permit to do a clean AND of all ptypes,
785          * It is also incomplete by design and we do not really care
786          * to have a best possible value in this context.
787          * We just return the ptypes of the device of highest
788          * priority, usually the PREFERRED device.
789          */
790         return SUBOPS(sdev, dev_supported_ptypes_get)(edev);
791 }
792
793 static int
794 fs_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
795 {
796         struct sub_device *sdev;
797         uint8_t i;
798         int ret;
799
800         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
801                 DEBUG("Calling rte_eth_dev_set_mtu on sub_device %d", i);
802                 ret = rte_eth_dev_set_mtu(PORT_ID(sdev), mtu);
803                 if ((ret = fs_err(sdev, ret))) {
804                         ERROR("Operation rte_eth_dev_set_mtu failed for sub_device %d with error %d",
805                               i, ret);
806                         return ret;
807                 }
808         }
809         return 0;
810 }
811
812 static int
813 fs_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
814 {
815         struct sub_device *sdev;
816         uint8_t i;
817         int ret;
818
819         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
820                 DEBUG("Calling rte_eth_dev_vlan_filter on sub_device %d", i);
821                 ret = rte_eth_dev_vlan_filter(PORT_ID(sdev), vlan_id, on);
822                 if ((ret = fs_err(sdev, ret))) {
823                         ERROR("Operation rte_eth_dev_vlan_filter failed for sub_device %d"
824                               " with error %d", i, ret);
825                         return ret;
826                 }
827         }
828         return 0;
829 }
830
831 static int
832 fs_flow_ctrl_get(struct rte_eth_dev *dev,
833                 struct rte_eth_fc_conf *fc_conf)
834 {
835         struct sub_device *sdev;
836
837         sdev = TX_SUBDEV(dev);
838         if (sdev == NULL)
839                 return 0;
840         if (SUBOPS(sdev, flow_ctrl_get) == NULL)
841                 return -ENOTSUP;
842         return SUBOPS(sdev, flow_ctrl_get)(ETH(sdev), fc_conf);
843 }
844
845 static int
846 fs_flow_ctrl_set(struct rte_eth_dev *dev,
847                 struct rte_eth_fc_conf *fc_conf)
848 {
849         struct sub_device *sdev;
850         uint8_t i;
851         int ret;
852
853         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
854                 DEBUG("Calling rte_eth_dev_flow_ctrl_set on sub_device %d", i);
855                 ret = rte_eth_dev_flow_ctrl_set(PORT_ID(sdev), fc_conf);
856                 if ((ret = fs_err(sdev, ret))) {
857                         ERROR("Operation rte_eth_dev_flow_ctrl_set failed for sub_device %d"
858                               " with error %d", i, ret);
859                         return ret;
860                 }
861         }
862         return 0;
863 }
864
865 static void
866 fs_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
867 {
868         struct sub_device *sdev;
869         uint8_t i;
870
871         /* No check: already done within the rte_eth_dev_mac_addr_remove
872          * call for the fail-safe device.
873          */
874         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
875                 rte_eth_dev_mac_addr_remove(PORT_ID(sdev),
876                                 &dev->data->mac_addrs[index]);
877         PRIV(dev)->mac_addr_pool[index] = 0;
878 }
879
880 static int
881 fs_mac_addr_add(struct rte_eth_dev *dev,
882                 struct ether_addr *mac_addr,
883                 uint32_t index,
884                 uint32_t vmdq)
885 {
886         struct sub_device *sdev;
887         int ret;
888         uint8_t i;
889
890         RTE_ASSERT(index < FAILSAFE_MAX_ETHADDR);
891         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
892                 ret = rte_eth_dev_mac_addr_add(PORT_ID(sdev), mac_addr, vmdq);
893                 if ((ret = fs_err(sdev, ret))) {
894                         ERROR("Operation rte_eth_dev_mac_addr_add failed for sub_device %"
895                               PRIu8 " with error %d", i, ret);
896                         return ret;
897                 }
898         }
899         if (index >= PRIV(dev)->nb_mac_addr) {
900                 DEBUG("Growing mac_addrs array");
901                 PRIV(dev)->nb_mac_addr = index;
902         }
903         PRIV(dev)->mac_addr_pool[index] = vmdq;
904         return 0;
905 }
906
907 static void
908 fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
909 {
910         struct sub_device *sdev;
911         uint8_t i;
912
913         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
914                 rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
915 }
916
917 static int
918 fs_filter_ctrl(struct rte_eth_dev *dev,
919                 enum rte_filter_type type,
920                 enum rte_filter_op op,
921                 void *arg)
922 {
923         struct sub_device *sdev;
924         uint8_t i;
925         int ret;
926
927         if (type == RTE_ETH_FILTER_GENERIC &&
928             op == RTE_ETH_FILTER_GET) {
929                 *(const void **)arg = &fs_flow_ops;
930                 return 0;
931         }
932         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
933                 DEBUG("Calling rte_eth_dev_filter_ctrl on sub_device %d", i);
934                 ret = rte_eth_dev_filter_ctrl(PORT_ID(sdev), type, op, arg);
935                 if ((ret = fs_err(sdev, ret))) {
936                         ERROR("Operation rte_eth_dev_filter_ctrl failed for sub_device %d"
937                               " with error %d", i, ret);
938                         return ret;
939                 }
940         }
941         return 0;
942 }
943
944 const struct eth_dev_ops failsafe_ops = {
945         .dev_configure = fs_dev_configure,
946         .dev_start = fs_dev_start,
947         .dev_stop = fs_dev_stop,
948         .dev_set_link_down = fs_dev_set_link_down,
949         .dev_set_link_up = fs_dev_set_link_up,
950         .dev_close = fs_dev_close,
951         .promiscuous_enable = fs_promiscuous_enable,
952         .promiscuous_disable = fs_promiscuous_disable,
953         .allmulticast_enable = fs_allmulticast_enable,
954         .allmulticast_disable = fs_allmulticast_disable,
955         .link_update = fs_link_update,
956         .stats_get = fs_stats_get,
957         .stats_reset = fs_stats_reset,
958         .dev_infos_get = fs_dev_infos_get,
959         .dev_supported_ptypes_get = fs_dev_supported_ptypes_get,
960         .mtu_set = fs_mtu_set,
961         .vlan_filter_set = fs_vlan_filter_set,
962         .rx_queue_setup = fs_rx_queue_setup,
963         .tx_queue_setup = fs_tx_queue_setup,
964         .rx_queue_release = fs_rx_queue_release,
965         .tx_queue_release = fs_tx_queue_release,
966         .rx_queue_intr_enable = fs_rx_intr_enable,
967         .rx_queue_intr_disable = fs_rx_intr_disable,
968         .flow_ctrl_get = fs_flow_ctrl_get,
969         .flow_ctrl_set = fs_flow_ctrl_set,
970         .mac_addr_remove = fs_mac_addr_remove,
971         .mac_addr_add = fs_mac_addr_add,
972         .mac_addr_set = fs_mac_addr_set,
973         .filter_ctrl = fs_filter_ctrl,
974 };