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