Home | History | Annotate | Line # | Download | only in dev
      1 /*	$NetBSD: octeon_gmx.c,v 1.25 2025/02/24 07:11:24 andvar 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.25 2025/02/24 07:11:24 andvar 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 configured 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