1 /* $OpenBSD: cn30xxgmx.c,v 1.44 2020/07/04 09:00:09 visa 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/param.h> 30 #include <sys/systm.h> 31 #include <sys/device.h> 32 #include <sys/malloc.h> 33 #include <sys/syslog.h> 34 35 #include <dev/ofw/openfirm.h> 36 37 #include <machine/bus.h> 38 #include <machine/octeon_model.h> 39 #include <machine/octeonvar.h> 40 41 #include <octeon/dev/iobusvar.h> 42 #include <octeon/dev/cn30xxasxvar.h> 43 #include <octeon/dev/cn30xxciureg.h> 44 #include <octeon/dev/cn30xxgmxreg.h> 45 #include <octeon/dev/cn30xxgmxvar.h> 46 #include <octeon/dev/cn30xxipdvar.h> 47 #include <octeon/dev/cn30xxpipvar.h> 48 #include <octeon/dev/cn30xxsmivar.h> 49 50 #define dprintf(...) 51 #define OCTEON_ETH_KASSERT KASSERT 52 53 #define ADDR2UINT64(u, a) \ 54 do { \ 55 u = \ 56 (((uint64_t)a[0] << 40) | ((uint64_t)a[1] << 32) | \ 57 ((uint64_t)a[2] << 24) | ((uint64_t)a[3] << 16) | \ 58 ((uint64_t)a[4] << 8) | ((uint64_t)a[5] << 0)); \ 59 } while (0) 60 #define UINT642ADDR(a, u) \ 61 do { \ 62 a[0] = (uint8_t)((u) >> 40); a[1] = (uint8_t)((u) >> 32); \ 63 a[2] = (uint8_t)((u) >> 24); a[3] = (uint8_t)((u) >> 16); \ 64 a[4] = (uint8_t)((u) >> 8); a[5] = (uint8_t)((u) >> 0); \ 65 } while (0) 66 67 #define _GMX_RD8(sc, off) \ 68 bus_space_read_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_gmx->sc_regh, (off)) 69 #define _GMX_WR8(sc, off, v) \ 70 bus_space_write_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_gmx->sc_regh, (off), (v)) 71 #define _GMX_PORT_RD8(sc, off) \ 72 bus_space_read_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_regh, (off)) 73 #define _GMX_PORT_WR8(sc, off, v) \ 74 bus_space_write_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_regh, (off), (v)) 75 76 #define PCS_READ_8(sc, reg) \ 77 bus_space_read_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_pcs_regh, \ 78 (reg)) 79 #define PCS_WRITE_8(sc, reg, val) \ 80 bus_space_write_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_pcs_regh, \ 81 (reg), (val)) 82 83 struct cn30xxgmx_port_ops { 84 int (*port_ops_enable)(struct cn30xxgmx_port_softc *, int); 85 int (*port_ops_speed)(struct cn30xxgmx_port_softc *); 86 int (*port_ops_timing)(struct cn30xxgmx_port_softc *); 87 }; 88 89 int cn30xxgmx_match(struct device *, void *, void *); 90 void cn30xxgmx_attach(struct device *, struct device *, void *); 91 int cn30xxgmx_print(void *, const char *); 92 int cn30xxgmx_port_phy_addr(int); 93 int cn30xxgmx_init(struct cn30xxgmx_softc *); 94 int cn30xxgmx_rx_frm_ctl_xable(struct cn30xxgmx_port_softc *, 95 uint64_t, int); 96 int cn30xxgmx_rgmii_enable(struct cn30xxgmx_port_softc *, int); 97 int cn30xxgmx_rgmii_speed(struct cn30xxgmx_port_softc *); 98 int cn30xxgmx_rgmii_speed_newlink(struct cn30xxgmx_port_softc *, 99 uint64_t *); 100 int cn30xxgmx_rgmii_speed_speed(struct cn30xxgmx_port_softc *); 101 int cn30xxgmx_rgmii_timing(struct cn30xxgmx_port_softc *); 102 int cn30xxgmx_sgmii_enable(struct cn30xxgmx_port_softc *, int); 103 int cn30xxgmx_sgmii_speed(struct cn30xxgmx_port_softc *); 104 int cn30xxgmx_sgmii_timing(struct cn30xxgmx_port_softc *); 105 int cn30xxgmx_tx_ovr_bp_enable(struct cn30xxgmx_port_softc *, int); 106 int cn30xxgmx_rx_pause_enable(struct cn30xxgmx_port_softc *, int); 107 108 #ifdef OCTEON_ETH_DEBUG 109 int cn30xxgmx_rgmii_speed_newlink_log(struct cn30xxgmx_port_softc *, 110 uint64_t); 111 #endif 112 113 static const int cn30xxgmx_rx_adr_cam_regs[] = { 114 GMX0_RX0_ADR_CAM0, GMX0_RX0_ADR_CAM1, GMX0_RX0_ADR_CAM2, 115 GMX0_RX0_ADR_CAM3, GMX0_RX0_ADR_CAM4, GMX0_RX0_ADR_CAM5 116 }; 117 118 struct cn30xxgmx_port_ops cn30xxgmx_port_ops_mii = { 119 /* XXX not implemented */ 120 }; 121 122 struct cn30xxgmx_port_ops cn30xxgmx_port_ops_gmii = { 123 .port_ops_enable = cn30xxgmx_rgmii_enable, 124 .port_ops_speed = cn30xxgmx_rgmii_speed, 125 .port_ops_timing = cn30xxgmx_rgmii_timing, 126 }; 127 128 struct cn30xxgmx_port_ops cn30xxgmx_port_ops_rgmii = { 129 .port_ops_enable = cn30xxgmx_rgmii_enable, 130 .port_ops_speed = cn30xxgmx_rgmii_speed, 131 .port_ops_timing = cn30xxgmx_rgmii_timing, 132 }; 133 134 struct cn30xxgmx_port_ops cn30xxgmx_port_ops_sgmii = { 135 .port_ops_enable = cn30xxgmx_sgmii_enable, 136 .port_ops_speed = cn30xxgmx_sgmii_speed, 137 .port_ops_timing = cn30xxgmx_sgmii_timing, 138 }; 139 140 struct cn30xxgmx_port_ops cn30xxgmx_port_ops_spi42 = { 141 /* XXX not implemented */ 142 }; 143 144 struct cn30xxgmx_port_ops *cn30xxgmx_port_ops[] = { 145 [GMX_MII_PORT] = &cn30xxgmx_port_ops_mii, 146 [GMX_GMII_PORT] = &cn30xxgmx_port_ops_gmii, 147 [GMX_RGMII_PORT] = &cn30xxgmx_port_ops_rgmii, 148 [GMX_SGMII_PORT] = &cn30xxgmx_port_ops_sgmii, 149 [GMX_SPI42_PORT] = &cn30xxgmx_port_ops_spi42 150 }; 151 152 struct cfattach octgmx_ca = {sizeof(struct cn30xxgmx_softc), 153 cn30xxgmx_match, cn30xxgmx_attach, NULL, NULL}; 154 155 struct cfdriver octgmx_cd = {NULL, "octgmx", DV_DULL}; 156 157 int 158 cn30xxgmx_match(struct device *parent, void *match, void *aux) 159 { 160 struct cfdata *cf = (struct cfdata *)match; 161 struct iobus_attach_args *aa = aux; 162 163 if (strcmp(cf->cf_driver->cd_name, aa->aa_name) != 0) 164 return 0; 165 return 1; 166 } 167 168 int 169 cn30xxgmx_get_phy_phandle(int interface, int port) 170 { 171 char name[64]; 172 int node; 173 int phandle = 0; 174 175 snprintf(name, sizeof(name), 176 "/soc/pip@11800a0000000/interface@%x/ethernet@%x", 177 interface, port); 178 node = OF_finddevice(name); 179 if (node != - 1) 180 phandle = OF_getpropint(node, "phy-handle", 0); 181 return phandle; 182 } 183 184 void 185 cn30xxgmx_attach(struct device *parent, struct device *self, void *aux) 186 { 187 struct cn30xxgmx_attach_args gmx_aa; 188 struct iobus_attach_args *aa = aux; 189 struct cn30xxgmx_port_softc *port_sc; 190 struct cn30xxgmx_softc *sc = (void *)self; 191 struct cn30xxsmi_softc *smi; 192 int i; 193 int phy_addr; 194 int port; 195 int status; 196 197 printf("\n"); 198 199 sc->sc_regt = aa->aa_bust; /* XXX why there are iot? */ 200 sc->sc_unitno = aa->aa_unitno; 201 202 status = bus_space_map(sc->sc_regt, aa->aa_addr, 203 GMX0_BASE_IF_SIZE(sc->sc_nports), 0, &sc->sc_regh); 204 if (status != 0) 205 panic(": can't map register"); 206 207 cn30xxgmx_init(sc); 208 209 sc->sc_ports = mallocarray(sc->sc_nports, sizeof(*sc->sc_ports), 210 M_DEVBUF, M_NOWAIT | M_ZERO); 211 if (sc->sc_ports == NULL) { 212 printf("%s: out of memory\n", sc->sc_dev.dv_xname); 213 return; 214 } 215 216 for (i = 0; i < sc->sc_nports; i++) { 217 port = GMX_PORT_NUM(sc->sc_unitno, i); 218 if (cn30xxsmi_get_phy(cn30xxgmx_get_phy_phandle(sc->sc_unitno, 219 i), port, &smi, &phy_addr)) 220 continue; 221 222 port_sc = &sc->sc_ports[i]; 223 port_sc->sc_port_gmx = sc; 224 port_sc->sc_port_no = port; 225 port_sc->sc_port_type = sc->sc_port_types[i]; 226 port_sc->sc_port_ops = cn30xxgmx_port_ops[port_sc->sc_port_type]; 227 status = bus_space_map(sc->sc_regt, 228 aa->aa_addr + GMX0_BASE_PORT_SIZE * i, 229 GMX0_BASE_PORT_SIZE, 0, &port_sc->sc_port_regh); 230 if (status != 0) 231 panic(": can't map port register"); 232 233 switch (port_sc->sc_port_type) { 234 case GMX_MII_PORT: 235 case GMX_GMII_PORT: 236 case GMX_RGMII_PORT: { 237 struct cn30xxasx_attach_args asx_aa; 238 239 asx_aa.aa_port = i; 240 asx_aa.aa_regt = aa->aa_bust; 241 cn30xxasx_init(&asx_aa, &port_sc->sc_port_asx); 242 break; 243 } 244 case GMX_SGMII_PORT: 245 if (bus_space_map(sc->sc_regt, 246 PCS_BASE(sc->sc_unitno, i), PCS_SIZE, 0, 247 &port_sc->sc_port_pcs_regh)) 248 panic("could not map PCS registers"); 249 break; 250 default: 251 /* nothing */ 252 break; 253 } 254 255 (void)memset(&gmx_aa, 0, sizeof(gmx_aa)); 256 gmx_aa.ga_regt = aa->aa_bust; 257 gmx_aa.ga_dmat = aa->aa_dmat; 258 gmx_aa.ga_addr = aa->aa_addr; 259 gmx_aa.ga_name = "cnmac"; 260 gmx_aa.ga_portno = port_sc->sc_port_no; 261 gmx_aa.ga_port_type = sc->sc_port_types[i]; 262 gmx_aa.ga_gmx = sc; 263 gmx_aa.ga_gmx_port = port_sc; 264 gmx_aa.ga_phy_addr = phy_addr; 265 gmx_aa.ga_smi = smi; 266 267 config_found(self, &gmx_aa, cn30xxgmx_print); 268 } 269 } 270 271 int 272 cn30xxgmx_print(void *aux, const char *pnp) 273 { 274 struct cn30xxgmx_attach_args *ga = aux; 275 static const char *types[] = { 276 [GMX_MII_PORT] = "MII", 277 [GMX_GMII_PORT] = "GMII", 278 [GMX_RGMII_PORT] = "RGMII", 279 [GMX_SGMII_PORT] = "SGMII" 280 }; 281 282 #if DEBUG 283 if (pnp) 284 printf("%s at %s", ga->ga_name, pnp); 285 #endif 286 287 printf(": %s", types[ga->ga_port_type]); 288 289 return UNCONF; 290 } 291 292 int 293 cn30xxgmx_init(struct cn30xxgmx_softc *sc) 294 { 295 int result = 0; 296 uint64_t inf_mode; 297 int i, id; 298 299 inf_mode = bus_space_read_8(sc->sc_regt, sc->sc_regh, GMX0_INF_MODE); 300 if ((inf_mode & INF_MODE_EN) == 0) { 301 printf("ports are disabled\n"); 302 sc->sc_nports = 0; 303 return 1; 304 } 305 306 id = octeon_get_chipid(); 307 308 switch (octeon_model_family(id)) { 309 case OCTEON_MODEL_FAMILY_CN31XX: 310 /* 311 * CN31XX-HM-1.01 312 * 14.1 Packet Interface Introduction 313 * Table 14-1 Packet Interface Configuration 314 * 14.8 GMX Registers, Interface Mode Register, GMX0_INF_MODE 315 */ 316 if ((inf_mode & INF_MODE_TYPE) == 0) { 317 /* all three ports configured as RGMII */ 318 sc->sc_nports = 3; 319 sc->sc_port_types[0] = GMX_RGMII_PORT; 320 sc->sc_port_types[1] = GMX_RGMII_PORT; 321 sc->sc_port_types[2] = GMX_RGMII_PORT; 322 } else { 323 /* port 0: RGMII, port 1: GMII, port 2: disabled */ 324 /* XXX CN31XX-HM-1.01 says "Port 3: disabled"; typo? */ 325 sc->sc_nports = 2; 326 sc->sc_port_types[0] = GMX_RGMII_PORT; 327 sc->sc_port_types[1] = GMX_GMII_PORT; 328 } 329 break; 330 case OCTEON_MODEL_FAMILY_CN30XX: 331 case OCTEON_MODEL_FAMILY_CN50XX: 332 /* 333 * CN30XX-HM-1.0 334 * 13.1 Packet Interface Introduction 335 * Table 13-1 Packet Interface Configuration 336 * 13.8 GMX Registers, Interface Mode Register, GMX0_INF_MODE 337 */ 338 if ((inf_mode & INF_MODE_P0MII) == 0) 339 sc->sc_port_types[0] = GMX_RGMII_PORT; 340 else 341 sc->sc_port_types[0] = GMX_MII_PORT; 342 if ((inf_mode & INF_MODE_TYPE) == 0) { 343 /* port 1 and 2 are configred as RGMII ports */ 344 sc->sc_nports = 3; 345 sc->sc_port_types[1] = GMX_RGMII_PORT; 346 sc->sc_port_types[2] = GMX_RGMII_PORT; 347 } else { 348 /* port 1: GMII/MII, port 2: disabled */ 349 /* GMII or MII port is slected by GMX_PRT1_CFG[SPEED] */ 350 sc->sc_nports = 2; 351 sc->sc_port_types[1] = GMX_GMII_PORT; 352 } 353 /* port 2 is in CN3010/CN5010 only */ 354 if ((octeon_model(id) != OCTEON_MODEL_CN3010) && 355 (octeon_model(id) != OCTEON_MODEL_CN5010)) 356 if (sc->sc_nports == 3) 357 sc->sc_nports = 2; 358 break; 359 case OCTEON_MODEL_FAMILY_CN61XX: { 360 uint64_t qlm_cfg; 361 362 if (sc->sc_unitno == 0) 363 qlm_cfg = octeon_xkphys_read_8(MIO_QLM_CFG(2)); 364 else 365 qlm_cfg = octeon_xkphys_read_8(MIO_QLM_CFG(0)); 366 if ((qlm_cfg & MIO_QLM_CFG_CFG) == 2) { 367 sc->sc_nports = 4; 368 for (i = 0; i < sc->sc_nports; i++) 369 sc->sc_port_types[i] = GMX_SGMII_PORT; 370 } else if ((qlm_cfg & MIO_QLM_CFG_CFG) == 3) { 371 printf("XAUI interface is not supported\n"); 372 sc->sc_nports = 0; 373 result = 1; 374 } else { 375 /* The interface is disabled. */ 376 sc->sc_nports = 0; 377 result = 1; 378 } 379 break; 380 } 381 case OCTEON_MODEL_FAMILY_CN71XX: 382 switch (inf_mode & INF_MODE_MODE) { 383 case INF_MODE_MODE_SGMII: 384 sc->sc_nports = 4; 385 for (i = 0; i < sc->sc_nports; i++) 386 sc->sc_port_types[i] = GMX_SGMII_PORT; 387 break; 388 #ifdef notyet 389 case INF_MODE_MODE_XAUI: 390 #endif 391 default: 392 sc->sc_nports = 0; 393 result = 1; 394 } 395 break; 396 case OCTEON_MODEL_FAMILY_CN38XX: 397 case OCTEON_MODEL_FAMILY_CN56XX: 398 case OCTEON_MODEL_FAMILY_CN58XX: 399 default: 400 printf("unsupported octeon model: 0x%x\n", octeon_get_chipid()); 401 sc->sc_nports = 0; 402 result = 1; 403 break; 404 } 405 406 return result; 407 } 408 409 /* XXX RGMII specific */ 410 int 411 cn30xxgmx_link_enable(struct cn30xxgmx_port_softc *sc, int enable) 412 { 413 uint64_t prt_cfg; 414 415 cn30xxgmx_tx_int_enable(sc, enable); 416 cn30xxgmx_rx_int_enable(sc, enable); 417 418 prt_cfg = _GMX_PORT_RD8(sc, GMX0_PRT0_CFG); 419 if (enable) { 420 if (cn30xxgmx_link_status(sc)) { 421 SET(prt_cfg, PRTN_CFG_EN); 422 } 423 } else { 424 CLR(prt_cfg, PRTN_CFG_EN); 425 } 426 _GMX_PORT_WR8(sc, GMX0_PRT0_CFG, prt_cfg); 427 /* 428 * According to CN30XX-HM-1.0, 13.4.2 Link Status Changes: 429 * > software should read back to flush the write operation. 430 */ 431 (void)_GMX_PORT_RD8(sc, GMX0_PRT0_CFG); 432 433 return 0; 434 } 435 436 /* XXX RGMII specific */ 437 int 438 cn30xxgmx_stats_init(struct cn30xxgmx_port_softc *sc) 439 { 440 _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS, 0x0ULL); 441 _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_DRP, 0x0ULL); 442 _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_BAD, 0x0ULL); 443 _GMX_PORT_WR8(sc, GMX0_TX0_STAT0, 0x0ULL); 444 _GMX_PORT_WR8(sc, GMX0_TX0_STAT1, 0x0ULL); 445 _GMX_PORT_WR8(sc, GMX0_TX0_STAT3, 0x0ULL); 446 _GMX_PORT_WR8(sc, GMX0_TX0_STAT9, 0x0ULL); 447 return 0; 448 } 449 450 int 451 cn30xxgmx_tx_stats_rd_clr(struct cn30xxgmx_port_softc *sc, int enable) 452 { 453 _GMX_PORT_WR8(sc, GMX0_TX0_STATS_CTL, enable ? 0x1ULL : 0x0ULL); 454 return 0; 455 } 456 457 int 458 cn30xxgmx_rx_stats_rd_clr(struct cn30xxgmx_port_softc *sc, int enable) 459 { 460 _GMX_PORT_WR8(sc, GMX0_RX0_STATS_CTL, enable ? 0x1ULL : 0x0ULL); 461 return 0; 462 } 463 464 void 465 cn30xxgmx_rx_stats_dec_bad(struct cn30xxgmx_port_softc *sc) 466 { 467 uint64_t tmp; 468 469 tmp = _GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_BAD); 470 _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_BAD, tmp - 1); 471 } 472 473 int 474 cn30xxgmx_tx_ovr_bp_enable(struct cn30xxgmx_port_softc *sc, int enable) 475 { 476 uint64_t ovr_bp; 477 int index = GMX_PORT_INDEX(sc->sc_port_no); 478 479 ovr_bp = _GMX_RD8(sc, GMX0_TX_OVR_BP); 480 if (enable) { 481 CLR(ovr_bp, (1 << index) << TX_OVR_BP_EN_SHIFT); 482 SET(ovr_bp, (1 << index) << TX_OVR_BP_BP_SHIFT); 483 /* XXX really??? */ 484 SET(ovr_bp, (1 << index) << TX_OVR_BP_IGN_FULL_SHIFT); 485 } else { 486 SET(ovr_bp, (1 << index) << TX_OVR_BP_EN_SHIFT); 487 CLR(ovr_bp, (1 << index) << TX_OVR_BP_BP_SHIFT); 488 /* XXX really??? */ 489 SET(ovr_bp, (1 << index) << TX_OVR_BP_IGN_FULL_SHIFT); 490 } 491 _GMX_WR8(sc, GMX0_TX_OVR_BP, ovr_bp); 492 return 0; 493 } 494 495 int 496 cn30xxgmx_rx_pause_enable(struct cn30xxgmx_port_softc *sc, int enable) 497 { 498 if (enable) { 499 cn30xxgmx_rx_frm_ctl_enable(sc, RXN_FRM_CTL_CTL_BCK); 500 } else { 501 cn30xxgmx_rx_frm_ctl_disable(sc, RXN_FRM_CTL_CTL_BCK); 502 } 503 504 return 0; 505 } 506 507 void 508 cn30xxgmx_tx_int_enable(struct cn30xxgmx_port_softc *sc, int enable) 509 { 510 uint64_t tx_int_xxx = 0; 511 512 SET(tx_int_xxx, 513 TX_INT_REG_LATE_COL | 514 TX_INT_REG_XSDEF | 515 TX_INT_REG_XSCOL | 516 TX_INT_REG_UNDFLW | 517 TX_INT_REG_PKO_NXA); 518 _GMX_WR8(sc, GMX0_TX_INT_REG, tx_int_xxx); 519 _GMX_WR8(sc, GMX0_TX_INT_EN, enable ? tx_int_xxx : 0); 520 } 521 522 void 523 cn30xxgmx_rx_int_enable(struct cn30xxgmx_port_softc *sc, int enable) 524 { 525 uint64_t rx_int_xxx = 0; 526 527 SET(rx_int_xxx, 0 | 528 RXN_INT_REG_PHY_DUPX | 529 RXN_INT_REG_PHY_SPD | 530 RXN_INT_REG_PHY_LINK | 531 RXN_INT_REG_IFGERR | 532 RXN_INT_REG_COLDET | 533 RXN_INT_REG_FALERR | 534 RXN_INT_REG_RSVERR | 535 RXN_INT_REG_PCTERR | 536 RXN_INT_REG_OVRERR | 537 RXN_INT_REG_NIBERR | 538 RXN_INT_REG_SKPERR | 539 RXN_INT_REG_RCVERR | 540 RXN_INT_REG_LENERR | 541 RXN_INT_REG_ALNERR | 542 RXN_INT_REG_FCSERR | 543 RXN_INT_REG_JABBER | 544 RXN_INT_REG_MAXERR | 545 RXN_INT_REG_CAREXT | 546 RXN_INT_REG_MINERR); 547 _GMX_PORT_WR8(sc, GMX0_RX0_INT_REG, rx_int_xxx); 548 _GMX_PORT_WR8(sc, GMX0_RX0_INT_EN, enable ? rx_int_xxx : 0); 549 } 550 551 int 552 cn30xxgmx_rx_frm_ctl_enable(struct cn30xxgmx_port_softc *sc, 553 uint64_t rx_frm_ctl) 554 { 555 struct ifnet *ifp = &sc->sc_port_ac->ac_if; 556 unsigned int maxlen; 557 558 maxlen = roundup(ifp->if_hardmtu + ETHER_HDR_LEN + ETHER_CRC_LEN + 559 ETHER_VLAN_ENCAP_LEN, 8); 560 _GMX_PORT_WR8(sc, GMX0_RX0_JABBER, maxlen); 561 562 return cn30xxgmx_rx_frm_ctl_xable(sc, rx_frm_ctl, 1); 563 } 564 565 int 566 cn30xxgmx_rx_frm_ctl_disable(struct cn30xxgmx_port_softc *sc, 567 uint64_t rx_frm_ctl) 568 { 569 return cn30xxgmx_rx_frm_ctl_xable(sc, rx_frm_ctl, 0); 570 } 571 572 int 573 cn30xxgmx_rx_frm_ctl_xable(struct cn30xxgmx_port_softc *sc, 574 uint64_t rx_frm_ctl, int enable) 575 { 576 uint64_t tmp; 577 578 tmp = _GMX_PORT_RD8(sc, GMX0_RX0_FRM_CTL); 579 if (enable) 580 SET(tmp, rx_frm_ctl); 581 else 582 CLR(tmp, rx_frm_ctl); 583 _GMX_PORT_WR8(sc, GMX0_RX0_FRM_CTL, tmp); 584 585 return 0; 586 } 587 588 int 589 cn30xxgmx_tx_thresh(struct cn30xxgmx_port_softc *sc, int cnt) 590 { 591 _GMX_PORT_WR8(sc, GMX0_TX0_THRESH, cnt); 592 return 0; 593 } 594 595 int 596 cn30xxgmx_set_mac_addr(struct cn30xxgmx_port_softc *sc, uint8_t *addr) 597 { 598 uint64_t mac; 599 int i; 600 601 ADDR2UINT64(mac, addr); 602 603 cn30xxgmx_link_enable(sc, 0); 604 605 sc->sc_mac = mac; 606 _GMX_PORT_WR8(sc, GMX0_SMAC0, mac); 607 for (i = 0; i < 6; i++) 608 _GMX_PORT_WR8(sc, cn30xxgmx_rx_adr_cam_regs[i], addr[i]); 609 610 cn30xxgmx_link_enable(sc, 1); 611 612 return 0; 613 } 614 615 int 616 cn30xxgmx_set_filter(struct cn30xxgmx_port_softc *sc) 617 { 618 struct ifnet *ifp = &sc->sc_port_ac->ac_if; 619 struct arpcom *ac = sc->sc_port_ac; 620 struct ether_multi *enm; 621 struct ether_multistep step; 622 uint64_t cam_en = 0x01ULL; 623 uint64_t ctl = 0; 624 int multi = 0; 625 626 cn30xxgmx_link_enable(sc, 0); 627 628 SET(ctl, RXN_ADR_CTL_CAM_MODE); 629 CLR(ctl, RXN_ADR_CTL_MCST_ACCEPT | RXN_ADR_CTL_MCST_AFCAM | 630 RXN_ADR_CTL_MCST_REJECT); 631 CLR(ifp->if_flags, IFF_ALLMULTI); 632 633 /* 634 * Always accept broadcast frames. 635 */ 636 SET(ctl, RXN_ADR_CTL_BCST); 637 638 if (ISSET(ifp->if_flags, IFF_PROMISC)) { 639 SET(ifp->if_flags, IFF_ALLMULTI); 640 CLR(ctl, RXN_ADR_CTL_CAM_MODE); 641 SET(ctl, RXN_ADR_CTL_MCST_ACCEPT); 642 cam_en = 0x00ULL; 643 } else if (ac->ac_multirangecnt > 0 || ac->ac_multicnt > 7) { 644 SET(ifp->if_flags, IFF_ALLMULTI); 645 SET(ctl, RXN_ADR_CTL_MCST_ACCEPT); 646 } else { 647 /* 648 * Note first entry is self MAC address; other 7 entires are 649 * available for multicast addresses. 650 */ 651 ETHER_FIRST_MULTI(step, sc->sc_port_ac, enm); 652 while (enm != NULL) { 653 int i; 654 655 dprintf("%d: %02x:%02x:%02x:%02x:%02x:%02x\n" 656 multi + 1, 657 enm->enm_addrlo[0], enm->enm_addrlo[1], 658 enm->enm_addrlo[2], enm->enm_addrlo[3], 659 enm->enm_addrlo[4], enm->enm_addrlo[5]); 660 multi++; 661 662 SET(cam_en, 1ULL << multi); /* XXX */ 663 664 for (i = 0; i < 6; i++) { 665 uint64_t tmp; 666 667 /* XXX */ 668 tmp = _GMX_PORT_RD8(sc, 669 cn30xxgmx_rx_adr_cam_regs[i]); 670 CLR(tmp, 0xffULL << (8 * multi)); 671 SET(tmp, (uint64_t)enm->enm_addrlo[i] << 672 (8 * multi)); 673 _GMX_PORT_WR8(sc, cn30xxgmx_rx_adr_cam_regs[i], 674 tmp); 675 } 676 677 for (i = 0; i < 6; i++) 678 dprintf("cam%d = %016llx\n", i, 679 _GMX_PORT_RD8(sc, 680 cn30xxgmx_rx_adr_cam_regs[i])); 681 682 ETHER_NEXT_MULTI(step, enm); 683 } 684 685 if (multi) 686 SET(ctl, RXN_ADR_CTL_MCST_AFCAM); 687 else 688 SET(ctl, RXN_ADR_CTL_MCST_REJECT); 689 690 OCTEON_ETH_KASSERT(enm == NULL); 691 } 692 693 dprintf("ctl = %llx, cam_en = %llx\n", ctl, cam_en); 694 _GMX_PORT_WR8(sc, GMX0_RX0_ADR_CTL, ctl); 695 _GMX_PORT_WR8(sc, GMX0_RX0_ADR_CAM_EN, cam_en); 696 697 cn30xxgmx_link_enable(sc, 1); 698 699 return 0; 700 } 701 702 int 703 cn30xxgmx_port_enable(struct cn30xxgmx_port_softc *sc, int enable) 704 { 705 (*sc->sc_port_ops->port_ops_enable)(sc, enable); 706 return 0; 707 } 708 709 int 710 cn30xxgmx_reset_speed(struct cn30xxgmx_port_softc *sc) 711 { 712 struct ifnet *ifp = &sc->sc_port_ac->ac_if; 713 if (ISSET(sc->sc_port_mii->mii_flags, MIIF_DOINGAUTO)) { 714 log(LOG_WARNING, 715 "%s: autonegotiation has not been completed yet\n", 716 ifp->if_xname); 717 return 1; 718 } 719 (*sc->sc_port_ops->port_ops_speed)(sc); 720 return 0; 721 } 722 723 int 724 cn30xxgmx_reset_timing(struct cn30xxgmx_port_softc *sc) 725 { 726 (*sc->sc_port_ops->port_ops_timing)(sc); 727 return 0; 728 } 729 730 int 731 cn30xxgmx_reset_flowctl(struct cn30xxgmx_port_softc *sc) 732 { 733 struct ifmedia_entry *ife = sc->sc_port_mii->mii_media.ifm_cur; 734 735 /* 736 * Get flow control negotiation result. 737 */ 738 #ifdef GMX_802_3X_DISABLE_AUTONEG 739 /* Tentative support for SEIL-compat.. */ 740 if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { 741 sc->sc_port_flowflags &= ~IFM_ETH_FMASK; 742 } 743 #else 744 /* Default configuration of NetBSD */ 745 if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO && 746 (sc->sc_port_mii->mii_media_active & IFM_ETH_FMASK) != 747 sc->sc_port_flowflags) { 748 sc->sc_port_flowflags = 749 sc->sc_port_mii->mii_media_active & IFM_ETH_FMASK; 750 sc->sc_port_mii->mii_media_active &= ~IFM_ETH_FMASK; 751 } 752 #endif /* GMX_802_3X_DISABLE_AUTONEG */ 753 754 /* 755 * 802.3x Flow Control Capabilities 756 */ 757 if (sc->sc_port_flowflags & IFM_ETH_TXPAUSE) { 758 cn30xxgmx_tx_ovr_bp_enable(sc, 1); 759 } else { 760 cn30xxgmx_tx_ovr_bp_enable(sc, 0); 761 } 762 if (sc->sc_port_flowflags & IFM_ETH_RXPAUSE) { 763 cn30xxgmx_rx_pause_enable(sc, 1); 764 } else { 765 cn30xxgmx_rx_pause_enable(sc, 0); 766 } 767 768 return 0; 769 } 770 771 int 772 cn30xxgmx_rgmii_enable(struct cn30xxgmx_port_softc *sc, int enable) 773 { 774 uint64_t mode; 775 776 /* XXX */ 777 mode = _GMX_RD8(sc, GMX0_INF_MODE); 778 if (ISSET(mode, INF_MODE_EN)) { 779 cn30xxasx_enable(sc->sc_port_asx, 1); 780 } 781 782 return 0; 783 } 784 785 int 786 cn30xxgmx_rgmii_speed(struct cn30xxgmx_port_softc *sc) 787 { 788 struct ifnet *ifp = &sc->sc_port_ac->ac_if; 789 uint64_t newlink; 790 int baudrate; 791 792 /* XXX */ 793 cn30xxgmx_link_enable(sc, 1); 794 795 cn30xxgmx_rgmii_speed_newlink(sc, &newlink); 796 if (sc->sc_link == newlink) { 797 return 0; 798 } 799 #ifdef OCTEON_ETH_DEBUG 800 cn30xxgmx_rgmii_speed_newlink_log(sc, newlink); 801 #endif 802 sc->sc_link = newlink; 803 804 switch (sc->sc_link & RXN_RX_INBND_SPEED) { 805 case RXN_RX_INBND_SPEED_2_5: 806 baudrate = IF_Mbps(10); 807 break; 808 case RXN_RX_INBND_SPEED_25: 809 baudrate = IF_Mbps(100); 810 break; 811 case RXN_RX_INBND_SPEED_125: 812 baudrate = IF_Gbps(1); 813 break; 814 default: 815 baudrate = 0/* XXX */; 816 break; 817 } 818 ifp->if_baudrate = baudrate; 819 820 cn30xxgmx_link_enable(sc, 0); 821 822 /* 823 * According to CN30XX-HM-1.0, 13.4.2 Link Status Changes: 824 * wait a max_packet_time 825 * max_packet_time(us) = (max_packet_size(bytes) * 8) / link_speed(Mbps) 826 */ 827 delay((GMX_FRM_MAX_SIZ * 8) / (baudrate / 1000000)); 828 829 cn30xxgmx_rgmii_speed_speed(sc); 830 831 cn30xxgmx_link_enable(sc, 1); 832 cn30xxasx_enable(sc->sc_port_asx, 1); 833 834 return 0; 835 } 836 837 int 838 cn30xxgmx_rgmii_speed_newlink(struct cn30xxgmx_port_softc *sc, 839 uint64_t *rnewlink) 840 { 841 uint64_t newlink; 842 843 /* Inband status does not seem to work */ 844 newlink = _GMX_PORT_RD8(sc, GMX0_RX0_RX_INBND); 845 846 *rnewlink = newlink; 847 return 0; 848 } 849 850 #ifdef OCTEON_ETH_DEBUG 851 int 852 cn30xxgmx_rgmii_speed_newlink_log(struct cn30xxgmx_port_softc *sc, 853 uint64_t newlink) 854 { 855 struct ifnet *ifp = &sc->sc_port_ac->ac_if; 856 const char *status_str; 857 const char *speed_str; 858 const char *duplex_str; 859 int is_status_changed; 860 int is_speed_changed; 861 int is_linked; 862 char status_buf[80/* XXX */]; 863 char speed_buf[80/* XXX */]; 864 865 is_status_changed = (newlink & RXN_RX_INBND_STATUS) != 866 (sc->sc_link & RXN_RX_INBND_STATUS); 867 is_speed_changed = (newlink & RXN_RX_INBND_SPEED) != 868 (sc->sc_link & RXN_RX_INBND_SPEED); 869 is_linked = ISSET(newlink, RXN_RX_INBND_STATUS); 870 if (is_status_changed) { 871 if (is_linked) 872 status_str = "link up"; 873 else 874 status_str = "link down"; 875 } else { 876 if (is_linked) { 877 /* any other conditions? */ 878 if (is_speed_changed) 879 status_str = "link change"; 880 else 881 status_str = NULL; 882 } else { 883 status_str = NULL; 884 } 885 } 886 887 if (status_str != NULL) { 888 if ((is_speed_changed && is_linked) || is_linked) { 889 switch (newlink & RXN_RX_INBND_SPEED) { 890 case RXN_RX_INBND_SPEED_2_5: 891 speed_str = "10baseT"; 892 break; 893 case RXN_RX_INBND_SPEED_25: 894 speed_str = "100baseTX"; 895 break; 896 case RXN_RX_INBND_SPEED_125: 897 speed_str = "1000baseT"; 898 break; 899 default: 900 panic("Unknown link speed"); 901 break; 902 } 903 904 if (ISSET(newlink, RXN_RX_INBND_DUPLEX)) 905 duplex_str = "-FDX"; 906 else 907 duplex_str = ""; 908 909 (void)snprintf(speed_buf, sizeof(speed_buf), "(%s%s)", 910 speed_str, duplex_str); 911 } else { 912 speed_buf[0] = '\0'; 913 } 914 (void)snprintf(status_buf, sizeof(status_buf), "%s: %s%s%s\n", 915 ifp->if_xname, status_str, (is_speed_changed | is_linked) ? " " : "", 916 speed_buf); 917 log(LOG_CRIT, status_buf); 918 } 919 920 return 0; 921 } 922 #endif 923 924 int 925 cn30xxgmx_rgmii_speed_speed(struct cn30xxgmx_port_softc *sc) 926 { 927 uint64_t prt_cfg; 928 uint64_t tx_clk, tx_slot, tx_burst; 929 930 prt_cfg = _GMX_PORT_RD8(sc, GMX0_PRT0_CFG); 931 932 switch (sc->sc_link & RXN_RX_INBND_SPEED) { 933 case RXN_RX_INBND_SPEED_2_5: 934 /* 10Mbps */ 935 /* 936 * "GMX Tx Clock Generation Registers", CN30XX-HM-1.0; 937 * > 8ns x 50 = 400ns (2.5MHz TXC clock) 938 */ 939 tx_clk = 50; 940 /* 941 * "TX Slottime Counter Registers", CN30XX-HM-1.0; 942 * > 10/100Mbps: set SLOT to 0x40 943 */ 944 tx_slot = 0x40; 945 /* 946 * "TX Burst-Counter Registers", CN30XX-HM-1.0; 947 * > 10/100Mbps: set BURST to 0x0 948 */ 949 tx_burst = 0; 950 /* 951 * "GMX Tx Port Configuration Registers", CN30XX-HM-1.0; 952 * > Slot time for half-duplex operation 953 * > 0 = 512 bittimes (10/100Mbps operation) 954 */ 955 CLR(prt_cfg, PRTN_CFG_SLOTTIME); 956 /* 957 * "GMX Port Configuration Registers", CN30XX-HM-1.0; 958 * > Link speed 959 * > 0 = 10/100Mbps operation 960 * > in RGMII mode: GMX0_TX(0..2)_CLK[CLK_CNT] > 1 961 */ 962 CLR(prt_cfg, PRTN_CFG_SPEED); 963 break; 964 case RXN_RX_INBND_SPEED_25: 965 /* 100Mbps */ 966 /* 967 * "GMX Tx Clock Generation Registers", CN30XX-HM-1.0; 968 * > 8ns x 5 = 40ns (25.0MHz TXC clock) 969 */ 970 tx_clk = 5; 971 /* 972 * "TX Slottime Counter Registers", CN30XX-HM-1.0; 973 * > 10/100Mbps: set SLOT to 0x40 974 */ 975 tx_slot = 0x40; 976 /* 977 * "TX Burst-Counter Registers", CN30XX-HM-1.0; 978 * > 10/100Mbps: set BURST to 0x0 979 */ 980 tx_burst = 0; 981 /* 982 * "GMX Tx Port Configuration Registers", CN30XX-HM-1.0; 983 * > Slot time for half-duplex operation 984 * > 0 = 512 bittimes (10/100Mbps operation) 985 */ 986 CLR(prt_cfg, PRTN_CFG_SLOTTIME); 987 /* 988 * "GMX Port Configuration Registers", CN30XX-HM-1.0; 989 * > Link speed 990 * > 0 = 10/100Mbps operation 991 * > in RGMII mode: GMX0_TX(0..2)_CLK[CLK_CNT] > 1 992 */ 993 CLR(prt_cfg, PRTN_CFG_SPEED); 994 break; 995 case RXN_RX_INBND_SPEED_125: 996 /* 1000Mbps */ 997 /* 998 * "GMX Tx Clock Generation Registers", CN30XX-HM-1.0; 999 * > 8ns x 1 = 8ns (125.0MHz TXC clock) 1000 */ 1001 tx_clk = 1; 1002 /* 1003 * "TX Slottime Counter Registers", CN30XX-HM-1.0; 1004 * > 1000Mbps: set SLOT to 0x200 1005 */ 1006 tx_slot = 0x200; 1007 /* 1008 * "TX Burst-Counter Registers", CN30XX-HM-1.0; 1009 * > 1000Mbps: set BURST to 0x2000 1010 */ 1011 tx_burst = 0x2000; 1012 /* 1013 * "GMX Tx Port Configuration Registers", CN30XX-HM-1.0; 1014 * > Slot time for half-duplex operation 1015 * > 1 = 4096 bittimes (1000Mbps operation) 1016 */ 1017 SET(prt_cfg, PRTN_CFG_SLOTTIME); 1018 /* 1019 * "GMX Port Configuration Registers", CN30XX-HM-1.0; 1020 * > Link speed 1021 * > 1 = 1000Mbps operation 1022 */ 1023 SET(prt_cfg, PRTN_CFG_SPEED); 1024 break; 1025 default: 1026 /* NOT REACHED! */ 1027 /* Following configuration is default value of system. 1028 */ 1029 tx_clk = 1; 1030 tx_slot = 0x200; 1031 tx_burst = 0x2000; 1032 SET(prt_cfg, PRTN_CFG_SLOTTIME); 1033 SET(prt_cfg, PRTN_CFG_SPEED); 1034 break; 1035 } 1036 1037 /* Setup Duplex mode(negotiated) */ 1038 /* 1039 * "GMX Port Configuration Registers", CN30XX-HM-1.0; 1040 * > Duplex mode: 0 = half-duplex mode, 1=full-duplex 1041 */ 1042 if (ISSET(sc->sc_link, RXN_RX_INBND_DUPLEX)) { 1043 /* Full-Duplex */ 1044 SET(prt_cfg, PRTN_CFG_DUPLEX); 1045 } else { 1046 /* Half-Duplex */ 1047 CLR(prt_cfg, PRTN_CFG_DUPLEX); 1048 } 1049 1050 _GMX_PORT_WR8(sc, GMX0_TX0_CLK, tx_clk); 1051 _GMX_PORT_WR8(sc, GMX0_TX0_SLOT, tx_slot); 1052 _GMX_PORT_WR8(sc, GMX0_TX0_BURST, tx_burst); 1053 _GMX_PORT_WR8(sc, GMX0_PRT0_CFG, prt_cfg); 1054 1055 return 0; 1056 } 1057 1058 int 1059 cn30xxgmx_rgmii_timing(struct cn30xxgmx_port_softc *sc) 1060 { 1061 int clk_tx_setting; 1062 int clk_rx_setting; 1063 uint64_t rx_frm_ctl; 1064 1065 /* RGMII TX Threshold Registers, CN30XX-HM-1.0; 1066 * > Number of 16-byte ticks to accumulate in the TX FIFO before 1067 * > sending on the RGMII interface. This field should be large 1068 * > enough to prevent underflow on the RGMII interface and must 1069 * > never be set to less than 0x4. This register cannot exceed 1070 * > the TX FIFO depth of 0x40 words. 1071 */ 1072 /* Default parameter of CN30XX */ 1073 cn30xxgmx_tx_thresh(sc, 32); 1074 1075 rx_frm_ctl = 0 | 1076 /* RXN_FRM_CTL_NULL_DIS | (cn5xxx only) */ 1077 /* RXN_FRM_CTL_PRE_ALIGN | (cn5xxx only) */ 1078 /* RXN_FRM_CTL_PAD_LEN | (cn3xxx only) */ 1079 /* RXN_FRM_CTL_VLAN_LEN | (cn3xxx only) */ 1080 RXN_FRM_CTL_PRE_FREE | 1081 RXN_FRM_CTL_CTL_SMAC | 1082 RXN_FRM_CTL_CTL_MCST | 1083 RXN_FRM_CTL_CTL_DRP | 1084 RXN_FRM_CTL_PRE_STRP | 1085 RXN_FRM_CTL_PRE_CHK; 1086 cn30xxgmx_rx_frm_ctl_enable(sc, rx_frm_ctl); 1087 1088 /* XXX PHY-dependent parameter */ 1089 /* RGMII RX Clock-Delay Registers, CN30XX-HM-1.0; 1090 * > Delay setting to place n RXC (RGMII receive clock) delay line. 1091 * > The intrinsic delay can range from 50ps to 80ps per tap, 1092 * > which corresponds to skews of 1.25ns to 2.00ns at 25 taps(CSR+1). 1093 * > This is the best match for the RGMII specification which wants 1094 * > 1ns - 2.6ns of skew. 1095 */ 1096 /* RGMII TX Clock-Delay Registers, CN30XX-HM-1.0; 1097 * > Delay setting to place n TXC (RGMII transmit clock) delay line. 1098 * > ... 1099 */ 1100 1101 switch (octeon_boot_info->board_type) { 1102 default: 1103 /* Default parameter of CN30XX */ 1104 clk_tx_setting = 24; 1105 clk_rx_setting = 24; 1106 break; 1107 case BOARD_TYPE_UBIQUITI_E100: 1108 case BOARD_TYPE_UBIQUITI_E120: 1109 clk_tx_setting = 16; 1110 clk_rx_setting = 0; 1111 break; 1112 } 1113 1114 cn30xxasx_clk_set(sc->sc_port_asx, clk_tx_setting, clk_rx_setting); 1115 1116 return 0; 1117 } 1118 1119 int 1120 cn30xxgmx_sgmii_enable(struct cn30xxgmx_port_softc *sc, int enable) 1121 { 1122 uint64_t ctl_reg, status, timer_count; 1123 uint64_t cpu_freq = octeon_boot_info->eclock / 1000000; 1124 int done; 1125 int i; 1126 1127 if (!enable) 1128 return 0; 1129 1130 /* Set link timer interval to 1.6ms. */ 1131 timer_count = PCS_READ_8(sc, PCS_LINK_TIMER_COUNT); 1132 CLR(timer_count, PCS_LINK_TIMER_COUNT_MASK); 1133 SET(timer_count, ((1600 * cpu_freq) >> 10) & PCS_LINK_TIMER_COUNT_MASK); 1134 PCS_WRITE_8(sc, PCS_LINK_TIMER_COUNT, timer_count); 1135 1136 /* Reset the PCS. */ 1137 ctl_reg = PCS_READ_8(sc, PCS_MR_CONTROL); 1138 SET(ctl_reg, PCS_MR_CONTROL_RESET); 1139 PCS_WRITE_8(sc, PCS_MR_CONTROL, ctl_reg); 1140 1141 /* Wait for the reset to complete. */ 1142 done = 0; 1143 for (i = 0; i < 1000000; i++) { 1144 ctl_reg = PCS_READ_8(sc, PCS_MR_CONTROL); 1145 if (!ISSET(ctl_reg, PCS_MR_CONTROL_RESET)) { 1146 done = 1; 1147 break; 1148 } 1149 } 1150 if (!done) { 1151 printf("SGMII reset timeout on port %d\n", sc->sc_port_no); 1152 return 1; 1153 } 1154 1155 /* Start a new SGMII autonegotiation. */ 1156 SET(ctl_reg, PCS_MR_CONTROL_AN_EN); 1157 SET(ctl_reg, PCS_MR_CONTROL_RST_AN); 1158 CLR(ctl_reg, PCS_MR_CONTROL_PWR_DN); 1159 PCS_WRITE_8(sc, PCS_MR_CONTROL, ctl_reg); 1160 1161 /* Wait for the SGMII autonegotiation to complete. */ 1162 done = 0; 1163 for (i = 0; i < 1000000; i++) { 1164 status = PCS_READ_8(sc, PCS_MR_STATUS); 1165 if (ISSET(status, PCS_MR_STATUS_AN_CPT)) { 1166 done = 1; 1167 break; 1168 } 1169 } 1170 if (!done) { 1171 printf("SGMII autonegotiation timeout on port %d\n", 1172 sc->sc_port_no); 1173 return 1; 1174 } 1175 1176 return 0; 1177 } 1178 1179 int 1180 cn30xxgmx_sgmii_speed(struct cn30xxgmx_port_softc *sc) 1181 { 1182 uint64_t misc_ctl, prt_cfg; 1183 int tx_burst, tx_slot; 1184 1185 cn30xxgmx_link_enable(sc, 0); 1186 1187 prt_cfg = _GMX_PORT_RD8(sc, GMX0_PRT0_CFG); 1188 1189 if (ISSET(sc->sc_port_mii->mii_media_active, IFM_FDX)) 1190 SET(prt_cfg, PRTN_CFG_DUPLEX); 1191 else 1192 CLR(prt_cfg, PRTN_CFG_DUPLEX); 1193 1194 misc_ctl = PCS_READ_8(sc, PCS_MISC_CTL); 1195 CLR(misc_ctl, PCS_MISC_CTL_SAMP_PT); 1196 1197 /* Disable the GMX port if the link is down. */ 1198 if (cn30xxgmx_link_status(sc)) 1199 CLR(misc_ctl, PCS_MISC_CTL_GMXENO); 1200 else 1201 SET(misc_ctl, PCS_MISC_CTL_GMXENO); 1202 1203 switch (sc->sc_port_ac->ac_if.if_baudrate) { 1204 case IF_Mbps(10): 1205 tx_slot = 0x40; 1206 tx_burst = 0; 1207 CLR(prt_cfg, PRTN_CFG_SPEED); 1208 SET(prt_cfg, PRTN_CFG_SPEED_MSB); 1209 CLR(prt_cfg, PRTN_CFG_SLOTTIME); 1210 misc_ctl |= 25 & PCS_MISC_CTL_SAMP_PT; 1211 break; 1212 case IF_Mbps(100): 1213 tx_slot = 0x40; 1214 tx_burst = 0; 1215 CLR(prt_cfg, PRTN_CFG_SPEED); 1216 CLR(prt_cfg, PRTN_CFG_SPEED_MSB); 1217 CLR(prt_cfg, PRTN_CFG_SLOTTIME); 1218 misc_ctl |= 5 & PCS_MISC_CTL_SAMP_PT; 1219 break; 1220 case IF_Gbps(1): 1221 default: 1222 tx_slot = 0x200; 1223 tx_burst = 0x2000; 1224 SET(prt_cfg, PRTN_CFG_SPEED); 1225 CLR(prt_cfg, PRTN_CFG_SPEED_MSB); 1226 SET(prt_cfg, PRTN_CFG_SLOTTIME); 1227 misc_ctl |= 1 & PCS_MISC_CTL_SAMP_PT; 1228 break; 1229 } 1230 1231 PCS_WRITE_8(sc, PCS_MISC_CTL, misc_ctl); 1232 1233 _GMX_PORT_WR8(sc, GMX0_TX0_SLOT, tx_slot); 1234 _GMX_PORT_WR8(sc, GMX0_TX0_BURST, tx_burst); 1235 _GMX_PORT_WR8(sc, GMX0_PRT0_CFG, prt_cfg); 1236 1237 cn30xxgmx_link_enable(sc, 1); 1238 1239 return 0; 1240 } 1241 1242 int 1243 cn30xxgmx_sgmii_timing(struct cn30xxgmx_port_softc *sc) 1244 { 1245 uint64_t rx_frm_ctl; 1246 1247 cn30xxgmx_tx_thresh(sc, 32); 1248 1249 rx_frm_ctl = 1250 RXN_FRM_CTL_PRE_FREE | 1251 RXN_FRM_CTL_CTL_SMAC | 1252 RXN_FRM_CTL_CTL_MCST | 1253 RXN_FRM_CTL_CTL_DRP | 1254 RXN_FRM_CTL_PRE_STRP | 1255 RXN_FRM_CTL_PRE_CHK; 1256 cn30xxgmx_rx_frm_ctl_enable(sc, rx_frm_ctl); 1257 1258 return 0; 1259 } 1260 1261 void 1262 cn30xxgmx_stats(struct cn30xxgmx_port_softc *sc) 1263 { 1264 struct ifnet *ifp = &sc->sc_port_ac->ac_if; 1265 uint64_t tmp; 1266 1267 ifp->if_ierrors += 1268 (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_BAD); 1269 ifp->if_iqdrops += 1270 (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_DRP); 1271 tmp = _GMX_PORT_RD8(sc, GMX0_TX0_STAT0); 1272 ifp->if_oerrors += 1273 (uint32_t)tmp + ((uint32_t)(tmp >> 32) * 16); 1274 ifp->if_collisions += ((uint32_t)tmp) * 16; 1275 tmp = _GMX_PORT_RD8(sc, GMX0_TX0_STAT1); 1276 ifp->if_collisions += 1277 ((uint32_t)tmp * 2) + (uint32_t)(tmp >> 32); 1278 tmp = _GMX_PORT_RD8(sc, GMX0_TX0_STAT9); 1279 ifp->if_oerrors += (uint32_t)(tmp >> 32); 1280 } 1281