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