xref: /dpdk/drivers/net/sfc/sfc_dp.c (revision 081e42dab11d1add2d038fdf2bd4c86b20043d08)
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_log.h>
15 #include <rte_mbuf_dyn.h>
16 
17 #include "efx.h"
18 
19 #include "sfc_dp.h"
20 #include "sfc_log.h"
21 
22 void
23 sfc_dp_queue_init(struct sfc_dp_queue *dpq, uint16_t port_id, uint16_t queue_id,
24 		  const struct rte_pci_addr *pci_addr)
25 {
26 	dpq->port_id = port_id;
27 	dpq->queue_id = queue_id;
28 	dpq->pci_addr = *pci_addr;
29 }
30 
31 struct sfc_dp *
32 sfc_dp_find_by_name(struct sfc_dp_list *head, enum sfc_dp_type type,
33 		    const char *name)
34 {
35 	struct sfc_dp *entry;
36 
37 	TAILQ_FOREACH(entry, head, links) {
38 		if (entry->type != type)
39 			continue;
40 
41 		if (strcmp(entry->name, name) == 0)
42 			return entry;
43 	}
44 
45 	return NULL;
46 }
47 
48 struct sfc_dp *
49 sfc_dp_find_by_caps(struct sfc_dp_list *head, enum sfc_dp_type type,
50 		    unsigned int avail_caps)
51 {
52 	struct sfc_dp *entry;
53 
54 	TAILQ_FOREACH(entry, head, links) {
55 		if (entry->type != type)
56 			continue;
57 
58 		/* Take the first matching */
59 		if (sfc_dp_match_hw_fw_caps(entry, avail_caps))
60 			return entry;
61 	}
62 
63 	return NULL;
64 }
65 
66 int
67 sfc_dp_register(struct sfc_dp_list *head, struct sfc_dp *entry)
68 {
69 	if (sfc_dp_find_by_name(head, entry->type, entry->name) != NULL) {
70 		SFC_GENERIC_LOG(ERR,
71 			"sfc %s dapapath '%s' already registered",
72 			entry->type == SFC_DP_RX ? "Rx" :
73 			entry->type == SFC_DP_TX ? "Tx" :
74 			"unknown",
75 			entry->name);
76 		return EEXIST;
77 	}
78 
79 	TAILQ_INSERT_TAIL(head, entry, links);
80 
81 	return 0;
82 }
83 
84 uint64_t sfc_dp_mport_override;
85 int sfc_dp_mport_offset = -1;
86 
87 int
88 sfc_dp_mport_register(void)
89 {
90 	static const struct rte_mbuf_dynfield mport = {
91 		.name = "rte_net_sfc_dynfield_mport",
92 		.size = sizeof(efx_mport_id_t),
93 		.align = __alignof__(efx_mport_id_t),
94 	};
95 	static const struct rte_mbuf_dynflag mport_override = {
96 		.name = "rte_net_sfc_dynflag_mport_override",
97 	};
98 
99 	int field_offset;
100 	int flag;
101 
102 	if (sfc_dp_mport_override != 0) {
103 		SFC_GENERIC_LOG(INFO, "%s() already registered", __func__);
104 		return 0;
105 	}
106 
107 	field_offset = rte_mbuf_dynfield_register(&mport);
108 	if (field_offset < 0) {
109 		SFC_GENERIC_LOG(ERR, "%s() failed to register mport dynfield",
110 				__func__);
111 		return -1;
112 	}
113 
114 	flag = rte_mbuf_dynflag_register(&mport_override);
115 	if (flag < 0) {
116 		SFC_GENERIC_LOG(ERR, "%s() failed to register mport dynflag",
117 				__func__);
118 		return -1;
119 	}
120 
121 	sfc_dp_mport_offset = field_offset;
122 	sfc_dp_mport_override = UINT64_C(1) << flag;
123 
124 	return 0;
125 }
126 
127 int sfc_dp_ft_id_offset = -1;
128 uint64_t sfc_dp_ft_id_valid;
129 
130 int
131 sfc_dp_ft_id_register(void)
132 {
133 	static const struct rte_mbuf_dynfield ft_id = {
134 		.name = "rte_net_sfc_dynfield_ft_id",
135 		.size = sizeof(uint8_t),
136 		.align = __alignof__(uint8_t),
137 	};
138 	static const struct rte_mbuf_dynflag ft_id_valid = {
139 		.name = "rte_net_sfc_dynflag_ft_id_valid",
140 	};
141 
142 	int field_offset;
143 	int flag;
144 
145 	SFC_GENERIC_LOG(INFO, "%s() entry", __func__);
146 
147 	if (sfc_dp_ft_id_valid != 0) {
148 		SFC_GENERIC_LOG(INFO, "%s() already registered", __func__);
149 		return 0;
150 	}
151 
152 	field_offset = rte_mbuf_dynfield_register(&ft_id);
153 	if (field_offset < 0) {
154 		SFC_GENERIC_LOG(ERR, "%s() failed to register ft_id dynfield",
155 				__func__);
156 		return -1;
157 	}
158 
159 	flag = rte_mbuf_dynflag_register(&ft_id_valid);
160 	if (flag < 0) {
161 		SFC_GENERIC_LOG(ERR, "%s() failed to register ft_id dynflag",
162 				__func__);
163 		return -1;
164 	}
165 
166 	sfc_dp_ft_id_offset = field_offset;
167 	sfc_dp_ft_id_valid = UINT64_C(1) << flag;
168 
169 	SFC_GENERIC_LOG(INFO, "%s() done", __func__);
170 
171 	return 0;
172 }
173