xref: /netbsd-src/sys/arch/mips/cavium/dev/octeon_gmx.c (revision ccd9df534e375a4366c5b55f23782053c7a98d82)
1 /*	$NetBSD: octeon_gmx.c,v 1.24 2024/06/29 12:11:11 riastradh Exp $	*/
2 
3 /*
4  * Copyright (c) 2007 Internet Initiative Japan, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: octeon_gmx.c,v 1.24 2024/06/29 12:11:11 riastradh Exp $");
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/cpu.h>
36 #include <sys/device.h>
37 #include <sys/lock.h>
38 #include <sys/cdefs.h>
39 #include <sys/kmem.h>
40 #include <sys/syslog.h>
41 
42 #include <mips/locore.h>
43 #include <mips/include/cpuregs.h>
44 
45 #include <mips/cavium/dev/octeon_asxvar.h>
46 #include <mips/cavium/dev/octeon_ciureg.h>
47 #include <mips/cavium/dev/octeon_gmxreg.h>
48 #include <mips/cavium/dev/octeon_gmxvar.h>
49 #include <mips/cavium/dev/octeon_ipdvar.h>
50 #include <mips/cavium/dev/octeon_pipvar.h>
51 #include <mips/cavium/dev/octeon_smivar.h>
52 
53 #include <mips/cavium/include/iobusvar.h>
54 
55 /*
56  * CNnnXX packet interface
57  *
58  *
59  * CN30XX  - 1 GMX interface  x 3 ports
60  * CN31XX  - 1 GMX interface  x 3 ports
61  * CN38XX  - 2 GMX interfaces x 4 ports
62  * CN50XX  - 1 GMX interface  x 3 ports
63  * CN52XX  - 1 GMX interface  x 4 ports
64  * CN56XX  - 2 GMX interfaces x 4 ports
65  * CN58XX  - 2 GMX interfaces x 4 ports
66  * CN61XX  - 2 GMX interfaces x 4 ports
67  * CN63XX  - 1 GMX interface  x 4 ports
68  * CN66XX  - 2 GMX interfaces x 4 ports
69  * CN68XX  - 5 GMX interfaces x 4 ports
70  * CN70XX  - 2 GMX interfaces x 4 ports
71  * CNF71XX - 1 GMX interface  x 2 ports
72  */
73 
74 #define	dprintf(...)
75 #define	CNMAC_KASSERT	KASSERT
76 
77 #define	ADDR2UINT64(u, a) \
78 	do { \
79 		u = \
80 		    (((uint64_t)a[0] << 40) | ((uint64_t)a[1] << 32) | \
81 		     ((uint64_t)a[2] << 24) | ((uint64_t)a[3] << 16) | \
82 		     ((uint64_t)a[4] <<  8) | ((uint64_t)a[5] <<  0)); \
83 	} while (0)
84 #define	UINT642ADDR(a, u) \
85 	do { \
86 		a[0] = (uint8_t)((u) >> 40); a[1] = (uint8_t)((u) >> 32); \
87 		a[2] = (uint8_t)((u) >> 24); a[3] = (uint8_t)((u) >> 16); \
88 		a[4] = (uint8_t)((u) >>  8); a[5] = (uint8_t)((u) >>  0); \
89 	} while (0)
90 
91 #define	_GMX_RD8(sc, off) \
92 	bus_space_read_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_gmx->sc_regh, (off))
93 #define	_GMX_WR8(sc, off, v) \
94 	bus_space_write_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_gmx->sc_regh, (off), (v))
95 #define	_GMX_PORT_RD8(sc, off) \
96 	bus_space_read_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_regh, (off))
97 #define	_GMX_PORT_WR8(sc, off, v) \
98 	bus_space_write_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_regh, (off), (v))
99 
100 #define PCS_READ_8(sc, reg) \
101 	bus_space_read_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_pcs_regh, (reg))
102 #define PCS_WRITE_8(sc, reg, val) \
103 	bus_space_write_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_pcs_regh, (reg), (val))
104 
105 struct octgmx_port_ops {
106 	int	(*port_ops_enable)(struct octgmx_port_softc *, int);
107 	int	(*port_ops_speed)(struct octgmx_port_softc *);
108 	int	(*port_ops_timing)(struct octgmx_port_softc *);
109 };
110 
111 static int	octgmx_match(device_t, struct cfdata *, void *);
112 static void	octgmx_attach(device_t, device_t, void *);
113 static int	octgmx_print(void *, const char *);
114 static int	octgmx_init(struct octgmx_softc *);
115 
116 static int	octgmx_link_enable(struct octgmx_port_softc *, int);
117 static int	octgmx_rx_frm_ctl_xable(struct octgmx_port_softc *, uint64_t,
118 		    int);
119 static void	octgmx_tx_int_enable(struct octgmx_port_softc *, int);
120 static void	octgmx_rx_int_enable(struct octgmx_port_softc *, int);
121 static int	octgmx_rx_frm_ctl_enable(struct octgmx_port_softc *, uint64_t);
122 static int	octgmx_rx_frm_ctl_disable(struct octgmx_port_softc *, uint64_t);
123 static int	octgmx_tx_thresh(struct octgmx_port_softc *, int);
124 
125 static int	octgmx_rgmii_enable(struct octgmx_port_softc *, int);
126 static int	octgmx_rgmii_speed(struct octgmx_port_softc *);
127 static int	octgmx_rgmii_speed_newlink(struct octgmx_port_softc *,
128 		    uint64_t *);
129 static int	octgmx_rgmii_speed_speed(struct octgmx_port_softc *);
130 static int	octgmx_rgmii_timing(struct octgmx_port_softc *);
131 
132 static int	octgmx_sgmii_enable(struct octgmx_port_softc *, int);
133 static int	octgmx_sgmii_speed(struct octgmx_port_softc *);
134 static int	octgmx_sgmii_timing(struct octgmx_port_softc *);
135 
136 static const int	octgmx_rx_adr_cam_regs[] = {
137 	GMX0_RX0_ADR_CAM0, GMX0_RX0_ADR_CAM1, GMX0_RX0_ADR_CAM2,
138 	GMX0_RX0_ADR_CAM3, GMX0_RX0_ADR_CAM4, GMX0_RX0_ADR_CAM5
139 };
140 
141 static struct octgmx_port_ops octgmx_port_ops_mii = {
142 	/* XXX not implemented */
143 };
144 
145 static struct octgmx_port_ops octgmx_port_ops_gmii = {
146 	.port_ops_enable = octgmx_rgmii_enable,
147 	.port_ops_speed = octgmx_rgmii_speed,
148 	.port_ops_timing = octgmx_rgmii_timing,
149 };
150 
151 static struct octgmx_port_ops octgmx_port_ops_rgmii = {
152 	.port_ops_enable = octgmx_rgmii_enable,
153 	.port_ops_speed = octgmx_rgmii_speed,
154 	.port_ops_timing = octgmx_rgmii_timing,
155 };
156 
157 static struct octgmx_port_ops octgmx_port_ops_sgmii = {
158 	.port_ops_enable = octgmx_sgmii_enable,
159 	.port_ops_speed = octgmx_sgmii_speed,
160 	.port_ops_timing = octgmx_sgmii_timing,
161 };
162 
163 static struct octgmx_port_ops octgmx_port_ops_spi42 = {
164 	/* XXX not implemented */
165 };
166 
167 static struct octgmx_port_ops *octgmx_port_ops[] = {
168 	[GMX_MII_PORT] = &octgmx_port_ops_mii,
169 	[GMX_GMII_PORT] = &octgmx_port_ops_gmii,
170 	[GMX_RGMII_PORT] = &octgmx_port_ops_rgmii,
171 	[GMX_SGMII_PORT] = &octgmx_port_ops_sgmii,
172 	[GMX_SPI42_PORT] = &octgmx_port_ops_spi42
173 };
174 static const char *octgmx_port_types[] = {
175 	[GMX_MII_PORT] = "MII",
176 	[GMX_GMII_PORT] = "GMII",
177 	[GMX_RGMII_PORT] = "RGMII",
178 	[GMX_SGMII_PORT] = "SGMII",
179 	[GMX_SPI42_PORT] = "SPI-4.2"
180 };
181 
182 CFATTACH_DECL_NEW(octgmx, sizeof(struct octgmx_softc),
183     octgmx_match, octgmx_attach, NULL, NULL);
184 
185 static int
186 octgmx_match(device_t parent, struct cfdata *cf, void *aux)
187 {
188 	struct iobus_attach_args *aa = aux;
189 
190 	if (strcmp(cf->cf_name, aa->aa_name) != 0)
191 		return 0;
192 	if (cf->cf_unit != aa->aa_unitno)
193 		return 0;
194 	return 1;
195 }
196 
197 static void
198 octgmx_attach(device_t parent, device_t self, void *aux)
199 {
200 	struct octgmx_softc *sc = device_private(self);
201 	struct iobus_attach_args *aa = aux;
202 	struct octsmi_softc *smi;
203 	struct octgmx_port_softc *port_sc;
204 	struct octgmx_attach_args gmx_aa;
205 	int port, status;
206 	int i;
207 
208 	sc->sc_dev = self;
209 	sc->sc_regt = aa->aa_bust;
210 	sc->sc_unitno = aa->aa_unitno;
211 
212 	aprint_normal("\n");
213 
214 	status = bus_space_map(sc->sc_regt, aa->aa_unit->addr,
215 	    GMX_PORT_SIZE, 0, &sc->sc_regh);
216 	if (status != 0)
217 		panic(": can't map register");
218 
219 	octgmx_init(sc);
220 
221 	sc->sc_ports = kmem_zalloc(sizeof(*sc->sc_ports) * sc->sc_nports,
222 	    KM_SLEEP);
223 
224 	for (i = 0; i < sc->sc_nports; i++) {
225 		port = GMX_PORT_NUM(sc->sc_unitno, i);
226 		smi = octsmi_lookup(/*XXX*/0, port);
227 		if (smi == NULL)
228 			continue;
229 
230 		port_sc = &sc->sc_ports[i];
231 		port_sc->sc_port_gmx = sc;
232 		port_sc->sc_port_no = port;
233 		port_sc->sc_port_type = sc->sc_port_types[i];
234 		port_sc->sc_port_ops = octgmx_port_ops[port_sc->sc_port_type];
235 		status = bus_space_map(sc->sc_regt,
236 		    aa->aa_unit->addr + GMX_PORT_SIZE * i,
237 		    GMX_PORT_SIZE, 0, &port_sc->sc_port_regh);
238 		if (status != 0)
239 			panic(": can't map port register");
240 
241 		switch (port_sc->sc_port_type) {
242 		case GMX_MII_PORT:
243 		case GMX_GMII_PORT:
244 		case GMX_RGMII_PORT: {
245 			struct octasx_attach_args asx_aa;
246 
247 			asx_aa.aa_port = i;
248 			asx_aa.aa_regt = aa->aa_bust;
249 			octasx_init(&asx_aa, &port_sc->sc_port_asx);
250 			break;
251 		}
252 		case GMX_SGMII_PORT:
253 			if (bus_space_map(sc->sc_regt,
254 			    PCS_BASE(sc->sc_unitno, i), PCS_SIZE, 0,
255 			    &port_sc->sc_port_pcs_regh))
256 				panic("could not map PCS registers");
257 			break;
258 		default:
259 			/* nothing */
260 			break;
261 		}
262 
263 		(void)memset(&gmx_aa, 0, sizeof(gmx_aa));
264 		gmx_aa.ga_regt = aa->aa_bust;
265 		gmx_aa.ga_addr = aa->aa_unit->addr;
266 		gmx_aa.ga_name = "cnmac";
267 		gmx_aa.ga_portno = port_sc->sc_port_no;
268 		gmx_aa.ga_port_type = sc->sc_port_types[i];
269 		gmx_aa.ga_smi = smi;
270 		gmx_aa.ga_gmx = sc;
271 		gmx_aa.ga_gmx_port = port_sc;
272 		config_found(self, &gmx_aa, octgmx_print, CFARGS_NONE);
273 	}
274 }
275 
276 static int
277 octgmx_print(void *aux, const char *pnp)
278 {
279 	struct octgmx_attach_args *ga = aux;
280 
281 	aprint_normal(": address=0x%" PRIx64 ": %s\n", ga->ga_addr,
282 	    octgmx_port_types[ga->ga_port_type]);
283 
284 	return UNCONF;
285 }
286 
287 static int
288 octgmx_init(struct octgmx_softc *sc)
289 {
290 	int result = 0;
291 	uint64_t inf_mode;
292 	const mips_prid_t cpu_id = mips_options.mips_cpu_id;
293 
294 	inf_mode = bus_space_read_8(sc->sc_regt, sc->sc_regh, GMX0_INF_MODE);
295 	if ((inf_mode & INF_MODE_EN) == 0) {
296 		aprint_normal("ports are disabled\n");
297 		sc->sc_nports = 0;
298 		return 1;
299 	}
300 
301 	if (MIPS_PRID_CID(cpu_id) != MIPS_PRID_CID_CAVIUM)
302 		return 1;
303 
304 	switch (MIPS_PRID_IMPL(cpu_id)) {
305 	case MIPS_CN31XX:
306 		/*
307 		 * Packet Interface Configuration
308 		 * GMX Registers, Interface Mode Register, GMX0_INF_MODE
309 		 */
310 		if ((inf_mode & INF_MODE_TYPE) == 0) {
311 			/* all three ports configured as RGMII */
312 			sc->sc_nports = 3;
313 			sc->sc_port_types[0] = GMX_RGMII_PORT;
314 			sc->sc_port_types[1] = GMX_RGMII_PORT;
315 			sc->sc_port_types[2] = GMX_RGMII_PORT;
316 		} else {
317 			/* port 0: RGMII, port 1: GMII, port 2: disabled */
318 			sc->sc_nports = 2;
319 			sc->sc_port_types[0] = GMX_RGMII_PORT;
320 			sc->sc_port_types[1] = GMX_GMII_PORT;
321 		}
322 		break;
323 	case MIPS_CN30XX:
324 	case MIPS_CN50XX:
325 		/*
326 		 * Packet Interface Configuration
327 		 * GMX Registers, Interface Mode Register, GMX0_INF_MODE
328 		 */
329 		if ((inf_mode & INF_MODE_P0MII) == 0)
330 			sc->sc_port_types[0] = GMX_RGMII_PORT;
331 		else
332 			sc->sc_port_types[0] = GMX_MII_PORT;
333 		if ((inf_mode & INF_MODE_TYPE) == 0) {
334 			/* port 1 and 2 are configred as RGMII ports */
335 			sc->sc_nports = 3;
336 			sc->sc_port_types[1] = GMX_RGMII_PORT;
337 			sc->sc_port_types[2] = GMX_RGMII_PORT;
338 		} else {
339 			/* port 1: GMII/MII, port 2: disabled */
340 			/* GMII or MII port is selected by GMX_PRT1_CFG[SPEED] */
341 			sc->sc_nports = 2;
342 			sc->sc_port_types[1] = GMX_GMII_PORT;
343 		}
344 #if 0 /* XXX XXX XXX */
345 		/* port 2 is in CN3010/CN5010 only */
346 		if ((octeon_model(id) != OCTEON_MODEL_CN3010) &&
347 		    (octeon_model(id) != OCTEON_MODEL_CN5010))
348 			if (sc->sc_nports == 3)
349 				sc->sc_nports = 2;
350 #endif
351 		break;
352 	case MIPS_CN70XX:
353 		switch (inf_mode & INF_MODE_MODE) {
354 		case INF_MODE_MODE_SGMII:
355 			sc->sc_nports = 4;
356 			for (int i = 0; i < sc->sc_nports; i++)
357 				sc->sc_port_types[i] = GMX_SGMII_PORT;
358 			break;
359 #ifdef notyet
360 		case INF_MODE_MODE_XAUI:
361 #endif
362 		default:
363 			sc->sc_nports = 0;
364 			result = 1;
365 		}
366 		break;
367 	default:
368 		aprint_normal("unsupported octeon model: 0x%x\n", cpu_id);
369 		sc->sc_nports = 0;
370 		result = 1;
371 		break;
372 	}
373 
374 	return result;
375 }
376 
377 /* XXX RGMII specific */
378 static int
379 octgmx_link_enable(struct octgmx_port_softc *sc, int enable)
380 {
381 	uint64_t prt_cfg;
382 
383 	octgmx_tx_int_enable(sc, enable);
384 	octgmx_rx_int_enable(sc, enable);
385 
386 	prt_cfg = _GMX_PORT_RD8(sc, GMX0_PRT0_CFG);
387 	if (enable) {
388 		if (octgmx_link_status(sc)) {
389 			SET(prt_cfg, PRTN_CFG_EN);
390 		}
391 	} else {
392 		CLR(prt_cfg, PRTN_CFG_EN);
393 	}
394 	_GMX_PORT_WR8(sc, GMX0_PRT0_CFG, prt_cfg);
395 	/* software should read back to flush the write operation. */
396 	(void)_GMX_PORT_RD8(sc, GMX0_PRT0_CFG);
397 
398 	return 0;
399 }
400 
401 /* XXX RGMII specific */
402 int
403 octgmx_stats_init(struct octgmx_port_softc *sc)
404 {
405         _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS, 0);
406         _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_DRP, 0);
407         _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_BAD, 0);
408         _GMX_PORT_WR8(sc, GMX0_TX0_STAT0, 0);
409         _GMX_PORT_WR8(sc, GMX0_TX0_STAT1, 0);
410         _GMX_PORT_WR8(sc, GMX0_TX0_STAT3, 0);
411         _GMX_PORT_WR8(sc, GMX0_TX0_STAT9, 0);
412 
413 	return 0;
414 }
415 
416 int
417 octgmx_tx_stats_rd_clr(struct octgmx_port_softc *sc, int enable)
418 {
419 	_GMX_PORT_WR8(sc, GMX0_TX0_STATS_CTL, enable ? 1 : 0);
420 	return 0;
421 }
422 
423 int
424 octgmx_rx_stats_rd_clr(struct octgmx_port_softc *sc, int enable)
425 {
426 	_GMX_PORT_WR8(sc, GMX0_RX0_STATS_CTL, enable ? 1 : 0);
427 	return 0;
428 }
429 
430 static int
431 octgmx_tx_ovr_bp_enable(struct octgmx_port_softc *sc, int enable)
432 {
433 	uint64_t ovr_bp;
434 	int index = GMX_PORT_INDEX(sc->sc_port_no);
435 
436 	ovr_bp = _GMX_RD8(sc, GMX0_TX_OVR_BP);
437 	if (enable) {
438 		CLR(ovr_bp, __SHIFTIN(__BIT(index), TX_OVR_BP_EN));
439 		SET(ovr_bp, __SHIFTIN(__BIT(index), TX_OVR_BP_BP));
440 		/* XXX really??? */
441 		SET(ovr_bp, __SHIFTIN(__BIT(index), TX_OVR_BP_IGN_FULL));
442 	} else {
443 		SET(ovr_bp, __SHIFTIN(__BIT(index), TX_OVR_BP_EN));
444 		CLR(ovr_bp, __SHIFTIN(__BIT(index), TX_OVR_BP_BP));
445 		/* XXX really??? */
446 		SET(ovr_bp, __SHIFTIN(__BIT(index), TX_OVR_BP_IGN_FULL));
447 	}
448 	_GMX_WR8(sc, GMX0_TX_OVR_BP, ovr_bp);
449 	return 0;
450 }
451 
452 static int
453 octgmx_rx_pause_enable(struct octgmx_port_softc *sc, int enable)
454 {
455 	if (enable) {
456 		octgmx_rx_frm_ctl_enable(sc, RXN_FRM_CTL_CTL_BCK);
457 	} else {
458 		octgmx_rx_frm_ctl_disable(sc, RXN_FRM_CTL_CTL_BCK);
459 	}
460 
461 	return 0;
462 }
463 
464 static void
465 octgmx_tx_int_enable(struct octgmx_port_softc *sc, int enable)
466 {
467 	uint64_t tx_int_xxx = 0;
468 
469 	SET(tx_int_xxx,
470 	    TX_INT_REG_LATE_COL |
471 	    TX_INT_REG_XSDEF |
472 	    TX_INT_REG_XSCOL |
473 	    TX_INT_REG_UNDFLW |
474 	    TX_INT_REG_PKO_NXA);
475 	_GMX_WR8(sc, GMX0_TX_INT_REG, tx_int_xxx);
476 	_GMX_WR8(sc, GMX0_TX_INT_EN, enable ? tx_int_xxx : 0);
477 }
478 
479 static void
480 octgmx_rx_int_enable(struct octgmx_port_softc *sc, int enable)
481 {
482 	uint64_t rx_int_xxx = 0;
483 
484 	SET(rx_int_xxx, 0 |
485 	    RXN_INT_REG_PHY_DUPX |
486 	    RXN_INT_REG_PHY_SPD |
487 	    RXN_INT_REG_PHY_LINK |
488 	    RXN_INT_REG_IFGERR |
489 	    RXN_INT_REG_COLDET |
490 	    RXN_INT_REG_FALERR |
491 	    RXN_INT_REG_RSVERR |
492 	    RXN_INT_REG_PCTERR |
493 	    RXN_INT_REG_OVRERR |
494 	    RXN_INT_REG_NIBERR |
495 	    RXN_INT_REG_SKPERR |
496 	    RXN_INT_REG_RCVERR |
497 	    RXN_INT_REG_LENERR |
498 	    RXN_INT_REG_ALNERR |
499 	    RXN_INT_REG_FCSERR |
500 	    RXN_INT_REG_JABBER |
501 	    RXN_INT_REG_MAXERR |
502 	    RXN_INT_REG_CAREXT |
503 	    RXN_INT_REG_MINERR);
504 	_GMX_PORT_WR8(sc, GMX0_RX0_INT_REG, rx_int_xxx);
505 	_GMX_PORT_WR8(sc, GMX0_RX0_INT_EN, enable ? rx_int_xxx : 0);
506 }
507 
508 static int
509 octgmx_rx_frm_ctl_enable(struct octgmx_port_softc *sc, uint64_t rx_frm_ctl)
510 {
511 	struct ifnet *ifp = &sc->sc_port_ec->ec_if;
512 	unsigned int maxlen;
513 
514 	maxlen = roundup(ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN +
515 	    ETHER_VLAN_ENCAP_LEN, 8);
516 	_GMX_PORT_WR8(sc, GMX0_RX0_JABBER, maxlen);
517 
518 	return octgmx_rx_frm_ctl_xable(sc, rx_frm_ctl, 1);
519 }
520 
521 static int
522 octgmx_rx_frm_ctl_disable(struct octgmx_port_softc *sc, uint64_t rx_frm_ctl)
523 {
524 	return octgmx_rx_frm_ctl_xable(sc, rx_frm_ctl, 0);
525 }
526 
527 static int
528 octgmx_rx_frm_ctl_xable(struct octgmx_port_softc *sc, uint64_t rx_frm_ctl,
529     int enable)
530 {
531 	uint64_t tmp;
532 
533 	tmp = _GMX_PORT_RD8(sc, GMX0_RX0_FRM_CTL);
534 	if (enable)
535 		SET(tmp, rx_frm_ctl);
536 	else
537 		CLR(tmp, rx_frm_ctl);
538 	_GMX_PORT_WR8(sc, GMX0_RX0_FRM_CTL, tmp);
539 
540 	return 0;
541 }
542 
543 static int
544 octgmx_tx_thresh(struct octgmx_port_softc *sc, int cnt)
545 {
546 	_GMX_PORT_WR8(sc, GMX0_TX0_THRESH, cnt);
547 	return 0;
548 }
549 
550 int
551 octgmx_set_mac_addr(struct octgmx_port_softc *sc, const uint8_t *addr)
552 {
553 	uint64_t mac;
554 	int i;
555 
556 	ADDR2UINT64(mac, addr);
557 
558 	octgmx_link_enable(sc, 0);
559 	sc->sc_mac = mac;
560 
561 	_GMX_PORT_WR8(sc, GMX0_SMAC0, mac);
562 	for (i = 0; i < 6; i++)
563 		_GMX_PORT_WR8(sc, octgmx_rx_adr_cam_regs[i], addr[i]);
564 
565 	octgmx_link_enable(sc, 1);
566 
567 	return 0;
568 }
569 
570 int
571 octgmx_set_filter(struct octgmx_port_softc *sc)
572 {
573 	struct ethercom *ec = sc->sc_port_ec;
574 	struct ifnet *ifp = &ec->ec_if;
575 	struct ether_multi *enm;
576 	struct ether_multistep step;
577 	uint64_t ctl = 0;
578 	int multi = 0;
579 	uint64_t cam_en = 1;	/* enable CAM 0 for self MAC addr */
580 
581 	octgmx_link_enable(sc, 0);
582 
583 	if (ISSET(ifp->if_flags, IFF_BROADCAST)) {
584 		dprintf("accept broadcast\n");
585 		SET(ctl, RXN_ADR_CTL_BCST);
586 	}
587 	if (ISSET(ifp->if_flags, IFF_PROMISC)) {
588 		dprintf("promiscuous (reject cam)\n");
589 		CLR(ctl, RXN_ADR_CTL_CAM_MODE);
590 	} else {
591 		dprintf("not promiscuous (accept cam)\n");
592 		SET(ctl, RXN_ADR_CTL_CAM_MODE);
593 	}
594 
595 	/*
596 	 * Note first entry is self MAC address; other 7 entries are available
597 	 * for multicast addresses.
598 	 */
599 
600 	ETHER_LOCK(ec);
601 	ETHER_FIRST_MULTI(step, ec, enm);
602 	while (enm != NULL) {
603 		int i;
604 
605 		dprintf("%d: lo(%02x:%02x:%02x:%02x:%02x:%02x) - "
606 		    "hi(%02x:%02x:%02x:%02x:%02x:%02x)\n",
607 		    multi + 1,
608 		    enm->enm_addrlo[0], enm->enm_addrlo[1],
609 		    enm->enm_addrlo[2], enm->enm_addrlo[3],
610 		    enm->enm_addrlo[4], enm->enm_addrlo[5],
611 		    enm->enm_addrhi[0], enm->enm_addrhi[1],
612 		    enm->enm_addrhi[2], enm->enm_addrhi[3],
613 		    enm->enm_addrhi[4], enm->enm_addrhi[5]);
614 		if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
615 			dprintf("all multicast\n");
616 			SET(ifp->if_flags, IFF_ALLMULTI);
617 			ETHER_UNLOCK(ec);
618 			goto setmulti;
619 		}
620 		multi++;
621 
622 		/* XXX XXX XXX */
623 		if (multi >= 8) {
624 			SET(ifp->if_flags, IFF_ALLMULTI);
625 			ETHER_UNLOCK(ec);
626 			goto setmulti;
627 		}
628 		/* XXX XXX XXX */
629 
630 		/* XXX XXX XXX */
631 		SET(cam_en, __BIT(multi));
632 		/* XXX XXX XXX */
633 
634 		for (i = 0; i < 6; i++) {
635 			uint64_t tmp;
636 
637 			/* XXX XXX XXX */
638 			tmp = _GMX_PORT_RD8(sc, octgmx_rx_adr_cam_regs[i]);
639 			CLR(tmp, 0xffULL << (8 * multi));
640 			SET(tmp, (uint64_t)enm->enm_addrlo[i] << (8 * multi));
641 			_GMX_PORT_WR8(sc, octgmx_rx_adr_cam_regs[i], tmp);
642 			/* XXX XXX XXX */
643 
644 		}
645 		for (i = 0; i < 6; i++)
646 			dprintf("cam%d = 0x%016lx\n", i,
647 			    _GMX_PORT_RD8(sc, octgmx_rx_adr_cam_regs[i]));
648 		ETHER_NEXT_MULTI(step, enm);
649 	}
650 	ETHER_UNLOCK(ec);
651 	CLR(ifp->if_flags, IFF_ALLMULTI);
652 
653 	CNMAC_KASSERT(enm == NULL);
654 
655 setmulti:
656 	/* XXX XXX XXX */
657 	if (ISSET(ifp->if_flags, IFF_ALLMULTI) ||
658 	    ISSET(ifp->if_flags, IFF_PROMISC)) {
659 		/* XXX XXX XXX */
660 		dprintf("accept all multicast\n");
661 		ctl |= __SHIFTIN(RXN_ADR_CTL_MCST_ACCEPT, RXN_ADR_CTL_MCST);
662 		/* XXX XXX XXX */
663 	} else if (multi) {
664 		/* XXX XXX XXX */
665 		dprintf("use cam\n");
666 		ctl |= __SHIFTIN(RXN_ADR_CTL_MCST_AFCAM, RXN_ADR_CTL_MCST);
667 		/* XXX XXX XXX */
668 	} else {
669 		/* XXX XXX XXX */
670 		dprintf("reject all multicast\n");
671 		ctl |= __SHIFTIN(RXN_ADR_CTL_MCST_REJECT, RXN_ADR_CTL_MCST);
672 		/* XXX XXX XXX */
673 	}
674 	/* XXX XXX XXX */
675 
676 	/* XXX XXX XXX */
677 	if (ISSET(ifp->if_flags, IFF_PROMISC)) {
678 		cam_en = 0x00ULL;
679 	} else if (ISSET(ifp->if_flags, IFF_ALLMULTI)) {
680 		cam_en = 0x01ULL;
681 	}
682 	/* XXX XXX XXX */
683 
684 	dprintf("ctl = %#lx, cam_en = %#lx\n", ctl, cam_en);
685 	_GMX_PORT_WR8(sc, GMX0_RX0_ADR_CTL, ctl);
686 	_GMX_PORT_WR8(sc, GMX0_RX0_ADR_CAM_EN, cam_en);
687 
688 	octgmx_link_enable(sc, 1);
689 
690 	return 0;
691 }
692 
693 int
694 octgmx_port_enable(struct octgmx_port_softc *sc, int enable)
695 {
696 	(*sc->sc_port_ops->port_ops_enable)(sc, enable);
697 	return 0;
698 }
699 
700 int
701 octgmx_reset_speed(struct octgmx_port_softc *sc)
702 {
703 	struct ifnet *ifp = &sc->sc_port_ec->ec_if;
704 	if (ISSET(sc->sc_port_mii->mii_flags, MIIF_DOINGAUTO)) {
705 		log(LOG_WARNING,
706 		    "%s: autonegotiation has not been completed yet\n",
707 		    ifp->if_xname);
708 		return 1;
709 	}
710 	(*sc->sc_port_ops->port_ops_speed)(sc);
711 	return 0;
712 }
713 
714 int
715 octgmx_reset_timing(struct octgmx_port_softc *sc)
716 {
717 	(*sc->sc_port_ops->port_ops_timing)(sc);
718 	return 0;
719 }
720 
721 int
722 octgmx_reset_flowctl(struct octgmx_port_softc *sc)
723 {
724 	struct ifmedia_entry *ife = sc->sc_port_mii->mii_media.ifm_cur;
725 
726 	/*
727 	 * Get flow control negotiation result.
728 	 */
729 	if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO &&
730 	    (sc->sc_port_mii->mii_media_active & IFM_ETH_FMASK) !=
731 			sc->sc_port_flowflags) {
732 		sc->sc_port_flowflags =
733 			sc->sc_port_mii->mii_media_active & IFM_ETH_FMASK;
734 		sc->sc_port_mii->mii_media_active &= ~IFM_ETH_FMASK;
735 	}
736 
737 	/*
738 	 * 802.3x Flow Control Capabilities
739 	 */
740 	if (sc->sc_port_flowflags & IFM_ETH_TXPAUSE) {
741 		octgmx_tx_ovr_bp_enable(sc, 1);
742 	} else {
743 		octgmx_tx_ovr_bp_enable(sc, 0);
744 	}
745 	if (sc->sc_port_flowflags & IFM_ETH_RXPAUSE) {
746 		octgmx_rx_pause_enable(sc, 1);
747 	} else {
748 		octgmx_rx_pause_enable(sc, 0);
749 	}
750 
751 	return 0;
752 }
753 
754 static int
755 octgmx_rgmii_enable(struct octgmx_port_softc *sc, int enable)
756 {
757 	uint64_t mode;
758 
759 	/* XXX XXX XXX */
760 	mode = _GMX_RD8(sc, GMX0_INF_MODE);
761 	if (ISSET(mode, INF_MODE_EN)) {
762 		octasx_enable(sc->sc_port_asx, 1);
763 	}
764 	/* XXX XXX XXX */
765 	return 0;
766 }
767 
768 static int
769 octgmx_rgmii_speed(struct octgmx_port_softc *sc)
770 {
771 	struct ifnet *ifp = &sc->sc_port_ec->ec_if;
772 	uint64_t newlink;
773 	int baudrate;
774 
775 	/* XXX XXX XXX */
776 	octgmx_link_enable(sc, 1);
777 
778 	octgmx_rgmii_speed_newlink(sc, &newlink);
779 	if (sc->sc_link == newlink) {
780 		return 0;
781 	}
782 	sc->sc_link = newlink;
783 
784 	switch (__SHIFTOUT(sc->sc_link, RXN_RX_INBND_SPEED)) {
785 	case RXN_RX_INBND_SPEED_2_5:
786 		baudrate = IF_Mbps(10);
787 		break;
788 	case RXN_RX_INBND_SPEED_25:
789 		baudrate = IF_Mbps(100);
790 		break;
791 	case RXN_RX_INBND_SPEED_125:
792 		baudrate = IF_Mbps(1000);
793 		break;
794 	default:
795 		baudrate = 0/* XXX */;
796 		panic("unable to get baudrate");
797 		break;
798 	}
799 	ifp->if_baudrate = baudrate;
800 
801 	octgmx_link_enable(sc, 0);
802 
803 	/*
804 	 * wait a max_packet_time
805 	 * max_packet_time(us) = (max_packet_size(bytes) * 8) / link_speed(Mbps)
806 	 */
807 	delay((GMX_FRM_MAX_SIZ * 8) / (baudrate / 1000000));
808 
809 	octgmx_rgmii_speed_speed(sc);
810 
811 	octgmx_link_enable(sc, 1);
812 	octasx_enable(sc->sc_port_asx, 1);
813 
814 	return 0;
815 }
816 
817 static int
818 octgmx_rgmii_speed_newlink(struct octgmx_port_softc *sc, uint64_t *rnewlink)
819 {
820 	uint64_t newlink;
821 
822 	/* Inband status does not seem to work */
823 	newlink = _GMX_PORT_RD8(sc, GMX0_RX0_RX_INBND);
824 
825 	*rnewlink = newlink;
826 	return 0;
827 }
828 
829 static int
830 octgmx_rgmii_speed_speed(struct octgmx_port_softc *sc)
831 {
832 	uint64_t prt_cfg;
833 	uint64_t tx_clk, tx_slot, tx_burst;
834 
835 	prt_cfg = _GMX_PORT_RD8(sc, GMX0_PRT0_CFG);
836 
837 	switch (__SHIFTOUT(sc->sc_link, RXN_RX_INBND_SPEED)) {
838 	case RXN_RX_INBND_SPEED_2_5:
839 		/* 10Mbps */
840 		/*
841 		 * GMX Tx Clock Generation Registers
842 		 * 8ns x 50 = 400ns (2.5MHz TXC clock)
843 		 */
844 		tx_clk = 50;
845 		/*
846 		 * TX Slottime Counter Registers
847 		 * 10/100Mbps: set SLOT to 0x40
848 		 */
849 		tx_slot = 0x40;
850 		/*
851 		 * TX Burst-Counter Registers
852 		 * 10/100Mbps: set BURST to 0x0
853 		 */
854 		tx_burst = 0;
855 		/*
856 		 * GMX Tx Port Configuration Registers
857 		 * Slot time for half-duplex operation
858 		 *   0 = 512 bittimes (10/100Mbps operation)
859 		 */
860 		CLR(prt_cfg, PRTN_CFG_SLOTTIME);
861 		/*
862 		 * GMX Port Configuration Registers
863 		 * Link speed
864 		 *   0 = 10/100Mbps operation
865 		 *     in RGMII mode: GMX0_TX(0..2)_CLK[CLK_CNT] > 1
866 		 */
867 		CLR(prt_cfg, PRTN_CFG_SPEED);
868 		break;
869 	case RXN_RX_INBND_SPEED_25:
870 		/* 100Mbps */
871 		/*
872 		 * GMX Tx Clock Generation Registers
873 		 *  8ns x 5 = 40ns (25.0MHz TXC clock)
874 		 */
875 		tx_clk = 5;
876 		/*
877 		 * TX Slottime Counter Registers
878 		 *  10/100Mbps: set SLOT to 0x40
879 		 */
880 		tx_slot = 0x40;
881 		/*
882 		 * TX Burst-Counter Registers
883 		 *  10/100Mbps: set BURST to 0x0
884 		 */
885 		tx_burst = 0;
886 		/*
887 		 * GMX Tx Port Configuration Registers
888 		 *  Slot time for half-duplex operation
889 		 *    0 = 512 bittimes (10/100Mbps operation)
890 		 */
891 		CLR(prt_cfg, PRTN_CFG_SLOTTIME);
892 		/*
893 		 * GMX Port Configuration Registers
894 		 *  Link speed
895 		 *    0 = 10/100Mbps operation
896 		 *      in RGMII mode: GMX0_TX(0..2)_CLK[CLK_CNT] > 1
897 		 */
898 		CLR(prt_cfg, PRTN_CFG_SPEED);
899 		break;
900 	case RXN_RX_INBND_SPEED_125:
901 		/* 1000Mbps */
902 		/*
903 		 * GMX Tx Clock Generation Registers
904 		 *  8ns x 1 = 8ns (125.0MHz TXC clock)
905 		 */
906 		tx_clk = 1;
907 		/*
908 		 * TX Slottime Counter Registers
909 		 * > 1000Mbps: set SLOT to 0x200
910 		 */
911 		tx_slot = 0x200;
912 		/*
913 		 * "TX Burst-Counter Registers
914 		 * > 1000Mbps: set BURST to 0x2000
915 		 */
916 		tx_burst = 0x2000;
917 		/*
918 		 * GMX Tx Port Configuration Registers
919 		 *  Slot time for half-duplex operation
920 		 *    1 = 4096 bittimes (1000Mbps operation)
921 		 */
922 		SET(prt_cfg, PRTN_CFG_SLOTTIME);
923 		/*
924 		 * GMX Port Configuration Registers
925 		 *  Link speed
926 		 *    1 = 1000Mbps operation
927 		 */
928 		SET(prt_cfg, PRTN_CFG_SPEED);
929 		break;
930 	default:
931 		/* NOT REACHED! */
932 		/* Following configuration is default value of system.
933 		*/
934 		tx_clk = 1;
935 		tx_slot = 0x200;
936 		tx_burst = 0x2000;
937 		SET(prt_cfg, PRTN_CFG_SLOTTIME);
938 		SET(prt_cfg, PRTN_CFG_SPEED);
939 		break;
940 	}
941 
942 	/* Setup Duplex mode(negotiated) */
943 	/*
944 	 * GMX Port Configuration Registers
945 	 *  Duplex mode: 0 = half-duplex mode, 1=full-duplex
946 	 */
947 	if (__SHIFTOUT(sc->sc_link, RXN_RX_INBND_DUPLEX)) {
948 		/* Full-Duplex */
949 		SET(prt_cfg, PRTN_CFG_DUPLEX);
950 	} else {
951 		/* Half-Duplex */
952 		CLR(prt_cfg, PRTN_CFG_DUPLEX);
953 	}
954 
955 	_GMX_PORT_WR8(sc, GMX0_TX0_CLK, tx_clk);
956 	_GMX_PORT_WR8(sc, GMX0_TX0_SLOT, tx_slot);
957 	_GMX_PORT_WR8(sc, GMX0_TX0_BURST, tx_burst);
958 	_GMX_PORT_WR8(sc, GMX0_PRT0_CFG, prt_cfg);
959 
960 	return 0;
961 }
962 
963 static int
964 octgmx_rgmii_timing(struct octgmx_port_softc *sc)
965 {
966 	uint64_t rx_frm_ctl;
967 
968 	/* RGMII TX Threshold Registers
969 	 * Number of 16-byte ticks to accumulate in the TX FIFO before
970 	 * sending on the RGMII interface. This field should be large
971 	 * enough to prevent underflow on the RGMII interface and must
972 	 * never be set to less than 0x4. This register cannot exceed
973 	 * the TX FIFO depth of 0x40 words.
974 	 */
975 	/* Default parameter of CN30XX */
976 	octgmx_tx_thresh(sc, 32);
977 
978 	rx_frm_ctl = 0 |
979 	    /* RXN_FRM_CTL_NULL_DIS |	(cn5xxx only) */
980 	    /* RXN_FRM_CTL_PRE_ALIGN |	(cn5xxx only) */
981 	    /* RXN_FRM_CTL_PAD_LEN |	(cn3xxx only) */
982 	    /* RXN_FRM_CTL_VLAN_LEN |	(cn3xxx only) */
983 	    RXN_FRM_CTL_PRE_FREE |
984 	    RXN_FRM_CTL_CTL_SMAC |
985 	    RXN_FRM_CTL_CTL_MCST |
986 	    RXN_FRM_CTL_CTL_DRP |
987 	    RXN_FRM_CTL_PRE_STRP |
988 	    RXN_FRM_CTL_PRE_CHK;
989 	octgmx_rx_frm_ctl_enable(sc, rx_frm_ctl);
990 
991 	/* RGMII RX Clock-Delay Registers
992 	 * Delay setting to place n RXC (RGMII receive clock) delay line.
993 	 * The intrinsic delay can range from 50ps to 80ps per tap,
994 	 * which corresponds to skews of 1.25ns to 2.00ns at 25 taps(CSR+1).
995 	 * This is the best match for the RGMII specification which wants
996 	 * 1ns - 2.6ns of skew.
997 	 */
998 	/* RGMII TX Clock-Delay Registers
999 	 * Delay setting to place n TXC (RGMII transmit clock) delay line.
1000 	 */
1001 
1002 	octasx_clk_set(sc->sc_port_asx,
1003 			   sc->sc_clk_tx_setting, sc->sc_clk_rx_setting);
1004 
1005 	return 0;
1006 }
1007 
1008 static int
1009 octgmx_sgmii_enable(struct octgmx_port_softc *sc, int enable)
1010 {
1011 	uint64_t ctl_reg, status, timer_count;
1012 	uint64_t cpu_freq_mhz = curcpu()->ci_cpu_freq / 1000000;
1013 	int done;
1014 	int i;
1015 
1016 	if (!enable)
1017 		return 0;
1018 
1019 	/* Set link timer interval to 1.6ms.  Timer multiple is 1024 (2^10). */
1020 	/*
1021 	 * XXX Should set timer to 10ms if not in SGMII mode (ie,
1022 	 * "cavium,sgmii-mac-1000x-mode" property exists
1023 	 */
1024 	timer_count = PCS_READ_8(sc, PCS_LINK_TIMER_COUNT);
1025 	CLR(timer_count, PCS_LINK_TIMER_COUNT_MASK);
1026 	SET(timer_count,
1027 	    __SHIFTIN((1600 * cpu_freq_mhz) >> 10, PCS_LINK_TIMER_COUNT_MASK));
1028 	PCS_WRITE_8(sc, PCS_LINK_TIMER_COUNT, timer_count);
1029 
1030 	/* Reset the PCS. */
1031 	ctl_reg = PCS_READ_8(sc, PCS_MR_CONTROL);
1032 	SET(ctl_reg, PCS_MR_CONTROL_RESET);
1033 	PCS_WRITE_8(sc, PCS_MR_CONTROL, ctl_reg);
1034 
1035 	/* Wait for the reset to complete. */
1036 	done = 0;
1037 	for (i = 0; i < 1000000; i++) {
1038 		ctl_reg = PCS_READ_8(sc, PCS_MR_CONTROL);
1039 		if (!ISSET(ctl_reg, PCS_MR_CONTROL_RESET)) {
1040 			done = 1;
1041 			break;
1042 		}
1043 	}
1044 	if (!done) {
1045 		printf("SGMII reset timeout on port %d\n", sc->sc_port_no);
1046 		return 1;
1047 	}
1048 
1049 	/* Start a new SGMII autonegotiation. */
1050 	SET(ctl_reg, PCS_MR_CONTROL_AN_EN);
1051 	SET(ctl_reg, PCS_MR_CONTROL_RST_AN);
1052 	CLR(ctl_reg, PCS_MR_CONTROL_PWR_DN);
1053 	PCS_WRITE_8(sc, PCS_MR_CONTROL, ctl_reg);
1054 
1055 	/* Wait for the SGMII autonegotiation to complete. */
1056 	done = 0;
1057 	for (i = 0; i < 1000000; i++) {
1058 		status = PCS_READ_8(sc, PCS_MR_STATUS);
1059 		if (ISSET(status, PCS_MR_STATUS_AN_CPT)) {
1060 			done = 1;
1061 			break;
1062 		}
1063 	}
1064 	if (!done) {
1065 		printf("SGMII autonegotiation timeout on port %d\n",
1066 		    sc->sc_port_no);
1067 		return 1;
1068 	}
1069 
1070 	return 0;
1071 }
1072 
1073 static int
1074 octgmx_sgmii_speed(struct octgmx_port_softc *sc)
1075 {
1076 	uint64_t misc_ctl, prt_cfg;
1077 	int tx_burst, tx_slot;
1078 
1079 	octgmx_link_enable(sc, 0);
1080 
1081 	prt_cfg = _GMX_PORT_RD8(sc, GMX0_PRT0_CFG);
1082 
1083 	if (ISSET(sc->sc_port_mii->mii_media_active, IFM_FDX))
1084 		SET(prt_cfg, PRTN_CFG_DUPLEX);
1085 	else
1086 		CLR(prt_cfg, PRTN_CFG_DUPLEX);
1087 
1088 	misc_ctl = PCS_READ_8(sc, PCS_MISC_CTL);
1089 	CLR(misc_ctl, PCS_MISC_CTL_SAMP_PT);
1090 
1091 	/* Disable the GMX port if the link is down. */
1092 	if (octgmx_link_status(sc))
1093 		CLR(misc_ctl, PCS_MISC_CTL_GMXENO);
1094 	else
1095 		SET(misc_ctl, PCS_MISC_CTL_GMXENO);
1096 
1097 	switch (sc->sc_port_ec->ec_if.if_baudrate) {
1098 	case IF_Mbps(10):
1099 		tx_slot = 0x40;
1100 		tx_burst = 0;
1101 		CLR(prt_cfg, PRTN_CFG_SPEED);
1102 		SET(prt_cfg, PRTN_CFG_SPEED_MSB);
1103 		CLR(prt_cfg, PRTN_CFG_SLOTTIME);
1104 		misc_ctl |= 25 & PCS_MISC_CTL_SAMP_PT;
1105 		break;
1106 	case IF_Mbps(100):
1107 		tx_slot = 0x40;
1108 		tx_burst = 0;
1109 		CLR(prt_cfg, PRTN_CFG_SPEED);
1110 		CLR(prt_cfg, PRTN_CFG_SPEED_MSB);
1111 		CLR(prt_cfg, PRTN_CFG_SLOTTIME);
1112 		misc_ctl |= 5 & PCS_MISC_CTL_SAMP_PT;
1113 		break;
1114 	case IF_Gbps(1):
1115 	default:
1116 		tx_slot = 0x200;
1117 		tx_burst = 0x2000;
1118 		SET(prt_cfg, PRTN_CFG_SPEED);
1119 		CLR(prt_cfg, PRTN_CFG_SPEED_MSB);
1120 		SET(prt_cfg, PRTN_CFG_SLOTTIME);
1121 		misc_ctl |= 1 & PCS_MISC_CTL_SAMP_PT;
1122 		break;
1123 	}
1124 
1125 	PCS_WRITE_8(sc, PCS_MISC_CTL, misc_ctl);
1126 
1127 	_GMX_PORT_WR8(sc, GMX0_TX0_SLOT, tx_slot);
1128 	_GMX_PORT_WR8(sc, GMX0_TX0_BURST, tx_burst);
1129 	_GMX_PORT_WR8(sc, GMX0_PRT0_CFG, prt_cfg);
1130 
1131 	octgmx_link_enable(sc, 1);
1132 
1133 	return 0;
1134 }
1135 
1136 static int
1137 octgmx_sgmii_timing(struct octgmx_port_softc *sc)
1138 {
1139 	uint64_t rx_frm_ctl;
1140 
1141 	octgmx_tx_thresh(sc, 32);
1142 
1143 	rx_frm_ctl =
1144 	    RXN_FRM_CTL_PRE_FREE |
1145 	    RXN_FRM_CTL_CTL_SMAC |
1146 	    RXN_FRM_CTL_CTL_MCST |
1147 	    RXN_FRM_CTL_CTL_DRP |
1148 	    RXN_FRM_CTL_PRE_STRP |
1149 	    RXN_FRM_CTL_PRE_CHK;
1150 	octgmx_rx_frm_ctl_enable(sc, rx_frm_ctl);
1151 
1152 	return 0;
1153 }
1154 
1155 void
1156 octgmx_stats(struct octgmx_port_softc *sc)
1157 {
1158 	struct ifnet *ifp = &sc->sc_port_ec->ec_if;
1159 	uint64_t tmp;
1160 
1161 	/*
1162 	 *  GMX0_RX0_STATS_PKTS is not count.
1163          *  input packet is counted when received packet in if_cnmac.
1164          */
1165 	/*
1166          *  GMX0_RX0_STATS_PKTS_BAD count is included
1167          *  receive error of work queue entry.
1168          *  this is not add to input packet errors of interface.
1169          */
1170 	net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
1171 	if_statadd_ref(ifp, nsr, if_iqdrops,
1172 	    (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_DRP));
1173 	if_statadd_ref(ifp, nsr, if_opackets,
1174 	    (uint32_t)_GMX_PORT_RD8(sc, GMX0_TX0_STAT3));
1175 
1176 	tmp = _GMX_PORT_RD8(sc, GMX0_TX0_STAT0);
1177 	if_statadd_ref(ifp, nsr, if_oerrors,
1178 	    (uint32_t)tmp + ((uint32_t)(tmp >> 32) * 16));
1179 	if_statadd_ref(ifp, nsr, if_collisions, (uint32_t)tmp);
1180 
1181 	tmp = _GMX_PORT_RD8(sc, GMX0_TX0_STAT1);
1182 	if_statadd_ref(ifp, nsr, if_collisions,
1183 	    (uint32_t)tmp + (uint32_t)(tmp >> 32));
1184 
1185 	tmp = _GMX_PORT_RD8(sc, GMX0_TX0_STAT9);
1186 	if_statadd_ref(ifp, nsr, if_oerrors, (uint32_t)(tmp >> 32));
1187 	IF_STAT_PUTREF(ifp);
1188 }
1189