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