xref: /freebsd/sys/dev/dpaa2/dpaa2_ni.c (revision c8cd633d78d04ff535960002ac9d1ab20f74b201)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2021-2026 Dmitry Salychev
5  * Copyright (c) 2022 Mathew McBride
6  * Copyright (c) 2026 Bjoern A. Zeeb
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #include <sys/cdefs.h>
31 /*
32  * The DPAA2 Network Interface (DPNI) driver.
33  *
34  * The DPNI object is a network interface that is configurable to support a wide
35  * range of features from a very basic Ethernet interface up to a
36  * high-functioning network interface. The DPNI supports features that are
37  * expected by standard network stacks, from basic features to offloads.
38  *
39  * DPNIs work with Ethernet traffic, starting with the L2 header. Additional
40  * functions are provided for standard network protocols (L2, L3, L4, etc.).
41  */
42 
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/kernel.h>
46 #include <sys/bus.h>
47 #include <sys/rman.h>
48 #include <sys/module.h>
49 #include <sys/malloc.h>
50 #include <sys/mutex.h>
51 #include <sys/socket.h>
52 #include <sys/sockio.h>
53 #include <sys/sysctl.h>
54 #include <sys/mbuf.h>
55 #include <sys/taskqueue.h>
56 #include <sys/sysctl.h>
57 #include <sys/buf_ring.h>
58 #include <sys/smp.h>
59 #include <sys/proc.h>
60 #include <sys/sbuf.h>
61 
62 #include <vm/vm.h>
63 #include <vm/pmap.h>
64 
65 #include <machine/bus.h>
66 #include <machine/resource.h>
67 #include <machine/atomic.h>
68 #include <machine/vmparam.h>
69 
70 #include <net/ethernet.h>
71 #include <net/bpf.h>
72 #include <net/if.h>
73 #include <net/if_dl.h>
74 #include <net/if_media.h>
75 #include <net/if_types.h>
76 #include <net/if_var.h>
77 
78 #include <dev/pci/pcivar.h>
79 #include <dev/mii/mii.h>
80 #include <dev/mii/miivar.h>
81 #include <dev/mdio/mdio.h>
82 
83 #include "opt_acpi.h"
84 #include "opt_platform.h"
85 
86 #include "pcib_if.h"
87 #include "pci_if.h"
88 #include "miibus_if.h"
89 #include "memac_mdio_if.h"
90 
91 #include "dpaa2_types.h"
92 #include "dpaa2_mc.h"
93 #include "dpaa2_mc_if.h"
94 #include "dpaa2_mcp.h"
95 #include "dpaa2_swp.h"
96 #include "dpaa2_swp_if.h"
97 #include "dpaa2_cmd_if.h"
98 #include "dpaa2_ni.h"
99 #include "dpaa2_channel.h"
100 #include "dpaa2_buf.h"
101 #include "dpaa2_frame.h"
102 
103 #define BIT(x)			(1ul << (x))
104 #define WRIOP_VERSION(x, y, z)	((x) << 10 | (y) << 5 | (z) << 0)
105 #define ARRAY_SIZE(a)		(sizeof(a) / sizeof((a)[0]))
106 
107 /* Frame Dequeue Response status bits. */
108 #define IS_NULL_RESPONSE(stat)	((((stat) >> 4) & 1) == 0)
109 
110 #define	ALIGN_UP(x, y)		roundup2((x), (y))
111 #define	ALIGN_DOWN(x, y)	rounddown2((x), (y))
112 #define CACHE_LINE_ALIGN(x)	ALIGN_UP((x), CACHE_LINE_SIZE)
113 
114 #define DPNI_LOCK(__sc) do {			\
115 	mtx_assert(&(__sc)->lock, MA_NOTOWNED);	\
116 	mtx_lock(&(__sc)->lock);		\
117 } while (0)
118 #define	DPNI_UNLOCK(__sc) do {			\
119 	mtx_assert(&(__sc)->lock, MA_OWNED);	\
120 	mtx_unlock(&(__sc)->lock);		\
121 } while (0)
122 #define	DPNI_LOCK_ASSERT(__sc) do {		\
123 	mtx_assert(&(__sc)->lock, MA_OWNED);	\
124 } while (0)
125 
126 #define DPAA2_TX_RING(sc, chan, tc) \
127 	(&(sc)->channels[(chan)]->txc_queue.tx_rings[(tc)])
128 
129 MALLOC_DEFINE(M_DPAA2_TXB, "dpaa2_txb", "DPAA2 DMA-mapped buffer (Tx)");
130 
131 /*
132  * How many times channel cleanup routine will be repeated if the RX or TX
133  * budget was depleted.
134  */
135 #define DPAA2_CLEAN_BUDGET	64 /* sysctl(9)? */
136 /* TX/RX budget for the channel cleanup task */
137 #define DPAA2_TX_BUDGET		128 /* sysctl(9)? */
138 #define DPAA2_RX_BUDGET		256 /* sysctl(9)? */
139 
140 #define DPNI_IRQ_INDEX		0 /* Index of the only DPNI IRQ. */
141 #define DPNI_IRQ_LINK_CHANGED	1 /* Link state changed */
142 #define DPNI_IRQ_EP_CHANGED	2 /* DPAA2 endpoint dis/connected */
143 
144 /* Default maximum RX frame length w/o CRC. */
145 #define	DPAA2_ETH_MFL		(ETHER_MAX_LEN_JUMBO + ETHER_VLAN_ENCAP_LEN - \
146     ETHER_CRC_LEN)
147 
148 /* Minimally supported version of the DPNI API. */
149 #define DPNI_VER_MAJOR		7
150 #define DPNI_VER_MINOR		0
151 
152 /* Rx/Tx buffers configuration. */
153 #define BUF_ALIGN_V1		256 /* WRIOP v1.0.0 limitation */
154 #define BUF_ALIGN		64
155 #define BUF_SWA_SIZE		64  /* SW annotation size */
156 #define BUF_RX_HWA_SIZE		64  /* HW annotation size */
157 #define BUF_TX_HWA_SIZE		128 /* HW annotation size */
158 
159 #define DPAA2_RX_BUFRING_SZ	(4096u)
160 #define DPAA2_RXE_BUFRING_SZ	(1024u)
161 #define DPAA2_TXC_BUFRING_SZ	(4096u)
162 
163 /* Size of a buffer to keep a QoS table key configuration. */
164 #define ETH_QOS_KCFG_BUF_SIZE	(PAGE_SIZE)
165 
166 /* Required by struct dpni_rx_tc_dist_cfg::key_cfg_iova */
167 #define DPAA2_CLASSIFIER_DMA_SIZE (PAGE_SIZE)
168 
169 /* Buffers layout options. */
170 #define BUF_LOPT_TIMESTAMP	0x1
171 #define BUF_LOPT_PARSER_RESULT	0x2
172 #define BUF_LOPT_FRAME_STATUS	0x4
173 #define BUF_LOPT_PRIV_DATA_SZ	0x8
174 #define BUF_LOPT_DATA_ALIGN	0x10
175 #define BUF_LOPT_DATA_HEAD_ROOM	0x20
176 #define BUF_LOPT_DATA_TAIL_ROOM	0x40
177 
178 #define DPAA2_NI_BUF_ADDR_MASK	(0x1FFFFFFFFFFFFul) /* 49-bit addresses max. */
179 #define DPAA2_NI_BUF_CHAN_MASK	(0xFu)
180 #define DPAA2_NI_BUF_CHAN_SHIFT	(60)
181 #define DPAA2_NI_BUF_IDX_MASK	(0x7FFFu)
182 #define DPAA2_NI_BUF_IDX_SHIFT	(49)
183 #define DPAA2_NI_TX_IDX_MASK	(0x7u)
184 #define DPAA2_NI_TX_IDX_SHIFT	(57)
185 #define DPAA2_NI_TXBUF_IDX_MASK	(0xFFu)
186 #define DPAA2_NI_TXBUF_IDX_SHIFT (49)
187 
188 /* Enables TCAM for Flow Steering and QoS look-ups. */
189 #define DPNI_OPT_HAS_KEY_MASKING 0x10
190 
191 /* Unique IDs for the supported Rx classification header fields. */
192 #define DPAA2_ETH_DIST_ETHDST	BIT(0)
193 #define DPAA2_ETH_DIST_ETHSRC	BIT(1)
194 #define DPAA2_ETH_DIST_ETHTYPE	BIT(2)
195 #define DPAA2_ETH_DIST_VLAN	BIT(3)
196 #define DPAA2_ETH_DIST_IPSRC	BIT(4)
197 #define DPAA2_ETH_DIST_IPDST	BIT(5)
198 #define DPAA2_ETH_DIST_IPPROTO	BIT(6)
199 #define DPAA2_ETH_DIST_L4SRC	BIT(7)
200 #define DPAA2_ETH_DIST_L4DST	BIT(8)
201 #define DPAA2_ETH_DIST_ALL	(~0ULL)
202 
203 /* L3-L4 network traffic flow hash options. */
204 #define	RXH_L2DA		(1 << 1)
205 #define	RXH_VLAN		(1 << 2)
206 #define	RXH_L3_PROTO		(1 << 3)
207 #define	RXH_IP_SRC		(1 << 4)
208 #define	RXH_IP_DST		(1 << 5)
209 #define	RXH_L4_B_0_1		(1 << 6) /* src port in case of TCP/UDP/SCTP */
210 #define	RXH_L4_B_2_3		(1 << 7) /* dst port in case of TCP/UDP/SCTP */
211 #define	RXH_DISCARD		(1 << 31)
212 
213 /* Transmit checksum offload */
214 #define DPAA2_CSUM_TX_OFFLOAD	(CSUM_IP | CSUM_DELAY_DATA | CSUM_DELAY_DATA_IPV6)
215 
216 /* Default Rx hash options, set during attaching. */
217 #define DPAA2_RXH_DEFAULT	(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3)
218 
219 MALLOC_DEFINE(M_DPAA2_NI, "dpaa2_ni", "DPAA2 Network Interface");
220 
221 /*
222  * DPAA2 Network Interface resource specification.
223  *
224  * NOTE: Don't forget to update macros in dpaa2_ni.h in case of any changes in
225  *       the specification!
226  */
227 struct resource_spec dpaa2_ni_spec[] = {
228 	/*
229 	 * DPMCP resources.
230 	 *
231 	 * NOTE: MC command portals (MCPs) are used to send commands to, and
232 	 *	 receive responses from, the MC firmware. One portal per DPNI.
233 	 */
234 	{ DPAA2_DEV_MCP, DPAA2_NI_MCP_RID(0),   RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
235 	/*
236 	 * DPIO resources (software portals).
237 	 *
238 	 * NOTE: One per running core. While DPIOs are the source of data
239 	 *	 availability interrupts, the DPCONs are used to identify the
240 	 *	 network interface that has produced ingress data to that core.
241 	 */
242 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(0),    RF_ACTIVE | RF_SHAREABLE },
243 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(1),    RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
244 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(2),    RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
245 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(3),    RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
246 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(4),    RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
247 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(5),    RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
248 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(6),    RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
249 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(7),    RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
250 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(8),    RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
251 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(9),    RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
252 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(10),   RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
253 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(11),   RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
254 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(12),   RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
255 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(13),   RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
256 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(14),   RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
257 	{ DPAA2_DEV_IO,  DPAA2_NI_IO_RID(15),   RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL },
258 	/*
259 	 * DPBP resources (buffer pools).
260 	 *
261 	 * NOTE: One per network interface.
262 	 */
263 	{ DPAA2_DEV_BP,  DPAA2_NI_BP_RID(0),   RF_ACTIVE },
264 	/*
265 	 * DPCON resources (channels).
266 	 *
267 	 * NOTE: One DPCON per core where Rx or Tx confirmation traffic to be
268 	 *	 distributed to.
269 	 * NOTE: Since it is necessary to distinguish between traffic from
270 	 *	 different network interfaces arriving on the same core, the
271 	 *	 DPCONs must be private to the DPNIs.
272 	 */
273 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(0),   RF_ACTIVE },
274 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(1),   RF_ACTIVE | RF_OPTIONAL },
275 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(2),   RF_ACTIVE | RF_OPTIONAL },
276 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(3),   RF_ACTIVE | RF_OPTIONAL },
277 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(4),   RF_ACTIVE | RF_OPTIONAL },
278 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(5),   RF_ACTIVE | RF_OPTIONAL },
279 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(6),   RF_ACTIVE | RF_OPTIONAL },
280 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(7),   RF_ACTIVE | RF_OPTIONAL },
281 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(8),   RF_ACTIVE | RF_OPTIONAL },
282 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(9),   RF_ACTIVE | RF_OPTIONAL },
283 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(10),  RF_ACTIVE | RF_OPTIONAL },
284 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(11),  RF_ACTIVE | RF_OPTIONAL },
285 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(12),  RF_ACTIVE | RF_OPTIONAL },
286 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(13),  RF_ACTIVE | RF_OPTIONAL },
287 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(14),  RF_ACTIVE | RF_OPTIONAL },
288 	{ DPAA2_DEV_CON, DPAA2_NI_CON_RID(15),  RF_ACTIVE | RF_OPTIONAL },
289 
290 	RESOURCE_SPEC_END
291 };
292 
293 /* Supported header fields for Rx hash distribution key */
294 static const struct dpaa2_eth_dist_fields dist_fields[] = {
295 	{
296 		/* L2 header */
297 		.rxnfc_field = RXH_L2DA,
298 		.cls_prot = NET_PROT_ETH,
299 		.cls_field = NH_FLD_ETH_DA,
300 		.id = DPAA2_ETH_DIST_ETHDST,
301 		.size = 6,
302 	}, {
303 		.cls_prot = NET_PROT_ETH,
304 		.cls_field = NH_FLD_ETH_SA,
305 		.id = DPAA2_ETH_DIST_ETHSRC,
306 		.size = 6,
307 	}, {
308 		/* This is the last ethertype field parsed:
309 		 * depending on frame format, it can be the MAC ethertype
310 		 * or the VLAN etype.
311 		 */
312 		.cls_prot = NET_PROT_ETH,
313 		.cls_field = NH_FLD_ETH_TYPE,
314 		.id = DPAA2_ETH_DIST_ETHTYPE,
315 		.size = 2,
316 	}, {
317 		/* VLAN header */
318 		.rxnfc_field = RXH_VLAN,
319 		.cls_prot = NET_PROT_VLAN,
320 		.cls_field = NH_FLD_VLAN_TCI,
321 		.id = DPAA2_ETH_DIST_VLAN,
322 		.size = 2,
323 	}, {
324 		/* IP header */
325 		.rxnfc_field = RXH_IP_SRC,
326 		.cls_prot = NET_PROT_IP,
327 		.cls_field = NH_FLD_IP_SRC,
328 		.id = DPAA2_ETH_DIST_IPSRC,
329 		.size = 4,
330 	}, {
331 		.rxnfc_field = RXH_IP_DST,
332 		.cls_prot = NET_PROT_IP,
333 		.cls_field = NH_FLD_IP_DST,
334 		.id = DPAA2_ETH_DIST_IPDST,
335 		.size = 4,
336 	}, {
337 		.rxnfc_field = RXH_L3_PROTO,
338 		.cls_prot = NET_PROT_IP,
339 		.cls_field = NH_FLD_IP_PROTO,
340 		.id = DPAA2_ETH_DIST_IPPROTO,
341 		.size = 1,
342 	}, {
343 		/* Using UDP ports, this is functionally equivalent to raw
344 		 * byte pairs from L4 header.
345 		 */
346 		.rxnfc_field = RXH_L4_B_0_1,
347 		.cls_prot = NET_PROT_UDP,
348 		.cls_field = NH_FLD_UDP_PORT_SRC,
349 		.id = DPAA2_ETH_DIST_L4SRC,
350 		.size = 2,
351 	}, {
352 		.rxnfc_field = RXH_L4_B_2_3,
353 		.cls_prot = NET_PROT_UDP,
354 		.cls_field = NH_FLD_UDP_PORT_DST,
355 		.id = DPAA2_ETH_DIST_L4DST,
356 		.size = 2,
357 	},
358 };
359 
360 static struct dpni_stat {
361 	int	 page;
362 	int	 cnt;
363 	char	*name;
364 	char	*desc;
365 } dpni_stat_sysctls[] = {
366 	/* PAGE, COUNTER, NAME, DESCRIPTION */
367 	{ 0, 0, "in_all_frames",	"All accepted ingress frames" },
368 	{ 0, 1, "in_all_bytes",		"Bytes in all accepted ingress frames" },
369 	{ 0, 2, "in_mc_frames",		"Multicast accepted ingress frames" },
370 	{ 0, 3, "in_mc_bytes",		"Bytes in received multicast frames" },
371 	{ 0, 4, "in_bc_frames",		"Broadcast accepted ingress frames" },
372 	{ 0, 5, "in_bc_bytes",		"Bytes in broadcast multicast frames" },
373 
374 	{ 1, 0, "eg_all_frames",	"All egress frames transmitted" },
375 	{ 1, 1, "eg_all_bytes",		"Bytes in all frames transmitted" },
376 	{ 1, 2, "eg_mc_frames",		"Multicast egress frames transmitted" },
377 	{ 1, 3, "eg_mc_bytes",		"Bytes in transmitted multicast frame" },
378 	{ 1, 4, "eg_bc_frames",		"Broadcast egress frames transmitted" },
379 	{ 1, 5, "eg_bc_bytes",		"Bytes in broadcast multicast frames" },
380 
381 	{ 2, 0, "in_filtered_frames",	"All ingress frames discarded due to filtering" },
382 	{ 2, 1, "in_discarded_frames",	"All frames discarded due to errors" },
383 	{ 2, 2, "in_nobuf_discards",	"Discards on ingress side due to buffer depletion in DPNI buffer pools" },
384 	{ 2, 3, "eg_frames_disc",	"Frames discarded on transmit due to DPNI configuration and/or frame state" },
385 	{ 2, 4, "eg_frames_tx",		"Frames that have been confirmed after transmission" },
386 
387 	/* XXX FIXME Page 3/4 can take a param as well not encoded here. */
388 	/* XXX 3/0 and 3/1 have the same description in the manual?  Where's the difference? */
389 	{ 3, 0, "bytes_dequeued",	"Cumulative count of the number of bytes dequeued" },
390 	{ 3, 1, "frames_dequeued",	"Cumulative count of the number of frames dequeued" },
391 	{ 3, 2, "bytes_enqueued_rej",	"Cumulative count of the number of bytes in all frames whose enqueue was rejected." },
392 	{ 3, 3, "frames_enqueued_rej",	"Cumulative count of all frame enqueues rejected." },
393 
394 	{ 4, 0, "fames_rej_tc",		"Rejected frames in associated congestion point (valid if this TC has an associated congestion point)" },
395 	{ 4, 1, "bytes_rej_tc",		"Rejected bytes in associated congestion point (valid if this TC has an associated congestion point)" },
396 
397 	{ 5, 0, "pol_red",		"Policer RED packet counter. 32bit value valid only when policer is enabled." },
398 	{ 5, 1, "pol_yel",		"Policer YELLOW packet counter. 32bit value valid only when policer is enabled." },
399 	{ 5, 2, "pol_gre",		"Policer GREEN packet counter. 32bit value valid only when policer is enabled." },
400 	{ 5, 3, "pol_re_red",		"Policer recolored RED packet counter. 32bit value valid only when policer is enabled." },
401 	{ 5, 4, "pol_re_yel",		"Policer recolored YELLOW packet counter. 32bit value valid only when policer is enabled." },
402 };
403 
404 struct dpaa2_ni_rx_ctx {
405 	struct mbuf	*head;
406 	struct mbuf	*tail;
407 	int		 cnt;
408 	bool		 last;
409 };
410 
411 /* Device interface */
412 static int dpaa2_ni_probe(device_t);
413 static int dpaa2_ni_attach(device_t);
414 static int dpaa2_ni_detach(device_t);
415 
416 /* DPAA2 network interface setup and configuration */
417 static int dpaa2_ni_setup(device_t);
418 static int dpaa2_ni_setup_channels(device_t);
419 static int dpaa2_ni_bind(device_t);
420 static int dpaa2_ni_setup_rx_dist(device_t);
421 static int dpaa2_ni_setup_irqs(device_t);
422 static int dpaa2_ni_setup_msi(struct dpaa2_ni_softc *);
423 static int dpaa2_ni_setup_if_caps(struct dpaa2_ni_softc *);
424 static int dpaa2_ni_setup_if_flags(struct dpaa2_ni_softc *);
425 static int dpaa2_ni_setup_sysctls(struct dpaa2_ni_softc *);
426 static int dpaa2_ni_setup_dma(struct dpaa2_ni_softc *);
427 
428 /* Tx/Rx flow configuration */
429 static int dpaa2_ni_setup_rx_flow(device_t, struct dpaa2_ni_fq *);
430 static int dpaa2_ni_setup_tx_flow(device_t, struct dpaa2_ni_fq *);
431 static int dpaa2_ni_setup_rx_err_flow(device_t, struct dpaa2_ni_fq *);
432 
433 /* Configuration subroutines */
434 static int dpaa2_ni_set_buf_layout(device_t);
435 static int dpaa2_ni_set_pause_frame(device_t);
436 static int dpaa2_ni_set_qos_table(device_t);
437 static int dpaa2_ni_set_mac_addr(device_t);
438 static int dpaa2_ni_set_hash(device_t, uint64_t);
439 static int dpaa2_ni_set_dist_key(device_t, enum dpaa2_ni_dist_mode, uint64_t);
440 
441 /* Various subroutines */
442 static int dpaa2_ni_cmp_api_version(struct dpaa2_ni_softc *, uint16_t, uint16_t);
443 static int dpaa2_ni_prepare_key_cfg(struct dpkg_profile_cfg *, uint8_t *);
444 static int dpaa2_ni_update_csum_flags(struct dpaa2_fd *, struct mbuf *);
445 
446 /* Network interface routines */
447 static void dpaa2_ni_init(void *);
448 static int  dpaa2_ni_transmit(if_t , struct mbuf *);
449 static void dpaa2_ni_qflush(if_t );
450 static int  dpaa2_ni_ioctl(if_t , u_long, caddr_t);
451 static int  dpaa2_ni_update_mac_filters(if_t );
452 static u_int dpaa2_ni_add_maddr(void *, struct sockaddr_dl *, u_int);
453 
454 /* Interrupt handlers */
455 static void dpaa2_ni_intr(void *);
456 
457 /* MII handlers */
458 static void dpaa2_ni_miibus_statchg(device_t);
459 static int  dpaa2_ni_media_change(if_t );
460 static void dpaa2_ni_media_status(if_t , struct ifmediareq *);
461 static void dpaa2_ni_media_tick(void *);
462 
463 /* Tx/Rx routines. */
464 static int dpaa2_ni_rx_cleanup(struct dpaa2_channel *);
465 static int dpaa2_ni_tx_cleanup(struct dpaa2_channel *);
466 static void dpaa2_ni_tx(struct dpaa2_ni_softc *, struct dpaa2_channel *,
467     struct dpaa2_ni_tx_ring *, struct mbuf *);
468 static void dpaa2_ni_cleanup_task(void *, int);
469 
470 /* Tx/Rx subroutines */
471 static int dpaa2_ni_consume_frames(struct dpaa2_channel *, struct dpaa2_ni_fq **,
472     uint32_t *);
473 static int dpaa2_ni_rx(struct dpaa2_channel *, struct dpaa2_ni_fq *,
474     struct dpaa2_fd *, struct dpaa2_ni_rx_ctx *);
475 static int dpaa2_ni_rx_err(struct dpaa2_channel *, struct dpaa2_ni_fq *,
476     struct dpaa2_fd *);
477 static int dpaa2_ni_tx_conf(struct dpaa2_channel *, struct dpaa2_ni_fq *,
478     struct dpaa2_fd *);
479 
480 /* sysctl(9) */
481 static int dpaa2_ni_collect_stats(SYSCTL_HANDLER_ARGS);
482 static int dpaa2_ni_collect_buf_num(SYSCTL_HANDLER_ARGS);
483 static int dpaa2_ni_collect_buf_free(SYSCTL_HANDLER_ARGS);
484 static int dpaa2_ni_sysctl_link_state(SYSCTL_HANDLER_ARGS);
485 
486 static int
dpaa2_ni_probe(device_t dev)487 dpaa2_ni_probe(device_t dev)
488 {
489 	/* DPNI device will be added by a parent resource container itself. */
490 	device_set_desc(dev, "DPAA2 Network Interface");
491 	return (BUS_PROBE_DEFAULT);
492 }
493 
494 static int
dpaa2_ni_attach(device_t dev)495 dpaa2_ni_attach(device_t dev)
496 {
497 	device_t pdev = device_get_parent(dev);
498 	device_t child = dev;
499 	device_t mcp_dev;
500 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
501 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
502 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
503 	struct dpaa2_devinfo *mcp_dinfo;
504 	struct dpaa2_cmd cmd;
505 	uint16_t rc_token, ni_token;
506 	if_t ifp;
507 	char tq_name[32];
508 	int error;
509 
510 	sc->dev = dev;
511 	sc->ifp = NULL;
512 	sc->miibus = NULL;
513 	sc->mii = NULL;
514 	sc->media_status = 0;
515 	sc->if_flags = 0;
516 	sc->link_state = LINK_STATE_UNKNOWN;
517 	sc->buf_align = 0;
518 
519 	/* For debug purposes only! */
520 	sc->rx_anomaly_frames = 0;
521 	sc->rx_single_buf_frames = 0;
522 	sc->rx_sg_buf_frames = 0;
523 	sc->rx_enq_rej_frames = 0;
524 	sc->rx_ieoi_err_frames = 0;
525 	sc->rx_other_err_frames = 0;
526 	sc->tx_single_buf_frames = 0;
527 	sc->tx_sg_frames = 0;
528 
529 	DPAA2_ATOMIC_XCHG(&sc->buf_num, 0);
530 	DPAA2_ATOMIC_XCHG(&sc->buf_free, 0);
531 
532 	sc->rxd_dmat = NULL;
533 	sc->qos_dmat = NULL;
534 
535 	sc->qos_kcfg.dmap = NULL;
536 	sc->qos_kcfg.paddr = 0;
537 	sc->qos_kcfg.vaddr = NULL;
538 
539 	sc->rxd_kcfg.dmap = NULL;
540 	sc->rxd_kcfg.paddr = 0;
541 	sc->rxd_kcfg.vaddr = NULL;
542 
543 	sc->mac.dpmac_id = 0;
544 	sc->mac.phy_dev = NULL;
545 	memset(sc->mac.addr, 0, ETHER_ADDR_LEN);
546 
547 	error = bus_alloc_resources(sc->dev, dpaa2_ni_spec, sc->res);
548 	if (error) {
549 		device_printf(dev, "%s: failed to allocate resources: "
550 		    "error=%d\n", __func__, error);
551 		goto err_exit;
552 	}
553 
554 	/* Obtain MC portal. */
555 	mcp_dev = (device_t) rman_get_start(sc->res[DPAA2_NI_MCP_RID(0)]);
556 	mcp_dinfo = device_get_ivars(mcp_dev);
557 	dinfo->portal = mcp_dinfo->portal;
558 
559 	mtx_init(&sc->lock, device_get_nameunit(dev), "dpaa2_ni", MTX_DEF);
560 
561 	/* Allocate network interface */
562 	ifp = if_alloc(IFT_ETHER);
563 	sc->ifp = ifp;
564 	if_initname(ifp, DPAA2_NI_IFNAME, device_get_unit(sc->dev));
565 
566 	if_setsoftc(ifp, sc);
567 	if_setflags(ifp, IFF_SIMPLEX | IFF_MULTICAST | IFF_BROADCAST);
568 	if_setinitfn(ifp, dpaa2_ni_init);
569 	if_setioctlfn(ifp, dpaa2_ni_ioctl);
570 	if_settransmitfn(ifp, dpaa2_ni_transmit);
571 	if_setqflushfn(ifp, dpaa2_ni_qflush);
572 
573 	if_sethwassist(sc->ifp, DPAA2_CSUM_TX_OFFLOAD);
574 	if_setcapabilities(ifp, IFCAP_VLAN_MTU | IFCAP_HWCSUM |
575 	    IFCAP_HWCSUM_IPV6 | IFCAP_JUMBO_MTU);
576 	if_setcapenable(ifp, if_getcapabilities(ifp));
577 
578 	DPAA2_CMD_INIT(&cmd);
579 
580 	/* Open resource container and network interface object. */
581 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
582 	if (error) {
583 		device_printf(dev, "%s: failed to open resource container: "
584 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
585 		goto err_exit;
586 	}
587 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
588 	if (error) {
589 		device_printf(dev, "%s: failed to open network interface: "
590 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
591 		goto close_rc;
592 	}
593 
594 	bzero(tq_name, sizeof(tq_name));
595 	snprintf(tq_name, sizeof(tq_name), "%s_tqbp", device_get_nameunit(dev));
596 
597 	/*
598 	 * XXX-DSL: Release new buffers on Buffer Pool State Change Notification
599 	 *          (BPSCN) returned as a result to the VDQ command instead.
600 	 *          It is similar to CDAN processed in dpaa2_io_intr().
601 	 */
602 	/* Create a taskqueue thread to release new buffers to the pool. */
603 	sc->bp_taskq = taskqueue_create(tq_name, M_WAITOK,
604 	    taskqueue_thread_enqueue, &sc->bp_taskq);
605 	taskqueue_start_threads(&sc->bp_taskq, 1, PI_NET, "%s", tq_name);
606 
607 	/* sc->cleanup_taskq = taskqueue_create("dpaa2_ch cleanup", M_WAITOK, */
608 	/*     taskqueue_thread_enqueue, &sc->cleanup_taskq); */
609 	/* taskqueue_start_threads(&sc->cleanup_taskq, 1, PI_NET, */
610 	/*     "dpaa2_ch cleanup"); */
611 
612 	error = dpaa2_ni_setup(dev);
613 	if (error) {
614 		device_printf(dev, "%s: failed to setup DPNI: error=%d\n",
615 		    __func__, error);
616 		goto close_ni;
617 	}
618 	error = dpaa2_ni_setup_channels(dev);
619 	if (error) {
620 		device_printf(dev, "%s: failed to setup QBMan channels: "
621 		    "error=%d\n", __func__, error);
622 		goto close_ni;
623 	}
624 
625 	error = dpaa2_ni_bind(dev);
626 	if (error) {
627 		device_printf(dev, "%s: failed to bind DPNI: error=%d\n",
628 		    __func__, error);
629 		goto close_ni;
630 	}
631 	error = dpaa2_ni_setup_irqs(dev);
632 	if (error) {
633 		device_printf(dev, "%s: failed to setup IRQs: error=%d\n",
634 		    __func__, error);
635 		goto close_ni;
636 	}
637 	error = dpaa2_ni_setup_sysctls(sc);
638 	if (error) {
639 		device_printf(dev, "%s: failed to setup sysctls: error=%d\n",
640 		    __func__, error);
641 		goto close_ni;
642 	}
643 	error = dpaa2_ni_setup_if_caps(sc);
644 	if (error) {
645 		device_printf(dev, "%s: failed to setup interface capabilities: "
646 		    "error=%d\n", __func__, error);
647 		goto close_ni;
648 	}
649 
650 	ether_ifattach(sc->ifp, sc->mac.addr);
651 	callout_init(&sc->mii_callout, 0);
652 
653 	return (0);
654 
655 close_ni:
656 	DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
657 close_rc:
658 	DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
659 err_exit:
660 	return (ENXIO);
661 }
662 
663 static void
dpaa2_ni_fixed_media_status(if_t ifp,struct ifmediareq * ifmr)664 dpaa2_ni_fixed_media_status(if_t ifp, struct ifmediareq* ifmr)
665 {
666 	struct dpaa2_ni_softc *sc = if_getsoftc(ifp);
667 
668 	DPNI_LOCK(sc);
669 	ifmr->ifm_count = 0;
670 	ifmr->ifm_mask = 0;
671 	ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
672 	ifmr->ifm_current = ifmr->ifm_active =
673 	    sc->fixed_ifmedia.ifm_cur->ifm_media;
674 
675 	/*
676 	 * In non-PHY usecases, we need to signal link state up, otherwise
677 	 * certain things requiring a link event (e.g async DHCP client) from
678 	 * devd do not happen.
679 	 */
680 	if (if_getlinkstate(ifp) == LINK_STATE_UNKNOWN) {
681 		if_link_state_change(ifp, LINK_STATE_UP);
682 	}
683 
684 	/*
685 	 * TODO: Check the status of the link partner (DPMAC, DPNI or other) and
686 	 * reset if down. This is different to the DPAA2_MAC_LINK_TYPE_PHY as
687 	 * the MC firmware sets the status, instead of us telling the MC what
688 	 * it is.
689 	 */
690 	DPNI_UNLOCK(sc);
691 
692 	return;
693 }
694 
695 static void
dpaa2_ni_setup_fixed_link(struct dpaa2_ni_softc * sc)696 dpaa2_ni_setup_fixed_link(struct dpaa2_ni_softc *sc)
697 {
698 	/*
699 	 * FIXME: When the DPNI is connected to a DPMAC, we can get the
700 	 * 'apparent' speed from it.
701 	 */
702 	sc->fixed_link = true;
703 
704 	ifmedia_init(&sc->fixed_ifmedia, 0, dpaa2_ni_media_change,
705 		     dpaa2_ni_fixed_media_status);
706 	ifmedia_add(&sc->fixed_ifmedia, IFM_ETHER | IFM_1000_T, 0, NULL);
707 	ifmedia_set(&sc->fixed_ifmedia, IFM_ETHER | IFM_1000_T);
708 }
709 
710 static int
dpaa2_ni_detach(device_t dev)711 dpaa2_ni_detach(device_t dev)
712 {
713 	/* TBD */
714 	return (0);
715 }
716 
717 /**
718  * @brief Configure DPAA2 network interface object.
719  */
720 static int
dpaa2_ni_setup(device_t dev)721 dpaa2_ni_setup(device_t dev)
722 {
723 	device_t pdev = device_get_parent(dev);
724 	device_t child = dev;
725 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
726 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
727 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
728 	struct dpaa2_ep_desc ep1_desc, ep2_desc; /* endpoint descriptors */
729 	struct dpaa2_cmd cmd;
730 	uint8_t eth_bca[ETHER_ADDR_LEN]; /* broadcast physical address */
731 	uint16_t rc_token, ni_token, mac_token;
732 	struct dpaa2_mac_attr attr;
733 	enum dpaa2_mac_link_type link_type;
734 	uint32_t link;
735 	int error;
736 
737 	DPAA2_CMD_INIT(&cmd);
738 
739 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
740 	if (error) {
741 		device_printf(dev, "%s: failed to open resource container: "
742 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
743 		goto err_exit;
744 	}
745 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
746 	if (error) {
747 		device_printf(dev, "%s: failed to open network interface: "
748 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
749 		goto close_rc;
750 	}
751 
752 	/* Check if we can work with this DPNI object. */
753 	error = DPAA2_CMD_NI_GET_API_VERSION(dev, child, &cmd, &sc->api_major,
754 	    &sc->api_minor);
755 	if (error) {
756 		device_printf(dev, "%s: failed to get DPNI API version\n",
757 		    __func__);
758 		goto close_ni;
759 	}
760 	if (dpaa2_ni_cmp_api_version(sc, DPNI_VER_MAJOR, DPNI_VER_MINOR) < 0) {
761 		device_printf(dev, "%s: DPNI API version %u.%u not supported, "
762 		    "need >= %u.%u\n", __func__, sc->api_major, sc->api_minor,
763 		    DPNI_VER_MAJOR, DPNI_VER_MINOR);
764 		error = ENODEV;
765 		goto close_ni;
766 	}
767 
768 	/* Reset the DPNI object. */
769 	error = DPAA2_CMD_NI_RESET(dev, child, &cmd);
770 	if (error) {
771 		device_printf(dev, "%s: failed to reset DPNI: id=%d\n",
772 		    __func__, dinfo->id);
773 		goto close_ni;
774 	}
775 
776 	/* Obtain attributes of the DPNI object. */
777 	error = DPAA2_CMD_NI_GET_ATTRIBUTES(dev, child, &cmd, &sc->attr);
778 	if (error) {
779 		device_printf(dev, "%s: failed to obtain DPNI attributes: "
780 		    "id=%d\n", __func__, dinfo->id);
781 		goto close_ni;
782 	}
783 	if (bootverbose) {
784 		device_printf(dev, "\toptions=0x%#x queues=%d tx_channels=%d "
785 		    "wriop_version=%#x\n", sc->attr.options, sc->attr.num.queues,
786 		    sc->attr.num.channels, sc->attr.wriop_ver);
787 		device_printf(dev, "\ttraffic classes: rx=%d tx=%d "
788 		    "cgs_groups=%d\n", sc->attr.num.rx_tcs, sc->attr.num.tx_tcs,
789 		    sc->attr.num.cgs);
790 		device_printf(dev, "\ttable entries: mac=%d vlan=%d qos=%d "
791 		    "fs=%d\n", sc->attr.entries.mac, sc->attr.entries.vlan,
792 		    sc->attr.entries.qos, sc->attr.entries.fs);
793 		device_printf(dev, "\tkey sizes: qos=%d fs=%d\n",
794 		    sc->attr.key_size.qos, sc->attr.key_size.fs);
795 	}
796 
797 	/* Configure buffer layouts of the DPNI queues. */
798 	error = dpaa2_ni_set_buf_layout(dev);
799 	if (error) {
800 		device_printf(dev, "%s: failed to configure buffer layout\n",
801 		    __func__);
802 		goto close_ni;
803 	}
804 
805 	/* Configure DMA resources. */
806 	error = dpaa2_ni_setup_dma(sc);
807 	if (error) {
808 		device_printf(dev, "%s: failed to setup DMA\n", __func__);
809 		goto close_ni;
810 	}
811 
812 	/* Setup link between DPNI and an object it's connected to. */
813 	ep1_desc.obj_id = dinfo->id;
814 	ep1_desc.if_id = 0; /* DPNI has the only endpoint */
815 	ep1_desc.type = dinfo->dtype;
816 
817 	error = DPAA2_CMD_RC_GET_CONN(dev, child, DPAA2_CMD_TK(&cmd, rc_token),
818 	    &ep1_desc, &ep2_desc, &link);
819 	if (error) {
820 		device_printf(dev, "%s: failed to obtain an object DPNI is "
821 		    "connected to: error=%d\n", __func__, error);
822 	} else {
823 		device_printf(dev, "connected to %s (id=%d)\n",
824 		    dpaa2_ttos(ep2_desc.type), ep2_desc.obj_id);
825 
826 		error = dpaa2_ni_set_mac_addr(dev);
827 		if (error) {
828 			device_printf(dev, "%s: failed to set MAC address: "
829 			    "error=%d\n", __func__, error);
830 		}
831 
832 		if (ep2_desc.type == DPAA2_DEV_MAC) {
833 			/*
834 			 * This is the simplest case when DPNI is connected to
835 			 * DPMAC directly.
836 			 */
837 			sc->mac.dpmac_id = ep2_desc.obj_id;
838 
839 			link_type = DPAA2_MAC_LINK_TYPE_NONE;
840 
841 			/*
842 			 * Need to determine if DPMAC type is PHY (attached to
843 			 * conventional MII PHY) or FIXED (usually SFP/SerDes,
844 			 * link state managed by MC firmware).
845 			 */
846 			error = DPAA2_CMD_MAC_OPEN(sc->dev, child,
847 			    DPAA2_CMD_TK(&cmd, rc_token), sc->mac.dpmac_id,
848 			    &mac_token);
849 			/*
850 			 * Under VFIO, the DPMAC might be sitting in another
851 			 * container (DPRC) we don't have access to.
852 			 * Assume DPAA2_MAC_LINK_TYPE_FIXED if this is
853 			 * the case.
854 			 */
855 			if (error) {
856 				device_printf(dev, "%s: failed to open "
857 				    "connected DPMAC: %d (assuming in other DPRC)\n", __func__,
858 				    sc->mac.dpmac_id);
859 				link_type = DPAA2_MAC_LINK_TYPE_FIXED;
860 			} else {
861 				error = DPAA2_CMD_MAC_GET_ATTRIBUTES(dev, child,
862 				    &cmd, &attr);
863 				if (error) {
864 					device_printf(dev, "%s: failed to get "
865 					    "DPMAC attributes: id=%d, "
866 					    "error=%d\n", __func__, dinfo->id,
867 					    error);
868 				} else {
869 					link_type = attr.link_type;
870 				}
871 			}
872 			DPAA2_CMD_MAC_CLOSE(dev, child, &cmd);
873 
874 			if (link_type == DPAA2_MAC_LINK_TYPE_FIXED) {
875 				device_printf(dev, "connected DPMAC is in FIXED "
876 				    "mode\n");
877 				dpaa2_ni_setup_fixed_link(sc);
878 			} else if (link_type == DPAA2_MAC_LINK_TYPE_PHY) {
879 				device_printf(dev, "connected DPMAC is in PHY "
880 				    "mode\n");
881 				error = DPAA2_MC_GET_PHY_DEV(dev,
882 				    &sc->mac.phy_dev, sc->mac.dpmac_id);
883 				if (error == 0) {
884 					error = MEMAC_MDIO_SET_NI_DEV(
885 					    sc->mac.phy_dev, dev);
886 					if (error != 0) {
887 						device_printf(dev, "%s: failed "
888 						    "to set dpni dev on memac "
889 						    "mdio dev %s: error=%d\n",
890 						    __func__,
891 						    device_get_nameunit(
892 						    sc->mac.phy_dev), error);
893 					}
894 				}
895 				if (error == 0) {
896 					error = MEMAC_MDIO_GET_PHY_LOC(
897 					    sc->mac.phy_dev, &sc->mac.phy_loc);
898 					if (error == ENODEV) {
899 						error = 0;
900 					}
901 					if (error != 0) {
902 						device_printf(dev, "%s: failed "
903 						    "to get phy location from "
904 						    "memac mdio dev %s: error=%d\n",
905 						    __func__, device_get_nameunit(
906 						    sc->mac.phy_dev), error);
907 					}
908 				}
909 				if (error == 0) {
910 					error = mii_attach(sc->mac.phy_dev,
911 					    &sc->miibus, sc->ifp,
912 					    dpaa2_ni_media_change,
913 					    dpaa2_ni_media_status,
914 					    BMSR_DEFCAPMASK, sc->mac.phy_loc,
915 					    MII_OFFSET_ANY, 0);
916 					if (error != 0) {
917 						device_printf(dev, "%s: failed "
918 						    "to attach to miibus: "
919 						    "error=%d\n",
920 						    __func__, error);
921 					}
922 				}
923 				if (error == 0) {
924 					sc->mii = device_get_softc(sc->miibus);
925 				}
926 			} else {
927 				device_printf(dev, "%s: DPMAC link type is not "
928 				    "supported\n", __func__);
929 			}
930 		} else if (ep2_desc.type == DPAA2_DEV_NI ||
931 			   ep2_desc.type == DPAA2_DEV_MUX ||
932 			   ep2_desc.type == DPAA2_DEV_SW) {
933 			dpaa2_ni_setup_fixed_link(sc);
934 		}
935 	}
936 
937 	/* Select mode to enqueue frames. */
938 	/* ... TBD ... */
939 
940 	/*
941 	 * Update link configuration to enable Rx/Tx pause frames support.
942 	 *
943 	 * NOTE: MC may generate an interrupt to the DPMAC and request changes
944 	 *       in link configuration. It might be necessary to attach miibus
945 	 *       and PHY before this point.
946 	 */
947 	error = dpaa2_ni_set_pause_frame(dev);
948 	if (error) {
949 		device_printf(dev, "%s: failed to configure Rx/Tx pause "
950 		    "frames\n", __func__);
951 		goto close_ni;
952 	}
953 
954 	/* Configure ingress traffic classification. */
955 	error = dpaa2_ni_set_qos_table(dev);
956 	if (error) {
957 		device_printf(dev, "%s: failed to configure QoS table: "
958 		    "error=%d\n", __func__, error);
959 		goto close_ni;
960 	}
961 
962 	/* Add broadcast physical address to the MAC filtering table. */
963 	memset(eth_bca, 0xff, ETHER_ADDR_LEN);
964 	error = DPAA2_CMD_NI_ADD_MAC_ADDR(dev, child, DPAA2_CMD_TK(&cmd,
965 	    ni_token), eth_bca);
966 	if (error) {
967 		device_printf(dev, "%s: failed to add broadcast physical "
968 		    "address to the MAC filtering table\n", __func__);
969 		goto close_ni;
970 	}
971 
972 	/* Set the maximum allowed length for received frames. */
973 	error = DPAA2_CMD_NI_SET_MFL(dev, child, &cmd, DPAA2_ETH_MFL);
974 	if (error) {
975 		device_printf(dev, "%s: failed to set maximum length for "
976 		    "received frames\n", __func__);
977 		goto close_ni;
978 	}
979 
980 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
981 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
982 	return (0);
983 
984 close_ni:
985 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
986 close_rc:
987 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
988 err_exit:
989 	return (error);
990 }
991 
992 /**
993  * @brief Сonfigure QBMan channels and register data availability notifications.
994  */
995 static int
dpaa2_ni_setup_channels(device_t dev)996 dpaa2_ni_setup_channels(device_t dev)
997 {
998 	device_t iodev, condev, bpdev;
999 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
1000 	uint32_t i, num_chan;
1001 	int error;
1002 
1003 	/* Calculate number of the channels based on the allocated resources */
1004 	for (i = 0; i < DPAA2_NI_IO_RES_NUM; i++) {
1005 		if (!sc->res[DPAA2_NI_IO_RID(i)]) {
1006 			break;
1007 		}
1008 	}
1009 	num_chan = i;
1010 	for (i = 0; i < DPAA2_NI_CON_RES_NUM; i++) {
1011 		if (!sc->res[DPAA2_NI_CON_RID(i)]) {
1012 			break;
1013 		}
1014 	}
1015 	num_chan = i < num_chan ? i : num_chan;
1016 	sc->chan_n = num_chan > DPAA2_MAX_CHANNELS
1017 	    ? DPAA2_MAX_CHANNELS : num_chan;
1018 	sc->chan_n = sc->chan_n > sc->attr.num.queues
1019 	    ? sc->attr.num.queues : sc->chan_n;
1020 
1021 	KASSERT(sc->chan_n > 0u, ("%s: positive number of channels expected: "
1022 	    "chan_n=%d", __func__, sc->chan_n));
1023 
1024 	device_printf(dev, "channels=%d\n", sc->chan_n);
1025 
1026 	for (i = 0; i < sc->chan_n; i++) {
1027 		iodev = (device_t)rman_get_start(sc->res[DPAA2_NI_IO_RID(i)]);
1028 		condev = (device_t)rman_get_start(sc->res[DPAA2_NI_CON_RID(i)]);
1029 		/* Only one buffer pool available at the moment */
1030 		bpdev = (device_t)rman_get_start(sc->res[DPAA2_NI_BP_RID(0)]);
1031 
1032 		error = dpaa2_chan_setup(dev, iodev, condev, bpdev,
1033 		    &sc->channels[i], i, dpaa2_ni_cleanup_task);
1034 		if (error != 0) {
1035 			device_printf(dev, "%s: dpaa2_chan_setup() failed: "
1036 			    "error=%d, chan_id=%d\n", __func__, error, i);
1037 			return (error);
1038 		}
1039 	}
1040 
1041 	/* There is exactly one Rx error queue per network interface */
1042 	error = dpaa2_chan_setup_fq(dev, sc->channels[0], DPAA2_NI_QUEUE_RX_ERR);
1043 	if (error != 0) {
1044 		device_printf(dev, "%s: failed to prepare RxError queue: "
1045 		    "error=%d\n", __func__, error);
1046 		return (error);
1047 	}
1048 
1049 	return (0);
1050 }
1051 
1052 /**
1053  * @brief Bind DPNI to DPBPs, DPIOs, frame queues and channels.
1054  */
1055 static int
dpaa2_ni_bind(device_t dev)1056 dpaa2_ni_bind(device_t dev)
1057 {
1058 	device_t pdev = device_get_parent(dev);
1059 	device_t child = dev;
1060 	device_t bp_dev;
1061 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
1062 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
1063 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
1064 	struct dpaa2_devinfo *bp_info;
1065 	struct dpaa2_cmd cmd;
1066 	struct dpaa2_ni_pools_cfg pools_cfg;
1067 	struct dpaa2_ni_err_cfg err_cfg;
1068 	struct dpaa2_channel *chan;
1069 	uint16_t rc_token, ni_token;
1070 	int error;
1071 
1072 	DPAA2_CMD_INIT(&cmd);
1073 
1074 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
1075 	if (error) {
1076 		device_printf(dev, "%s: failed to open resource container: "
1077 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
1078 		goto err_exit;
1079 	}
1080 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
1081 	if (error) {
1082 		device_printf(dev, "%s: failed to open network interface: "
1083 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
1084 		goto close_rc;
1085 	}
1086 
1087 	/* Select buffer pool (only one available at the moment). */
1088 	bp_dev = (device_t) rman_get_start(sc->res[DPAA2_NI_BP_RID(0)]);
1089 	bp_info = device_get_ivars(bp_dev);
1090 
1091 	/* Configure buffers pool. */
1092 	pools_cfg.pools_num = 1;
1093 	pools_cfg.pools[0].bp_obj_id = bp_info->id;
1094 	pools_cfg.pools[0].backup_flag = 0;
1095 	pools_cfg.pools[0].buf_sz = sc->buf_sz;
1096 	error = DPAA2_CMD_NI_SET_POOLS(dev, child, &cmd, &pools_cfg);
1097 	if (error) {
1098 		device_printf(dev, "%s: failed to set buffer pools\n", __func__);
1099 		goto close_ni;
1100 	}
1101 
1102 	/* Setup ingress traffic distribution. */
1103 	error = dpaa2_ni_setup_rx_dist(dev);
1104 	if (error && error != EOPNOTSUPP) {
1105 		device_printf(dev, "%s: failed to setup ingress traffic "
1106 		    "distribution\n", __func__);
1107 		goto close_ni;
1108 	}
1109 	if (bootverbose && error == EOPNOTSUPP) {
1110 		device_printf(dev, "Ingress traffic distribution not "
1111 		    "supported\n");
1112 	}
1113 
1114 	/* Configure handling of error frames. */
1115 	err_cfg.err_mask = DPAA2_NI_FAS_RX_ERR_MASK;
1116 	err_cfg.set_err_fas = false;
1117 	err_cfg.action = DPAA2_NI_ERR_DISCARD;
1118 	error = DPAA2_CMD_NI_SET_ERR_BEHAVIOR(dev, child, &cmd, &err_cfg);
1119 	if (error) {
1120 		device_printf(dev, "%s: failed to set errors behavior\n",
1121 		    __func__);
1122 		goto close_ni;
1123 	}
1124 
1125 	/* Configure channel queues to generate CDANs. */
1126 	for (uint32_t i = 0; i < sc->chan_n; i++) {
1127 		chan = sc->channels[i];
1128 
1129 		/* Setup Rx flows. */
1130 		for (uint32_t j = 0; j < chan->rxq_n; j++) {
1131 			error = dpaa2_ni_setup_rx_flow(dev, &chan->rx_queues[j]);
1132 			if (error) {
1133 				device_printf(dev, "%s: failed to setup Rx "
1134 				    "flow: error=%d\n", __func__, error);
1135 				goto close_ni;
1136 			}
1137 		}
1138 
1139 		/* Setup Tx flow. */
1140 		error = dpaa2_ni_setup_tx_flow(dev, &chan->txc_queue);
1141 		if (error) {
1142 			device_printf(dev, "%s: failed to setup Tx "
1143 			    "flow: error=%d\n", __func__, error);
1144 			goto close_ni;
1145 		}
1146 	}
1147 
1148 	/* Configure RxError queue to generate CDAN. */
1149 	error = dpaa2_ni_setup_rx_err_flow(dev, &sc->rxe_queue);
1150 	if (error) {
1151 		device_printf(dev, "%s: failed to setup RxError flow: "
1152 		    "error=%d\n", __func__, error);
1153 		goto close_ni;
1154 	}
1155 
1156 	/*
1157 	 * Get the Queuing Destination ID (QDID) that should be used for frame
1158 	 * enqueue operations.
1159 	 */
1160 	error = DPAA2_CMD_NI_GET_QDID(dev, child, &cmd, DPAA2_NI_QUEUE_TX,
1161 	    &sc->tx_qdid);
1162 	if (error) {
1163 		device_printf(dev, "%s: failed to get Tx queuing destination "
1164 		    "ID\n", __func__);
1165 		goto close_ni;
1166 	}
1167 
1168 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
1169 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1170 	return (0);
1171 
1172 close_ni:
1173 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
1174 close_rc:
1175 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1176 err_exit:
1177 	return (error);
1178 }
1179 
1180 /**
1181  * @brief Setup ingress traffic distribution.
1182  *
1183  * NOTE: Ingress traffic distribution is valid only when DPNI_OPT_NO_FS option
1184  *	 hasn't been set for DPNI and a number of DPNI queues > 1.
1185  */
1186 static int
dpaa2_ni_setup_rx_dist(device_t dev)1187 dpaa2_ni_setup_rx_dist(device_t dev)
1188 {
1189 	/*
1190 	 * Have the interface implicitly distribute traffic based on the default
1191 	 * hash key.
1192 	 */
1193 	return (dpaa2_ni_set_hash(dev, DPAA2_RXH_DEFAULT));
1194 }
1195 
1196 static int
dpaa2_ni_setup_rx_flow(device_t dev,struct dpaa2_ni_fq * fq)1197 dpaa2_ni_setup_rx_flow(device_t dev, struct dpaa2_ni_fq *fq)
1198 {
1199 	device_t pdev = device_get_parent(dev);
1200 	device_t child = dev;
1201 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
1202 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
1203 	struct dpaa2_devinfo *con_info;
1204 	struct dpaa2_cmd cmd;
1205 	struct dpaa2_ni_queue_cfg queue_cfg = {0};
1206 	uint16_t rc_token, ni_token;
1207 	int error;
1208 
1209 	DPAA2_CMD_INIT(&cmd);
1210 
1211 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
1212 	if (error) {
1213 		device_printf(dev, "%s: failed to open resource container: "
1214 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
1215 		goto err_exit;
1216 	}
1217 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
1218 	if (error) {
1219 		device_printf(dev, "%s: failed to open network interface: "
1220 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
1221 		goto close_rc;
1222 	}
1223 
1224 	/* Obtain DPCON associated with the FQ's channel. */
1225 	con_info = device_get_ivars(fq->chan->con_dev);
1226 
1227 	queue_cfg.type = DPAA2_NI_QUEUE_RX;
1228 	queue_cfg.tc = fq->tc;
1229 	queue_cfg.idx = fq->flowid;
1230 	error = DPAA2_CMD_NI_GET_QUEUE(dev, child, &cmd, &queue_cfg);
1231 	if (error) {
1232 		device_printf(dev, "%s: failed to obtain Rx queue "
1233 		    "configuration: tc=%d, flowid=%d\n", __func__, queue_cfg.tc,
1234 		    queue_cfg.idx);
1235 		goto close_ni;
1236 	}
1237 
1238 	fq->fqid = queue_cfg.fqid;
1239 
1240 	queue_cfg.dest_id = con_info->id;
1241 	queue_cfg.dest_type = DPAA2_NI_DEST_DPCON;
1242 	queue_cfg.priority = 1;
1243 	queue_cfg.user_ctx = (uint64_t)(uintmax_t) fq;
1244 	queue_cfg.options =
1245 	    DPAA2_NI_QUEUE_OPT_USER_CTX |
1246 	    DPAA2_NI_QUEUE_OPT_DEST;
1247 	error = DPAA2_CMD_NI_SET_QUEUE(dev, child, &cmd, &queue_cfg);
1248 	if (error) {
1249 		device_printf(dev, "%s: failed to update Rx queue "
1250 		    "configuration: tc=%d, flowid=%d\n", __func__, queue_cfg.tc,
1251 		    queue_cfg.idx);
1252 		goto close_ni;
1253 	}
1254 
1255 	if (bootverbose) {
1256 		device_printf(dev, "RX queue idx=%d, tc=%d, chan=%d, fqid=%d, "
1257 		    "user_ctx=%#jx\n", fq->flowid, fq->tc, fq->chan->id,
1258 		    fq->fqid, (uint64_t) fq);
1259 	}
1260 
1261 	(void)DPAA2_CMD_NI_CLOSE(dev, child, &cmd);
1262 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1263 	return (0);
1264 
1265 close_ni:
1266 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
1267 close_rc:
1268 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1269 err_exit:
1270 	return (error);
1271 }
1272 
1273 static int
dpaa2_ni_setup_tx_flow(device_t dev,struct dpaa2_ni_fq * fq)1274 dpaa2_ni_setup_tx_flow(device_t dev, struct dpaa2_ni_fq *fq)
1275 {
1276 	device_t pdev = device_get_parent(dev);
1277 	device_t child = dev;
1278 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
1279 	struct dpaa2_channel *ch = fq->chan;
1280 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
1281 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
1282 	struct dpaa2_devinfo *con_info;
1283 	struct dpaa2_ni_queue_cfg queue_cfg = {0};
1284 	struct dpaa2_ni_tx_ring *tx;
1285 	struct dpaa2_buf *buf;
1286 	struct dpaa2_cmd cmd;
1287 	uint32_t tx_rings_n = 0;
1288 	uint16_t rc_token, ni_token;
1289 	int error;
1290 
1291 	DPAA2_CMD_INIT(&cmd);
1292 
1293 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
1294 	if (error) {
1295 		device_printf(dev, "%s: failed to open resource container: "
1296 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
1297 		goto err_exit;
1298 	}
1299 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
1300 	if (error) {
1301 		device_printf(dev, "%s: failed to open network interface: "
1302 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
1303 		goto close_rc;
1304 	}
1305 
1306 	/* Obtain DPCON associated with the FQ's channel. */
1307 	con_info = device_get_ivars(fq->chan->con_dev);
1308 
1309 	KASSERT(sc->attr.num.tx_tcs <= DPAA2_MAX_TCS,
1310 	    ("%s: too many Tx traffic classes: tx_tcs=%d\n", __func__,
1311 	    sc->attr.num.tx_tcs));
1312 	KASSERT(DPAA2_NI_BUFS_PER_TX <= DPAA2_NI_MAX_BPTX,
1313 	    ("%s: too many Tx buffers (%d): max=%d\n", __func__,
1314 	    DPAA2_NI_BUFS_PER_TX, DPAA2_NI_MAX_BPTX));
1315 
1316 	/* Setup Tx rings. */
1317 	for (int i = 0; i < sc->attr.num.tx_tcs; i++) {
1318 		queue_cfg.type = DPAA2_NI_QUEUE_TX;
1319 		queue_cfg.tc = i;
1320 		queue_cfg.idx = fq->flowid;
1321 		queue_cfg.chan_id = fq->chan->id;
1322 
1323 		error = DPAA2_CMD_NI_GET_QUEUE(dev, child, &cmd, &queue_cfg);
1324 		if (error) {
1325 			device_printf(dev, "%s: failed to obtain Tx queue "
1326 			    "configuration: tc=%d, flowid=%d\n", __func__,
1327 			    queue_cfg.tc, queue_cfg.idx);
1328 			goto close_ni;
1329 		}
1330 
1331 		tx = &fq->tx_rings[i];
1332 		tx->fq = fq;
1333 		tx->fqid = queue_cfg.fqid;
1334 		tx->txid = tx_rings_n;
1335 
1336 		if (bootverbose) {
1337 			device_printf(dev, "TX queue idx=%d, tc=%d, chan=%d, "
1338 			    "fqid=%d\n", fq->flowid, i, fq->chan->id,
1339 			    queue_cfg.fqid);
1340 		}
1341 
1342 		mtx_init(&tx->lock, "dpaa2_tx_ring", NULL, MTX_DEF);
1343 
1344 		/* Allocate Tx ring buffer. */
1345 		tx->br = buf_ring_alloc(DPAA2_TX_BUFRING_SZ, M_DEVBUF, M_NOWAIT,
1346 		    &tx->lock);
1347 		if (tx->br == NULL) {
1348 			device_printf(dev, "%s: failed to setup Tx ring buffer"
1349 			    " (2) fqid=%d\n", __func__, tx->fqid);
1350 			goto close_ni;
1351 		}
1352 
1353 		/* Configure Tx buffers */
1354 		for (uint64_t j = 0; j < DPAA2_NI_BUFS_PER_TX; j++) {
1355 			buf = malloc(sizeof(struct dpaa2_buf), M_DPAA2_TXB,
1356 			    M_WAITOK);
1357 			/* Keep DMA tag and Tx ring linked to the buffer */
1358 			DPAA2_BUF_INIT_TAGOPT(buf, ch->tx_dmat, tx);
1359 
1360 			buf->sgt = malloc(sizeof(struct dpaa2_buf), M_DPAA2_TXB,
1361 			    M_WAITOK);
1362 			/* Link SGT to DMA tag and back to its Tx buffer */
1363 			DPAA2_BUF_INIT_TAGOPT(buf->sgt, ch->sgt_dmat, buf);
1364 
1365 			error = dpaa2_buf_seed_txb(dev, buf);
1366 
1367 			/* Add Tx buffer to the ring */
1368 			buf_ring_enqueue(tx->br, buf);
1369 		}
1370 
1371 		tx_rings_n++;
1372 	}
1373 
1374 	/* All Tx queues which belong to the same flowid have the same qdbin. */
1375 	fq->tx_qdbin = queue_cfg.qdbin;
1376 
1377 	queue_cfg.type = DPAA2_NI_QUEUE_TX_CONF;
1378 	queue_cfg.tc = 0; /* ignored for TxConf queue */
1379 	queue_cfg.idx = fq->flowid;
1380 	error = DPAA2_CMD_NI_GET_QUEUE(dev, child, &cmd, &queue_cfg);
1381 	if (error) {
1382 		device_printf(dev, "%s: failed to obtain TxConf queue "
1383 		    "configuration: tc=%d, flowid=%d\n", __func__, queue_cfg.tc,
1384 		    queue_cfg.idx);
1385 		goto close_ni;
1386 	}
1387 
1388 	fq->fqid = queue_cfg.fqid;
1389 
1390 	queue_cfg.dest_id = con_info->id;
1391 	queue_cfg.dest_type = DPAA2_NI_DEST_DPCON;
1392 	queue_cfg.priority = 0;
1393 	queue_cfg.user_ctx = (uint64_t)(uintmax_t) fq;
1394 	queue_cfg.options =
1395 	    DPAA2_NI_QUEUE_OPT_USER_CTX |
1396 	    DPAA2_NI_QUEUE_OPT_DEST;
1397 	error = DPAA2_CMD_NI_SET_QUEUE(dev, child, &cmd, &queue_cfg);
1398 	if (error) {
1399 		device_printf(dev, "%s: failed to update TxConf queue "
1400 		    "configuration: tc=%d, flowid=%d\n", __func__, queue_cfg.tc,
1401 		    queue_cfg.idx);
1402 		goto close_ni;
1403 	}
1404 
1405 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
1406 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1407 	return (0);
1408 
1409 close_ni:
1410 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
1411 close_rc:
1412 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1413 err_exit:
1414 	return (error);
1415 }
1416 
1417 static int
dpaa2_ni_setup_rx_err_flow(device_t dev,struct dpaa2_ni_fq * fq)1418 dpaa2_ni_setup_rx_err_flow(device_t dev, struct dpaa2_ni_fq *fq)
1419 {
1420 	device_t pdev = device_get_parent(dev);
1421 	device_t child = dev;
1422 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
1423 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
1424 	struct dpaa2_devinfo *con_info;
1425 	struct dpaa2_ni_queue_cfg queue_cfg = {0};
1426 	struct dpaa2_cmd cmd;
1427 	uint16_t rc_token, ni_token;
1428 	int error;
1429 
1430 	DPAA2_CMD_INIT(&cmd);
1431 
1432 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
1433 	if (error) {
1434 		device_printf(dev, "%s: failed to open resource container: "
1435 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
1436 		goto err_exit;
1437 	}
1438 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
1439 	if (error) {
1440 		device_printf(dev, "%s: failed to open network interface: "
1441 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
1442 		goto close_rc;
1443 	}
1444 
1445 	/* Obtain DPCON associated with the FQ's channel. */
1446 	con_info = device_get_ivars(fq->chan->con_dev);
1447 
1448 	queue_cfg.type = DPAA2_NI_QUEUE_RX_ERR;
1449 	queue_cfg.tc = fq->tc; /* ignored */
1450 	queue_cfg.idx = fq->flowid; /* ignored */
1451 	error = DPAA2_CMD_NI_GET_QUEUE(dev, child, &cmd, &queue_cfg);
1452 	if (error) {
1453 		device_printf(dev, "%s: failed to obtain RxErr queue "
1454 		    "configuration\n", __func__);
1455 		goto close_ni;
1456 	}
1457 
1458 	fq->fqid = queue_cfg.fqid;
1459 
1460 	queue_cfg.dest_id = con_info->id;
1461 	queue_cfg.dest_type = DPAA2_NI_DEST_DPCON;
1462 	queue_cfg.priority = 1;
1463 	queue_cfg.user_ctx = (uint64_t)(uintmax_t) fq;
1464 	queue_cfg.options =
1465 	    DPAA2_NI_QUEUE_OPT_USER_CTX |
1466 	    DPAA2_NI_QUEUE_OPT_DEST;
1467 	error = DPAA2_CMD_NI_SET_QUEUE(dev, child, &cmd, &queue_cfg);
1468 	if (error) {
1469 		device_printf(dev, "%s: failed to update RxErr queue "
1470 		    "configuration\n", __func__);
1471 		goto close_ni;
1472 	}
1473 
1474 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
1475 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1476 	return (0);
1477 
1478 close_ni:
1479 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
1480 close_rc:
1481 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1482 err_exit:
1483 	return (error);
1484 }
1485 
1486 /**
1487  * @brief Configure DPNI object to generate interrupts.
1488  */
1489 static int
dpaa2_ni_setup_irqs(device_t dev)1490 dpaa2_ni_setup_irqs(device_t dev)
1491 {
1492 	device_t pdev = device_get_parent(dev);
1493 	device_t child = dev;
1494 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
1495 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
1496 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
1497 	struct dpaa2_cmd cmd;
1498 	uint16_t rc_token, ni_token;
1499 	int error;
1500 
1501 	DPAA2_CMD_INIT(&cmd);
1502 
1503 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
1504 	if (error) {
1505 		device_printf(dev, "%s: failed to open resource container: "
1506 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
1507 		goto err_exit;
1508 	}
1509 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
1510 	if (error) {
1511 		device_printf(dev, "%s: failed to open network interface: "
1512 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
1513 		goto close_rc;
1514 	}
1515 
1516 	/* Configure IRQs. */
1517 	error = dpaa2_ni_setup_msi(sc);
1518 	if (error) {
1519 		device_printf(dev, "%s: failed to allocate MSI\n", __func__);
1520 		goto close_ni;
1521 	}
1522 	if ((sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
1523 	    &sc->irq_rid[0], RF_ACTIVE | RF_SHAREABLE)) == NULL) {
1524 		device_printf(dev, "%s: failed to allocate IRQ resource\n",
1525 		    __func__);
1526 		goto close_ni;
1527 	}
1528 	if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
1529 	    NULL, dpaa2_ni_intr, sc, &sc->intr)) {
1530 		device_printf(dev, "%s: failed to setup IRQ resource\n",
1531 		    __func__);
1532 		goto close_ni;
1533 	}
1534 
1535 	error = DPAA2_CMD_NI_SET_IRQ_MASK(dev, child, &cmd, DPNI_IRQ_INDEX,
1536 	    DPNI_IRQ_LINK_CHANGED | DPNI_IRQ_EP_CHANGED);
1537 	if (error) {
1538 		device_printf(dev, "%s: failed to set DPNI IRQ mask\n",
1539 		    __func__);
1540 		goto close_ni;
1541 	}
1542 
1543 	error = DPAA2_CMD_NI_SET_IRQ_ENABLE(dev, child, &cmd, DPNI_IRQ_INDEX,
1544 	    true);
1545 	if (error) {
1546 		device_printf(dev, "%s: failed to enable DPNI IRQ\n", __func__);
1547 		goto close_ni;
1548 	}
1549 
1550 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
1551 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1552 	return (0);
1553 
1554 close_ni:
1555 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
1556 close_rc:
1557 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1558 err_exit:
1559 	return (error);
1560 }
1561 
1562 /**
1563  * @brief Allocate MSI interrupts for DPNI.
1564  */
1565 static int
dpaa2_ni_setup_msi(struct dpaa2_ni_softc * sc)1566 dpaa2_ni_setup_msi(struct dpaa2_ni_softc *sc)
1567 {
1568 	int val;
1569 
1570 	val = pci_msi_count(sc->dev);
1571 	if (val < DPAA2_NI_MSI_COUNT)
1572 		device_printf(sc->dev, "MSI: actual=%d, expected=%d\n", val,
1573 		    DPAA2_IO_MSI_COUNT);
1574 	val = MIN(val, DPAA2_NI_MSI_COUNT);
1575 
1576 	if (pci_alloc_msi(sc->dev, &val) != 0)
1577 		return (EINVAL);
1578 
1579 	for (int i = 0; i < val; i++)
1580 		sc->irq_rid[i] = i + 1;
1581 
1582 	return (0);
1583 }
1584 
1585 /**
1586  * @brief Update DPNI according to the updated interface capabilities.
1587  */
1588 static int
dpaa2_ni_setup_if_caps(struct dpaa2_ni_softc * sc)1589 dpaa2_ni_setup_if_caps(struct dpaa2_ni_softc *sc)
1590 {
1591 	bool en_rxcsum, en_txcsum;
1592 	device_t pdev = device_get_parent(sc->dev);
1593 	device_t dev = sc->dev;
1594 	device_t child = dev;
1595 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
1596 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
1597 	struct dpaa2_cmd cmd;
1598 	uint16_t rc_token, ni_token;
1599 	int error;
1600 
1601 	DPAA2_CMD_INIT(&cmd);
1602 
1603 	/*
1604 	 * XXX-DSL: DPAA2 allows to validate L3/L4 checksums on reception and/or
1605 	 *          generate L3/L4 checksums on transmission without
1606 	 *          differentiating between IPv4/v6, i.e. enable for both
1607 	 *          protocols if requested.
1608 	 */
1609 	en_rxcsum = if_getcapenable(sc->ifp) &
1610 	    (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6);
1611 	en_txcsum = if_getcapenable(sc->ifp) &
1612 	    (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6);
1613 
1614 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
1615 	if (error) {
1616 		device_printf(dev, "%s: failed to open resource container: "
1617 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
1618 		goto err_exit;
1619 	}
1620 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
1621 	if (error) {
1622 		device_printf(dev, "%s: failed to open network interface: "
1623 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
1624 		goto close_rc;
1625 	}
1626 
1627 	/* Setup checksums validation. */
1628 	error = DPAA2_CMD_NI_SET_OFFLOAD(dev, child, &cmd,
1629 	    DPAA2_NI_OFL_RX_L3_CSUM, en_rxcsum);
1630 	if (error) {
1631 		device_printf(dev, "%s: failed to %s L3 checksum validation\n",
1632 		    __func__, en_rxcsum ? "enable" : "disable");
1633 		goto close_ni;
1634 	}
1635 	error = DPAA2_CMD_NI_SET_OFFLOAD(dev, child, &cmd,
1636 	    DPAA2_NI_OFL_RX_L4_CSUM, en_rxcsum);
1637 	if (error) {
1638 		device_printf(dev, "%s: failed to %s L4 checksum validation\n",
1639 		    __func__, en_rxcsum ? "enable" : "disable");
1640 		goto close_ni;
1641 	}
1642 
1643 	/* Setup checksums generation. */
1644 	error = DPAA2_CMD_NI_SET_OFFLOAD(dev, child, &cmd,
1645 	    DPAA2_NI_OFL_TX_L3_CSUM, en_txcsum);
1646 	if (error) {
1647 		device_printf(dev, "%s: failed to %s L3 checksum generation\n",
1648 		    __func__, en_txcsum ? "enable" : "disable");
1649 		goto close_ni;
1650 	}
1651 	error = DPAA2_CMD_NI_SET_OFFLOAD(dev, child, &cmd,
1652 	    DPAA2_NI_OFL_TX_L4_CSUM, en_txcsum);
1653 	if (error) {
1654 		device_printf(dev, "%s: failed to %s L4 checksum generation\n",
1655 		    __func__, en_txcsum ? "enable" : "disable");
1656 		goto close_ni;
1657 	}
1658 
1659 	if (bootverbose) {
1660 		device_printf(dev, "%s: L3/L4 checksum validation %s\n",
1661 		    __func__, en_rxcsum ? "enabled" : "disabled");
1662 		device_printf(dev, "%s: L3/L4 checksum generation %s\n",
1663 		    __func__, en_txcsum ? "enabled" : "disabled");
1664 	}
1665 
1666 	(void)DPAA2_CMD_NI_CLOSE(dev, child, &cmd);
1667 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1668 	return (0);
1669 
1670 close_ni:
1671 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
1672 close_rc:
1673 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1674 err_exit:
1675 	return (error);
1676 }
1677 
1678 /**
1679  * @brief Update DPNI according to the updated interface flags.
1680  */
1681 static int
dpaa2_ni_setup_if_flags(struct dpaa2_ni_softc * sc)1682 dpaa2_ni_setup_if_flags(struct dpaa2_ni_softc *sc)
1683 {
1684 	const bool en_promisc = if_getflags(sc->ifp) & IFF_PROMISC;
1685 	const bool en_allmulti = if_getflags(sc->ifp) & IFF_ALLMULTI;
1686 	device_t pdev = device_get_parent(sc->dev);
1687 	device_t dev = sc->dev;
1688 	device_t child = dev;
1689 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
1690 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
1691 	struct dpaa2_cmd cmd;
1692 	uint16_t rc_token, ni_token;
1693 	int error;
1694 
1695 	DPAA2_CMD_INIT(&cmd);
1696 
1697 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
1698 	if (error) {
1699 		device_printf(dev, "%s: failed to open resource container: "
1700 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
1701 		goto err_exit;
1702 	}
1703 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
1704 	if (error) {
1705 		device_printf(dev, "%s: failed to open network interface: "
1706 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
1707 		goto close_rc;
1708 	}
1709 
1710 	error = DPAA2_CMD_NI_SET_MULTI_PROMISC(dev, child, &cmd,
1711 	    en_promisc ? true : en_allmulti);
1712 	if (error) {
1713 		device_printf(dev, "%s: failed to %s multicast promiscuous "
1714 		    "mode\n", __func__, en_allmulti ? "enable" : "disable");
1715 		goto close_ni;
1716 	}
1717 
1718 	error = DPAA2_CMD_NI_SET_UNI_PROMISC(dev, child, &cmd, en_promisc);
1719 	if (error) {
1720 		device_printf(dev, "%s: failed to %s unicast promiscuous mode\n",
1721 		    __func__, en_promisc ? "enable" : "disable");
1722 		goto close_ni;
1723 	}
1724 
1725 	(void)DPAA2_CMD_NI_CLOSE(dev, child, &cmd);
1726 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1727 	return (0);
1728 
1729 close_ni:
1730 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
1731 close_rc:
1732 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
1733 err_exit:
1734 	return (error);
1735 }
1736 
1737 static int
dpaa2_ni_setup_sysctls(struct dpaa2_ni_softc * sc)1738 dpaa2_ni_setup_sysctls(struct dpaa2_ni_softc *sc)
1739 {
1740 	struct sysctl_ctx_list *ctx;
1741 	struct sysctl_oid *node, *node2;
1742 	struct sysctl_oid_list *parent, *parent2;
1743 	char cbuf[128];
1744 	int i;
1745 
1746 	ctx = device_get_sysctl_ctx(sc->dev);
1747 	parent = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev));
1748 
1749 	/* Add DPNI statistics. */
1750 	node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "stats",
1751 	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "DPNI Statistics");
1752 	parent = SYSCTL_CHILDREN(node);
1753 	for (i = 0; i < nitems(dpni_stat_sysctls); ++i) {
1754 		SYSCTL_ADD_PROC(ctx, parent, i, dpni_stat_sysctls[i].name,
1755 		    CTLTYPE_U64 | CTLFLAG_RD, sc, 0, dpaa2_ni_collect_stats,
1756 		    "IU", dpni_stat_sysctls[i].desc);
1757 	}
1758 	SYSCTL_ADD_UQUAD(ctx, parent, OID_AUTO, "rx_anomaly_frames",
1759 	    CTLFLAG_RD, &sc->rx_anomaly_frames,
1760 	    "Rx frames in the buffers outside of the buffer pools");
1761 	SYSCTL_ADD_UQUAD(ctx, parent, OID_AUTO, "rx_single_buf_frames",
1762 	    CTLFLAG_RD, &sc->rx_single_buf_frames,
1763 	    "Rx frames in single buffers");
1764 	SYSCTL_ADD_UQUAD(ctx, parent, OID_AUTO, "rx_sg_buf_frames",
1765 	    CTLFLAG_RD, &sc->rx_sg_buf_frames,
1766 	    "Rx frames in scatter/gather list");
1767 	SYSCTL_ADD_UQUAD(ctx, parent, OID_AUTO, "rx_enq_rej_frames",
1768 	    CTLFLAG_RD, &sc->rx_enq_rej_frames,
1769 	    "Enqueue rejected by QMan");
1770 	SYSCTL_ADD_UQUAD(ctx, parent, OID_AUTO, "rx_ieoi_err_frames",
1771 	    CTLFLAG_RD, &sc->rx_ieoi_err_frames,
1772 	    "QMan IEOI error");
1773 	SYSCTL_ADD_UQUAD(ctx, parent, OID_AUTO, "rx_other_err_frames",
1774 	    CTLFLAG_RD, &sc->rx_other_err_frames,
1775 	    "Other Rx frames with errors");
1776 	SYSCTL_ADD_UQUAD(ctx, parent, OID_AUTO, "tx_single_buf_frames",
1777 	    CTLFLAG_RD, &sc->tx_single_buf_frames,
1778 	    "Tx single buffer frames");
1779 	SYSCTL_ADD_UQUAD(ctx, parent, OID_AUTO, "tx_sg_frames",
1780 	    CTLFLAG_RD, &sc->tx_sg_frames,
1781 	    "Tx S/G frames");
1782 
1783 	SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "buf_num",
1784 	    CTLTYPE_U32 | CTLFLAG_RD, sc, 0, dpaa2_ni_collect_buf_num,
1785 	    "IU", "number of Rx buffers in the buffer pool");
1786 	SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "buf_free",
1787 	    CTLTYPE_U32 | CTLFLAG_RD, sc, 0, dpaa2_ni_collect_buf_free,
1788 	    "IU", "number of free Rx buffers in the buffer pool");
1789 
1790 	/* Add channels statistics. */
1791 	parent = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev));
1792 	node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "channels",
1793 	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "DPNI Channels");
1794 	parent = SYSCTL_CHILDREN(node);
1795 	for (int i = 0; i < sc->chan_n; i++) {
1796 		snprintf(cbuf, sizeof(cbuf), "%d", i);
1797 
1798 		node2 = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, cbuf,
1799 		    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "DPNI Channel");
1800 		parent2 = SYSCTL_CHILDREN(node2);
1801 
1802 		SYSCTL_ADD_UQUAD(ctx, parent2, OID_AUTO, "tx_frames",
1803 		    CTLFLAG_RD, &sc->channels[i]->tx_frames,
1804 		    "Tx frames counter");
1805 		SYSCTL_ADD_UQUAD(ctx, parent2, OID_AUTO, "tx_dropped",
1806 		    CTLFLAG_RD, &sc->channels[i]->tx_dropped,
1807 		    "Tx dropped counter");
1808 	}
1809 
1810 	/* Add Link debugging options. */
1811 	parent = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev));
1812 	node = SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "link",
1813 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
1814 	    sc, 0, dpaa2_ni_sysctl_link_state,
1815 	    "A", "DPNI link state information");
1816 
1817 	return (0);
1818 }
1819 
1820 static int
dpaa2_ni_setup_dma(struct dpaa2_ni_softc * sc)1821 dpaa2_ni_setup_dma(struct dpaa2_ni_softc *sc)
1822 {
1823 	device_t dev = sc->dev;
1824 	int error;
1825 
1826 	KASSERT((sc->buf_align == BUF_ALIGN) || (sc->buf_align == BUF_ALIGN_V1),
1827 	    ("unexpected buffer alignment: %d\n", sc->buf_align));
1828 
1829 	/* DMA tag for Rx distribution key. */
1830 	error = bus_dma_tag_create(
1831 	    bus_get_dma_tag(dev),
1832 	    PAGE_SIZE, 0,		/* alignment, boundary */
1833 	    BUS_SPACE_MAXADDR,		/* low restricted addr */
1834 	    BUS_SPACE_MAXADDR,		/* high restricted addr */
1835 	    NULL, NULL,			/* filter, filterarg */
1836 	    DPAA2_CLASSIFIER_DMA_SIZE, 1, /* maxsize, nsegments */
1837 	    DPAA2_CLASSIFIER_DMA_SIZE, 0, /* maxsegsize, flags */
1838 	    NULL, NULL,			/* lockfunc, lockarg */
1839 	    &sc->rxd_dmat);
1840 	if (error) {
1841 		device_printf(dev, "%s: failed to create DMA tag for Rx "
1842 		    "distribution key\n", __func__);
1843 		return (error);
1844 	}
1845 
1846 	error = bus_dma_tag_create(
1847 	    bus_get_dma_tag(dev),
1848 	    PAGE_SIZE, 0,		/* alignment, boundary */
1849 	    BUS_SPACE_MAXADDR,		/* low restricted addr */
1850 	    BUS_SPACE_MAXADDR,		/* high restricted addr */
1851 	    NULL, NULL,			/* filter, filterarg */
1852 	    ETH_QOS_KCFG_BUF_SIZE, 1,	/* maxsize, nsegments */
1853 	    ETH_QOS_KCFG_BUF_SIZE, 0,	/* maxsegsize, flags */
1854 	    NULL, NULL,			/* lockfunc, lockarg */
1855 	    &sc->qos_dmat);
1856 	if (error) {
1857 		device_printf(dev, "%s: failed to create DMA tag for QoS key\n",
1858 		    __func__);
1859 		return (error);
1860 	}
1861 
1862 	return (0);
1863 }
1864 
1865 /**
1866  * @brief Configure buffer layouts of the different DPNI queues.
1867  */
1868 static int
dpaa2_ni_set_buf_layout(device_t dev)1869 dpaa2_ni_set_buf_layout(device_t dev)
1870 {
1871 	device_t pdev = device_get_parent(dev);
1872 	device_t child = dev;
1873 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
1874 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
1875 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
1876 	struct dpaa2_ni_buf_layout buf_layout = {0};
1877 	struct dpaa2_cmd cmd;
1878 	uint16_t rc_token, ni_token;
1879 	int error;
1880 
1881 	DPAA2_CMD_INIT(&cmd);
1882 
1883 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
1884 	if (error) {
1885 		device_printf(dev, "%s: failed to open resource container: "
1886 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
1887 		goto err_exit;
1888 	}
1889 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
1890 	if (error) {
1891 		device_printf(sc->dev, "%s: failed to open DPMAC: id=%d, "
1892 		    "error=%d\n", __func__, dinfo->id, error);
1893 		goto close_rc;
1894 	}
1895 
1896 	/*
1897 	 * Select Rx/Tx buffer alignment. It's necessary to ensure that the
1898 	 * buffer size seen by WRIOP is a multiple of 64 or 256 bytes depending
1899 	 * on the WRIOP version.
1900 	 */
1901 	sc->buf_align = (sc->attr.wriop_ver == WRIOP_VERSION(0, 0, 0) ||
1902 	    sc->attr.wriop_ver == WRIOP_VERSION(1, 0, 0))
1903 	    ? BUF_ALIGN_V1 : BUF_ALIGN;
1904 
1905 	/*
1906 	 * We need to ensure that the buffer size seen by WRIOP is a multiple
1907 	 * of 64 or 256 bytes depending on the WRIOP version.
1908 	 */
1909 	sc->buf_sz = ALIGN_DOWN(DPAA2_RX_BUF_SIZE, sc->buf_align);
1910 
1911 	if (bootverbose) {
1912 		device_printf(dev, "Rx/Tx buffers: size=%d, alignment=%d\n",
1913 		    sc->buf_sz, sc->buf_align);
1914 	}
1915 
1916 	/*
1917 	 *    Frame Descriptor       Tx buffer layout
1918 	 *
1919 	 *                ADDR -> |---------------------|
1920 	 *                        | SW FRAME ANNOTATION | BUF_SWA_SIZE bytes
1921 	 *                        |---------------------|
1922 	 *                        | HW FRAME ANNOTATION | BUF_TX_HWA_SIZE bytes
1923 	 *                        |---------------------|
1924 	 *                        |    DATA HEADROOM    |
1925 	 *       ADDR + OFFSET -> |---------------------|
1926 	 *                        |                     |
1927 	 *                        |                     |
1928 	 *                        |     FRAME DATA      |
1929 	 *                        |                     |
1930 	 *                        |                     |
1931 	 *                        |---------------------|
1932 	 *                        |    DATA TAILROOM    |
1933 	 *                        |---------------------|
1934 	 *
1935 	 * NOTE: It's for a single buffer frame only.
1936 	 */
1937 	buf_layout.queue_type = DPAA2_NI_QUEUE_TX;
1938 	buf_layout.pd_size = BUF_SWA_SIZE;
1939 	buf_layout.pass_timestamp = true;
1940 	buf_layout.pass_frame_status = true;
1941 	buf_layout.options =
1942 	    BUF_LOPT_PRIV_DATA_SZ |
1943 	    BUF_LOPT_TIMESTAMP | /* requires 128 bytes in HWA */
1944 	    BUF_LOPT_FRAME_STATUS;
1945 	error = DPAA2_CMD_NI_SET_BUF_LAYOUT(dev, child, &cmd, &buf_layout);
1946 	if (error) {
1947 		device_printf(dev, "%s: failed to set Tx buffer layout\n",
1948 		    __func__);
1949 		goto close_ni;
1950 	}
1951 
1952 	/* Tx-confirmation buffer layout */
1953 	buf_layout.queue_type = DPAA2_NI_QUEUE_TX_CONF;
1954 	buf_layout.options =
1955 	    BUF_LOPT_TIMESTAMP |
1956 	    BUF_LOPT_FRAME_STATUS;
1957 	error = DPAA2_CMD_NI_SET_BUF_LAYOUT(dev, child, &cmd, &buf_layout);
1958 	if (error) {
1959 		device_printf(dev, "%s: failed to set TxConf buffer layout\n",
1960 		    __func__);
1961 		goto close_ni;
1962 	}
1963 
1964 	/*
1965 	 * Driver should reserve the amount of space indicated by this command
1966 	 * as headroom in all Tx frames.
1967 	 */
1968 	error = DPAA2_CMD_NI_GET_TX_DATA_OFF(dev, child, &cmd, &sc->tx_data_off);
1969 	if (error) {
1970 		device_printf(dev, "%s: failed to obtain Tx data offset\n",
1971 		    __func__);
1972 		goto close_ni;
1973 	}
1974 
1975 	if (bootverbose) {
1976 		device_printf(dev, "Tx data offset=%d\n", sc->tx_data_off);
1977 	}
1978 	if ((sc->tx_data_off % 64) != 0) {
1979 		device_printf(dev, "Tx data offset (%d) is not a multiplication "
1980 		    "of 64 bytes\n", sc->tx_data_off);
1981 	}
1982 
1983 	/*
1984 	 *    Frame Descriptor       Rx buffer layout
1985 	 *
1986 	 *                ADDR -> |---------------------|
1987 	 *                        | SW FRAME ANNOTATION | BUF_SWA_SIZE bytes
1988 	 *                        |---------------------|
1989 	 *                        | HW FRAME ANNOTATION | BUF_RX_HWA_SIZE bytes
1990 	 *                        |---------------------|
1991 	 *                        |    DATA HEADROOM    | OFFSET-BUF_RX_HWA_SIZE
1992 	 *       ADDR + OFFSET -> |---------------------|
1993 	 *                        |                     |
1994 	 *                        |                     |
1995 	 *                        |     FRAME DATA      |
1996 	 *                        |                     |
1997 	 *                        |                     |
1998 	 *                        |---------------------|
1999 	 *                        |    DATA TAILROOM    | 0 bytes
2000 	 *                        |---------------------|
2001 	 *
2002 	 * NOTE: It's for a single buffer frame only.
2003 	 */
2004 	buf_layout.queue_type = DPAA2_NI_QUEUE_RX;
2005 	buf_layout.pd_size = BUF_SWA_SIZE;
2006 	buf_layout.fd_align = sc->buf_align;
2007 	buf_layout.head_size = sc->tx_data_off - BUF_RX_HWA_SIZE - BUF_SWA_SIZE;
2008 	buf_layout.tail_size = 0;
2009 	buf_layout.pass_frame_status = true;
2010 	buf_layout.pass_parser_result = true;
2011 	buf_layout.pass_timestamp = true;
2012 	buf_layout.options =
2013 	    BUF_LOPT_PRIV_DATA_SZ |
2014 	    BUF_LOPT_DATA_ALIGN |
2015 	    BUF_LOPT_DATA_HEAD_ROOM |
2016 	    BUF_LOPT_DATA_TAIL_ROOM |
2017 	    BUF_LOPT_FRAME_STATUS |
2018 	    BUF_LOPT_PARSER_RESULT |
2019 	    BUF_LOPT_TIMESTAMP;
2020 	error = DPAA2_CMD_NI_SET_BUF_LAYOUT(dev, child, &cmd, &buf_layout);
2021 	if (error) {
2022 		device_printf(dev, "%s: failed to set Rx buffer layout\n",
2023 		    __func__);
2024 		goto close_ni;
2025 	}
2026 
2027 	error = 0;
2028 close_ni:
2029 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
2030 close_rc:
2031 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
2032 err_exit:
2033 	return (error);
2034 }
2035 
2036 /**
2037  * @brief Enable Rx/Tx pause frames.
2038  *
2039  * NOTE: DPNI stops sending when a pause frame is received (Rx frame) or DPNI
2040  *       itself generates pause frames (Tx frame).
2041  */
2042 static int
dpaa2_ni_set_pause_frame(device_t dev)2043 dpaa2_ni_set_pause_frame(device_t dev)
2044 {
2045 	device_t pdev = device_get_parent(dev);
2046 	device_t child = dev;
2047 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
2048 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
2049 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
2050 	struct dpaa2_ni_link_cfg link_cfg = {0};
2051 	struct dpaa2_cmd cmd;
2052 	uint16_t rc_token, ni_token;
2053 	int error;
2054 
2055 	DPAA2_CMD_INIT(&cmd);
2056 
2057 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
2058 	if (error) {
2059 		device_printf(dev, "%s: failed to open resource container: "
2060 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
2061 		goto err_exit;
2062 	}
2063 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
2064 	if (error) {
2065 		device_printf(sc->dev, "%s: failed to open DPMAC: id=%d, "
2066 		    "error=%d\n", __func__, dinfo->id, error);
2067 		goto close_rc;
2068 	}
2069 
2070 	error = DPAA2_CMD_NI_GET_LINK_CFG(dev, child, &cmd, &link_cfg);
2071 	if (error) {
2072 		device_printf(dev, "%s: failed to obtain link configuration: "
2073 		    "error=%d\n", __func__, error);
2074 		goto close_ni;
2075 	}
2076 
2077 	/* Enable both Rx and Tx pause frames by default. */
2078 	link_cfg.options |= DPAA2_NI_LINK_OPT_PAUSE;
2079 	link_cfg.options &= ~DPAA2_NI_LINK_OPT_ASYM_PAUSE;
2080 
2081 	error = DPAA2_CMD_NI_SET_LINK_CFG(dev, child, &cmd, &link_cfg);
2082 	if (error) {
2083 		device_printf(dev, "%s: failed to set link configuration: "
2084 		    "error=%d\n", __func__, error);
2085 		goto close_ni;
2086 	}
2087 
2088 	sc->link_options = link_cfg.options;
2089 	error = 0;
2090 close_ni:
2091 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
2092 close_rc:
2093 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
2094 err_exit:
2095 	return (error);
2096 }
2097 
2098 /**
2099  * @brief Configure QoS table to determine the traffic class for the received
2100  * frame.
2101  */
2102 static int
dpaa2_ni_set_qos_table(device_t dev)2103 dpaa2_ni_set_qos_table(device_t dev)
2104 {
2105 	device_t pdev = device_get_parent(dev);
2106 	device_t child = dev;
2107 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
2108 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
2109 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
2110 	struct dpaa2_ni_qos_table tbl;
2111 	struct dpaa2_buf *buf = &sc->qos_kcfg;
2112 	struct dpaa2_cmd cmd;
2113 	uint16_t rc_token, ni_token;
2114 	int error;
2115 
2116 	if (sc->attr.num.rx_tcs == 1 ||
2117 	    !(sc->attr.options & DPNI_OPT_HAS_KEY_MASKING)) {
2118 		if (bootverbose) {
2119 			device_printf(dev, "Ingress traffic classification is "
2120 			    "not supported\n");
2121 		}
2122 		return (0);
2123 	}
2124 
2125 	/*
2126 	 * Allocate a buffer visible to the device to hold the QoS table key
2127 	 * configuration.
2128 	 */
2129 
2130 	if (__predict_true(buf->dmat == NULL)) {
2131 		buf->dmat = sc->qos_dmat;
2132 	}
2133 
2134 	error = bus_dmamem_alloc(buf->dmat, (void **)&buf->vaddr,
2135 	    BUS_DMA_ZERO | BUS_DMA_COHERENT, &buf->dmap);
2136 	if (error) {
2137 		device_printf(dev, "%s: failed to allocate a buffer for QoS key "
2138 		    "configuration\n", __func__);
2139 		goto err_exit;
2140 	}
2141 
2142 	error = bus_dmamap_load(buf->dmat, buf->dmap, buf->vaddr,
2143 	    ETH_QOS_KCFG_BUF_SIZE, dpaa2_dmamap_oneseg_cb, &buf->paddr,
2144 	    BUS_DMA_NOWAIT);
2145 	if (error) {
2146 		device_printf(dev, "%s: failed to map QoS key configuration "
2147 		    "buffer into bus space\n", __func__);
2148 		goto err_exit;
2149 	}
2150 
2151 	DPAA2_CMD_INIT(&cmd);
2152 
2153 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
2154 	if (error) {
2155 		device_printf(dev, "%s: failed to open resource container: "
2156 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
2157 		goto err_exit;
2158 	}
2159 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
2160 	if (error) {
2161 		device_printf(sc->dev, "%s: failed to open DPMAC: id=%d, "
2162 		    "error=%d\n", __func__, dinfo->id, error);
2163 		goto close_rc;
2164 	}
2165 
2166 	tbl.default_tc = 0;
2167 	tbl.discard_on_miss = false;
2168 	tbl.keep_entries = false;
2169 	tbl.kcfg_busaddr = buf->paddr;
2170 	error = DPAA2_CMD_NI_SET_QOS_TABLE(dev, child, &cmd, &tbl);
2171 	if (error) {
2172 		device_printf(dev, "%s: failed to set QoS table\n", __func__);
2173 		goto close_ni;
2174 	}
2175 
2176 	error = DPAA2_CMD_NI_CLEAR_QOS_TABLE(dev, child, &cmd);
2177 	if (error) {
2178 		device_printf(dev, "%s: failed to clear QoS table\n", __func__);
2179 		goto close_ni;
2180 	}
2181 
2182 	error = 0;
2183 close_ni:
2184 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
2185 close_rc:
2186 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
2187 err_exit:
2188 	return (error);
2189 }
2190 
2191 static int
dpaa2_ni_set_mac_addr(device_t dev)2192 dpaa2_ni_set_mac_addr(device_t dev)
2193 {
2194 	device_t pdev = device_get_parent(dev);
2195 	device_t child = dev;
2196 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
2197 	if_t ifp = sc->ifp;
2198 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
2199 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
2200 	struct dpaa2_cmd cmd;
2201 	struct ether_addr rnd_mac_addr;
2202 	uint16_t rc_token, ni_token;
2203 	uint8_t mac_addr[ETHER_ADDR_LEN];
2204 	uint8_t dpni_mac_addr[ETHER_ADDR_LEN];
2205 	int error;
2206 
2207 	DPAA2_CMD_INIT(&cmd);
2208 
2209 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
2210 	if (error) {
2211 		device_printf(dev, "%s: failed to open resource container: "
2212 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
2213 		goto err_exit;
2214 	}
2215 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
2216 	if (error) {
2217 		device_printf(sc->dev, "%s: failed to open DPMAC: id=%d, "
2218 		    "error=%d\n", __func__, dinfo->id, error);
2219 		goto close_rc;
2220 	}
2221 
2222 	/*
2223 	 * Get the MAC address associated with the physical port, if the DPNI is
2224 	 * connected to a DPMAC directly associated with one of the physical
2225 	 * ports.
2226 	 */
2227 	error = DPAA2_CMD_NI_GET_PORT_MAC_ADDR(dev, child, &cmd, mac_addr);
2228 	if (error) {
2229 		device_printf(dev, "%s: failed to obtain the MAC address "
2230 		    "associated with the physical port\n", __func__);
2231 		goto close_ni;
2232 	}
2233 
2234 	/* Get primary MAC address from the DPNI attributes. */
2235 	error = DPAA2_CMD_NI_GET_PRIM_MAC_ADDR(dev, child, &cmd, dpni_mac_addr);
2236 	if (error) {
2237 		device_printf(dev, "%s: failed to obtain primary MAC address\n",
2238 		    __func__);
2239 		goto close_ni;
2240 	}
2241 
2242 	if (!ETHER_IS_ZERO(mac_addr)) {
2243 		/* Set MAC address of the physical port as DPNI's primary one. */
2244 		error = DPAA2_CMD_NI_SET_PRIM_MAC_ADDR(dev, child, &cmd,
2245 		    mac_addr);
2246 		if (error) {
2247 			device_printf(dev, "%s: failed to set primary MAC "
2248 			    "address\n", __func__);
2249 			goto close_ni;
2250 		}
2251 		for (int i = 0; i < ETHER_ADDR_LEN; i++) {
2252 			sc->mac.addr[i] = mac_addr[i];
2253 		}
2254 	} else if (ETHER_IS_ZERO(dpni_mac_addr)) {
2255 		/* Generate random MAC address as DPNI's primary one. */
2256 		ether_gen_addr(ifp, &rnd_mac_addr);
2257 		for (int i = 0; i < ETHER_ADDR_LEN; i++) {
2258 			mac_addr[i] = rnd_mac_addr.octet[i];
2259 		}
2260 
2261 		error = DPAA2_CMD_NI_SET_PRIM_MAC_ADDR(dev, child, &cmd,
2262 		    mac_addr);
2263 		if (error) {
2264 			device_printf(dev, "%s: failed to set random primary "
2265 			    "MAC address\n", __func__);
2266 			goto close_ni;
2267 		}
2268 		for (int i = 0; i < ETHER_ADDR_LEN; i++) {
2269 			sc->mac.addr[i] = mac_addr[i];
2270 		}
2271 	} else {
2272 		for (int i = 0; i < ETHER_ADDR_LEN; i++) {
2273 			sc->mac.addr[i] = dpni_mac_addr[i];
2274 		}
2275 	}
2276 
2277 	error = 0;
2278 close_ni:
2279 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
2280 close_rc:
2281 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
2282 err_exit:
2283 	return (error);
2284 }
2285 
2286 static void
dpaa2_ni_miibus_statchg(device_t dev)2287 dpaa2_ni_miibus_statchg(device_t dev)
2288 {
2289 	device_t pdev = device_get_parent(dev);
2290 	device_t child = dev;
2291 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
2292 	struct dpaa2_mac_link_state mac_link = { 0 };
2293 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
2294 	struct dpaa2_cmd cmd;
2295 	uint16_t rc_token, mac_token;
2296 	int error, link_state;
2297 
2298 	if (sc->fixed_link || sc->mii == NULL) {
2299 		return;
2300 	}
2301 	if ((if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) == 0) {
2302 		/*
2303 		 * We will receive calls and adjust the changes but
2304 		 * not have setup everything (called before dpaa2_ni_init()
2305 		 * really).  This will then setup the link and internal
2306 		 * sc->link_state and not trigger the update once needed,
2307 		 * so basically dpmac never knows about it.
2308 		 */
2309 		return;
2310 	}
2311 
2312 	/*
2313 	 * Note: ifp link state will only be changed AFTER we are called so we
2314 	 * cannot rely on ifp->if_linkstate here.
2315 	 */
2316 	if (sc->mii->mii_media_status & IFM_AVALID) {
2317 		if (sc->mii->mii_media_status & IFM_ACTIVE) {
2318 			link_state = LINK_STATE_UP;
2319 		} else {
2320 			link_state = LINK_STATE_DOWN;
2321 		}
2322 	} else {
2323 		link_state = LINK_STATE_UNKNOWN;
2324 	}
2325 
2326 	if (link_state != sc->link_state) {
2327 		sc->link_state = link_state;
2328 
2329 		DPAA2_CMD_INIT(&cmd);
2330 
2331 		error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id,
2332 		    &rc_token);
2333 		if (error) {
2334 			device_printf(dev, "%s: failed to open resource "
2335 			    "container: id=%d, error=%d\n", __func__, rcinfo->id,
2336 			    error);
2337 			goto err_exit;
2338 		}
2339 		error = DPAA2_CMD_MAC_OPEN(dev, child, &cmd, sc->mac.dpmac_id,
2340 		    &mac_token);
2341 		if (error) {
2342 			device_printf(sc->dev, "%s: failed to open DPMAC: "
2343 			    "id=%d, error=%d\n", __func__, sc->mac.dpmac_id,
2344 			    error);
2345 			goto close_rc;
2346 		}
2347 
2348 		if (link_state == LINK_STATE_UP ||
2349 		    link_state == LINK_STATE_DOWN) {
2350 			/* Update DPMAC link state. */
2351 			mac_link.supported = sc->mii->mii_media.ifm_media;
2352 			mac_link.advert = sc->mii->mii_media.ifm_media;
2353 			mac_link.rate = 1000; /* TODO: Where to get from? */	/* ifmedia_baudrate? */
2354 			mac_link.options =
2355 			    DPAA2_MAC_LINK_OPT_AUTONEG |
2356 			    DPAA2_MAC_LINK_OPT_PAUSE;
2357 			mac_link.up = (link_state == LINK_STATE_UP) ? true : false;
2358 			mac_link.state_valid = true;
2359 
2360 			/* Inform DPMAC about link state. */
2361 			error = DPAA2_CMD_MAC_SET_LINK_STATE(dev, child, &cmd,
2362 			    &mac_link);
2363 			if (error) {
2364 				device_printf(sc->dev, "%s: failed to set DPMAC "
2365 				    "link state: id=%d, error=%d\n", __func__,
2366 				    sc->mac.dpmac_id, error);
2367 			}
2368 		}
2369 		(void)DPAA2_CMD_MAC_CLOSE(dev, child, &cmd);
2370 		(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd,
2371 		    rc_token));
2372 	}
2373 
2374 	return;
2375 
2376 close_rc:
2377 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
2378 err_exit:
2379 	return;
2380 }
2381 
2382 /**
2383  * @brief Callback function to process media change request.
2384  */
2385 static int
dpaa2_ni_media_change_locked(struct dpaa2_ni_softc * sc)2386 dpaa2_ni_media_change_locked(struct dpaa2_ni_softc *sc)
2387 {
2388 
2389 	DPNI_LOCK_ASSERT(sc);
2390 	if (sc->mii) {
2391 		mii_mediachg(sc->mii);
2392 		sc->media_status = sc->mii->mii_media.ifm_media;
2393 	} else if (sc->fixed_link) {
2394 		if_printf(sc->ifp, "%s: can't change media in fixed mode\n",
2395 		    __func__);
2396 	}
2397 
2398 	return (0);
2399 }
2400 
2401 static int
dpaa2_ni_media_change(if_t ifp)2402 dpaa2_ni_media_change(if_t ifp)
2403 {
2404 	struct dpaa2_ni_softc *sc = if_getsoftc(ifp);
2405 	int error;
2406 
2407 	DPNI_LOCK(sc);
2408 	error = dpaa2_ni_media_change_locked(sc);
2409 	DPNI_UNLOCK(sc);
2410 	return (error);
2411 }
2412 
2413 /**
2414  * @brief Callback function to process media status request.
2415  */
2416 static void
dpaa2_ni_media_status(if_t ifp,struct ifmediareq * ifmr)2417 dpaa2_ni_media_status(if_t ifp, struct ifmediareq *ifmr)
2418 {
2419 	struct dpaa2_ni_softc *sc = if_getsoftc(ifp);
2420 
2421 	DPNI_LOCK(sc);
2422 	if (sc->mii) {
2423 		mii_pollstat(sc->mii);
2424 		ifmr->ifm_active = sc->mii->mii_media_active;
2425 		ifmr->ifm_status = sc->mii->mii_media_status;
2426 	}
2427 	DPNI_UNLOCK(sc);
2428 }
2429 
2430 /**
2431  * @brief Callout function to check and update media status.
2432  */
2433 static void
dpaa2_ni_media_tick(void * arg)2434 dpaa2_ni_media_tick(void *arg)
2435 {
2436 	struct dpaa2_ni_softc *sc = (struct dpaa2_ni_softc *) arg;
2437 
2438 	/* Check for media type change */
2439 	if (sc->mii) {
2440 		mii_tick(sc->mii);
2441 		if (sc->media_status != sc->mii->mii_media.ifm_media) {
2442 			printf("%s: media type changed (ifm_media=%x)\n",
2443 			    __func__, sc->mii->mii_media.ifm_media);
2444 			dpaa2_ni_media_change(sc->ifp);
2445 		}
2446 	}
2447 
2448 	/* Schedule another timeout one second from now */
2449 	callout_reset(&sc->mii_callout, hz, dpaa2_ni_media_tick, sc);
2450 }
2451 
2452 static void
dpaa2_ni_init(void * arg)2453 dpaa2_ni_init(void *arg)
2454 {
2455 	struct dpaa2_ni_softc *sc = (struct dpaa2_ni_softc *) arg;
2456 	if_t ifp = sc->ifp;
2457 	device_t pdev = device_get_parent(sc->dev);
2458 	device_t dev = sc->dev;
2459 	device_t child = dev;
2460 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
2461 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
2462 	struct dpaa2_cmd cmd;
2463 	uint16_t rc_token, ni_token;
2464 	int error;
2465 
2466 	DPNI_LOCK(sc);
2467 	if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) != 0) {
2468 		DPNI_UNLOCK(sc);
2469 		return;
2470 	}
2471 	DPNI_UNLOCK(sc);
2472 
2473 	DPAA2_CMD_INIT(&cmd);
2474 
2475 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
2476 	if (error) {
2477 		device_printf(dev, "%s: failed to open resource container: "
2478 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
2479 		goto err_exit;
2480 	}
2481 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
2482 	if (error) {
2483 		device_printf(dev, "%s: failed to open network interface: "
2484 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
2485 		goto close_rc;
2486 	}
2487 
2488 	error = DPAA2_CMD_NI_ENABLE(dev, child, &cmd);
2489 	if (error) {
2490 		device_printf(dev, "%s: failed to enable DPNI: error=%d\n",
2491 		    __func__, error);
2492 	}
2493 
2494 	DPNI_LOCK(sc);
2495 	/* Announce we are up and running and can queue packets. */
2496 	if_setdrvflagbits(ifp, IFF_DRV_RUNNING, IFF_DRV_OACTIVE);
2497 
2498 	if (sc->mii) {
2499 		/*
2500 		 * mii_mediachg() will trigger a call into
2501 		 * dpaa2_ni_miibus_statchg() to setup link state.
2502 		 */
2503 		dpaa2_ni_media_change_locked(sc);
2504 	}
2505 	callout_reset(&sc->mii_callout, hz, dpaa2_ni_media_tick, sc);
2506 
2507 	DPNI_UNLOCK(sc);
2508 
2509 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
2510 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
2511 	return;
2512 
2513 close_rc:
2514 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
2515 err_exit:
2516 	return;
2517 }
2518 
2519 static int
dpaa2_ni_transmit(if_t ifp,struct mbuf * m)2520 dpaa2_ni_transmit(if_t ifp, struct mbuf *m)
2521 {
2522 	struct dpaa2_ni_softc *sc = if_getsoftc(ifp);
2523 	struct dpaa2_channel *ch;
2524 	uint32_t fqid;
2525 	bool found = false;
2526 	int chidx = 0, error;
2527 
2528 	if (__predict_false(!(if_getdrvflags(ifp) & IFF_DRV_RUNNING))) {
2529 		return (0);
2530 	}
2531 
2532 	if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) {
2533 		fqid = m->m_pkthdr.flowid;
2534 		for (int i = 0; i < sc->chan_n; i++) {
2535 			ch = sc->channels[i];
2536 			for (int j = 0; j < ch->rxq_n; j++) {
2537 				if (fqid == ch->rx_queues[j].fqid) {
2538 					chidx = ch->flowid;
2539 					found = true;
2540 					break;
2541 				}
2542 			}
2543 			if (found) {
2544 				break;
2545 			}
2546 		}
2547 	}
2548 
2549 	ch = sc->channels[chidx];
2550 	error = buf_ring_enqueue(ch->xmit_br, m);
2551 	if (__predict_false(error != 0)) {
2552 		if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
2553 		m_freem(m);
2554 	} else {
2555 		taskqueue_enqueue(ch->cleanup_tq, &ch->cleanup_task);
2556 	}
2557 
2558 	return (error);
2559 }
2560 
2561 static void
dpaa2_ni_qflush(if_t ifp)2562 dpaa2_ni_qflush(if_t ifp)
2563 {
2564 	/* TODO: Find a way to drain Tx queues in QBMan. */
2565 	if_qflush(ifp);
2566 }
2567 
2568 static int
dpaa2_ni_ioctl(if_t ifp,u_long c,caddr_t data)2569 dpaa2_ni_ioctl(if_t ifp, u_long c, caddr_t data)
2570 {
2571 	struct dpaa2_ni_softc *sc = if_getsoftc(ifp);
2572 	struct ifreq *ifr = (struct ifreq *) data;
2573 	device_t pdev = device_get_parent(sc->dev);
2574 	device_t dev = sc->dev;
2575 	device_t child = dev;
2576 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
2577 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
2578 	struct dpaa2_cmd cmd;
2579 	uint32_t changed = 0;
2580 	uint16_t rc_token, ni_token;
2581 	int mtu, error, rc = 0;
2582 
2583 	DPAA2_CMD_INIT(&cmd);
2584 
2585 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
2586 	if (error) {
2587 		device_printf(dev, "%s: failed to open resource container: "
2588 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
2589 		goto err_exit;
2590 	}
2591 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
2592 	if (error) {
2593 		device_printf(dev, "%s: failed to open network interface: "
2594 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
2595 		goto close_rc;
2596 	}
2597 
2598 	switch (c) {
2599 	case SIOCSIFMTU:
2600 		DPNI_LOCK(sc);
2601 		mtu = ifr->ifr_mtu;
2602 		if (mtu < ETHERMIN || mtu > ETHERMTU_JUMBO) {
2603 			DPNI_UNLOCK(sc);
2604 			error = EINVAL;
2605 			goto close_ni;
2606 		}
2607 		if_setmtu(ifp, mtu);
2608 		DPNI_UNLOCK(sc);
2609 
2610 		/* Update maximum frame length. */
2611 		mtu += ETHER_HDR_LEN;
2612 		if (if_getcapenable(ifp) & IFCAP_VLAN_MTU)
2613 			mtu += ETHER_VLAN_ENCAP_LEN;
2614 		error = DPAA2_CMD_NI_SET_MFL(dev, child, &cmd, mtu);
2615 		if (error) {
2616 			device_printf(dev, "%s: failed to update maximum frame "
2617 			    "length: error=%d\n", __func__, error);
2618 			goto close_ni;
2619 		}
2620 		break;
2621 	case SIOCSIFCAP:
2622 		changed = if_getcapenable(ifp) ^ ifr->ifr_reqcap;
2623 		if ((changed & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) != 0)
2624 			if_togglecapenable(ifp, IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6);
2625 		if ((changed & (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6)) != 0) {
2626 			if_togglecapenable(ifp, IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6);
2627 			if_togglehwassist(ifp, DPAA2_CSUM_TX_OFFLOAD);
2628 		}
2629 
2630 		rc = dpaa2_ni_setup_if_caps(sc);
2631 		if (rc) {
2632 			printf("%s: failed to update iface capabilities: "
2633 			    "error=%d\n", __func__, rc);
2634 			rc = ENXIO;
2635 		}
2636 		break;
2637 	case SIOCSIFFLAGS:
2638 		DPNI_LOCK(sc);
2639 		if (if_getflags(ifp) & IFF_UP) {
2640 			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
2641 				changed = if_getflags(ifp) ^ sc->if_flags;
2642 				if (changed & IFF_PROMISC ||
2643 				    changed & IFF_ALLMULTI) {
2644 					rc = dpaa2_ni_setup_if_flags(sc);
2645 				}
2646 			} else {
2647 				DPNI_UNLOCK(sc);
2648 				dpaa2_ni_init(sc);
2649 				DPNI_LOCK(sc);
2650 			}
2651 		} else if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
2652 			/* FIXME: Disable DPNI. See dpaa2_ni_init(). */
2653 		}
2654 
2655 		sc->if_flags = if_getflags(ifp);
2656 		DPNI_UNLOCK(sc);
2657 		break;
2658 	case SIOCADDMULTI:
2659 	case SIOCDELMULTI:
2660 		DPNI_LOCK(sc);
2661 		if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
2662 			DPNI_UNLOCK(sc);
2663 			rc = dpaa2_ni_update_mac_filters(ifp);
2664 			if (rc) {
2665 				device_printf(dev, "%s: failed to update MAC "
2666 				    "filters: error=%d\n", __func__, rc);
2667 			}
2668 			DPNI_LOCK(sc);
2669 		}
2670 		DPNI_UNLOCK(sc);
2671 		break;
2672 	case SIOCGIFMEDIA:
2673 	case SIOCSIFMEDIA:
2674 		if (sc->mii)
2675 			rc = ifmedia_ioctl(ifp, ifr, &sc->mii->mii_media, c);
2676 		else if(sc->fixed_link) {
2677 			rc = ifmedia_ioctl(ifp, ifr, &sc->fixed_ifmedia, c);
2678 		}
2679 		break;
2680 	default:
2681 		rc = ether_ioctl(ifp, c, data);
2682 		break;
2683 	}
2684 
2685 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
2686 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
2687 	return (rc);
2688 
2689 close_ni:
2690 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
2691 close_rc:
2692 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
2693 err_exit:
2694 	return (error);
2695 }
2696 
2697 static int
dpaa2_ni_update_mac_filters(if_t ifp)2698 dpaa2_ni_update_mac_filters(if_t ifp)
2699 {
2700 	struct dpaa2_ni_softc *sc = if_getsoftc(ifp);
2701 	struct dpaa2_ni_mcaddr_ctx ctx;
2702 	device_t pdev = device_get_parent(sc->dev);
2703 	device_t dev = sc->dev;
2704 	device_t child = dev;
2705 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
2706 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
2707 	struct dpaa2_cmd cmd;
2708 	uint16_t rc_token, ni_token;
2709 	int error;
2710 
2711 	DPAA2_CMD_INIT(&cmd);
2712 
2713 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
2714 	if (error) {
2715 		device_printf(dev, "%s: failed to open resource container: "
2716 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
2717 		goto err_exit;
2718 	}
2719 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
2720 	if (error) {
2721 		device_printf(dev, "%s: failed to open network interface: "
2722 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
2723 		goto close_rc;
2724 	}
2725 
2726 	/* Remove all multicast MAC filters. */
2727 	error = DPAA2_CMD_NI_CLEAR_MAC_FILTERS(dev, child, &cmd, false, true);
2728 	if (error) {
2729 		device_printf(dev, "%s: failed to clear multicast MAC filters: "
2730 		    "error=%d\n", __func__, error);
2731 		goto close_ni;
2732 	}
2733 
2734 	ctx.ifp = ifp;
2735 	ctx.error = 0;
2736 	ctx.nent = 0;
2737 
2738 	if_foreach_llmaddr(ifp, dpaa2_ni_add_maddr, &ctx);
2739 
2740 	error = ctx.error;
2741 close_ni:
2742 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
2743 close_rc:
2744 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
2745 err_exit:
2746 	return (error);
2747 }
2748 
2749 static u_int
dpaa2_ni_add_maddr(void * arg,struct sockaddr_dl * sdl,u_int cnt)2750 dpaa2_ni_add_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
2751 {
2752 	struct dpaa2_ni_mcaddr_ctx *ctx = arg;
2753 	struct dpaa2_ni_softc *sc = if_getsoftc(ctx->ifp);
2754 	device_t pdev = device_get_parent(sc->dev);
2755 	device_t dev = sc->dev;
2756 	device_t child = dev;
2757 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
2758 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
2759 	struct dpaa2_cmd cmd;
2760 	uint16_t rc_token, ni_token;
2761 	int error;
2762 
2763 	if (ctx->error != 0) {
2764 		return (0);
2765 	}
2766 
2767 	if (ETHER_IS_MULTICAST(LLADDR(sdl))) {
2768 		DPAA2_CMD_INIT(&cmd);
2769 
2770 		error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id,
2771 		    &rc_token);
2772 		if (error) {
2773 			device_printf(dev, "%s: failed to open resource "
2774 			    "container: id=%d, error=%d\n", __func__, rcinfo->id,
2775 			    error);
2776 			return (0);
2777 		}
2778 		error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id,
2779 		    &ni_token);
2780 		if (error) {
2781 			device_printf(dev, "%s: failed to open network interface: "
2782 			    "id=%d, error=%d\n", __func__, dinfo->id, error);
2783 			(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd,
2784 			    rc_token));
2785 			return (0);
2786 		}
2787 
2788 		ctx->error = DPAA2_CMD_NI_ADD_MAC_ADDR(dev, child, &cmd,
2789 		    LLADDR(sdl));
2790 
2791 		(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd,
2792 		    ni_token));
2793 		(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd,
2794 		    rc_token));
2795 
2796 		if (ctx->error != 0) {
2797 			device_printf(dev, "%s: can't add more then %d MAC "
2798 			    "addresses, switching to the multicast promiscuous "
2799 			    "mode\n", __func__, ctx->nent);
2800 
2801 			/* Enable multicast promiscuous mode. */
2802 			DPNI_LOCK(sc);
2803 			if_setflagbits(ctx->ifp, IFF_ALLMULTI, 0);
2804 			sc->if_flags |= IFF_ALLMULTI;
2805 			ctx->error = dpaa2_ni_setup_if_flags(sc);
2806 			DPNI_UNLOCK(sc);
2807 
2808 			return (0);
2809 		}
2810 		ctx->nent++;
2811 	}
2812 
2813 	return (1);
2814 }
2815 
2816 static void
dpaa2_ni_intr(void * arg)2817 dpaa2_ni_intr(void *arg)
2818 {
2819 	struct dpaa2_ni_softc *sc = (struct dpaa2_ni_softc *) arg;
2820 	device_t pdev = device_get_parent(sc->dev);
2821 	device_t dev = sc->dev;
2822 	device_t child = dev;
2823 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
2824 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
2825 	struct dpaa2_cmd cmd;
2826 	uint32_t status = ~0u; /* clear all IRQ status bits */
2827 	uint16_t rc_token, ni_token;
2828 	int error;
2829 
2830 	DPAA2_CMD_INIT(&cmd);
2831 
2832 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
2833 	if (error) {
2834 		device_printf(dev, "%s: failed to open resource container: "
2835 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
2836 		goto err_exit;
2837 	}
2838 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
2839 	if (error) {
2840 		device_printf(dev, "%s: failed to open network interface: "
2841 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
2842 		goto close_rc;
2843 	}
2844 
2845 	error = DPAA2_CMD_NI_GET_IRQ_STATUS(dev, child, &cmd, DPNI_IRQ_INDEX,
2846 	    &status);
2847 	if (error) {
2848 		device_printf(sc->dev, "%s: failed to obtain IRQ status: "
2849 		    "error=%d\n", __func__, error);
2850 	}
2851 
2852 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
2853 close_rc:
2854 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
2855 err_exit:
2856 	return;
2857 }
2858 
2859 /**
2860  * @brief Execute channel's Rx/Tx routines.
2861  *
2862  * NOTE: Should not be re-entrant for the same channel. It is achieved by
2863  *       enqueuing the cleanup routine on a single-threaded taskqueue.
2864  */
2865 static void
dpaa2_ni_cleanup_task(void * arg,int count)2866 dpaa2_ni_cleanup_task(void *arg, int count)
2867 {
2868 	struct dpaa2_channel *ch = (struct dpaa2_channel *)arg;
2869 	struct dpaa2_ni_softc *sc = device_get_softc(ch->ni_dev);
2870 	int error, rxc, txc;
2871 
2872 	for (int i = 0; i < DPAA2_CLEAN_BUDGET; i++) {
2873 		rxc  = dpaa2_ni_rx_cleanup(ch);
2874 		txc  = dpaa2_ni_tx_cleanup(ch);
2875 
2876 		if (__predict_false((if_getdrvflags(sc->ifp) &
2877 		    IFF_DRV_RUNNING) == 0)) {
2878 			return;
2879 		}
2880 
2881 		if ((txc != DPAA2_TX_BUDGET) && (rxc != DPAA2_RX_BUDGET)) {
2882 			break;
2883 		}
2884 	}
2885 
2886 	/* Re-arm channel to generate CDAN */
2887 	error = DPAA2_SWP_CONF_WQ_CHANNEL(ch->io_dev, &ch->ctx);
2888 	if (error != 0) {
2889 		panic("%s: failed to rearm channel: chan_id=%d, error=%d\n",
2890 		    __func__, ch->id, error);
2891 	}
2892 }
2893 
2894 /**
2895  * @brief Poll frames from a specific channel when CDAN is received.
2896  */
2897 static int
dpaa2_ni_rx_cleanup(struct dpaa2_channel * ch)2898 dpaa2_ni_rx_cleanup(struct dpaa2_channel *ch)
2899 {
2900 	struct dpaa2_io_softc *iosc = device_get_softc(ch->io_dev);
2901 	struct dpaa2_swp *swp = iosc->swp;
2902 	struct dpaa2_ni_fq *fq;
2903 	struct dpaa2_buf *buf = &ch->store;
2904 	int budget = DPAA2_RX_BUDGET;
2905 	int error, consumed = 0;
2906 
2907 	do {
2908 		error = dpaa2_swp_pull(swp, ch->id, buf, DPAA2_ETH_STORE_FRAMES);
2909 		if (error) {
2910 			device_printf(ch->ni_dev, "%s: failed to pull frames: "
2911 			    "chan_id=%d, error=%d\n", __func__, ch->id, error);
2912 			break;
2913 		}
2914 		error = dpaa2_ni_consume_frames(ch, &fq, &consumed);
2915 		if (error == ENOENT || error == EALREADY) {
2916 			break;
2917 		}
2918 		if (error == ETIMEDOUT) {
2919 			device_printf(ch->ni_dev, "%s: timeout to consume "
2920 			    "frames: chan_id=%d\n", __func__, ch->id);
2921 		}
2922 	} while (--budget);
2923 
2924 	return (DPAA2_RX_BUDGET - budget);
2925 }
2926 
2927 static int
dpaa2_ni_tx_cleanup(struct dpaa2_channel * ch)2928 dpaa2_ni_tx_cleanup(struct dpaa2_channel *ch)
2929 {
2930 	struct dpaa2_ni_softc *sc = device_get_softc(ch->ni_dev);
2931 	struct dpaa2_ni_tx_ring *tx = &ch->txc_queue.tx_rings[0];
2932 	struct mbuf *m = NULL;
2933 	int budget = DPAA2_TX_BUDGET;
2934 
2935 	do {
2936 		mtx_assert(&ch->xmit_mtx, MA_NOTOWNED);
2937 		mtx_lock(&ch->xmit_mtx);
2938 		m = buf_ring_dequeue_sc(ch->xmit_br);
2939 		mtx_unlock(&ch->xmit_mtx);
2940 
2941 		if (__predict_false(m == NULL)) {
2942 			/* TODO: Do not give up easily */
2943 			break;
2944 		} else {
2945 			dpaa2_ni_tx(sc, ch, tx, m);
2946 		}
2947 	} while (--budget);
2948 
2949 	return (DPAA2_TX_BUDGET - budget);
2950 }
2951 
2952 static void
dpaa2_ni_tx(struct dpaa2_ni_softc * sc,struct dpaa2_channel * ch,struct dpaa2_ni_tx_ring * tx,struct mbuf * m)2953 dpaa2_ni_tx(struct dpaa2_ni_softc *sc, struct dpaa2_channel *ch,
2954     struct dpaa2_ni_tx_ring *tx, struct mbuf *m)
2955 {
2956 	device_t dev = sc->dev;
2957 	struct dpaa2_ni_fq *fq = tx->fq;
2958 	struct dpaa2_buf *buf, *sgt;
2959 	struct dpaa2_fd fd;
2960 	struct mbuf *md;
2961 	bus_dma_segment_t segs[DPAA2_TX_SEGLIMIT];
2962 	int rc, nsegs;
2963 	int error;
2964 	int len;
2965 	bool mcast;
2966 
2967 	mtx_assert(&tx->lock, MA_NOTOWNED);
2968 	mtx_lock(&tx->lock);
2969 	buf = buf_ring_dequeue_sc(tx->br);
2970 	mtx_unlock(&tx->lock);
2971 	if (__predict_false(buf == NULL)) {
2972 		/* TODO: Do not give up easily */
2973 		m_freem(m);
2974 		return;
2975 	} else {
2976 		DPAA2_BUF_ASSERT_TXREADY(buf);
2977 		buf->m = m;
2978 		sgt = buf->sgt;
2979 	}
2980 	len = m->m_pkthdr.len;
2981 	mcast = (m->m_flags & M_MCAST) != 0;
2982 
2983 #if defined(INVARIANTS)
2984 	struct dpaa2_ni_tx_ring *btx = (struct dpaa2_ni_tx_ring *)buf->opt;
2985 	KASSERT(buf->opt == tx, ("%s: unexpected Tx ring", __func__));
2986 	KASSERT(btx->fq->chan == ch, ("%s: unexpected channel", __func__));
2987 #endif /* INVARIANTS */
2988 
2989 	BPF_MTAP(sc->ifp, m);
2990 
2991 	error = bus_dmamap_load_mbuf_sg(buf->dmat, buf->dmap, m, segs, &nsegs,
2992 	    BUS_DMA_NOWAIT);
2993 	if (__predict_false(error != 0)) {
2994 		/* Too many fragments, trying to defragment... */
2995 		md = m_collapse(m, M_NOWAIT, DPAA2_TX_SEGLIMIT);
2996 		if (md == NULL) {
2997 			device_printf(dev, "%s: m_collapse() failed\n", __func__);
2998 			fq->chan->tx_dropped++;
2999 			if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
3000 			goto err;
3001 		}
3002 
3003 		buf->m = m = md;
3004 		error = bus_dmamap_load_mbuf_sg(buf->dmat, buf->dmap, m, segs,
3005 		    &nsegs, BUS_DMA_NOWAIT);
3006 		if (__predict_false(error != 0)) {
3007 			device_printf(dev, "%s: bus_dmamap_load_mbuf_sg() "
3008 			    "failed: error=%d\n", __func__, error);
3009 			fq->chan->tx_dropped++;
3010 			if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
3011 			goto err;
3012 		}
3013 	}
3014 
3015 	error = dpaa2_fd_build(dev, sc->tx_data_off, buf, segs, nsegs, &fd);
3016 	if (__predict_false(error != 0)) {
3017 		device_printf(dev, "%s: failed to build frame descriptor: "
3018 		    "error=%d\n", __func__, error);
3019 		fq->chan->tx_dropped++;
3020 		if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
3021 		goto err_unload;
3022 	} else
3023 		sc->tx_sg_frames++; /* for sysctl(9) */
3024 
3025 	bus_dmamap_sync(buf->dmat, buf->dmap, BUS_DMASYNC_PREWRITE);
3026 	bus_dmamap_sync(sgt->dmat, sgt->dmap, BUS_DMASYNC_PREWRITE);
3027 
3028 	/* TODO: Enqueue several frames in a single command */
3029 	for (int i = 0; i < DPAA2_NI_ENQUEUE_RETRIES; i++) {
3030 		/* TODO: Return error codes instead of # of frames */
3031 		rc = DPAA2_SWP_ENQ_MULTIPLE_FQ(fq->chan->io_dev, tx->fqid, &fd, 1);
3032 		if (rc == 1) {
3033 			break;
3034 		}
3035 	}
3036 
3037 	if (rc != 1) {
3038 		fq->chan->tx_dropped++;
3039 		if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
3040 		goto err_unload;
3041 	} else {
3042 		if (mcast)
3043 			if_inc_counter(sc->ifp, IFCOUNTER_OMCASTS, 1);
3044 		if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1);
3045 		if_inc_counter(sc->ifp, IFCOUNTER_OBYTES, len);
3046 		fq->chan->tx_frames++;
3047 	}
3048 	return;
3049 
3050 err_unload:
3051 	bus_dmamap_unload(buf->dmat, buf->dmap);
3052 	if (sgt->paddr != 0) {
3053 		bus_dmamap_unload(sgt->dmat, sgt->dmap);
3054 	}
3055 err:
3056 	m_freem(buf->m);
3057 	buf_ring_enqueue(tx->br, buf);
3058 }
3059 
3060 static int
dpaa2_ni_consume_frames(struct dpaa2_channel * chan,struct dpaa2_ni_fq ** src,uint32_t * consumed)3061 dpaa2_ni_consume_frames(struct dpaa2_channel *chan, struct dpaa2_ni_fq **src,
3062     uint32_t *consumed)
3063 {
3064 	struct dpaa2_ni_fq *fq = NULL;
3065 	struct dpaa2_dq *dq;
3066 	struct dpaa2_fd *fd;
3067 	struct dpaa2_ni_rx_ctx ctx = {
3068 		.head = NULL,
3069 		.tail = NULL,
3070 		.cnt = 0,
3071 		.last = false
3072 	};
3073 	int rc, frames = 0;
3074 
3075 	do {
3076 		rc = dpaa2_chan_next_frame(chan, &dq);
3077 		if (rc == EINPROGRESS) {
3078 			if (dq != NULL && !IS_NULL_RESPONSE(dq->fdr.desc.stat)) {
3079 				fd = &dq->fdr.fd;
3080 				fq = (struct dpaa2_ni_fq *) dq->fdr.desc.fqd_ctx;
3081 
3082 				switch (fq->type) {
3083 				case DPAA2_NI_QUEUE_RX:
3084 					(void)dpaa2_ni_rx(chan, fq, fd, &ctx);
3085 					break;
3086 				case DPAA2_NI_QUEUE_RX_ERR:
3087 					(void)dpaa2_ni_rx_err(chan, fq, fd);
3088 					break;
3089 				case DPAA2_NI_QUEUE_TX_CONF:
3090 					(void)dpaa2_ni_tx_conf(chan, fq, fd);
3091 					break;
3092 				default:
3093 					panic("%s: unknown queue type (1)",
3094 					    __func__);
3095 				}
3096 				frames++;
3097 			}
3098 		} else if (rc == EALREADY || rc == ENOENT) {
3099 			if (dq != NULL && !IS_NULL_RESPONSE(dq->fdr.desc.stat)) {
3100 				fd = &dq->fdr.fd;
3101 				fq = (struct dpaa2_ni_fq *) dq->fdr.desc.fqd_ctx;
3102 
3103 				switch (fq->type) {
3104 				case DPAA2_NI_QUEUE_RX:
3105 					/*
3106 					 * Last VDQ response (mbuf) in a chain
3107 					 * obtained from the Rx queue.
3108 					 */
3109 					ctx.last = true;
3110 					(void)dpaa2_ni_rx(chan, fq, fd, &ctx);
3111 					break;
3112 				case DPAA2_NI_QUEUE_RX_ERR:
3113 					(void)dpaa2_ni_rx_err(chan, fq, fd);
3114 					break;
3115 				case DPAA2_NI_QUEUE_TX_CONF:
3116 					(void)dpaa2_ni_tx_conf(chan, fq, fd);
3117 					break;
3118 				default:
3119 					panic("%s: unknown queue type (2)",
3120 					    __func__);
3121 				}
3122 				frames++;
3123 			}
3124 			break;
3125 		} else {
3126 			panic("%s: should not reach here: rc=%d", __func__, rc);
3127 		}
3128 	} while (true);
3129 
3130 	KASSERT(chan->store_idx < chan->store_sz, ("%s: store_idx(%d) >= "
3131 	    "store_sz(%d)", __func__, chan->store_idx, chan->store_sz));
3132 
3133 	/*
3134 	 * VDQ operation pulls frames from a single queue into the store.
3135 	 * Return the frame queue and a number of consumed frames as an output.
3136 	 */
3137 	if (src != NULL) {
3138 		*src = fq;
3139 	}
3140 	if (consumed != NULL) {
3141 		*consumed = frames;
3142 	}
3143 
3144 	return (rc);
3145 }
3146 
3147 /**
3148  * @brief Receive frames.
3149  */
3150 static int
dpaa2_ni_rx(struct dpaa2_channel * ch,struct dpaa2_ni_fq * fq,struct dpaa2_fd * fd,struct dpaa2_ni_rx_ctx * ctx)3151 dpaa2_ni_rx(struct dpaa2_channel *ch, struct dpaa2_ni_fq *fq,
3152     struct dpaa2_fd *fd, struct dpaa2_ni_rx_ctx *ctx)
3153 {
3154 	bus_addr_t paddr;
3155 	struct dpaa2_swa *swa;
3156 	struct dpaa2_buf *buf;
3157 	struct dpaa2_channel *bch;
3158 	struct dpaa2_ni_softc *sc;
3159 	struct dpaa2_bp_softc *bpsc;
3160 	struct mbuf *m;
3161 	device_t bpdev;
3162 	bus_addr_t released[DPAA2_SWP_BUFS_PER_CMD];
3163 	void *buf_data;
3164 	int buf_len, error, released_n = 0;
3165 	bool update_csum_flags;
3166 
3167 	error = dpaa2_fa_get_swa(fd, &swa);
3168 	if (__predict_false(error != 0))
3169 		panic("%s: frame has no software annotation: error=%d",
3170 		    __func__, error);
3171 
3172 	paddr = (bus_addr_t)fd->addr;
3173 	buf = swa->buf;
3174 	bch = (struct dpaa2_channel *)buf->opt;
3175 	sc = device_get_softc(bch->ni_dev);
3176 	update_csum_flags = true;
3177 
3178 	KASSERT(swa->magic == DPAA2_MAGIC, ("%s: wrong magic", __func__));
3179 	/*
3180 	 * NOTE: Current channel might not be the same as the "buffer" channel
3181 	 * and it's fine. It must not be NULL though.
3182 	 */
3183 	KASSERT(bch != NULL, ("%s: buffer channel is NULL", __func__));
3184 
3185 	if (__predict_false(paddr != buf->paddr)) {
3186 		panic("%s: unexpected physical address: fd(%#jx) != buf(%#jx)",
3187 		    __func__, paddr, buf->paddr);
3188 	}
3189 
3190 	switch (dpaa2_fd_err(fd)) {
3191 	case 0:
3192 		/*
3193 		 * FD[ERR] = 0 value is reserved to indicate that there is no
3194 		 * error encoded in this field. See 3.4.5 Error handling,
3195 		 * LX2160A DPAA2 Low-Level Hardware Reference Manual, Rev. 0,
3196 		 * 06/2020.
3197 		 */
3198 		break;
3199 	case 1: /* Enqueue rejected by QMan */
3200 		sc->rx_enq_rej_frames++;
3201 		break;
3202 	case 2: /* QMan IEOI error */
3203 		sc->rx_ieoi_err_frames++;
3204 		break;
3205 	default:
3206 		sc->rx_other_err_frames++;
3207 		break;
3208 	}
3209 
3210 	switch (dpaa2_fd_format(fd)) {
3211 	case DPAA2_FD_SINGLE:
3212 		sc->rx_single_buf_frames++;
3213 		break;
3214 	case DPAA2_FD_SG:
3215 		sc->rx_sg_buf_frames++;
3216 		break;
3217 	default:
3218 		update_csum_flags = false;
3219 		break;
3220 	}
3221 
3222 	mtx_assert(&bch->dma_mtx, MA_NOTOWNED);
3223 	mtx_lock(&bch->dma_mtx);
3224 
3225 	bus_dmamap_sync(buf->dmat, buf->dmap, BUS_DMASYNC_POSTREAD);
3226 	bus_dmamap_unload(buf->dmat, buf->dmap);
3227 
3228 	m = buf->m;
3229 	buf_len = dpaa2_fd_data_len(fd);
3230 	buf_data = (uint8_t *)buf->vaddr + dpaa2_fd_offset(fd);
3231 
3232 	/* Prepare buffer to be re-cycled */
3233 	buf->m = NULL;
3234 	buf->paddr = 0;
3235 	buf->vaddr = NULL;
3236 	buf->seg.ds_addr = 0;
3237 	buf->seg.ds_len = 0;
3238 	buf->nseg = 0;
3239 
3240 	mtx_unlock(&bch->dma_mtx);
3241 
3242 	m->m_flags |= M_PKTHDR;
3243 	m->m_data = buf_data;
3244 	m->m_len = buf_len;
3245 	m->m_pkthdr.len = buf_len;
3246 	m->m_pkthdr.rcvif = sc->ifp;
3247 	m->m_pkthdr.flowid = fq->fqid;
3248 	M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE);
3249 	if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
3250 
3251 	if (update_csum_flags && ((if_getcapenable(sc->ifp) & (IFCAP_RXCSUM |
3252 	    IFCAP_RXCSUM_IPV6)) != 0)) {
3253 		error = dpaa2_ni_update_csum_flags(fd, m);
3254 		if (error != 0)
3255 			device_printf(sc->dev, "%s: failed to update checksum "
3256 			    "flags: error=%d\n", __func__, error);
3257 	}
3258 
3259 	if (ctx->head == NULL) {
3260 		KASSERT(ctx->tail == NULL, ("%s: tail already given?", __func__));
3261 		ctx->head = m;
3262 		ctx->tail = m;
3263 	} else {
3264 		KASSERT(ctx->head != NULL, ("%s: head is NULL", __func__));
3265 		ctx->tail->m_nextpkt = m;
3266 		ctx->tail = m;
3267 	}
3268 	ctx->cnt++;
3269 
3270 	if (ctx->last) {
3271 		ctx->tail->m_nextpkt = NULL;
3272 		if_input(sc->ifp, ctx->head);
3273 	}
3274 
3275 	/* Keep the buffer to be recycled */
3276 	ch->recycled[ch->recycled_n++] = buf;
3277 
3278 	/* Re-seed and release recycled buffers back to the pool */
3279 	if (ch->recycled_n == DPAA2_SWP_BUFS_PER_CMD) {
3280 		/* Release new buffers to the pool if needed */
3281 		taskqueue_enqueue(sc->bp_taskq, &ch->bp_task);
3282 
3283 		for (int i = 0; i < ch->recycled_n; i++) {
3284 			buf = ch->recycled[i];
3285 			bch = (struct dpaa2_channel *)buf->opt;
3286 
3287 			mtx_assert(&bch->dma_mtx, MA_NOTOWNED);
3288 			mtx_lock(&bch->dma_mtx);
3289 			error = dpaa2_buf_seed_rxb(sc->dev, buf,
3290 			    DPAA2_RX_BUF_SIZE, &bch->dma_mtx);
3291 			mtx_unlock(&bch->dma_mtx);
3292 
3293 			if (__predict_false(error != 0)) {
3294 				/* TODO: What else to do with the buffer? */
3295 				panic("%s: failed to recycle buffer: error=%d",
3296 				    __func__, error);
3297 			}
3298 
3299 			/* Prepare buffer to be released in a single command */
3300 			released[released_n++] = buf->paddr;
3301 		}
3302 
3303 		/* There's only one buffer pool for now */
3304 		bpdev = (device_t)rman_get_start(sc->res[DPAA2_NI_BP_RID(0)]);
3305 		bpsc = device_get_softc(bpdev);
3306 
3307 		error = DPAA2_SWP_RELEASE_BUFS(ch->io_dev, bpsc->attr.bpid,
3308 		    released, released_n);
3309 		if (__predict_false(error != 0)) {
3310 			device_printf(sc->dev, "%s: failed to release buffers "
3311 			    "to the pool: error=%d\n", __func__, error);
3312 			return (error);
3313 		}
3314 		ch->recycled_n = 0;
3315 	}
3316 
3317 	return (0);
3318 }
3319 
3320 /**
3321  * @brief Receive Rx error frames.
3322  */
3323 static int
dpaa2_ni_rx_err(struct dpaa2_channel * ch,struct dpaa2_ni_fq * fq,struct dpaa2_fd * fd)3324 dpaa2_ni_rx_err(struct dpaa2_channel *ch, struct dpaa2_ni_fq *fq,
3325     struct dpaa2_fd *fd)
3326 {
3327 	bus_addr_t paddr;
3328 	struct dpaa2_swa *swa;
3329 	struct dpaa2_buf *buf;
3330 	struct dpaa2_channel *bch;
3331 	struct dpaa2_ni_softc *sc;
3332 	device_t bpdev;
3333 	struct dpaa2_bp_softc *bpsc;
3334 	int error;
3335 
3336 	error = dpaa2_fa_get_swa(fd, &swa);
3337 	if (__predict_false(error != 0))
3338 		panic("%s: frame has no software annotation: error=%d",
3339 		    __func__, error);
3340 
3341 	paddr = (bus_addr_t)fd->addr;
3342 	buf = swa->buf;
3343 	bch = (struct dpaa2_channel *)buf->opt;
3344 	sc = device_get_softc(bch->ni_dev);
3345 
3346 	KASSERT(swa->magic == DPAA2_MAGIC, ("%s: wrong magic", __func__));
3347 	/*
3348 	 * NOTE: Current channel might not be the same as the "buffer" channel
3349 	 * and it's fine. It must not be NULL though.
3350 	 */
3351 	KASSERT(bch != NULL, ("%s: buffer channel is NULL", __func__));
3352 
3353 	if (__predict_false(paddr != buf->paddr)) {
3354 		panic("%s: unexpected physical address: fd(%#jx) != buf(%#jx)",
3355 		    __func__, paddr, buf->paddr);
3356 	}
3357 
3358 	/* There's only one buffer pool for now */
3359 	bpdev = (device_t)rman_get_start(sc->res[DPAA2_NI_BP_RID(0)]);
3360 	bpsc = device_get_softc(bpdev);
3361 
3362 	/* Release buffer to QBMan buffer pool */
3363 	error = DPAA2_SWP_RELEASE_BUFS(ch->io_dev, bpsc->attr.bpid, &paddr, 1);
3364 	if (error != 0) {
3365 		device_printf(sc->dev, "%s: failed to release frame buffer to "
3366 		    "the pool: error=%d\n", __func__, error);
3367 		return (error);
3368 	}
3369 
3370 	return (0);
3371 }
3372 
3373 /**
3374  * @brief Receive Tx confirmation frames.
3375  */
3376 static int
dpaa2_ni_tx_conf(struct dpaa2_channel * ch,struct dpaa2_ni_fq * fq,struct dpaa2_fd * fd)3377 dpaa2_ni_tx_conf(struct dpaa2_channel *ch, struct dpaa2_ni_fq *fq,
3378     struct dpaa2_fd *fd)
3379 {
3380 	bus_addr_t paddr;
3381 	struct dpaa2_swa *swa;
3382 	struct dpaa2_buf *buf;
3383 	struct dpaa2_buf *sgt;
3384 	struct dpaa2_ni_tx_ring *tx;
3385 	struct dpaa2_channel *bch;
3386 	int error;
3387 
3388 	error = dpaa2_fa_get_swa(fd, &swa);
3389 	if (__predict_false(error != 0))
3390 		panic("%s: frame has no software annotation: error=%d",
3391 		    __func__, error);
3392 
3393 	paddr = (bus_addr_t)fd->addr;
3394 	buf = swa->buf;
3395 	sgt = buf->sgt;
3396 	tx = (struct dpaa2_ni_tx_ring *)buf->opt;
3397 	bch = tx->fq->chan;
3398 
3399 	KASSERT(swa->magic == DPAA2_MAGIC, ("%s: wrong magic", __func__));
3400 	KASSERT(tx != NULL, ("%s: Tx ring is NULL", __func__));
3401 	KASSERT(sgt != NULL, ("%s: S/G table is NULL", __func__));
3402 	/*
3403 	 * NOTE: Current channel might not be the same as the "buffer" channel
3404 	 * and it's fine. It must not be NULL though.
3405 	 */
3406 	KASSERT(bch != NULL, ("%s: buffer channel is NULL", __func__));
3407 
3408 	if (paddr != buf->paddr) {
3409 		panic("%s: unexpected physical address: fd(%#jx) != buf(%#jx)",
3410 		    __func__, paddr, buf->paddr);
3411 	}
3412 
3413 	mtx_assert(&bch->dma_mtx, MA_NOTOWNED);
3414 	mtx_lock(&bch->dma_mtx);
3415 
3416 	bus_dmamap_sync(buf->dmat, buf->dmap, BUS_DMASYNC_POSTWRITE);
3417 	bus_dmamap_sync(sgt->dmat, sgt->dmap, BUS_DMASYNC_POSTWRITE);
3418 	bus_dmamap_unload(buf->dmat, buf->dmap);
3419 	bus_dmamap_unload(sgt->dmat, sgt->dmap);
3420 	m_freem(buf->m);
3421 	buf->m = NULL;
3422 	buf->paddr = 0;
3423 	buf->vaddr = NULL;
3424 	sgt->paddr = 0;
3425 
3426 	mtx_unlock(&bch->dma_mtx);
3427 
3428 	/* Return Tx buffer back to the ring */
3429 	buf_ring_enqueue(tx->br, buf);
3430 
3431 	return (0);
3432 }
3433 
3434 /**
3435  * @brief Compare versions of the DPAA2 network interface API.
3436  */
3437 static int
dpaa2_ni_cmp_api_version(struct dpaa2_ni_softc * sc,uint16_t major,uint16_t minor)3438 dpaa2_ni_cmp_api_version(struct dpaa2_ni_softc *sc, uint16_t major,
3439     uint16_t minor)
3440 {
3441 	if (sc->api_major == major) {
3442 		return sc->api_minor - minor;
3443 	}
3444 	return sc->api_major - major;
3445 }
3446 
3447 /**
3448  * @brief Collect statistics of the network interface.
3449  */
3450 static int
dpaa2_ni_collect_stats(SYSCTL_HANDLER_ARGS)3451 dpaa2_ni_collect_stats(SYSCTL_HANDLER_ARGS)
3452 {
3453 	struct dpaa2_ni_softc *sc = (struct dpaa2_ni_softc *) arg1;
3454 	struct dpni_stat *stat = &dpni_stat_sysctls[oidp->oid_number];
3455 	device_t pdev = device_get_parent(sc->dev);
3456 	device_t dev = sc->dev;
3457 	device_t child = dev;
3458 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
3459 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
3460 	struct dpaa2_cmd cmd;
3461 	uint64_t cnt[DPAA2_NI_STAT_COUNTERS_PER_PAGE];
3462 	uint64_t result = 0;
3463 	uint16_t rc_token, ni_token;
3464 	int error;
3465 
3466 	DPAA2_CMD_INIT(&cmd);
3467 
3468 	error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
3469 	if (error) {
3470 		device_printf(dev, "%s: failed to open resource container: "
3471 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
3472 		goto exit;
3473 	}
3474 	error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id, &ni_token);
3475 	if (error) {
3476 		device_printf(dev, "%s: failed to open network interface: "
3477 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
3478 		goto close_rc;
3479 	}
3480 
3481 	error = DPAA2_CMD_NI_GET_STATISTICS(dev, child, &cmd, stat->page, 0, cnt);
3482 	if (!error) {
3483 		result = cnt[stat->cnt];
3484 	}
3485 
3486 	(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, ni_token));
3487 close_rc:
3488 	(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
3489 exit:
3490 	return (sysctl_handle_64(oidp, &result, 0, req));
3491 }
3492 
3493 static int
dpaa2_ni_sysctl_link_state(SYSCTL_HANDLER_ARGS)3494 dpaa2_ni_sysctl_link_state(SYSCTL_HANDLER_ARGS)
3495 {
3496 	struct dpaa2_ni_softc *sc;
3497 	struct dpaa2_devinfo *rcinfo;
3498 	struct dpaa2_devinfo *dinfo;
3499 	struct dpaa2_cmd cmd;
3500 	struct dpaa2_ni_link_state ls;
3501 	struct sbuf s;
3502 	int error;
3503 	uint16_t rc_token, ni_token;
3504 
3505 	if (req->newptr)
3506 		return (EPERM);
3507 
3508 	sc = (struct dpaa2_ni_softc *)arg1;
3509 
3510 	rcinfo = device_get_ivars(device_get_parent(sc->dev));
3511 	dinfo = device_get_ivars(sc->dev);
3512 
3513 	DPAA2_CMD_INIT(&cmd);
3514 
3515 	error = DPAA2_CMD_RC_OPEN(sc->dev, sc->dev, &cmd, rcinfo->id, &rc_token);
3516 	if (error != 0) {
3517 		device_printf(sc->dev, "%s: failed to open resource container: "
3518 		    "id=%d, error=%d\n", __func__, rcinfo->id, error);
3519 		goto exit;
3520 	}
3521 	error = DPAA2_CMD_NI_OPEN(sc->dev, sc->dev, &cmd, dinfo->id, &ni_token);
3522 	if (error != 0) {
3523 		device_printf(sc->dev, "%s: failed to open network interface: "
3524 		    "id=%d, error=%d\n", __func__, dinfo->id, error);
3525 		goto close_rc;
3526 	}
3527 
3528 	error = DPAA2_CMD_NI_GET_LINK_STATE(sc->dev, sc->dev, &cmd, &ls);
3529 
3530 	(void)DPAA2_CMD_NI_CLOSE(sc->dev, sc->dev, DPAA2_CMD_TK(&cmd, ni_token));
3531 close_rc:
3532 	(void)DPAA2_CMD_RC_CLOSE(sc->dev, sc->dev, DPAA2_CMD_TK(&cmd, rc_token));
3533 
3534 	if (error != 0)
3535 		goto exit;
3536 
3537 #define	NI_LINK_STATE_OPTIONS_BITS					\
3538     "\20\1AUTONEG\2HDX\3PAUSE\4ASYM_PAUSE"
3539 
3540 	sbuf_new_for_sysctl(&s, NULL, 1024, req);
3541 	sbuf_putc(&s, '\n');
3542 	sbuf_printf(&s, "Link State: %s (%s)\n", ls.link_up ? "UP" : "DOWN",
3543 	    ls.state_valid ? "VALID" : "IGNORE");
3544 	sbuf_printf(&s, "Link Rate: %ju\n", (uintmax_t)ls.rate);
3545 	sbuf_printf(&s, "Link Options: %b\n",
3546 	    (int)ls.options, NI_LINK_STATE_OPTIONS_BITS);
3547 	sbuf_printf(&s, "Link Speed Capabilities: %#018jx\n",
3548 	    (uintmax_t)ls.sup_speeds);
3549 	sbuf_printf(&s, "Link Speed Advertised for autoneg: %#018jx\n",
3550 	    (uintmax_t)ls.adv_speeds);
3551 	sbuf_finish(&s);
3552 	sbuf_delete(&s);
3553 
3554 exit:
3555 	return (error);
3556 }
3557 
3558 static int
dpaa2_ni_collect_buf_num(SYSCTL_HANDLER_ARGS)3559 dpaa2_ni_collect_buf_num(SYSCTL_HANDLER_ARGS)
3560 {
3561 	struct dpaa2_ni_softc *sc = (struct dpaa2_ni_softc *) arg1;
3562 	uint32_t buf_num = DPAA2_ATOMIC_READ(&sc->buf_num);
3563 
3564 	return (sysctl_handle_32(oidp, &buf_num, 0, req));
3565 }
3566 
3567 static int
dpaa2_ni_collect_buf_free(SYSCTL_HANDLER_ARGS)3568 dpaa2_ni_collect_buf_free(SYSCTL_HANDLER_ARGS)
3569 {
3570 	struct dpaa2_ni_softc *sc = (struct dpaa2_ni_softc *) arg1;
3571 	uint32_t buf_free = DPAA2_ATOMIC_READ(&sc->buf_free);
3572 
3573 	return (sysctl_handle_32(oidp, &buf_free, 0, req));
3574 }
3575 
3576 static int
dpaa2_ni_set_hash(device_t dev,uint64_t flags)3577 dpaa2_ni_set_hash(device_t dev, uint64_t flags)
3578 {
3579 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
3580 	uint64_t key = 0;
3581 	int i;
3582 
3583 	if (!(sc->attr.num.queues > 1)) {
3584 		return (EOPNOTSUPP);
3585 	}
3586 
3587 	for (i = 0; i < ARRAY_SIZE(dist_fields); i++) {
3588 		if (dist_fields[i].rxnfc_field & flags) {
3589 			key |= dist_fields[i].id;
3590 		}
3591 	}
3592 
3593 	return (dpaa2_ni_set_dist_key(dev, DPAA2_NI_DIST_MODE_HASH, key));
3594 }
3595 
3596 /**
3597  * @brief Set Rx distribution (hash or flow classification) key flags is a
3598  * combination of RXH_ bits.
3599  */
3600 static int
dpaa2_ni_set_dist_key(device_t dev,enum dpaa2_ni_dist_mode type,uint64_t flags)3601 dpaa2_ni_set_dist_key(device_t dev, enum dpaa2_ni_dist_mode type, uint64_t flags)
3602 {
3603 	device_t pdev = device_get_parent(dev);
3604 	device_t child = dev;
3605 	struct dpaa2_ni_softc *sc = device_get_softc(dev);
3606 	struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
3607 	struct dpaa2_devinfo *dinfo = device_get_ivars(dev);
3608 	struct dpkg_profile_cfg cls_cfg;
3609 	struct dpkg_extract *key;
3610 	struct dpaa2_buf *buf = &sc->rxd_kcfg;
3611 	struct dpaa2_cmd cmd;
3612 	uint16_t rc_token, ni_token;
3613 	int i, error = 0;
3614 
3615 	if (__predict_true(buf->dmat == NULL)) {
3616 		buf->dmat = sc->rxd_dmat;
3617 	}
3618 
3619 	memset(&cls_cfg, 0, sizeof(cls_cfg));
3620 
3621 	/* Configure extracts according to the given flags. */
3622 	for (i = 0; i < ARRAY_SIZE(dist_fields); i++) {
3623 		key = &cls_cfg.extracts[cls_cfg.num_extracts];
3624 
3625 		if (!(flags & dist_fields[i].id)) {
3626 			continue;
3627 		}
3628 
3629 		if (cls_cfg.num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) {
3630 			device_printf(dev, "%s: failed to add key extraction "
3631 			    "rule\n", __func__);
3632 			return (E2BIG);
3633 		}
3634 
3635 		key->type = DPKG_EXTRACT_FROM_HDR;
3636 		key->extract.from_hdr.prot = dist_fields[i].cls_prot;
3637 		key->extract.from_hdr.type = DPKG_FULL_FIELD;
3638 		key->extract.from_hdr.field = dist_fields[i].cls_field;
3639 		cls_cfg.num_extracts++;
3640 	}
3641 
3642 	error = bus_dmamem_alloc(buf->dmat, (void **)&buf->vaddr,
3643 	    BUS_DMA_ZERO | BUS_DMA_COHERENT, &buf->dmap);
3644 	if (error != 0) {
3645 		device_printf(dev, "%s: failed to allocate a buffer for Rx "
3646 		    "traffic distribution key configuration\n", __func__);
3647 		return (error);
3648 	}
3649 
3650 	error = dpaa2_ni_prepare_key_cfg(&cls_cfg, (uint8_t *)buf->vaddr);
3651 	if (error != 0) {
3652 		device_printf(dev, "%s: failed to prepare key configuration: "
3653 		    "error=%d\n", __func__, error);
3654 		return (error);
3655 	}
3656 
3657 	/* Prepare for setting the Rx dist. */
3658 	error = bus_dmamap_load(buf->dmat, buf->dmap, buf->vaddr,
3659 	    DPAA2_CLASSIFIER_DMA_SIZE, dpaa2_dmamap_oneseg_cb, &buf->paddr,
3660 	    BUS_DMA_NOWAIT);
3661 	if (error != 0) {
3662 		device_printf(sc->dev, "%s: failed to map a buffer for Rx "
3663 		    "traffic distribution key configuration\n", __func__);
3664 		return (error);
3665 	}
3666 
3667 	if (type == DPAA2_NI_DIST_MODE_HASH) {
3668 		DPAA2_CMD_INIT(&cmd);
3669 
3670 		error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id,
3671 		    &rc_token);
3672 		if (error) {
3673 			device_printf(dev, "%s: failed to open resource "
3674 			    "container: id=%d, error=%d\n", __func__, rcinfo->id,
3675 			    error);
3676 			goto err_exit;
3677 		}
3678 		error = DPAA2_CMD_NI_OPEN(dev, child, &cmd, dinfo->id,
3679 		    &ni_token);
3680 		if (error) {
3681 			device_printf(dev, "%s: failed to open network "
3682 			    "interface: id=%d, error=%d\n", __func__, dinfo->id,
3683 			    error);
3684 			goto close_rc;
3685 		}
3686 
3687 		error = DPAA2_CMD_NI_SET_RX_TC_DIST(dev, child, &cmd,
3688 		    sc->attr.num.queues, 0, DPAA2_NI_DIST_MODE_HASH, buf->paddr);
3689 		if (error != 0) {
3690 			device_printf(dev, "%s: failed to set distribution mode "
3691 			    "and size for the traffic class\n", __func__);
3692 		}
3693 
3694 		(void)DPAA2_CMD_NI_CLOSE(dev, child, DPAA2_CMD_TK(&cmd,
3695 		    ni_token));
3696 close_rc:
3697 		(void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd,
3698 		    rc_token));
3699 	}
3700 
3701 err_exit:
3702 	return (error);
3703 }
3704 
3705 /**
3706  * @brief Prepares extract parameters.
3707  *
3708  * cfg:		Defining a full Key Generation profile.
3709  * key_cfg_buf:	Zeroed 256 bytes of memory before mapping it to DMA.
3710  */
3711 static int
dpaa2_ni_prepare_key_cfg(struct dpkg_profile_cfg * cfg,uint8_t * key_cfg_buf)3712 dpaa2_ni_prepare_key_cfg(struct dpkg_profile_cfg *cfg, uint8_t *key_cfg_buf)
3713 {
3714 	struct dpni_ext_set_rx_tc_dist *dpni_ext;
3715 	struct dpni_dist_extract *extr;
3716 	int i, j;
3717 
3718 	if (cfg->num_extracts > DPKG_MAX_NUM_OF_EXTRACTS)
3719 		return (EINVAL);
3720 
3721 	dpni_ext = (struct dpni_ext_set_rx_tc_dist *) key_cfg_buf;
3722 	dpni_ext->num_extracts = cfg->num_extracts;
3723 
3724 	for (i = 0; i < cfg->num_extracts; i++) {
3725 		extr = &dpni_ext->extracts[i];
3726 
3727 		switch (cfg->extracts[i].type) {
3728 		case DPKG_EXTRACT_FROM_HDR:
3729 			extr->prot = cfg->extracts[i].extract.from_hdr.prot;
3730 			extr->efh_type =
3731 			    cfg->extracts[i].extract.from_hdr.type & 0x0Fu;
3732 			extr->size = cfg->extracts[i].extract.from_hdr.size;
3733 			extr->offset = cfg->extracts[i].extract.from_hdr.offset;
3734 			extr->field = cfg->extracts[i].extract.from_hdr.field;
3735 			extr->hdr_index =
3736 				cfg->extracts[i].extract.from_hdr.hdr_index;
3737 			break;
3738 		case DPKG_EXTRACT_FROM_DATA:
3739 			extr->size = cfg->extracts[i].extract.from_data.size;
3740 			extr->offset =
3741 				cfg->extracts[i].extract.from_data.offset;
3742 			break;
3743 		case DPKG_EXTRACT_FROM_PARSE:
3744 			extr->size = cfg->extracts[i].extract.from_parse.size;
3745 			extr->offset =
3746 				cfg->extracts[i].extract.from_parse.offset;
3747 			break;
3748 		default:
3749 			return (EINVAL);
3750 		}
3751 
3752 		extr->num_of_byte_masks = cfg->extracts[i].num_of_byte_masks;
3753 		extr->extract_type = cfg->extracts[i].type & 0x0Fu;
3754 
3755 		for (j = 0; j < DPKG_NUM_OF_MASKS; j++) {
3756 			extr->masks[j].mask = cfg->extracts[i].masks[j].mask;
3757 			extr->masks[j].offset =
3758 				cfg->extracts[i].masks[j].offset;
3759 		}
3760 	}
3761 
3762 	return (0);
3763 }
3764 
3765 static int
dpaa2_ni_update_csum_flags(struct dpaa2_fd * fd,struct mbuf * m)3766 dpaa2_ni_update_csum_flags(struct dpaa2_fd *fd, struct mbuf *m)
3767 {
3768 	struct dpaa2_hwa_fas fas;
3769 	uint32_t status;
3770 	int rc;
3771 
3772 	if (__predict_false((dpaa2_fd_get_frc(fd) & DPAA2_FD_FRC_FASV)) == 0u)
3773 		return (EINVAL);
3774 
3775 	/*
3776 	 * XXX-DSL: Frame context of the frame descriptor (FD[FRC]) contains
3777 	 *          an Accelerator ID in the MSbits on some SoCs (e.g. LS1088A),
3778 	 *          but a frame ParseSummary on the others (e.g. LX2160A).
3779 	 *          However, frame annotation valid bits seem to be at the
3780 	 *          same offsets. This is the reason why different accelerators
3781 	 *          are treated the same here. It isn't clear whether this is
3782 	 *          a hardware limitation of the SoCs, version of the firmware
3783 	 *          or DPL configuration.
3784 	 */
3785 
3786 	rc = dpaa2_fa_get_fas(fd, &fas);
3787 	if (rc != 0)
3788 		return (rc);
3789 
3790 	status = le32toh(fas.status);
3791 	rc = 0;
3792 
3793 	/* L3 */
3794 	if ((status & DPAA2_FAS_L3CV) != 0) {
3795 		m->m_pkthdr.csum_flags |= CSUM_L3_CALC;
3796 		if ((status & DPAA2_FAS_L3CE) == 0)
3797 			m->m_pkthdr.csum_flags |= CSUM_L3_VALID;
3798 	}
3799 	/* L4 */
3800 	if ((status & DPAA2_FAS_L4CV) != 0) {
3801 		m->m_pkthdr.csum_flags |= CSUM_L4_CALC;
3802 		m->m_pkthdr.csum_data = 0xffff;
3803 		if ((status & DPAA2_FAS_L4CE) == 0)
3804 			m->m_pkthdr.csum_flags |= CSUM_L4_VALID;
3805 	}
3806 
3807 	return (rc);
3808 }
3809 
3810 static device_method_t dpaa2_ni_methods[] = {
3811 	/* Device interface */
3812 	DEVMETHOD(device_probe,		dpaa2_ni_probe),
3813 	DEVMETHOD(device_attach,	dpaa2_ni_attach),
3814 	DEVMETHOD(device_detach,	dpaa2_ni_detach),
3815 
3816 	/* mii via memac_mdio */
3817 	DEVMETHOD(miibus_statchg,	dpaa2_ni_miibus_statchg),
3818 
3819 	DEVMETHOD_END
3820 };
3821 
3822 static driver_t dpaa2_ni_driver = {
3823 	"dpaa2_ni",
3824 	dpaa2_ni_methods,
3825 	sizeof(struct dpaa2_ni_softc),
3826 };
3827 
3828 DRIVER_MODULE(miibus, dpaa2_ni, miibus_driver, 0, 0);
3829 DRIVER_MODULE(dpaa2_ni, dpaa2_rc, dpaa2_ni_driver, 0, 0);
3830 
3831 MODULE_DEPEND(dpaa2_ni, miibus, 1, 1, 1);
3832 #ifdef DEV_ACPI
3833 MODULE_DEPEND(dpaa2_ni, memac_mdio_acpi, 1, 1, 1);
3834 #endif
3835 #ifdef FDT
3836 MODULE_DEPEND(dpaa2_ni, memac_mdio_fdt, 1, 1, 1);
3837 #endif
3838