Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : *
3 : : * Copyright(c) 2019-2021 Xilinx, Inc.
4 : : * Copyright(c) 2017-2019 Solarflare Communications Inc.
5 : : *
6 : : * This software was jointly developed between OKTET Labs (under contract
7 : : * for Solarflare) and Solarflare Communications, Inc.
8 : : */
9 : :
10 : : #include <sys/queue.h>
11 : : #include <string.h>
12 : : #include <errno.h>
13 : :
14 : : #include <rte_ethdev.h>
15 : : #include <rte_log.h>
16 : : #include <rte_mbuf_dyn.h>
17 : :
18 : : #include "efx.h"
19 : :
20 : : #include "sfc_dp.h"
21 : : #include "sfc_log.h"
22 : :
23 : : void
24 : 0 : sfc_dp_queue_init(struct sfc_dp_queue *dpq, uint16_t port_id, uint16_t queue_id,
25 : : const struct rte_pci_addr *pci_addr)
26 : : {
27 : 0 : dpq->port_id = port_id;
28 : 0 : dpq->queue_id = queue_id;
29 : 0 : dpq->pci_addr = *pci_addr;
30 : 0 : }
31 : :
32 : : struct sfc_dp *
33 : 0 : sfc_dp_find_by_name(struct sfc_dp_list *head, enum sfc_dp_type type,
34 : : const char *name)
35 : : {
36 : : struct sfc_dp *entry;
37 : :
38 [ # # ]: 0 : TAILQ_FOREACH(entry, head, links) {
39 [ # # ]: 0 : if (entry->type != type)
40 : 0 : continue;
41 : :
42 [ # # ]: 0 : if (strcmp(entry->name, name) == 0)
43 : 0 : return entry;
44 : : }
45 : :
46 : : return NULL;
47 : : }
48 : :
49 : : struct sfc_dp *
50 : 0 : sfc_dp_find_by_caps(struct sfc_dp_list *head, enum sfc_dp_type type,
51 : : unsigned int avail_caps)
52 : : {
53 : : struct sfc_dp *entry;
54 : :
55 [ # # ]: 0 : TAILQ_FOREACH(entry, head, links) {
56 [ # # ]: 0 : if (entry->type != type)
57 : 0 : continue;
58 : :
59 : : /* Take the first matching */
60 [ # # ]: 0 : if (sfc_dp_match_hw_fw_caps(entry, avail_caps))
61 : 0 : return entry;
62 : : }
63 : :
64 : : return NULL;
65 : : }
66 : :
67 : : int
68 : 0 : sfc_dp_register(struct sfc_dp_list *head, struct sfc_dp *entry)
69 : : {
70 [ # # ]: 0 : if (sfc_dp_find_by_name(head, entry->type, entry->name) != NULL) {
71 [ # # # # ]: 0 : SFC_GENERIC_LOG(ERR,
72 : : "sfc %s datapath '%s' already registered",
73 : : entry->type == SFC_DP_RX ? "Rx" :
74 : : entry->type == SFC_DP_TX ? "Tx" :
75 : : "unknown",
76 : : entry->name);
77 : 0 : return EEXIST;
78 : : }
79 : :
80 : 0 : TAILQ_INSERT_TAIL(head, entry, links);
81 : :
82 : 0 : return 0;
83 : : }
84 : :
85 : : uint64_t sfc_dp_mport_override;
86 : : int sfc_dp_mport_offset = -1;
87 : :
88 : : int
89 : 0 : sfc_dp_mport_register(void)
90 : : {
91 : : static const struct rte_mbuf_dynfield mport = {
92 : : .name = "rte_net_sfc_dynfield_mport",
93 : : .size = sizeof(efx_mport_id_t),
94 : : .align = __alignof__(efx_mport_id_t),
95 : : };
96 : : static const struct rte_mbuf_dynflag mport_override = {
97 : : .name = "rte_net_sfc_dynflag_mport_override",
98 : : };
99 : :
100 : : int field_offset;
101 : : int flag;
102 : :
103 [ # # ]: 0 : if (sfc_dp_mport_override != 0) {
104 : 0 : SFC_GENERIC_LOG(INFO, "%s() already registered", __func__);
105 : 0 : return 0;
106 : : }
107 : :
108 : 0 : field_offset = rte_mbuf_dynfield_register(&mport);
109 [ # # ]: 0 : if (field_offset < 0) {
110 : 0 : SFC_GENERIC_LOG(ERR, "%s() failed to register mport dynfield",
111 : : __func__);
112 : 0 : return -1;
113 : : }
114 : :
115 : 0 : flag = rte_mbuf_dynflag_register(&mport_override);
116 [ # # ]: 0 : if (flag < 0) {
117 : 0 : SFC_GENERIC_LOG(ERR, "%s() failed to register mport dynflag",
118 : : __func__);
119 : 0 : return -1;
120 : : }
121 : :
122 : 0 : sfc_dp_mport_offset = field_offset;
123 : 0 : sfc_dp_mport_override = UINT64_C(1) << flag;
124 : :
125 : 0 : return 0;
126 : : }
127 : :
128 : : int sfc_dp_ft_ctx_id_offset = -1;
129 : : uint64_t sfc_dp_ft_ctx_id_valid;
130 : :
131 : : int
132 : 0 : sfc_dp_ft_ctx_id_register(void)
133 : : {
134 : : static const struct rte_mbuf_dynfield ft_ctx_id = {
135 : : .name = "rte_net_sfc_dynfield_ft_ctx_id",
136 : : .size = sizeof(uint8_t),
137 : : .align = __alignof__(uint8_t),
138 : : };
139 : :
140 : : int field_offset;
141 : :
142 : 0 : SFC_GENERIC_LOG(INFO, "%s() entry", __func__);
143 : :
144 [ # # ]: 0 : if (sfc_dp_ft_ctx_id_valid != 0) {
145 : 0 : SFC_GENERIC_LOG(INFO, "%s() already registered", __func__);
146 : 0 : return 0;
147 : : }
148 : :
149 : 0 : field_offset = rte_mbuf_dynfield_register(&ft_ctx_id);
150 [ # # ]: 0 : if (field_offset < 0) {
151 : 0 : SFC_GENERIC_LOG(ERR, "%s() failed to register ft_ctx_id dynfield",
152 : : __func__);
153 : 0 : return -1;
154 : : }
155 : :
156 : 0 : sfc_dp_ft_ctx_id_valid = rte_flow_restore_info_dynflag();
157 : 0 : sfc_dp_ft_ctx_id_offset = field_offset;
158 : :
159 : 0 : SFC_GENERIC_LOG(INFO, "%s() done", __func__);
160 : :
161 : 0 : return 0;
162 : : }
|