1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2011-2012 Stefan Bethke. 5 * Copyright (c) 2012 Adrian Chadd. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/param.h> 31 #include <sys/bus.h> 32 #include <sys/errno.h> 33 #include <sys/kernel.h> 34 #include <sys/malloc.h> 35 #include <sys/module.h> 36 #include <sys/socket.h> 37 #include <sys/sockio.h> 38 #include <sys/sysctl.h> 39 #include <sys/systm.h> 40 41 #include <net/if.h> 42 #include <net/if_var.h> 43 #include <net/if_arp.h> 44 #include <net/ethernet.h> 45 #include <net/if_dl.h> 46 #include <net/if_media.h> 47 #include <net/if_types.h> 48 49 #include <machine/bus.h> 50 #include <dev/iicbus/iic.h> 51 #include <dev/iicbus/iiconf.h> 52 #include <dev/iicbus/iicbus.h> 53 #include <dev/mii/mii.h> 54 #include <dev/mii/miivar.h> 55 #include <dev/mdio/mdio.h> 56 57 #include <dev/etherswitch/etherswitch.h> 58 59 #include <dev/etherswitch/arswitch/arswitchreg.h> 60 #include <dev/etherswitch/arswitch/arswitchvar.h> 61 #include <dev/etherswitch/arswitch/arswitch_reg.h> 62 #include <dev/etherswitch/arswitch/arswitch_phy.h> 63 #include <dev/etherswitch/arswitch/arswitch_vlans.h> 64 65 #include <dev/etherswitch/arswitch/arswitch_8216.h> 66 #include <dev/etherswitch/arswitch/arswitch_8226.h> 67 #include <dev/etherswitch/arswitch/arswitch_8316.h> 68 #include <dev/etherswitch/arswitch/arswitch_8327.h> 69 70 #include "mdio_if.h" 71 #include "miibus_if.h" 72 #include "etherswitch_if.h" 73 74 /* Map ETHERSWITCH_PORT_LED_* to Atheros pattern codes */ 75 static int led_pattern_table[] = { 76 [ETHERSWITCH_PORT_LED_DEFAULT] = 0x3, 77 [ETHERSWITCH_PORT_LED_ON] = 0x2, 78 [ETHERSWITCH_PORT_LED_OFF] = 0x0, 79 [ETHERSWITCH_PORT_LED_BLINK] = 0x1 80 }; 81 82 static inline int arswitch_portforphy(int phy); 83 static void arswitch_tick(void *arg); 84 static int arswitch_ifmedia_upd(if_t); 85 static void arswitch_ifmedia_sts(if_t, struct ifmediareq *); 86 static int ar8xxx_port_vlan_setup(struct arswitch_softc *sc, 87 etherswitch_port_t *p); 88 static int ar8xxx_port_vlan_get(struct arswitch_softc *sc, 89 etherswitch_port_t *p); 90 static int arswitch_setled(struct arswitch_softc *sc, int phy, int led, 91 int style); 92 93 static int 94 arswitch_probe(device_t dev) 95 { 96 struct arswitch_softc *sc; 97 uint32_t id; 98 char *chipname; 99 100 sc = device_get_softc(dev); 101 bzero(sc, sizeof(*sc)); 102 sc->page = -1; 103 104 /* AR8xxx probe */ 105 id = arswitch_readreg(dev, AR8X16_REG_MASK_CTRL); 106 sc->chip_rev = (id & AR8X16_MASK_CTRL_REV_MASK); 107 sc->chip_ver = (id & AR8X16_MASK_CTRL_VER_MASK) >> AR8X16_MASK_CTRL_VER_SHIFT; 108 switch (id & (AR8X16_MASK_CTRL_VER_MASK | AR8X16_MASK_CTRL_REV_MASK)) { 109 case 0x0101: 110 chipname = "AR8216"; 111 sc->sc_switchtype = AR8X16_SWITCH_AR8216; 112 break; 113 case 0x0201: 114 chipname = "AR8226"; 115 sc->sc_switchtype = AR8X16_SWITCH_AR8226; 116 break; 117 /* 0x0301 - AR8236 */ 118 case 0x1000: 119 case 0x1001: 120 chipname = "AR8316"; 121 sc->sc_switchtype = AR8X16_SWITCH_AR8316; 122 break; 123 case 0x1202: 124 case 0x1204: 125 chipname = "AR8327"; 126 sc->sc_switchtype = AR8X16_SWITCH_AR8327; 127 sc->mii_lo_first = 1; 128 break; 129 default: 130 chipname = NULL; 131 } 132 133 DPRINTF(sc, ARSWITCH_DBG_ANY, "chipname=%s, id=%08x\n", chipname, id); 134 if (chipname != NULL) { 135 device_set_descf(dev, 136 "Atheros %s Ethernet Switch (ver %d rev %d)", 137 chipname, sc->chip_ver, sc->chip_rev); 138 return (BUS_PROBE_DEFAULT); 139 } 140 return (ENXIO); 141 } 142 143 static int 144 arswitch_attach_phys(struct arswitch_softc *sc) 145 { 146 int phy, err = 0; 147 char name[IFNAMSIZ]; 148 149 /* PHYs need an interface, so we generate a dummy one */ 150 snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(sc->sc_dev)); 151 for (phy = 0; phy < sc->numphys; phy++) { 152 sc->ifp[phy] = if_alloc(IFT_ETHER); 153 if (sc->ifp[phy] == NULL) { 154 device_printf(sc->sc_dev, "couldn't allocate ifnet structure\n"); 155 err = ENOMEM; 156 break; 157 } 158 159 if_setsoftc(sc->ifp[phy], sc); 160 if_setflagbits(sc->ifp[phy], IFF_UP | IFF_BROADCAST | 161 IFF_DRV_RUNNING | IFF_SIMPLEX, 0); 162 sc->ifname[phy] = malloc(strlen(name)+1, M_DEVBUF, M_WAITOK); 163 bcopy(name, sc->ifname[phy], strlen(name)+1); 164 if_initname(sc->ifp[phy], sc->ifname[phy], 165 arswitch_portforphy(phy)); 166 err = mii_attach(sc->sc_dev, &sc->miibus[phy], sc->ifp[phy], 167 arswitch_ifmedia_upd, arswitch_ifmedia_sts, \ 168 BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0); 169 #if 0 170 DPRINTF(sc->sc_dev, "%s attached to pseudo interface %s\n", 171 device_get_nameunit(sc->miibus[phy]), 172 sc->ifp[phy]->if_xname); 173 #endif 174 if (err != 0) { 175 device_printf(sc->sc_dev, 176 "attaching PHY %d failed\n", 177 phy); 178 return (err); 179 } 180 181 if (AR8X16_IS_SWITCH(sc, AR8327)) { 182 int led; 183 char ledname[IFNAMSIZ+4]; 184 185 for (led = 0; led < 3; led++) { 186 sprintf(ledname, "%s%dled%d", name, 187 arswitch_portforphy(phy), led+1); 188 sc->dev_led[phy][led].sc = sc; 189 sc->dev_led[phy][led].phy = phy; 190 sc->dev_led[phy][led].lednum = led; 191 } 192 } 193 } 194 return (0); 195 } 196 197 static int 198 arswitch_reset(device_t dev) 199 { 200 201 arswitch_writereg(dev, AR8X16_REG_MASK_CTRL, 202 AR8X16_MASK_CTRL_SOFT_RESET); 203 DELAY(1000); 204 if (arswitch_readreg(dev, AR8X16_REG_MASK_CTRL) & 205 AR8X16_MASK_CTRL_SOFT_RESET) { 206 device_printf(dev, "unable to reset switch\n"); 207 return (-1); 208 } 209 return (0); 210 } 211 212 static int 213 arswitch_set_vlan_mode(struct arswitch_softc *sc, uint32_t mode) 214 { 215 216 /* Check for invalid modes. */ 217 if ((mode & sc->info.es_vlan_caps) != mode) 218 return (EINVAL); 219 220 switch (mode) { 221 case ETHERSWITCH_VLAN_DOT1Q: 222 sc->vlan_mode = ETHERSWITCH_VLAN_DOT1Q; 223 break; 224 case ETHERSWITCH_VLAN_PORT: 225 sc->vlan_mode = ETHERSWITCH_VLAN_PORT; 226 break; 227 default: 228 sc->vlan_mode = 0; 229 } 230 231 /* Reset VLANs. */ 232 sc->hal.arswitch_vlan_init_hw(sc); 233 234 return (0); 235 } 236 237 static void 238 ar8xxx_port_init(struct arswitch_softc *sc, int port) 239 { 240 241 /* Port0 - CPU */ 242 if (port == AR8X16_PORT_CPU) { 243 arswitch_writereg(sc->sc_dev, AR8X16_REG_PORT_STS(0), 244 (AR8X16_IS_SWITCH(sc, AR8216) ? 245 AR8X16_PORT_STS_SPEED_100 : AR8X16_PORT_STS_SPEED_1000) | 246 (AR8X16_IS_SWITCH(sc, AR8216) ? 0 : AR8X16_PORT_STS_RXFLOW) | 247 (AR8X16_IS_SWITCH(sc, AR8216) ? 0 : AR8X16_PORT_STS_TXFLOW) | 248 AR8X16_PORT_STS_RXMAC | 249 AR8X16_PORT_STS_TXMAC | 250 AR8X16_PORT_STS_DUPLEX); 251 arswitch_writereg(sc->sc_dev, AR8X16_REG_PORT_CTRL(0), 252 arswitch_readreg(sc->sc_dev, AR8X16_REG_PORT_CTRL(0)) & 253 ~AR8X16_PORT_CTRL_HEADER); 254 } else { 255 /* Set ports to auto negotiation. */ 256 arswitch_writereg(sc->sc_dev, AR8X16_REG_PORT_STS(port), 257 AR8X16_PORT_STS_LINK_AUTO); 258 arswitch_writereg(sc->sc_dev, AR8X16_REG_PORT_CTRL(port), 259 arswitch_readreg(sc->sc_dev, AR8X16_REG_PORT_CTRL(port)) & 260 ~AR8X16_PORT_CTRL_HEADER); 261 } 262 } 263 264 static int 265 ar8xxx_atu_wait_ready(struct arswitch_softc *sc) 266 { 267 int ret; 268 269 ARSWITCH_LOCK_ASSERT(sc, MA_OWNED); 270 271 ret = arswitch_waitreg(sc->sc_dev, 272 AR8216_REG_ATU, 273 AR8216_ATU_ACTIVE, 274 0, 275 1000); 276 277 return (ret); 278 } 279 280 /* 281 * Flush all ATU entries. 282 */ 283 static int 284 ar8xxx_atu_flush(struct arswitch_softc *sc) 285 { 286 int ret; 287 288 ARSWITCH_LOCK_ASSERT(sc, MA_OWNED); 289 290 DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: flushing all ports\n", __func__); 291 292 ret = ar8xxx_atu_wait_ready(sc); 293 if (ret) 294 device_printf(sc->sc_dev, "%s: waitreg failed\n", __func__); 295 296 if (!ret) 297 arswitch_writereg(sc->sc_dev, 298 AR8216_REG_ATU, 299 AR8216_ATU_OP_FLUSH | AR8216_ATU_ACTIVE); 300 301 return (ret); 302 } 303 304 /* 305 * Flush ATU entries for a single port. 306 */ 307 static int 308 ar8xxx_atu_flush_port(struct arswitch_softc *sc, int port) 309 { 310 int ret, val; 311 312 DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: flushing port %d\n", __func__, 313 port); 314 315 ARSWITCH_LOCK_ASSERT(sc, MA_OWNED); 316 317 /* Flush unicast entries on port */ 318 val = AR8216_ATU_OP_FLUSH_UNICAST; 319 320 /* TODO: bit 4 indicates whether to flush dynamic (0) or static (1) */ 321 322 /* Which port */ 323 val |= SM(port, AR8216_ATU_PORT_NUM); 324 325 ret = ar8xxx_atu_wait_ready(sc); 326 if (ret) 327 device_printf(sc->sc_dev, "%s: waitreg failed\n", __func__); 328 329 if (!ret) 330 arswitch_writereg(sc->sc_dev, 331 AR8216_REG_ATU, 332 val | AR8216_ATU_ACTIVE); 333 334 return (ret); 335 } 336 337 /* 338 * XXX TODO: flush a single MAC address. 339 */ 340 341 /* 342 * Fetch a single entry from the ATU. 343 */ 344 static int 345 ar8xxx_atu_fetch_table(struct arswitch_softc *sc, etherswitch_atu_entry_t *e, 346 int atu_fetch_op) 347 { 348 uint32_t ret0, ret1, ret2, val; 349 350 ARSWITCH_LOCK_ASSERT(sc, MA_OWNED); 351 352 switch (atu_fetch_op) { 353 case 0: 354 /* Initialise things for the first fetch */ 355 356 DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: initializing\n", __func__); 357 (void) ar8xxx_atu_wait_ready(sc); 358 359 arswitch_writereg(sc->sc_dev, 360 AR8216_REG_ATU, AR8216_ATU_OP_GET_NEXT); 361 arswitch_writereg(sc->sc_dev, 362 AR8216_REG_ATU_DATA, 0); 363 arswitch_writereg(sc->sc_dev, 364 AR8216_REG_ATU_CTRL2, 0); 365 366 return (0); 367 case 1: 368 DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: reading next\n", __func__); 369 /* 370 * Attempt to read the next address entry; don't modify what 371 * is there in AT_ADDR{4,5} as its used for the next fetch 372 */ 373 (void) ar8xxx_atu_wait_ready(sc); 374 375 /* Begin the next read event; not modifying anything */ 376 val = arswitch_readreg(sc->sc_dev, AR8216_REG_ATU); 377 val |= AR8216_ATU_ACTIVE; 378 arswitch_writereg(sc->sc_dev, AR8216_REG_ATU, val); 379 380 /* Wait for it to complete */ 381 (void) ar8xxx_atu_wait_ready(sc); 382 383 /* Fetch the ethernet address and ATU status */ 384 ret0 = arswitch_readreg(sc->sc_dev, AR8216_REG_ATU); 385 ret1 = arswitch_readreg(sc->sc_dev, AR8216_REG_ATU_DATA); 386 ret2 = arswitch_readreg(sc->sc_dev, AR8216_REG_ATU_CTRL2); 387 388 /* If the status is zero, then we're done */ 389 if (MS(ret2, AR8216_ATU_CTRL2_AT_STATUS) == 0) 390 return (-1); 391 392 /* MAC address */ 393 e->es_macaddr[5] = MS(ret0, AR8216_ATU_ADDR5); 394 e->es_macaddr[4] = MS(ret0, AR8216_ATU_ADDR4); 395 e->es_macaddr[3] = MS(ret1, AR8216_ATU_ADDR3); 396 e->es_macaddr[2] = MS(ret1, AR8216_ATU_ADDR2); 397 e->es_macaddr[1] = MS(ret1, AR8216_ATU_ADDR1); 398 e->es_macaddr[0] = MS(ret1, AR8216_ATU_ADDR0); 399 400 /* Bitmask of ports this entry is for */ 401 e->es_portmask = MS(ret2, AR8216_ATU_CTRL2_DESPORT); 402 403 /* TODO: other flags that are interesting */ 404 405 DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: MAC %6D portmask 0x%08x\n", 406 __func__, 407 e->es_macaddr, ":", e->es_portmask); 408 return (0); 409 default: 410 return (-1); 411 } 412 return (-1); 413 } 414 415 /* 416 * Configure aging register defaults. 417 */ 418 static int 419 ar8xxx_atu_learn_default(struct arswitch_softc *sc) 420 { 421 int ret; 422 uint32_t val; 423 424 DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: resetting learning\n", __func__); 425 426 /* 427 * For now, configure the aging defaults: 428 * 429 * + ARP_EN - enable "acknowledgement" of ARP frames - they are 430 * forwarded to the CPU port 431 * + LEARN_CHANGE_EN - hash table violations when learning MAC addresses 432 * will force an entry to be expired/updated and a new one to be 433 * programmed in. 434 * + AGE_EN - enable address table aging 435 * + AGE_TIME - set to 5 minutes 436 */ 437 val = 0; 438 val |= AR8216_ATU_CTRL_ARP_EN; 439 val |= AR8216_ATU_CTRL_LEARN_CHANGE; 440 val |= AR8216_ATU_CTRL_AGE_EN; 441 val |= 0x2b; /* 5 minutes; bits 15:0 */ 442 443 ret = arswitch_writereg(sc->sc_dev, 444 AR8216_REG_ATU_CTRL, 445 val); 446 447 if (ret) 448 device_printf(sc->sc_dev, "%s: writereg failed\n", __func__); 449 450 return (ret); 451 } 452 453 /* 454 * XXX TODO: add another routine to configure the leaky behaviour 455 * when unknown frames are received. These must be consistent 456 * between ethernet switches. 457 */ 458 459 /* 460 * Fetch the configured switch MAC address. 461 */ 462 static int 463 ar8xxx_hw_get_switch_macaddr(struct arswitch_softc *sc, struct ether_addr *ea) 464 { 465 uint32_t ret0, ret1; 466 char *s; 467 468 s = (void *) ea; 469 470 ret0 = arswitch_readreg(sc->sc_dev, AR8X16_REG_SW_MAC_ADDR0); 471 ret1 = arswitch_readreg(sc->sc_dev, AR8X16_REG_SW_MAC_ADDR1); 472 473 s[5] = MS(ret0, AR8X16_REG_SW_MAC_ADDR0_BYTE5); 474 s[4] = MS(ret0, AR8X16_REG_SW_MAC_ADDR0_BYTE4); 475 s[3] = MS(ret1, AR8X16_REG_SW_MAC_ADDR1_BYTE3); 476 s[2] = MS(ret1, AR8X16_REG_SW_MAC_ADDR1_BYTE2); 477 s[1] = MS(ret1, AR8X16_REG_SW_MAC_ADDR1_BYTE1); 478 s[0] = MS(ret1, AR8X16_REG_SW_MAC_ADDR1_BYTE0); 479 480 return (0); 481 } 482 483 /* 484 * Set the switch mac address. 485 */ 486 static int 487 ar8xxx_hw_set_switch_macaddr(struct arswitch_softc *sc, 488 const struct ether_addr *ea) 489 { 490 491 return (ENXIO); 492 } 493 494 /* 495 * XXX TODO: this attach routine does NOT free all memory, resources 496 * upon failure! 497 */ 498 static int 499 arswitch_attach(device_t dev) 500 { 501 struct arswitch_softc *sc = device_get_softc(dev); 502 struct sysctl_ctx_list *ctx; 503 struct sysctl_oid *tree; 504 int err = 0; 505 int port; 506 507 /* sc->sc_switchtype is already decided in arswitch_probe() */ 508 sc->sc_dev = dev; 509 mtx_init(&sc->sc_mtx, "arswitch", NULL, MTX_DEF); 510 sc->page = -1; 511 strlcpy(sc->info.es_name, device_get_desc(dev), 512 sizeof(sc->info.es_name)); 513 514 /* Debugging */ 515 ctx = device_get_sysctl_ctx(sc->sc_dev); 516 tree = device_get_sysctl_tree(sc->sc_dev); 517 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 518 "debug", CTLFLAG_RW, &sc->sc_debug, 0, 519 "control debugging printfs"); 520 521 /* Allocate a 128 entry ATU table; hopefully its big enough! */ 522 /* XXX TODO: make this per chip */ 523 sc->atu.entries = malloc(sizeof(etherswitch_atu_entry_t) * 128, 524 M_DEVBUF, M_NOWAIT); 525 if (sc->atu.entries == NULL) { 526 device_printf(sc->sc_dev, "%s: failed to allocate ATU table\n", 527 __func__); 528 return (ENXIO); 529 } 530 sc->atu.count = 0; 531 sc->atu.size = 128; 532 533 /* Default HAL methods */ 534 sc->hal.arswitch_port_init = ar8xxx_port_init; 535 sc->hal.arswitch_port_vlan_setup = ar8xxx_port_vlan_setup; 536 sc->hal.arswitch_port_vlan_get = ar8xxx_port_vlan_get; 537 sc->hal.arswitch_vlan_init_hw = ar8xxx_reset_vlans; 538 sc->hal.arswitch_hw_get_switch_macaddr = ar8xxx_hw_get_switch_macaddr; 539 sc->hal.arswitch_hw_set_switch_macaddr = ar8xxx_hw_set_switch_macaddr; 540 541 sc->hal.arswitch_vlan_getvgroup = ar8xxx_getvgroup; 542 sc->hal.arswitch_vlan_setvgroup = ar8xxx_setvgroup; 543 544 sc->hal.arswitch_vlan_get_pvid = ar8xxx_get_pvid; 545 sc->hal.arswitch_vlan_set_pvid = ar8xxx_set_pvid; 546 547 sc->hal.arswitch_get_dot1q_vlan = ar8xxx_get_dot1q_vlan; 548 sc->hal.arswitch_set_dot1q_vlan = ar8xxx_set_dot1q_vlan; 549 sc->hal.arswitch_flush_dot1q_vlan = ar8xxx_flush_dot1q_vlan; 550 sc->hal.arswitch_purge_dot1q_vlan = ar8xxx_purge_dot1q_vlan; 551 sc->hal.arswitch_get_port_vlan = ar8xxx_get_port_vlan; 552 sc->hal.arswitch_set_port_vlan = ar8xxx_set_port_vlan; 553 554 sc->hal.arswitch_atu_flush = ar8xxx_atu_flush; 555 sc->hal.arswitch_atu_flush_port = ar8xxx_atu_flush_port; 556 sc->hal.arswitch_atu_learn_default = ar8xxx_atu_learn_default; 557 sc->hal.arswitch_atu_fetch_table = ar8xxx_atu_fetch_table; 558 559 sc->hal.arswitch_phy_read = arswitch_readphy_internal; 560 sc->hal.arswitch_phy_write = arswitch_writephy_internal; 561 562 /* 563 * Attach switch related functions 564 */ 565 if (AR8X16_IS_SWITCH(sc, AR8216)) 566 ar8216_attach(sc); 567 else if (AR8X16_IS_SWITCH(sc, AR8226)) 568 ar8226_attach(sc); 569 else if (AR8X16_IS_SWITCH(sc, AR8316)) 570 ar8316_attach(sc); 571 else if (AR8X16_IS_SWITCH(sc, AR8327)) 572 ar8327_attach(sc); 573 else { 574 DPRINTF(sc, ARSWITCH_DBG_ANY, 575 "%s: unknown switch (%d)?\n", __func__, sc->sc_switchtype); 576 return (ENXIO); 577 } 578 579 /* Common defaults. */ 580 sc->info.es_nports = 5; /* XXX technically 6, but 6th not used */ 581 582 /* XXX Defaults for externally connected AR8316 */ 583 sc->numphys = 4; 584 sc->phy4cpu = 1; 585 sc->is_rgmii = 1; 586 sc->is_gmii = 0; 587 sc->is_mii = 0; 588 589 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 590 "numphys", &sc->numphys); 591 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 592 "phy4cpu", &sc->phy4cpu); 593 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 594 "is_rgmii", &sc->is_rgmii); 595 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 596 "is_gmii", &sc->is_gmii); 597 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 598 "is_mii", &sc->is_mii); 599 600 if (sc->numphys > AR8X16_NUM_PHYS) 601 sc->numphys = AR8X16_NUM_PHYS; 602 603 /* Reset the switch. */ 604 if (arswitch_reset(dev)) { 605 DPRINTF(sc, ARSWITCH_DBG_ANY, 606 "%s: arswitch_reset: failed\n", __func__); 607 return (ENXIO); 608 } 609 610 err = sc->hal.arswitch_hw_setup(sc); 611 if (err != 0) { 612 DPRINTF(sc, ARSWITCH_DBG_ANY, 613 "%s: hw_setup: err=%d\n", __func__, err); 614 return (err); 615 } 616 617 err = sc->hal.arswitch_hw_global_setup(sc); 618 if (err != 0) { 619 DPRINTF(sc, ARSWITCH_DBG_ANY, 620 "%s: hw_global_setup: err=%d\n", __func__, err); 621 return (err); 622 } 623 624 /* 625 * Configure the default address table learning parameters for this 626 * switch. 627 */ 628 err = sc->hal.arswitch_atu_learn_default(sc); 629 if (err != 0) { 630 DPRINTF(sc, ARSWITCH_DBG_ANY, 631 "%s: atu_learn_default: err=%d\n", __func__, err); 632 return (err); 633 } 634 635 /* Initialize the switch ports. */ 636 for (port = 0; port <= sc->numphys; port++) { 637 sc->hal.arswitch_port_init(sc, port); 638 } 639 640 /* 641 * Attach the PHYs and complete the bus enumeration. 642 */ 643 err = arswitch_attach_phys(sc); 644 if (err != 0) { 645 DPRINTF(sc, ARSWITCH_DBG_ANY, 646 "%s: attach_phys: err=%d\n", __func__, err); 647 return (err); 648 } 649 650 /* Default to ingress filters off. */ 651 err = arswitch_set_vlan_mode(sc, 0); 652 if (err != 0) { 653 DPRINTF(sc, ARSWITCH_DBG_ANY, 654 "%s: set_vlan_mode: err=%d\n", __func__, err); 655 return (err); 656 } 657 658 bus_generic_probe(dev); 659 bus_enumerate_hinted_children(dev); 660 err = bus_generic_attach(dev); 661 if (err != 0) { 662 DPRINTF(sc, ARSWITCH_DBG_ANY, 663 "%s: bus_generic_attach: err=%d\n", __func__, err); 664 return (err); 665 } 666 667 callout_init_mtx(&sc->callout_tick, &sc->sc_mtx, 0); 668 669 ARSWITCH_LOCK(sc); 670 arswitch_tick(sc); 671 ARSWITCH_UNLOCK(sc); 672 673 return (err); 674 } 675 676 static int 677 arswitch_detach(device_t dev) 678 { 679 struct arswitch_softc *sc = device_get_softc(dev); 680 int i; 681 682 callout_drain(&sc->callout_tick); 683 684 for (i=0; i < sc->numphys; i++) { 685 if (sc->miibus[i] != NULL) 686 device_delete_child(dev, sc->miibus[i]); 687 if (sc->ifp[i] != NULL) 688 if_free(sc->ifp[i]); 689 free(sc->ifname[i], M_DEVBUF); 690 } 691 692 free(sc->atu.entries, M_DEVBUF); 693 694 bus_generic_detach(dev); 695 mtx_destroy(&sc->sc_mtx); 696 697 return (0); 698 } 699 700 /* 701 * Convert PHY number to port number. PHY0 is connected to port 1, PHY1 to 702 * port 2, etc. 703 */ 704 static inline int 705 arswitch_portforphy(int phy) 706 { 707 return (phy+1); 708 } 709 710 static inline struct mii_data * 711 arswitch_miiforport(struct arswitch_softc *sc, int port) 712 { 713 int phy = port-1; 714 715 if (phy < 0 || phy >= sc->numphys) 716 return (NULL); 717 return (device_get_softc(sc->miibus[phy])); 718 } 719 720 static inline if_t 721 arswitch_ifpforport(struct arswitch_softc *sc, int port) 722 { 723 int phy = port-1; 724 725 if (phy < 0 || phy >= sc->numphys) 726 return (NULL); 727 return (sc->ifp[phy]); 728 } 729 730 /* 731 * Convert port status to ifmedia. 732 */ 733 static void 734 arswitch_update_ifmedia(int portstatus, u_int *media_status, u_int *media_active) 735 { 736 *media_active = IFM_ETHER; 737 *media_status = IFM_AVALID; 738 739 if ((portstatus & AR8X16_PORT_STS_LINK_UP) != 0) 740 *media_status |= IFM_ACTIVE; 741 else { 742 *media_active |= IFM_NONE; 743 return; 744 } 745 switch (portstatus & AR8X16_PORT_STS_SPEED_MASK) { 746 case AR8X16_PORT_STS_SPEED_10: 747 *media_active |= IFM_10_T; 748 break; 749 case AR8X16_PORT_STS_SPEED_100: 750 *media_active |= IFM_100_TX; 751 break; 752 case AR8X16_PORT_STS_SPEED_1000: 753 *media_active |= IFM_1000_T; 754 break; 755 } 756 if ((portstatus & AR8X16_PORT_STS_DUPLEX) == 0) 757 *media_active |= IFM_FDX; 758 else 759 *media_active |= IFM_HDX; 760 if ((portstatus & AR8X16_PORT_STS_TXFLOW) != 0) 761 *media_active |= IFM_ETH_TXPAUSE; 762 if ((portstatus & AR8X16_PORT_STS_RXFLOW) != 0) 763 *media_active |= IFM_ETH_RXPAUSE; 764 } 765 766 /* 767 * Poll the status for all PHYs. We're using the switch port status because 768 * thats a lot quicker to read than talking to all the PHYs. Care must be 769 * taken that the resulting ifmedia_active is identical to what the PHY will 770 * compute, or gratuitous link status changes will occur whenever the PHYs 771 * update function is called. 772 */ 773 static void 774 arswitch_miipollstat(struct arswitch_softc *sc) 775 { 776 int i; 777 struct mii_data *mii; 778 struct mii_softc *miisc; 779 int portstatus; 780 int port_flap = 0; 781 782 ARSWITCH_LOCK_ASSERT(sc, MA_OWNED); 783 784 for (i = 0; i < sc->numphys; i++) { 785 if (sc->miibus[i] == NULL) 786 continue; 787 mii = device_get_softc(sc->miibus[i]); 788 /* XXX This would be nice to have abstracted out to be per-chip */ 789 /* AR8327/AR8337 has a different register base */ 790 if (AR8X16_IS_SWITCH(sc, AR8327)) 791 portstatus = arswitch_readreg(sc->sc_dev, 792 AR8327_REG_PORT_STATUS(arswitch_portforphy(i))); 793 else 794 portstatus = arswitch_readreg(sc->sc_dev, 795 AR8X16_REG_PORT_STS(arswitch_portforphy(i))); 796 #if 1 797 DPRINTF(sc, ARSWITCH_DBG_POLL, "p[%d]=0x%08x (%b)\n", 798 i, 799 portstatus, 800 portstatus, 801 "\20\3TXMAC\4RXMAC\5TXFLOW\6RXFLOW\7" 802 "DUPLEX\11LINK_UP\12LINK_AUTO\13LINK_PAUSE"); 803 #endif 804 /* 805 * If the current status is down, but we have a link 806 * status showing up, we need to do an ATU flush. 807 */ 808 if ((mii->mii_media_status & IFM_ACTIVE) == 0 && 809 (portstatus & AR8X16_PORT_STS_LINK_UP) != 0) { 810 device_printf(sc->sc_dev, "%s: port %d: port -> UP\n", 811 __func__, 812 i); 813 port_flap = 1; 814 } 815 /* 816 * and maybe if a port goes up->down? 817 */ 818 if ((mii->mii_media_status & IFM_ACTIVE) != 0 && 819 (portstatus & AR8X16_PORT_STS_LINK_UP) == 0) { 820 device_printf(sc->sc_dev, "%s: port %d: port -> DOWN\n", 821 __func__, 822 i); 823 port_flap = 1; 824 } 825 arswitch_update_ifmedia(portstatus, &mii->mii_media_status, 826 &mii->mii_media_active); 827 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) { 828 if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) != 829 miisc->mii_inst) 830 continue; 831 mii_phy_update(miisc, MII_POLLSTAT); 832 } 833 } 834 835 /* If a port went from down->up, flush the ATU */ 836 if (port_flap) 837 sc->hal.arswitch_atu_flush(sc); 838 } 839 840 static void 841 arswitch_tick(void *arg) 842 { 843 struct arswitch_softc *sc = arg; 844 845 arswitch_miipollstat(sc); 846 callout_reset(&sc->callout_tick, hz, arswitch_tick, sc); 847 } 848 849 static void 850 arswitch_lock(device_t dev) 851 { 852 struct arswitch_softc *sc = device_get_softc(dev); 853 854 ARSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED); 855 ARSWITCH_LOCK(sc); 856 } 857 858 static void 859 arswitch_unlock(device_t dev) 860 { 861 struct arswitch_softc *sc = device_get_softc(dev); 862 863 ARSWITCH_LOCK_ASSERT(sc, MA_OWNED); 864 ARSWITCH_UNLOCK(sc); 865 } 866 867 static etherswitch_info_t * 868 arswitch_getinfo(device_t dev) 869 { 870 struct arswitch_softc *sc = device_get_softc(dev); 871 872 return (&sc->info); 873 } 874 875 static int 876 ar8xxx_port_vlan_get(struct arswitch_softc *sc, etherswitch_port_t *p) 877 { 878 uint32_t reg; 879 880 ARSWITCH_LOCK(sc); 881 882 /* Retrieve the PVID. */ 883 sc->hal.arswitch_vlan_get_pvid(sc, p->es_port, &p->es_pvid); 884 885 /* Port flags. */ 886 reg = arswitch_readreg(sc->sc_dev, AR8X16_REG_PORT_CTRL(p->es_port)); 887 if (reg & AR8X16_PORT_CTRL_DOUBLE_TAG) 888 p->es_flags |= ETHERSWITCH_PORT_DOUBLE_TAG; 889 reg >>= AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_SHIFT; 890 if ((reg & 0x3) == AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_ADD) 891 p->es_flags |= ETHERSWITCH_PORT_ADDTAG; 892 if ((reg & 0x3) == AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_STRIP) 893 p->es_flags |= ETHERSWITCH_PORT_STRIPTAG; 894 ARSWITCH_UNLOCK(sc); 895 896 return (0); 897 } 898 899 static int 900 arswitch_is_cpuport(struct arswitch_softc *sc, int port) 901 { 902 903 return ((port == AR8X16_PORT_CPU) || 904 ((AR8X16_IS_SWITCH(sc, AR8327) && 905 port == AR8327_PORT_GMAC6))); 906 } 907 908 static int 909 arswitch_getport(device_t dev, etherswitch_port_t *p) 910 { 911 struct arswitch_softc *sc; 912 struct mii_data *mii; 913 struct ifmediareq *ifmr; 914 int err; 915 916 sc = device_get_softc(dev); 917 /* XXX +1 is for AR8327; should make this configurable! */ 918 if (p->es_port < 0 || p->es_port > sc->info.es_nports) 919 return (ENXIO); 920 921 err = sc->hal.arswitch_port_vlan_get(sc, p); 922 if (err != 0) 923 return (err); 924 925 mii = arswitch_miiforport(sc, p->es_port); 926 if (arswitch_is_cpuport(sc, p->es_port)) { 927 /* fill in fixed values for CPU port */ 928 /* XXX is this valid in all cases? */ 929 p->es_flags |= ETHERSWITCH_PORT_CPU; 930 ifmr = &p->es_ifmr; 931 ifmr->ifm_count = 0; 932 ifmr->ifm_current = ifmr->ifm_active = 933 IFM_ETHER | IFM_1000_T | IFM_FDX; 934 ifmr->ifm_mask = 0; 935 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID; 936 } else if (mii != NULL) { 937 err = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, 938 &mii->mii_media, SIOCGIFMEDIA); 939 if (err) 940 return (err); 941 } else { 942 return (ENXIO); 943 } 944 945 if (!arswitch_is_cpuport(sc, p->es_port) && 946 AR8X16_IS_SWITCH(sc, AR8327)) { 947 int led; 948 p->es_nleds = 3; 949 950 for (led = 0; led < p->es_nleds; led++) 951 { 952 int style; 953 uint32_t val; 954 955 /* Find the right style enum for our pattern */ 956 val = arswitch_readreg(dev, 957 ar8327_led_mapping[p->es_port-1][led].reg); 958 val = (val>>ar8327_led_mapping[p->es_port-1][led].shift)&0x03; 959 960 for (style = 0; style < ETHERSWITCH_PORT_LED_MAX; style++) 961 { 962 if (led_pattern_table[style] == val) break; 963 } 964 965 /* can't happen */ 966 if (style == ETHERSWITCH_PORT_LED_MAX) 967 style = ETHERSWITCH_PORT_LED_DEFAULT; 968 969 p->es_led[led] = style; 970 } 971 } else 972 { 973 p->es_nleds = 0; 974 } 975 976 return (0); 977 } 978 979 static int 980 ar8xxx_port_vlan_setup(struct arswitch_softc *sc, etherswitch_port_t *p) 981 { 982 uint32_t reg; 983 int err; 984 985 ARSWITCH_LOCK(sc); 986 987 /* Set the PVID. */ 988 if (p->es_pvid != 0) 989 sc->hal.arswitch_vlan_set_pvid(sc, p->es_port, p->es_pvid); 990 991 /* Mutually exclusive. */ 992 if (p->es_flags & ETHERSWITCH_PORT_ADDTAG && 993 p->es_flags & ETHERSWITCH_PORT_STRIPTAG) { 994 ARSWITCH_UNLOCK(sc); 995 return (EINVAL); 996 } 997 998 reg = 0; 999 if (p->es_flags & ETHERSWITCH_PORT_DOUBLE_TAG) 1000 reg |= AR8X16_PORT_CTRL_DOUBLE_TAG; 1001 if (p->es_flags & ETHERSWITCH_PORT_ADDTAG) 1002 reg |= AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_ADD << 1003 AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_SHIFT; 1004 if (p->es_flags & ETHERSWITCH_PORT_STRIPTAG) 1005 reg |= AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_STRIP << 1006 AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_SHIFT; 1007 1008 err = arswitch_modifyreg(sc->sc_dev, 1009 AR8X16_REG_PORT_CTRL(p->es_port), 1010 0x3 << AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_SHIFT | 1011 AR8X16_PORT_CTRL_DOUBLE_TAG, reg); 1012 1013 ARSWITCH_UNLOCK(sc); 1014 return (err); 1015 } 1016 1017 static int 1018 arswitch_setport(device_t dev, etherswitch_port_t *p) 1019 { 1020 int err, i; 1021 struct arswitch_softc *sc; 1022 struct ifmedia *ifm; 1023 struct mii_data *mii; 1024 if_t ifp; 1025 1026 sc = device_get_softc(dev); 1027 if (p->es_port < 0 || p->es_port > sc->info.es_nports) 1028 return (ENXIO); 1029 1030 /* Port flags. */ 1031 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { 1032 err = sc->hal.arswitch_port_vlan_setup(sc, p); 1033 if (err) 1034 return (err); 1035 } 1036 1037 /* Do not allow media or led changes on CPU port. */ 1038 if (arswitch_is_cpuport(sc, p->es_port)) 1039 return (0); 1040 1041 if (AR8X16_IS_SWITCH(sc, AR8327)) 1042 { 1043 for (i = 0; i < 3; i++) 1044 { 1045 int err; 1046 err = arswitch_setled(sc, p->es_port-1, i, p->es_led[i]); 1047 if (err) 1048 return (err); 1049 } 1050 } 1051 1052 mii = arswitch_miiforport(sc, p->es_port); 1053 if (mii == NULL) 1054 return (ENXIO); 1055 1056 ifp = arswitch_ifpforport(sc, p->es_port); 1057 1058 ifm = &mii->mii_media; 1059 return (ifmedia_ioctl(ifp, &p->es_ifr, ifm, SIOCSIFMEDIA)); 1060 } 1061 1062 static int 1063 arswitch_setled(struct arswitch_softc *sc, int phy, int led, int style) 1064 { 1065 int shift; 1066 int err; 1067 1068 if (phy < 0 || phy > sc->numphys) 1069 return EINVAL; 1070 1071 if (style < 0 || style > ETHERSWITCH_PORT_LED_MAX) 1072 return (EINVAL); 1073 1074 ARSWITCH_LOCK(sc); 1075 1076 shift = ar8327_led_mapping[phy][led].shift; 1077 err = (arswitch_modifyreg(sc->sc_dev, 1078 ar8327_led_mapping[phy][led].reg, 1079 0x03 << shift, led_pattern_table[style] << shift)); 1080 ARSWITCH_UNLOCK(sc); 1081 1082 return (err); 1083 } 1084 1085 static void 1086 arswitch_statchg(device_t dev) 1087 { 1088 struct arswitch_softc *sc = device_get_softc(dev); 1089 1090 DPRINTF(sc, ARSWITCH_DBG_POLL, "%s\n", __func__); 1091 } 1092 1093 static int 1094 arswitch_ifmedia_upd(if_t ifp) 1095 { 1096 struct arswitch_softc *sc = if_getsoftc(ifp); 1097 struct mii_data *mii = arswitch_miiforport(sc, if_getdunit(ifp)); 1098 1099 if (mii == NULL) 1100 return (ENXIO); 1101 mii_mediachg(mii); 1102 return (0); 1103 } 1104 1105 static void 1106 arswitch_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr) 1107 { 1108 struct arswitch_softc *sc = if_getsoftc(ifp); 1109 struct mii_data *mii = arswitch_miiforport(sc, if_getdunit(ifp)); 1110 1111 DPRINTF(sc, ARSWITCH_DBG_POLL, "%s\n", __func__); 1112 1113 if (mii == NULL) 1114 return; 1115 mii_pollstat(mii); 1116 ifmr->ifm_active = mii->mii_media_active; 1117 ifmr->ifm_status = mii->mii_media_status; 1118 } 1119 1120 static int 1121 arswitch_getconf(device_t dev, etherswitch_conf_t *conf) 1122 { 1123 struct arswitch_softc *sc; 1124 int ret; 1125 1126 sc = device_get_softc(dev); 1127 1128 /* Return the VLAN mode. */ 1129 conf->cmd = ETHERSWITCH_CONF_VLAN_MODE; 1130 conf->vlan_mode = sc->vlan_mode; 1131 1132 /* Return the switch ethernet address. */ 1133 ret = sc->hal.arswitch_hw_get_switch_macaddr(sc, 1134 &conf->switch_macaddr); 1135 if (ret == 0) { 1136 conf->cmd |= ETHERSWITCH_CONF_SWITCH_MACADDR; 1137 } 1138 1139 return (0); 1140 } 1141 1142 static int 1143 arswitch_setconf(device_t dev, etherswitch_conf_t *conf) 1144 { 1145 struct arswitch_softc *sc; 1146 int err; 1147 1148 sc = device_get_softc(dev); 1149 1150 /* Set the VLAN mode. */ 1151 if (conf->cmd & ETHERSWITCH_CONF_VLAN_MODE) { 1152 err = arswitch_set_vlan_mode(sc, conf->vlan_mode); 1153 if (err != 0) 1154 return (err); 1155 } 1156 1157 /* TODO: Set the switch ethernet address. */ 1158 1159 return (0); 1160 } 1161 1162 static int 1163 arswitch_atu_flush_all(device_t dev) 1164 { 1165 struct arswitch_softc *sc; 1166 int err; 1167 1168 sc = device_get_softc(dev); 1169 ARSWITCH_LOCK(sc); 1170 err = sc->hal.arswitch_atu_flush(sc); 1171 /* Invalidate cached ATU */ 1172 sc->atu.count = 0; 1173 ARSWITCH_UNLOCK(sc); 1174 return (err); 1175 } 1176 1177 static int 1178 arswitch_atu_flush_port(device_t dev, int port) 1179 { 1180 struct arswitch_softc *sc; 1181 int err; 1182 1183 sc = device_get_softc(dev); 1184 ARSWITCH_LOCK(sc); 1185 err = sc->hal.arswitch_atu_flush_port(sc, port); 1186 /* Invalidate cached ATU */ 1187 sc->atu.count = 0; 1188 ARSWITCH_UNLOCK(sc); 1189 return (err); 1190 } 1191 1192 static int 1193 arswitch_atu_fetch_table(device_t dev, etherswitch_atu_table_t *table) 1194 { 1195 struct arswitch_softc *sc; 1196 int err, nitems; 1197 1198 sc = device_get_softc(dev); 1199 1200 ARSWITCH_LOCK(sc); 1201 /* Initial setup */ 1202 nitems = 0; 1203 err = sc->hal.arswitch_atu_fetch_table(sc, NULL, 0); 1204 1205 /* fetch - ideally yes we'd fetch into a separate table then switch */ 1206 while (err == 0 && nitems < sc->atu.size) { 1207 err = sc->hal.arswitch_atu_fetch_table(sc, 1208 &sc->atu.entries[nitems], 1); 1209 if (err == 0) { 1210 sc->atu.entries[nitems].id = nitems; 1211 nitems++; 1212 } 1213 } 1214 sc->atu.count = nitems; 1215 ARSWITCH_UNLOCK(sc); 1216 1217 table->es_nitems = nitems; 1218 1219 return (0); 1220 } 1221 1222 static int 1223 arswitch_atu_fetch_table_entry(device_t dev, etherswitch_atu_entry_t *e) 1224 { 1225 struct arswitch_softc *sc; 1226 int id; 1227 1228 sc = device_get_softc(dev); 1229 id = e->id; 1230 1231 ARSWITCH_LOCK(sc); 1232 if (id > sc->atu.count) { 1233 ARSWITCH_UNLOCK(sc); 1234 return (ENOENT); 1235 } 1236 1237 memcpy(e, &sc->atu.entries[id], sizeof(*e)); 1238 ARSWITCH_UNLOCK(sc); 1239 return (0); 1240 } 1241 1242 static int 1243 arswitch_getvgroup(device_t dev, etherswitch_vlangroup_t *e) 1244 { 1245 struct arswitch_softc *sc = device_get_softc(dev); 1246 1247 return (sc->hal.arswitch_vlan_getvgroup(sc, e)); 1248 } 1249 1250 static int 1251 arswitch_setvgroup(device_t dev, etherswitch_vlangroup_t *e) 1252 { 1253 struct arswitch_softc *sc = device_get_softc(dev); 1254 1255 return (sc->hal.arswitch_vlan_setvgroup(sc, e)); 1256 } 1257 1258 static int 1259 arswitch_readphy(device_t dev, int phy, int reg) 1260 { 1261 struct arswitch_softc *sc = device_get_softc(dev); 1262 1263 return (sc->hal.arswitch_phy_read(dev, phy, reg)); 1264 } 1265 1266 static int 1267 arswitch_writephy(device_t dev, int phy, int reg, int val) 1268 { 1269 struct arswitch_softc *sc = device_get_softc(dev); 1270 1271 return (sc->hal.arswitch_phy_write(dev, phy, reg, val)); 1272 } 1273 1274 static device_method_t arswitch_methods[] = { 1275 /* Device interface */ 1276 DEVMETHOD(device_probe, arswitch_probe), 1277 DEVMETHOD(device_attach, arswitch_attach), 1278 DEVMETHOD(device_detach, arswitch_detach), 1279 1280 /* bus interface */ 1281 DEVMETHOD(bus_add_child, device_add_child_ordered), 1282 1283 /* MII interface */ 1284 DEVMETHOD(miibus_readreg, arswitch_readphy), 1285 DEVMETHOD(miibus_writereg, arswitch_writephy), 1286 DEVMETHOD(miibus_statchg, arswitch_statchg), 1287 1288 /* MDIO interface */ 1289 DEVMETHOD(mdio_readreg, arswitch_readphy), 1290 DEVMETHOD(mdio_writereg, arswitch_writephy), 1291 1292 /* etherswitch interface */ 1293 DEVMETHOD(etherswitch_lock, arswitch_lock), 1294 DEVMETHOD(etherswitch_unlock, arswitch_unlock), 1295 DEVMETHOD(etherswitch_getinfo, arswitch_getinfo), 1296 DEVMETHOD(etherswitch_readreg, arswitch_readreg), 1297 DEVMETHOD(etherswitch_writereg, arswitch_writereg), 1298 DEVMETHOD(etherswitch_readphyreg, arswitch_readphy), 1299 DEVMETHOD(etherswitch_writephyreg, arswitch_writephy), 1300 DEVMETHOD(etherswitch_getport, arswitch_getport), 1301 DEVMETHOD(etherswitch_setport, arswitch_setport), 1302 DEVMETHOD(etherswitch_getvgroup, arswitch_getvgroup), 1303 DEVMETHOD(etherswitch_setvgroup, arswitch_setvgroup), 1304 DEVMETHOD(etherswitch_getconf, arswitch_getconf), 1305 DEVMETHOD(etherswitch_setconf, arswitch_setconf), 1306 DEVMETHOD(etherswitch_flush_all, arswitch_atu_flush_all), 1307 DEVMETHOD(etherswitch_flush_port, arswitch_atu_flush_port), 1308 DEVMETHOD(etherswitch_fetch_table, arswitch_atu_fetch_table), 1309 DEVMETHOD(etherswitch_fetch_table_entry, arswitch_atu_fetch_table_entry), 1310 1311 DEVMETHOD_END 1312 }; 1313 1314 DEFINE_CLASS_0(arswitch, arswitch_driver, arswitch_methods, 1315 sizeof(struct arswitch_softc)); 1316 1317 DRIVER_MODULE(arswitch, mdio, arswitch_driver, 0, 0); 1318 DRIVER_MODULE(miibus, arswitch, miibus_driver, 0, 0); 1319 DRIVER_MODULE(mdio, arswitch, mdio_driver, 0, 0); 1320 DRIVER_MODULE(etherswitch, arswitch, etherswitch_driver, 0, 0); 1321 MODULE_VERSION(arswitch, 1); 1322 MODULE_DEPEND(arswitch, miibus, 1, 1, 1); /* XXX which versions? */ 1323 MODULE_DEPEND(arswitch, etherswitch, 1, 1, 1); /* XXX which versions? */ 1324