xref: /freebsd/sys/dev/dpaa/fman_port_rx.c (revision c4fde87a3236b500246d4fce76dbca2a3d64f73a)
1 /*
2  * Copyright (c) 2026 Justin Hibbits
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  *
6  * FMan RX port driver.
7  */
8 
9 #include <sys/param.h>
10 #include <sys/bus.h>
11 #include <sys/kernel.h>
12 #include <sys/module.h>
13 
14 #include <dev/ofw/ofw_bus.h>
15 #include <dev/ofw/ofw_bus_subr.h>
16 #include <machine/bus.h>
17 
18 #include "fman.h"
19 #include "fman_parser.h"
20 #include "fman_port.h"
21 #include "fman_port_var.h"
22 #include "fman_if.h"
23 #include "fman_port_if.h"
24 
25 #define	RX_10G_PORT_BASE	0x10
26 
27 /* BMI Rx registers. */
28 #define	FMBM_RCFG		0x000
29 #define	FMBM_RST		0x004
30 #define	FMBM_RDA		0x008
31 #define	  RDA_WOPT		  0x00100000
32 #define	FMBM_RFP		0x00c
33 #define	FMBM_RFED		0x010
34 #define	  BMI_RX_FRAME_END_CUT_SHIFT	16
35 #define	FMBM_RICP		0x014	/* Counts are units of 16 bytes */
36 #define	  RICP_ICEOF_M		  0x001f0000
37 #define	  RICP_ICEOF_S		  16
38 #define	  RICP_ICIOF_M		  0x00000f00
39 #define	  RICP_ICIOF_S		  8
40 #define	  RICP_ICSZ_S		  0x0000001f
41 #define	FMBM_RIM		0x018
42 #define	FMBM_REBM		0x01c
43 #define	  REBM_BSM_M		  0x01ff0000
44 #define	  REBM_BSM_S		  16
45 #define	  REBM_BEM_M		  0x000001ff
46 #define	FMBM_RFNE		0x020
47 #define	FMBM_RFCA		0x024
48 #define	  RFCA_OR		  0x80000000
49 #define	  RFCA_COLOR		  0x0c000000
50 #define	  RFCA_SYNC		  0x03000000
51 #define	  RFCA_SYNC_REQ		  0x02000000
52 #define	  RFCA_MR		  0x003f0000
53 #define	  RFCA_MR_DEF		  0x003c0000
54 #define	FMBM_RFPNE		0x028
55 #define	FMBM_RETH		0x038
56 #define	  RETH_ETHE		  0x80000000 /* Excessive Threshold Enable */
57 #define	FMBM_RFQID		0x060
58 #define	FMBM_REFQID		0x064
59 #define	FMBM_RFSDM		0x068
60 #define	FMBM_RFSEM		0x06c
61 #define	FMBM_RFENE		0x070
62 #define	FMBM_REBMPI(i)		(0x100 + (4 * (i)))
63 #define	  REBMPI_VAL		  0x80000000
64 #define	  REBMPI_ACE		  0x40000000
65 #define	  REBMPI_BPID_S		  16
66 #define	FMBM_RSTC		0x0200
67 #define	  RSTC_EN		  0x80000000
68 
69 /* Hardware Parser (HWP). */
70 #define	HWP_PCAC		0xbf8
71 #define	  HWP_PCAC_PSTOP	  0x00000001
72 #define	  HWP_HXS_PCAC_PSTAT	  0x00000100
73 #define	HWP_HXS_SSA(x)		(0x800 + x * 2 * sizeof(uint32_t))
74 #define	HWP_HXS_LCV(x)		(0x800 + (x * 2 + 1) * sizeof(uint32_t))
75 #define	HWP_HXS_TCP		  0xA
76 #define	HWP_HXS_UDP		  0xB
77 #define	HXS_SH_PAD_REM		  0x80000000
78 #define	HWP_HXS_COUNT		16
79 
80 #define	BMI_RX_ERR		(FM_FD_ERR_DMA | FM_FD_ERR_FPE |	\
81 				 FM_FD_ERR_FSE | FM_FD_ERR_DIS |	\
82 				 FM_FD_ERR_EOF | FM_FD_ERR_NSS |	\
83 				 FM_FD_ERR_KSO | FM_FD_ERR_IPP |	\
84 				 FM_FD_ERR_PTE | FM_FD_ERR_PHE |	\
85 				 FM_FD_ERR_BLE)
86 
87 #define	DEFAULT_RX_CUT_END_BYTES	4
88 
89 struct fman_port_rx_softc {
90 	struct fman_port_softc sc_base;
91 	struct fman_port_buffer_pool sc_bpools[FMAN_PORT_MAX_POOLS];
92 };
93 
94 static struct ofw_compat_data rx_compats[] = {
95 	{ "fsl,fman-v2-port-rx", 0 },
96 	{ "fsl,fman-v3-port-rx", PORT_V3 },
97 	{ NULL, 0 }
98 };
99 
100 static int
101 fman_port_rx_probe(device_t dev)
102 {
103 
104 	if (ofw_bus_search_compatible(dev, rx_compats)->ocd_str == NULL)
105 		return (ENXIO);
106 
107 	device_set_desc(dev, "FMan RX port");
108 	return (BUS_PROBE_DEFAULT);
109 }
110 
111 static int
112 fman_port_rx_attach(device_t dev)
113 {
114 	struct fman_port_rx_softc *sc;
115 	uintptr_t compat_data;
116 	int port_speed;
117 
118 	sc = device_get_softc(dev);
119 	compat_data = ofw_bus_search_compatible(dev, rx_compats)->ocd_data;
120 
121 	port_speed = 1000;
122 	if ((compat_data & PORT_V3) == PORT_V3) {
123 		if (OF_hasprop(ofw_bus_get_node(dev), "fsl,fman-10g-port"))
124 			port_speed = 10000;
125 	} else {
126 		int cell = 0;
127 		OF_getencprop(ofw_bus_get_node(dev), "cell-index", &cell,
128 		    sizeof(cell));
129 		if (cell > RX_10G_PORT_BASE)
130 			port_speed = 10000;
131 	}
132 
133 	return (fman_port_attach_common(dev, &sc->sc_base, port_speed));
134 }
135 
136 static int
137 fman_port_rx_detach(device_t dev)
138 {
139 	struct fman_port_rx_softc *sc = device_get_softc(dev);
140 
141 	return (fman_port_detach_common(dev, &sc->sc_base));
142 }
143 
144 static int
145 fman_port_rx_config(device_t dev, struct fman_port_params *params)
146 {
147 	struct fman_port_rx_softc *sc = device_get_softc(dev);
148 	struct fman_port_softc *base = &sc->sc_base;
149 
150 	fman_port_config_common(base, params);
151 
152 	base->sc_tasks.extra = 0;
153 	base->sc_open_dmas.extra = 0;
154 	switch (base->sc_port_speed) {
155 	case 10000:
156 		if (base->sc_revision_major < 6) {
157 			base->sc_tasks.num = 16;
158 			base->sc_open_dmas.num = 8;
159 			base->sc_open_dmas.extra = 8;
160 			base->sc_fifo_bufs.num = 48;
161 		} else {
162 			base->sc_tasks.num = 14;
163 			base->sc_open_dmas.num = 8;
164 			base->sc_fifo_bufs.num = 96;
165 		}
166 		break;
167 	case 1000:
168 		if (base->sc_revision_major < 6) {
169 			base->sc_tasks.num = 3;
170 			base->sc_tasks.extra = 2;
171 			base->sc_open_dmas.num = 1;
172 			base->sc_open_dmas.extra = 1;
173 			base->sc_fifo_bufs.num = 45;
174 		} else {
175 			base->sc_tasks.num = 4;
176 			base->sc_open_dmas.num = 2;
177 			base->sc_fifo_bufs.num = 50;
178 		}
179 		break;
180 	default:
181 		base->sc_tasks.num = 0;
182 		break;
183 	}
184 
185 	base->sc_fifo_bufs.extra = 0;
186 	base->sc_fifo_bufs.num *= FMAN_BMI_FIFO_UNITS;
187 
188 	for (int i = 0; i < params->rx_params.num_pools; i++)
189 		sc->sc_bpools[i] = params->rx_params.bpools[i];
190 
191 	/* TODO: buf_margins?  See fman_sp_build_buffer_struct */
192 	return (0);
193 }
194 
195 static int
196 fman_port_rx_init_bmi(struct fman_port_rx_softc *sc)
197 {
198 	struct fman_port_softc *base = &sc->sc_base;
199 	uint32_t reg;
200 
201 	/* TODO: Sort the buffer pool list.  */
202 	/* TODO: Backup pools */
203 	/* TODO: Depletion mode */
204 	for (int i = 0; i < FMAN_PORT_MAX_POOLS; i++) {
205 		if (sc->sc_bpools[i].size != 0) {
206 			bus_write_4(base->sc_mem, FMBM_REBMPI(i),
207 			    REBMPI_VAL | REBMPI_ACE |
208 			    (sc->sc_bpools[i].bpid << REBMPI_BPID_S) |
209 			    sc->sc_bpools[i].size);
210 		} else
211 			bus_write_4(base->sc_mem, FMBM_REBMPI(i), 0);
212 	}
213 
214 	bus_write_4(base->sc_mem, FMBM_RDA, RDA_WOPT);
215 
216 	bus_write_4(base->sc_mem, FMBM_RFCA,
217 	    RFCA_OR | RFCA_SYNC_REQ | RFCA_MR_DEF);
218 
219 	/*
220 	 * Route the Parser output through KeyGen (HWK), not straight to
221 	 * BMI enqueue.  KG then hands off to BMI-enqueue via its own
222 	 * default NIA (FMKG_GCR low bits, programmed by fman_kg_init as
223 	 * NIA_ENG_BMI|NIA_BMI_AC_ENQ_FRAME).  Ports with no bound KG
224 	 * scheme fall through KG's default path to the port's dflt_fqid,
225 	 * matching the old direct-to-BMI behaviour; ports with a scheme
226 	 * bound (via fman_kg_alloc_hash_scheme, e.g. from the dpaa_eth
227 	 * RSS setup) get real hash distribution.
228 	 */
229 	bus_write_4(base->sc_mem, FMBM_RFPNE, NIA_ENG_HWK);
230 	bus_write_4(base->sc_mem, FMBM_RFENE,
231 	    NIA_ENG_QMI_ENQ | NIA_ORDER_RESTORE);
232 
233 	bus_write_4(base->sc_mem, FMBM_RFQID, base->sc_default_fqid);
234 	bus_write_4(base->sc_mem, FMBM_REFQID, base->sc_err_fqid);
235 
236 	if (base->sc_revision_major < 6)
237 		bus_write_4(base->sc_mem, FMBM_RETH, RETH_ETHE);
238 
239 	/* Errata A006320 makes CFED field bad */
240 	if (base->sc_revision_major == 6 && base->sc_revision_minor == 0)
241 		/* These are under errata A006320 */;
242 	else
243 		bus_write_4(base->sc_mem, FMBM_RFED,
244 		    DEFAULT_RX_CUT_END_BYTES << BMI_RX_FRAME_END_CUT_SHIFT);
245 
246 	/* Insert internal context ahead of the frame */
247 	reg = sizeof(struct fman_internal_context) << REBM_BSM_S;
248 	bus_write_4(base->sc_mem, FMBM_REBM, reg);
249 	reg = howmany(FMAN_PARSE_RESULT_OFF, 0x10) << RICP_ICIOF_S;
250 	reg |= howmany(sizeof(struct fman_internal_context), 0x10);
251 	bus_write_4(base->sc_mem, FMBM_RICP, reg);
252 
253 	bus_write_4(base->sc_mem, FMBM_RFNE, NIA_ENG_HWP);
254 	bus_write_4(base->sc_mem, FMBM_RFSDM, FM_FD_ERR_DIS);
255 	bus_write_4(base->sc_mem, FMBM_RFSEM, BMI_RX_ERR & ~FM_FD_ERR_DIS);
256 
257 	return (0);
258 }
259 
260 static int
261 fman_port_rx_init_hwp(struct fman_port_rx_softc *sc)
262 {
263 	struct fman_port_softc *base = &sc->sc_base;
264 	int i;
265 
266 	bus_write_4(base->sc_mem, HWP_PCAC, HWP_PCAC_PSTOP);
267 	for (i = 0; i < 100 &&
268 	    (bus_read_4(base->sc_mem, HWP_PCAC) & HWP_HXS_PCAC_PSTAT) != 0;
269 	    i++) {
270 		DELAY(10);
271 	}
272 	if (i == 100) {
273 		device_printf(base->sc_dev, "Timeout stopping HW parser\n");
274 		return (ENXIO);
275 	}
276 
277 	for (i = 0; i < HWP_HXS_COUNT; i++) {
278 		bus_write_4(base->sc_mem, HWP_HXS_SSA(i), 0);
279 		bus_write_4(base->sc_mem, HWP_HXS_LCV(i), 0xffffffff);
280 	}
281 	bus_write_4(base->sc_mem, HWP_HXS_SSA(HWP_HXS_TCP), HXS_SH_PAD_REM);
282 	bus_write_4(base->sc_mem, HWP_HXS_SSA(HWP_HXS_UDP), HXS_SH_PAD_REM);
283 
284 	bus_write_4(base->sc_mem, HWP_PCAC, 0);
285 	return (0);
286 }
287 
288 static int
289 fman_port_rx_init(device_t dev)
290 {
291 	struct fman_port_rx_softc *sc = device_get_softc(dev);
292 	struct fman_port_softc *base = &sc->sc_base;
293 	struct fman_port_init_params params;
294 	int err;
295 
296 	params.port_id = base->sc_port_id;
297 	params.is_rx_port = true;
298 	params.num_tasks = base->sc_tasks.num;
299 	params.extra_tasks = base->sc_tasks.extra;
300 	params.open_dmas = base->sc_open_dmas.num;
301 	params.extra_dmas = base->sc_open_dmas.extra;
302 	params.fifo_size = base->sc_fifo_bufs.num;
303 	params.extra_fifo_size = base->sc_fifo_bufs.extra;
304 	params.max_frame_length = base->sc_max_frame_length;
305 	params.deq_pipeline_size = 0;
306 
307 	/* TODO: verify_size_of_fifo() from Linux driver */
308 	err = FMAN_SET_PORT_PARAMS(device_get_parent(dev), &params);
309 	if (err != 0)
310 		return (err);
311 
312 	err = fman_port_rx_init_bmi(sc);
313 	if (err == 0)
314 		err = fman_port_rx_init_hwp(sc);
315 	if (err != 0)
316 		return (err);
317 
318 	bus_write_4(base->sc_mem, FMQM_PNEN,
319 	    NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
320 
321 	/* TODO: keygen here */
322 	return (0);
323 }
324 
325 static int
326 fman_port_rx_disable(device_t dev)
327 {
328 	struct fman_port_rx_softc *sc = device_get_softc(dev);
329 	struct fman_port_softc *base = &sc->sc_base;
330 	uint32_t reg;
331 	int count;
332 
333 	reg = bus_read_4(base->sc_mem, FMBM_RCFG);
334 	bus_write_4(base->sc_mem, FMBM_RCFG, reg & ~BMI_PORT_CFG_EN);
335 	for (count = 0; count < 100; count++) {
336 		DELAY(10);
337 		reg = bus_read_4(base->sc_mem, FMBM_RST);
338 		if (!(reg & PNS_DEQ_FD_BSY))
339 			break;
340 	}
341 	if (count == 100)
342 		device_printf(base->sc_dev, "Timeout stopping BMI\n");
343 
344 	return (0);
345 }
346 
347 static int
348 fman_port_rx_enable(device_t dev)
349 {
350 	struct fman_port_rx_softc *sc = device_get_softc(dev);
351 	struct fman_port_softc *base = &sc->sc_base;
352 	uint32_t reg;
353 
354 	reg = bus_read_4(base->sc_mem, FMQM_PNC);
355 	bus_write_4(base->sc_mem, FMQM_PNC, reg | PNC_EN | PNC_STEN);
356 
357 	reg = bus_read_4(base->sc_mem, FMBM_RCFG);
358 	bus_write_4(base->sc_mem, FMBM_RCFG, reg | BMI_PORT_CFG_EN);
359 
360 	bus_write_4(base->sc_mem, FMBM_RSTC, RSTC_EN);
361 
362 	return (0);
363 }
364 
365 void
366 fman_port_rx_use_kg(device_t dev, bool enable)
367 {
368 	struct fman_port_rx_softc *sc = device_get_softc(dev);
369 
370 	bus_write_4(sc->sc_base.sc_mem, FMBM_RFPNE,
371 	    enable ? NIA_ENG_HWK :
372 	    (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
373 }
374 
375 static device_method_t fman_port_rx_methods[] = {
376 	DEVMETHOD(device_probe,		fman_port_rx_probe),
377 	DEVMETHOD(device_attach,	fman_port_rx_attach),
378 	DEVMETHOD(device_detach,	fman_port_rx_detach),
379 
380 	DEVMETHOD(fman_port_config,	fman_port_rx_config),
381 	DEVMETHOD(fman_port_init,	fman_port_rx_init),
382 	DEVMETHOD(fman_port_enable,	fman_port_rx_enable),
383 	DEVMETHOD(fman_port_disable,	fman_port_rx_disable),
384 
385 	DEVMETHOD_END
386 };
387 
388 DEFINE_CLASS_0(fman_port_rx, fman_port_rx_driver, fman_port_rx_methods,
389     sizeof(struct fman_port_rx_softc));
390 EARLY_DRIVER_MODULE(fman_port_rx, fman, fman_port_rx_driver, 0, 0,
391     BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE);
392