New upstream version 18.02
[deb_dpdk.git] / drivers / net / sfc / sfc_dp.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright (c) 2017-2018 Solarflare Communications Inc.
4  * All rights reserved.
5  *
6  * This software was jointly developed between OKTET Labs (under contract
7  * for Solarflare) and Solarflare Communications, Inc.
8  */
9
10 #ifndef _SFC_DP_H
11 #define _SFC_DP_H
12
13 #include <stdbool.h>
14 #include <sys/queue.h>
15
16 #include <rte_pci.h>
17
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21
22 #define SFC_DIV_ROUND_UP(a, b) \
23         __extension__ ({                \
24                 typeof(a) _a = (a);     \
25                 typeof(b) _b = (b);     \
26                                         \
27                 (_a + (_b - 1)) / _b;   \
28         })
29
30 /**
31  * Datapath exception handler to be provided by the control path.
32  */
33 typedef void (sfc_dp_exception_t)(void *ctrl);
34
35 enum sfc_dp_type {
36         SFC_DP_RX = 0,  /**< Receive datapath */
37         SFC_DP_TX,      /**< Transmit datapath */
38 };
39
40
41 /** Datapath queue run-time information */
42 struct sfc_dp_queue {
43         uint16_t                        port_id;
44         uint16_t                        queue_id;
45         struct rte_pci_addr             pci_addr;
46 };
47
48 void sfc_dp_queue_init(struct sfc_dp_queue *dpq,
49                        uint16_t port_id, uint16_t queue_id,
50                        const struct rte_pci_addr *pci_addr);
51
52 /*
53  * Helper macro to define datapath logging macros and have uniform
54  * logging.
55  */
56 #define SFC_DP_LOG(dp_name, level, dpq, ...) \
57         do {                                                            \
58                 const struct sfc_dp_queue *_dpq = (dpq);                \
59                 const struct rte_pci_addr *_addr = &(_dpq)->pci_addr;   \
60                                                                         \
61                 RTE_LOG(level, PMD,                                     \
62                         RTE_FMT("%s " PCI_PRI_FMT                       \
63                                 " #%" PRIu16 ".%" PRIu16 ": "           \
64                                 RTE_FMT_HEAD(__VA_ARGS__,) "\n",        \
65                                 dp_name,                                \
66                                 _addr->domain, _addr->bus,              \
67                                 _addr->devid, _addr->function,          \
68                                 _dpq->port_id, _dpq->queue_id,          \
69                                 RTE_FMT_TAIL(__VA_ARGS__,)));           \
70         } while (0)
71
72
73 /** Datapath definition */
74 struct sfc_dp {
75         TAILQ_ENTRY(sfc_dp)             links;
76         const char                      *name;
77         enum sfc_dp_type                type;
78         /* Mask of required hardware/firmware capabilities */
79         unsigned int                    hw_fw_caps;
80 #define SFC_DP_HW_FW_CAP_EF10           0x1
81 };
82
83 /** List of datapath variants */
84 TAILQ_HEAD(sfc_dp_list, sfc_dp);
85
86 /* Check if available HW/FW capabilities are sufficient for the datapath */
87 static inline bool
88 sfc_dp_match_hw_fw_caps(const struct sfc_dp *dp, unsigned int avail_caps)
89 {
90         return (dp->hw_fw_caps & avail_caps) == dp->hw_fw_caps;
91 }
92
93 struct sfc_dp *sfc_dp_find_by_name(struct sfc_dp_list *head,
94                                    enum sfc_dp_type type, const char *name);
95 struct sfc_dp *sfc_dp_find_by_caps(struct sfc_dp_list *head,
96                                    enum sfc_dp_type type,
97                                    unsigned int avail_caps);
98 int sfc_dp_register(struct sfc_dp_list *head, struct sfc_dp *entry);
99
100 #ifdef __cplusplus
101 }
102 #endif
103 #endif /* _SFC_DP_H */