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