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