1 /*- 2 * Copyright (c) 2015 Semihalf 3 * Copyright (c) 2015 Stormshield 4 * Copyright (c) 2018-2019, Rubicon Communications, LLC (Netgate) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 #include "opt_platform.h" 31 32 #include <sys/param.h> 33 #include <sys/bus.h> 34 #include <sys/errno.h> 35 #include <sys/kernel.h> 36 #include <sys/kthread.h> 37 #include <sys/module.h> 38 #include <sys/taskqueue.h> 39 #include <sys/socket.h> 40 #include <sys/sockio.h> 41 42 #include <net/if.h> 43 #include <net/if_media.h> 44 #include <net/if_types.h> 45 46 #include <dev/etherswitch/etherswitch.h> 47 #include <dev/mii/mii.h> 48 #include <dev/mii/miivar.h> 49 50 #ifdef FDT 51 #include <dev/ofw/ofw_bus.h> 52 #include <dev/ofw/ofw_bus_subr.h> 53 #else 54 #include <machine/stdarg.h> 55 #endif 56 57 #include "e6000swreg.h" 58 #include "etherswitch_if.h" 59 #include "miibus_if.h" 60 #include "mdio_if.h" 61 62 MALLOC_DECLARE(M_E6000SW); 63 MALLOC_DEFINE(M_E6000SW, "e6000sw", "e6000sw switch"); 64 65 #define E6000SW_LOCK(_sc) sx_xlock(&(_sc)->sx) 66 #define E6000SW_UNLOCK(_sc) sx_unlock(&(_sc)->sx) 67 #define E6000SW_LOCK_ASSERT(_sc, _what) sx_assert(&(_sc)->sx, (_what)) 68 #define E6000SW_TRYLOCK(_sc) sx_tryxlock(&(_sc)->sx) 69 #define E6000SW_WAITREADY(_sc, _reg, _bit) \ 70 e6000sw_waitready((_sc), REG_GLOBAL, (_reg), (_bit)) 71 #define E6000SW_WAITREADY2(_sc, _reg, _bit) \ 72 e6000sw_waitready((_sc), REG_GLOBAL2, (_reg), (_bit)) 73 #define MDIO_READ(dev, addr, reg) \ 74 MDIO_READREG(device_get_parent(dev), (addr), (reg)) 75 #define MDIO_WRITE(dev, addr, reg, val) \ 76 MDIO_WRITEREG(device_get_parent(dev), (addr), (reg), (val)) 77 78 79 typedef struct e6000sw_softc { 80 device_t dev; 81 #ifdef FDT 82 phandle_t node; 83 #endif 84 85 struct sx sx; 86 if_t ifp[E6000SW_MAX_PORTS]; 87 char *ifname[E6000SW_MAX_PORTS]; 88 device_t miibus[E6000SW_MAX_PORTS]; 89 struct taskqueue *sc_tq; 90 struct timeout_task sc_tt; 91 92 int vlans[E6000SW_NUM_VLANS]; 93 uint32_t swid; 94 uint32_t vlan_mode; 95 uint32_t cpuports_mask; 96 uint32_t fixed_mask; 97 uint32_t fixed25_mask; 98 uint32_t ports_mask; 99 int phy_base; 100 int sw_addr; 101 int num_ports; 102 } e6000sw_softc_t; 103 104 static etherswitch_info_t etherswitch_info = { 105 .es_nports = 0, 106 .es_nvlangroups = 0, 107 .es_vlan_caps = ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOT1Q, 108 .es_name = "Marvell 6000 series switch" 109 }; 110 111 static void e6000sw_identify(driver_t *, device_t); 112 static int e6000sw_probe(device_t); 113 #ifdef FDT 114 static int e6000sw_parse_fixed_link(e6000sw_softc_t *, phandle_t, uint32_t); 115 static int e6000sw_parse_ethernet(e6000sw_softc_t *, phandle_t, uint32_t); 116 #endif 117 static int e6000sw_attach(device_t); 118 static int e6000sw_detach(device_t); 119 static int e6000sw_read_xmdio(device_t, int, int, int); 120 static int e6000sw_write_xmdio(device_t, int, int, int, int); 121 static int e6000sw_readphy(device_t, int, int); 122 static int e6000sw_writephy(device_t, int, int, int); 123 static int e6000sw_readphy_locked(device_t, int, int); 124 static int e6000sw_writephy_locked(device_t, int, int, int); 125 static etherswitch_info_t* e6000sw_getinfo(device_t); 126 static int e6000sw_getconf(device_t, etherswitch_conf_t *); 127 static int e6000sw_setconf(device_t, etherswitch_conf_t *); 128 static void e6000sw_lock(device_t); 129 static void e6000sw_unlock(device_t); 130 static int e6000sw_getport(device_t, etherswitch_port_t *); 131 static int e6000sw_setport(device_t, etherswitch_port_t *); 132 static int e6000sw_set_vlan_mode(e6000sw_softc_t *, uint32_t); 133 static int e6000sw_readreg_wrapper(device_t, int); 134 static int e6000sw_writereg_wrapper(device_t, int, int); 135 static int e6000sw_getvgroup_wrapper(device_t, etherswitch_vlangroup_t *); 136 static int e6000sw_setvgroup_wrapper(device_t, etherswitch_vlangroup_t *); 137 static int e6000sw_setvgroup(device_t, etherswitch_vlangroup_t *); 138 static int e6000sw_getvgroup(device_t, etherswitch_vlangroup_t *); 139 static void e6000sw_setup(device_t, e6000sw_softc_t *); 140 static void e6000sw_tick(void *, int); 141 static void e6000sw_set_atustat(device_t, e6000sw_softc_t *, int, int); 142 static int e6000sw_atu_flush(device_t, e6000sw_softc_t *, int); 143 static int e6000sw_vtu_flush(e6000sw_softc_t *); 144 static int e6000sw_vtu_update(e6000sw_softc_t *, int, int, int, int, int); 145 static __inline void e6000sw_writereg(e6000sw_softc_t *, int, int, int); 146 static __inline uint32_t e6000sw_readreg(e6000sw_softc_t *, int, int); 147 static int e6000sw_ifmedia_upd(if_t); 148 static void e6000sw_ifmedia_sts(if_t, struct ifmediareq *); 149 static int e6000sw_atu_mac_table(device_t, e6000sw_softc_t *, struct atu_opt *, 150 int); 151 static int e6000sw_get_pvid(e6000sw_softc_t *, int, int *); 152 static void e6000sw_set_pvid(e6000sw_softc_t *, int, int); 153 static __inline bool e6000sw_is_cpuport(e6000sw_softc_t *, int); 154 static __inline bool e6000sw_is_fixedport(e6000sw_softc_t *, int); 155 static __inline bool e6000sw_is_fixed25port(e6000sw_softc_t *, int); 156 static __inline bool e6000sw_is_phyport(e6000sw_softc_t *, int); 157 static __inline bool e6000sw_is_portenabled(e6000sw_softc_t *, int); 158 static __inline struct mii_data *e6000sw_miiforphy(e6000sw_softc_t *, 159 unsigned int); 160 161 static device_method_t e6000sw_methods[] = { 162 /* device interface */ 163 DEVMETHOD(device_identify, e6000sw_identify), 164 DEVMETHOD(device_probe, e6000sw_probe), 165 DEVMETHOD(device_attach, e6000sw_attach), 166 DEVMETHOD(device_detach, e6000sw_detach), 167 168 /* bus interface */ 169 DEVMETHOD(bus_add_child, device_add_child_ordered), 170 171 /* mii interface */ 172 DEVMETHOD(miibus_readreg, e6000sw_readphy_locked), 173 DEVMETHOD(miibus_writereg, e6000sw_writephy_locked), 174 175 /* etherswitch interface */ 176 DEVMETHOD(etherswitch_getinfo, e6000sw_getinfo), 177 DEVMETHOD(etherswitch_getconf, e6000sw_getconf), 178 DEVMETHOD(etherswitch_setconf, e6000sw_setconf), 179 DEVMETHOD(etherswitch_lock, e6000sw_lock), 180 DEVMETHOD(etherswitch_unlock, e6000sw_unlock), 181 DEVMETHOD(etherswitch_getport, e6000sw_getport), 182 DEVMETHOD(etherswitch_setport, e6000sw_setport), 183 DEVMETHOD(etherswitch_readreg, e6000sw_readreg_wrapper), 184 DEVMETHOD(etherswitch_writereg, e6000sw_writereg_wrapper), 185 DEVMETHOD(etherswitch_readphyreg, e6000sw_readphy), 186 DEVMETHOD(etherswitch_writephyreg, e6000sw_writephy), 187 DEVMETHOD(etherswitch_setvgroup, e6000sw_setvgroup_wrapper), 188 DEVMETHOD(etherswitch_getvgroup, e6000sw_getvgroup_wrapper), 189 190 DEVMETHOD_END 191 }; 192 193 DEFINE_CLASS_0(e6000sw, e6000sw_driver, e6000sw_methods, 194 sizeof(e6000sw_softc_t)); 195 196 DRIVER_MODULE(e6000sw, mdio, e6000sw_driver, 0, 0); 197 DRIVER_MODULE(etherswitch, e6000sw, etherswitch_driver, 0, 0); 198 DRIVER_MODULE(miibus, e6000sw, miibus_driver, 0, 0); 199 MODULE_DEPEND(e6000sw, mdio, 1, 1, 1); 200 201 202 static void 203 e6000sw_identify(driver_t *driver, device_t parent) 204 { 205 206 if (device_find_child(parent, "e6000sw", -1) == NULL) 207 BUS_ADD_CHILD(parent, 0, "e6000sw", -1); 208 } 209 210 static int 211 e6000sw_probe(device_t dev) 212 { 213 e6000sw_softc_t *sc; 214 const char *description; 215 #ifdef FDT 216 phandle_t switch_node; 217 #else 218 int is_6190; 219 #endif 220 221 sc = device_get_softc(dev); 222 sc->dev = dev; 223 224 #ifdef FDT 225 switch_node = ofw_bus_find_compatible(OF_finddevice("/"), 226 "marvell,mv88e6085"); 227 if (switch_node == 0) { 228 switch_node = ofw_bus_find_compatible(OF_finddevice("/"), 229 "marvell,mv88e6190"); 230 231 if (switch_node == 0) 232 return (ENXIO); 233 234 /* 235 * Trust DTS and fix the port register offset for the MV88E6190 236 * detection bellow. 237 */ 238 sc->swid = MV88E6190; 239 } 240 241 if (bootverbose) 242 device_printf(dev, "Found switch_node: 0x%x\n", switch_node); 243 244 sc->node = switch_node; 245 246 if (OF_getencprop(sc->node, "reg", &sc->sw_addr, 247 sizeof(sc->sw_addr)) < 0) 248 return (ENXIO); 249 #else 250 if (resource_int_value(device_get_name(sc->dev), 251 device_get_unit(sc->dev), "addr", &sc->sw_addr) != 0) 252 return (ENXIO); 253 if (resource_int_value(device_get_name(sc->dev), 254 device_get_unit(sc->dev), "is6190", &is_6190) != 0) 255 /* 256 * Check "is8190" to keep backward compatibility with 257 * older setups. 258 */ 259 resource_int_value(device_get_name(sc->dev), 260 device_get_unit(sc->dev), "is8190", &is_6190); 261 if (is_6190 != 0) 262 sc->swid = MV88E6190; 263 #endif 264 if (sc->sw_addr < 0 || sc->sw_addr > 32) 265 return (ENXIO); 266 267 /* 268 * Create temporary lock, just to satisfy assertions, 269 * when obtaining the switch ID. Destroy immediately afterwards. 270 */ 271 sx_init(&sc->sx, "e6000sw_tmp"); 272 E6000SW_LOCK(sc); 273 sc->swid = e6000sw_readreg(sc, REG_PORT(sc, 0), SWITCH_ID) & 0xfff0; 274 E6000SW_UNLOCK(sc); 275 sx_destroy(&sc->sx); 276 277 switch (sc->swid) { 278 case MV88E6141: 279 description = "Marvell 88E6141"; 280 sc->phy_base = 0x10; 281 sc->num_ports = 6; 282 break; 283 case MV88E6341: 284 description = "Marvell 88E6341"; 285 sc->phy_base = 0x10; 286 sc->num_ports = 6; 287 break; 288 case MV88E6352: 289 description = "Marvell 88E6352"; 290 sc->num_ports = 7; 291 break; 292 case MV88E6172: 293 description = "Marvell 88E6172"; 294 sc->num_ports = 7; 295 break; 296 case MV88E6176: 297 description = "Marvell 88E6176"; 298 sc->num_ports = 7; 299 break; 300 case MV88E6190: 301 description = "Marvell 88E6190"; 302 sc->num_ports = 11; 303 break; 304 default: 305 device_printf(dev, "Unrecognized device, id 0x%x.\n", sc->swid); 306 return (ENXIO); 307 } 308 309 device_set_desc(dev, description); 310 311 return (BUS_PROBE_DEFAULT); 312 } 313 314 #ifdef FDT 315 static int 316 e6000sw_parse_fixed_link(e6000sw_softc_t *sc, phandle_t node, uint32_t port) 317 { 318 int speed; 319 phandle_t fixed_link; 320 321 fixed_link = ofw_bus_find_child(node, "fixed-link"); 322 323 if (fixed_link != 0) { 324 sc->fixed_mask |= (1 << port); 325 326 if (OF_getencprop(fixed_link, 327 "speed", &speed, sizeof(speed)) < 0) { 328 device_printf(sc->dev, 329 "Port %d has a fixed-link node without a speed " 330 "property\n", port); 331 return (ENXIO); 332 } 333 if (speed == 2500 && (MVSWITCH(sc, MV88E6141) || 334 MVSWITCH(sc, MV88E6341) || MVSWITCH(sc, MV88E6190))) 335 sc->fixed25_mask |= (1 << port); 336 } 337 338 return (0); 339 } 340 341 static int 342 e6000sw_parse_ethernet(e6000sw_softc_t *sc, phandle_t port_handle, uint32_t port) { 343 phandle_t switch_eth, switch_eth_handle; 344 345 if (OF_getencprop(port_handle, "ethernet", (void*)&switch_eth_handle, 346 sizeof(switch_eth_handle)) > 0) { 347 if (switch_eth_handle > 0) { 348 switch_eth = OF_node_from_xref(switch_eth_handle); 349 350 device_printf(sc->dev, "CPU port at %d\n", port); 351 sc->cpuports_mask |= (1 << port); 352 353 return (e6000sw_parse_fixed_link(sc, switch_eth, port)); 354 } else 355 device_printf(sc->dev, 356 "Port %d has ethernet property but it points " 357 "to an invalid location\n", port); 358 } 359 360 return (0); 361 } 362 363 static int 364 e6000sw_parse_child_fdt(e6000sw_softc_t *sc, phandle_t child, int *pport) 365 { 366 uint32_t port; 367 368 if (pport == NULL) 369 return (ENXIO); 370 371 if (OF_getencprop(child, "reg", (void *)&port, sizeof(port)) < 0) 372 return (ENXIO); 373 if (port >= sc->num_ports) 374 return (ENXIO); 375 *pport = port; 376 377 if (e6000sw_parse_fixed_link(sc, child, port) != 0) 378 return (ENXIO); 379 380 if (e6000sw_parse_ethernet(sc, child, port) != 0) 381 return (ENXIO); 382 383 if ((sc->fixed_mask & (1 << port)) != 0) 384 device_printf(sc->dev, "fixed port at %d\n", port); 385 else 386 device_printf(sc->dev, "PHY at port %d\n", port); 387 388 return (0); 389 } 390 #else 391 392 static int 393 e6000sw_check_hint_val(device_t dev, int *val, char *fmt, ...) 394 { 395 char *resname; 396 int err, len; 397 va_list ap; 398 399 len = min(strlen(fmt) * 2, 128); 400 if (len == 0) 401 return (-1); 402 resname = malloc(len, M_E6000SW, M_WAITOK); 403 memset(resname, 0, len); 404 va_start(ap, fmt); 405 vsnprintf(resname, len - 1, fmt, ap); 406 va_end(ap); 407 err = resource_int_value(device_get_name(dev), device_get_unit(dev), 408 resname, val); 409 free(resname, M_E6000SW); 410 411 return (err); 412 } 413 414 static int 415 e6000sw_parse_hinted_port(e6000sw_softc_t *sc, int port) 416 { 417 int err, val; 418 419 err = e6000sw_check_hint_val(sc->dev, &val, "port%ddisabled", port); 420 if (err == 0 && val != 0) 421 return (1); 422 423 err = e6000sw_check_hint_val(sc->dev, &val, "port%dcpu", port); 424 if (err == 0 && val != 0) { 425 sc->cpuports_mask |= (1 << port); 426 sc->fixed_mask |= (1 << port); 427 if (bootverbose) 428 device_printf(sc->dev, "CPU port at %d\n", port); 429 } 430 err = e6000sw_check_hint_val(sc->dev, &val, "port%dspeed", port); 431 if (err == 0 && val != 0) { 432 sc->fixed_mask |= (1 << port); 433 if (val == 2500) 434 sc->fixed25_mask |= (1 << port); 435 } 436 437 if (bootverbose) { 438 if ((sc->fixed_mask & (1 << port)) != 0) 439 device_printf(sc->dev, "fixed port at %d\n", port); 440 else 441 device_printf(sc->dev, "PHY at port %d\n", port); 442 } 443 444 return (0); 445 } 446 #endif 447 448 static int 449 e6000sw_init_interface(e6000sw_softc_t *sc, int port) 450 { 451 char name[IFNAMSIZ]; 452 453 snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(sc->dev)); 454 455 sc->ifp[port] = if_alloc(IFT_ETHER); 456 if (sc->ifp[port] == NULL) 457 return (ENOMEM); 458 if_setsoftc(sc->ifp[port], sc); 459 if_setflagbits(sc->ifp[port], IFF_UP | IFF_BROADCAST | 460 IFF_DRV_RUNNING | IFF_SIMPLEX, 0); 461 sc->ifname[port] = malloc(strlen(name) + 1, M_E6000SW, M_NOWAIT); 462 if (sc->ifname[port] == NULL) { 463 if_free(sc->ifp[port]); 464 return (ENOMEM); 465 } 466 memcpy(sc->ifname[port], name, strlen(name) + 1); 467 if_initname(sc->ifp[port], sc->ifname[port], port); 468 469 return (0); 470 } 471 472 static int 473 e6000sw_attach_miibus(e6000sw_softc_t *sc, int port) 474 { 475 int err; 476 477 err = mii_attach(sc->dev, &sc->miibus[port], sc->ifp[port], 478 e6000sw_ifmedia_upd, e6000sw_ifmedia_sts, BMSR_DEFCAPMASK, 479 port + sc->phy_base, MII_OFFSET_ANY, 0); 480 if (err != 0) 481 return (err); 482 483 return (0); 484 } 485 486 static void 487 e6000sw_serdes_power(device_t dev, int port, bool sgmii) 488 { 489 uint32_t reg; 490 491 /* SGMII */ 492 reg = e6000sw_read_xmdio(dev, port, E6000SW_SERDES_DEV, 493 E6000SW_SERDES_SGMII_CTL); 494 if (sgmii) 495 reg &= ~E6000SW_SERDES_PDOWN; 496 else 497 reg |= E6000SW_SERDES_PDOWN; 498 e6000sw_write_xmdio(dev, port, E6000SW_SERDES_DEV, 499 E6000SW_SERDES_SGMII_CTL, reg); 500 501 /* 10GBASE-R/10GBASE-X4/X2 */ 502 reg = e6000sw_read_xmdio(dev, port, E6000SW_SERDES_DEV, 503 E6000SW_SERDES_PCS_CTL1); 504 if (sgmii) 505 reg |= E6000SW_SERDES_PDOWN; 506 else 507 reg &= ~E6000SW_SERDES_PDOWN; 508 e6000sw_write_xmdio(dev, port, E6000SW_SERDES_DEV, 509 E6000SW_SERDES_PCS_CTL1, reg); 510 } 511 512 static int 513 e6000sw_attach(device_t dev) 514 { 515 bool sgmii; 516 e6000sw_softc_t *sc; 517 #ifdef FDT 518 phandle_t child, ports; 519 #endif 520 int err, port; 521 uint32_t reg; 522 523 err = 0; 524 sc = device_get_softc(dev); 525 526 /* 527 * According to the Linux source code, all of the Switch IDs we support 528 * are multi_chip capable, and should go into multi-chip mode if the 529 * sw_addr != 0. 530 */ 531 if (MVSWITCH_MULTICHIP(sc)) 532 device_printf(dev, "multi-chip addressing mode (%#x)\n", 533 sc->sw_addr); 534 else 535 device_printf(dev, "single-chip addressing mode\n"); 536 537 sx_init(&sc->sx, "e6000sw"); 538 539 E6000SW_LOCK(sc); 540 e6000sw_setup(dev, sc); 541 542 sc->sc_tq = taskqueue_create("e6000sw_taskq", M_NOWAIT, 543 taskqueue_thread_enqueue, &sc->sc_tq); 544 545 TIMEOUT_TASK_INIT(sc->sc_tq, &sc->sc_tt, 0, e6000sw_tick, sc); 546 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", 547 device_get_nameunit(dev)); 548 549 #ifdef FDT 550 ports = ofw_bus_find_child(sc->node, "ports"); 551 if (ports == 0) { 552 device_printf(dev, "failed to parse DTS: no ports found for " 553 "switch\n"); 554 E6000SW_UNLOCK(sc); 555 return (ENXIO); 556 } 557 558 for (child = OF_child(ports); child != 0; child = OF_peer(child)) { 559 err = e6000sw_parse_child_fdt(sc, child, &port); 560 if (err != 0) { 561 device_printf(sc->dev, "failed to parse DTS\n"); 562 goto out_fail; 563 } 564 #else 565 for (port = 0; port < sc->num_ports; port++) { 566 err = e6000sw_parse_hinted_port(sc, port); 567 if (err != 0) 568 continue; 569 #endif 570 571 /* Port is in use. */ 572 sc->ports_mask |= (1 << port); 573 574 err = e6000sw_init_interface(sc, port); 575 if (err != 0) { 576 device_printf(sc->dev, "failed to init interface\n"); 577 goto out_fail; 578 } 579 580 if (e6000sw_is_fixedport(sc, port)) { 581 /* Link must be down to change speed force value. */ 582 reg = e6000sw_readreg(sc, REG_PORT(sc, port), 583 PSC_CONTROL); 584 reg &= ~PSC_CONTROL_LINK_UP; 585 reg |= PSC_CONTROL_FORCED_LINK; 586 e6000sw_writereg(sc, REG_PORT(sc, port), PSC_CONTROL, 587 reg); 588 589 /* 590 * Force speed, full-duplex, EEE off and flow-control 591 * on. 592 */ 593 reg &= ~(PSC_CONTROL_SPD2500 | PSC_CONTROL_ALT_SPD | 594 PSC_CONTROL_FORCED_FC | PSC_CONTROL_FC_ON | 595 PSC_CONTROL_FORCED_EEE); 596 if (e6000sw_is_fixed25port(sc, port)) 597 reg |= PSC_CONTROL_SPD2500; 598 else 599 reg |= PSC_CONTROL_SPD1000; 600 if (MVSWITCH(sc, MV88E6190) && 601 e6000sw_is_fixed25port(sc, port)) 602 reg |= PSC_CONTROL_ALT_SPD; 603 reg |= PSC_CONTROL_FORCED_DPX | PSC_CONTROL_FULLDPX | 604 PSC_CONTROL_FORCED_LINK | PSC_CONTROL_LINK_UP | 605 PSC_CONTROL_FORCED_SPD; 606 if (!MVSWITCH(sc, MV88E6190)) 607 reg |= PSC_CONTROL_FORCED_FC | PSC_CONTROL_FC_ON; 608 if (MVSWITCH(sc, MV88E6141) || 609 MVSWITCH(sc, MV88E6341) || 610 MVSWITCH(sc, MV88E6190)) 611 reg |= PSC_CONTROL_FORCED_EEE; 612 e6000sw_writereg(sc, REG_PORT(sc, port), PSC_CONTROL, 613 reg); 614 /* Power on the SERDES interfaces. */ 615 if (MVSWITCH(sc, MV88E6190) && 616 (port == 9 || port == 10)) { 617 if (e6000sw_is_fixed25port(sc, port)) 618 sgmii = false; 619 else 620 sgmii = true; 621 e6000sw_serdes_power(sc->dev, port, sgmii); 622 } 623 } 624 625 /* Don't attach miibus at CPU/fixed ports */ 626 if (!e6000sw_is_phyport(sc, port)) 627 continue; 628 629 err = e6000sw_attach_miibus(sc, port); 630 if (err != 0) { 631 device_printf(sc->dev, "failed to attach miibus\n"); 632 goto out_fail; 633 } 634 } 635 636 etherswitch_info.es_nports = sc->num_ports; 637 638 /* Default to port vlan. */ 639 e6000sw_set_vlan_mode(sc, ETHERSWITCH_VLAN_PORT); 640 641 reg = e6000sw_readreg(sc, REG_GLOBAL, SWITCH_GLOBAL_STATUS); 642 if (reg & SWITCH_GLOBAL_STATUS_IR) 643 device_printf(dev, "switch is ready.\n"); 644 E6000SW_UNLOCK(sc); 645 646 bus_generic_probe(dev); 647 bus_generic_attach(dev); 648 649 taskqueue_enqueue_timeout(sc->sc_tq, &sc->sc_tt, hz); 650 651 return (0); 652 653 out_fail: 654 e6000sw_detach(dev); 655 656 return (err); 657 } 658 659 static int 660 e6000sw_waitready(e6000sw_softc_t *sc, uint32_t phy, uint32_t reg, 661 uint32_t busybit) 662 { 663 int i; 664 665 for (i = 0; i < E6000SW_RETRIES; i++) { 666 if ((e6000sw_readreg(sc, phy, reg) & busybit) == 0) 667 return (0); 668 DELAY(1); 669 } 670 671 return (1); 672 } 673 674 /* XMDIO/Clause 45 access. */ 675 static int 676 e6000sw_read_xmdio(device_t dev, int phy, int devaddr, int devreg) 677 { 678 e6000sw_softc_t *sc; 679 uint32_t reg; 680 681 sc = device_get_softc(dev); 682 E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); 683 if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) { 684 device_printf(dev, "Timeout while waiting for switch\n"); 685 return (ETIMEDOUT); 686 } 687 688 reg = devaddr & SMI_CMD_REG_ADDR_MASK; 689 reg |= (phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK; 690 691 /* Load C45 register address. */ 692 e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG, devreg); 693 e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG, 694 reg | SMI_CMD_OP_C45_ADDR); 695 if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) { 696 device_printf(dev, "Timeout while waiting for switch\n"); 697 return (ETIMEDOUT); 698 } 699 700 /* Start C45 read operation. */ 701 e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG, 702 reg | SMI_CMD_OP_C45_READ); 703 if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) { 704 device_printf(dev, "Timeout while waiting for switch\n"); 705 return (ETIMEDOUT); 706 } 707 708 /* Read C45 data. */ 709 reg = e6000sw_readreg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG); 710 711 return (reg & PHY_DATA_MASK); 712 } 713 714 static int 715 e6000sw_write_xmdio(device_t dev, int phy, int devaddr, int devreg, int val) 716 { 717 e6000sw_softc_t *sc; 718 uint32_t reg; 719 720 sc = device_get_softc(dev); 721 E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); 722 if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) { 723 device_printf(dev, "Timeout while waiting for switch\n"); 724 return (ETIMEDOUT); 725 } 726 727 reg = devaddr & SMI_CMD_REG_ADDR_MASK; 728 reg |= (phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK; 729 730 /* Load C45 register address. */ 731 e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG, devreg); 732 e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG, 733 reg | SMI_CMD_OP_C45_ADDR); 734 if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) { 735 device_printf(dev, "Timeout while waiting for switch\n"); 736 return (ETIMEDOUT); 737 } 738 739 /* Load data and start the C45 write operation. */ 740 e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG, devreg); 741 e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG, 742 reg | SMI_CMD_OP_C45_WRITE); 743 744 return (0); 745 } 746 747 static int e6000sw_readphy(device_t dev, int phy, int reg) 748 { 749 e6000sw_softc_t *sc; 750 int ret; 751 752 sc = device_get_softc(dev); 753 E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED); 754 755 E6000SW_LOCK(sc); 756 ret = e6000sw_readphy_locked(dev, phy, reg); 757 E6000SW_UNLOCK(sc); 758 759 return (ret); 760 } 761 762 /* 763 * PHY registers are paged. Put page index in reg 22 (accessible from every 764 * page), then access specific register. 765 */ 766 static int 767 e6000sw_readphy_locked(device_t dev, int phy, int reg) 768 { 769 e6000sw_softc_t *sc; 770 uint32_t val; 771 772 sc = device_get_softc(dev); 773 E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); 774 775 if (!e6000sw_is_phyport(sc, phy) || reg >= E6000SW_NUM_PHY_REGS) { 776 device_printf(dev, "Wrong register address.\n"); 777 return (EINVAL); 778 } 779 780 if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) { 781 device_printf(dev, "Timeout while waiting for switch\n"); 782 return (ETIMEDOUT); 783 } 784 785 e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG, 786 SMI_CMD_OP_C22_READ | (reg & SMI_CMD_REG_ADDR_MASK) | 787 ((phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK)); 788 if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) { 789 device_printf(dev, "Timeout while waiting for switch\n"); 790 return (ETIMEDOUT); 791 } 792 793 val = e6000sw_readreg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG); 794 795 return (val & PHY_DATA_MASK); 796 } 797 798 static int e6000sw_writephy(device_t dev, int phy, int reg, int data) 799 { 800 e6000sw_softc_t *sc; 801 int ret; 802 803 sc = device_get_softc(dev); 804 E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED); 805 806 E6000SW_LOCK(sc); 807 ret = e6000sw_writephy_locked(dev, phy, reg, data); 808 E6000SW_UNLOCK(sc); 809 810 return (ret); 811 } 812 813 static int 814 e6000sw_writephy_locked(device_t dev, int phy, int reg, int data) 815 { 816 e6000sw_softc_t *sc; 817 818 sc = device_get_softc(dev); 819 E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); 820 821 if (!e6000sw_is_phyport(sc, phy) || reg >= E6000SW_NUM_PHY_REGS) { 822 device_printf(dev, "Wrong register address.\n"); 823 return (EINVAL); 824 } 825 826 if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) { 827 device_printf(dev, "Timeout while waiting for switch\n"); 828 return (ETIMEDOUT); 829 } 830 831 e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG, 832 data & PHY_DATA_MASK); 833 e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG, 834 SMI_CMD_OP_C22_WRITE | (reg & SMI_CMD_REG_ADDR_MASK) | 835 ((phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK)); 836 837 return (0); 838 } 839 840 static int 841 e6000sw_detach(device_t dev) 842 { 843 int phy; 844 e6000sw_softc_t *sc; 845 846 sc = device_get_softc(dev); 847 848 if (device_is_attached(dev)) 849 taskqueue_drain_timeout(sc->sc_tq, &sc->sc_tt); 850 851 if (sc->sc_tq != NULL) 852 taskqueue_free(sc->sc_tq); 853 854 device_delete_children(dev); 855 856 sx_destroy(&sc->sx); 857 for (phy = 0; phy < sc->num_ports; phy++) { 858 if (sc->ifp[phy] != NULL) 859 if_free(sc->ifp[phy]); 860 if (sc->ifname[phy] != NULL) 861 free(sc->ifname[phy], M_E6000SW); 862 } 863 864 return (0); 865 } 866 867 static etherswitch_info_t* 868 e6000sw_getinfo(device_t dev) 869 { 870 871 return (ðerswitch_info); 872 } 873 874 static int 875 e6000sw_getconf(device_t dev, etherswitch_conf_t *conf) 876 { 877 struct e6000sw_softc *sc; 878 879 /* Return the VLAN mode. */ 880 sc = device_get_softc(dev); 881 conf->cmd = ETHERSWITCH_CONF_VLAN_MODE; 882 conf->vlan_mode = sc->vlan_mode; 883 884 return (0); 885 } 886 887 static int 888 e6000sw_setconf(device_t dev, etherswitch_conf_t *conf) 889 { 890 struct e6000sw_softc *sc; 891 892 /* Set the VLAN mode. */ 893 sc = device_get_softc(dev); 894 if (conf->cmd & ETHERSWITCH_CONF_VLAN_MODE) { 895 E6000SW_LOCK(sc); 896 e6000sw_set_vlan_mode(sc, conf->vlan_mode); 897 E6000SW_UNLOCK(sc); 898 } 899 900 return (0); 901 } 902 903 static void 904 e6000sw_lock(device_t dev) 905 { 906 struct e6000sw_softc *sc; 907 908 sc = device_get_softc(dev); 909 910 E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED); 911 E6000SW_LOCK(sc); 912 } 913 914 static void 915 e6000sw_unlock(device_t dev) 916 { 917 struct e6000sw_softc *sc; 918 919 sc = device_get_softc(dev); 920 921 E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); 922 E6000SW_UNLOCK(sc); 923 } 924 925 static int 926 e6000sw_getport(device_t dev, etherswitch_port_t *p) 927 { 928 struct mii_data *mii; 929 int err; 930 struct ifmediareq *ifmr; 931 uint32_t reg; 932 933 e6000sw_softc_t *sc = device_get_softc(dev); 934 E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED); 935 936 if (p->es_port >= sc->num_ports || p->es_port < 0) 937 return (EINVAL); 938 if (!e6000sw_is_portenabled(sc, p->es_port)) 939 return (0); 940 941 E6000SW_LOCK(sc); 942 e6000sw_get_pvid(sc, p->es_port, &p->es_pvid); 943 944 /* Port flags. */ 945 reg = e6000sw_readreg(sc, REG_PORT(sc, p->es_port), PORT_CONTROL2); 946 if (reg & PORT_CONTROL2_DISC_TAGGED) 947 p->es_flags |= ETHERSWITCH_PORT_DROPTAGGED; 948 if (reg & PORT_CONTROL2_DISC_UNTAGGED) 949 p->es_flags |= ETHERSWITCH_PORT_DROPUNTAGGED; 950 951 err = 0; 952 if (e6000sw_is_fixedport(sc, p->es_port)) { 953 if (e6000sw_is_cpuport(sc, p->es_port)) 954 p->es_flags |= ETHERSWITCH_PORT_CPU; 955 ifmr = &p->es_ifmr; 956 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID; 957 ifmr->ifm_count = 0; 958 if (e6000sw_is_fixed25port(sc, p->es_port)) 959 ifmr->ifm_active = IFM_2500_T; 960 else 961 ifmr->ifm_active = IFM_1000_T; 962 ifmr->ifm_active |= IFM_ETHER | IFM_FDX; 963 ifmr->ifm_current = ifmr->ifm_active; 964 ifmr->ifm_mask = 0; 965 } else { 966 mii = e6000sw_miiforphy(sc, p->es_port); 967 err = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, 968 &mii->mii_media, SIOCGIFMEDIA); 969 } 970 E6000SW_UNLOCK(sc); 971 972 return (err); 973 } 974 975 static int 976 e6000sw_setport(device_t dev, etherswitch_port_t *p) 977 { 978 e6000sw_softc_t *sc; 979 int err; 980 struct mii_data *mii; 981 uint32_t reg; 982 983 sc = device_get_softc(dev); 984 E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED); 985 986 if (p->es_port >= sc->num_ports || p->es_port < 0) 987 return (EINVAL); 988 if (!e6000sw_is_portenabled(sc, p->es_port)) 989 return (0); 990 991 E6000SW_LOCK(sc); 992 993 /* Port flags. */ 994 reg = e6000sw_readreg(sc, REG_PORT(sc, p->es_port), PORT_CONTROL2); 995 if (p->es_flags & ETHERSWITCH_PORT_DROPTAGGED) 996 reg |= PORT_CONTROL2_DISC_TAGGED; 997 else 998 reg &= ~PORT_CONTROL2_DISC_TAGGED; 999 if (p->es_flags & ETHERSWITCH_PORT_DROPUNTAGGED) 1000 reg |= PORT_CONTROL2_DISC_UNTAGGED; 1001 else 1002 reg &= ~PORT_CONTROL2_DISC_UNTAGGED; 1003 e6000sw_writereg(sc, REG_PORT(sc, p->es_port), PORT_CONTROL2, reg); 1004 1005 err = 0; 1006 if (p->es_pvid != 0) 1007 e6000sw_set_pvid(sc, p->es_port, p->es_pvid); 1008 if (e6000sw_is_phyport(sc, p->es_port)) { 1009 mii = e6000sw_miiforphy(sc, p->es_port); 1010 err = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, &mii->mii_media, 1011 SIOCSIFMEDIA); 1012 } 1013 E6000SW_UNLOCK(sc); 1014 1015 return (err); 1016 } 1017 1018 static __inline void 1019 e6000sw_port_vlan_assign(e6000sw_softc_t *sc, int port, uint32_t fid, 1020 uint32_t members) 1021 { 1022 uint32_t reg; 1023 1024 reg = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_VLAN_MAP); 1025 reg &= ~(PORT_MASK(sc) | PORT_VLAN_MAP_FID_MASK); 1026 reg |= members & PORT_MASK(sc) & ~(1 << port); 1027 reg |= (fid << PORT_VLAN_MAP_FID) & PORT_VLAN_MAP_FID_MASK; 1028 e6000sw_writereg(sc, REG_PORT(sc, port), PORT_VLAN_MAP, reg); 1029 reg = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL1); 1030 reg &= ~PORT_CONTROL1_FID_MASK; 1031 reg |= (fid >> 4) & PORT_CONTROL1_FID_MASK; 1032 e6000sw_writereg(sc, REG_PORT(sc, port), PORT_CONTROL1, reg); 1033 } 1034 1035 static int 1036 e6000sw_init_vlan(struct e6000sw_softc *sc) 1037 { 1038 int i, port, ret; 1039 uint32_t members; 1040 1041 /* Disable all ports */ 1042 for (port = 0; port < sc->num_ports; port++) { 1043 ret = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL); 1044 e6000sw_writereg(sc, REG_PORT(sc, port), PORT_CONTROL, 1045 (ret & ~PORT_CONTROL_ENABLE)); 1046 } 1047 1048 /* Flush VTU. */ 1049 e6000sw_vtu_flush(sc); 1050 1051 for (port = 0; port < sc->num_ports; port++) { 1052 /* Reset the egress and frame mode. */ 1053 ret = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL); 1054 ret &= ~(PORT_CONTROL_EGRESS | PORT_CONTROL_FRAME); 1055 e6000sw_writereg(sc, REG_PORT(sc, port), PORT_CONTROL, ret); 1056 1057 /* Set the 802.1q mode. */ 1058 ret = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL2); 1059 ret &= ~PORT_CONTROL2_DOT1Q; 1060 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) 1061 ret |= PORT_CONTROL2_DOT1Q; 1062 e6000sw_writereg(sc, REG_PORT(sc, port), PORT_CONTROL2, ret); 1063 } 1064 1065 for (port = 0; port < sc->num_ports; port++) { 1066 if (!e6000sw_is_portenabled(sc, port)) 1067 continue; 1068 1069 ret = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_VID); 1070 1071 /* Set port priority */ 1072 ret &= ~PORT_VID_PRIORITY_MASK; 1073 1074 /* Set VID map */ 1075 ret &= ~PORT_VID_DEF_VID_MASK; 1076 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) 1077 ret |= 1; 1078 else 1079 ret |= (port + 1); 1080 e6000sw_writereg(sc, REG_PORT(sc, port), PORT_VID, ret); 1081 } 1082 1083 /* Assign the member ports to each origin port. */ 1084 for (port = 0; port < sc->num_ports; port++) { 1085 members = 0; 1086 if (e6000sw_is_portenabled(sc, port)) { 1087 for (i = 0; i < sc->num_ports; i++) { 1088 if (i == port || !e6000sw_is_portenabled(sc, i)) 1089 continue; 1090 members |= (1 << i); 1091 } 1092 } 1093 /* Default to FID 0. */ 1094 e6000sw_port_vlan_assign(sc, port, 0, members); 1095 } 1096 1097 /* Reset internal VLAN table. */ 1098 for (i = 0; i < nitems(sc->vlans); i++) 1099 sc->vlans[i] = 0; 1100 1101 /* Create default VLAN (1). */ 1102 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { 1103 sc->vlans[0] = 1; 1104 e6000sw_vtu_update(sc, 0, sc->vlans[0], 1, 0, sc->ports_mask); 1105 } 1106 1107 /* Enable all ports */ 1108 for (port = 0; port < sc->num_ports; port++) { 1109 if (!e6000sw_is_portenabled(sc, port)) 1110 continue; 1111 ret = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL); 1112 e6000sw_writereg(sc, REG_PORT(sc, port), PORT_CONTROL, 1113 (ret | PORT_CONTROL_ENABLE)); 1114 } 1115 1116 return (0); 1117 } 1118 1119 static int 1120 e6000sw_set_vlan_mode(struct e6000sw_softc *sc, uint32_t mode) 1121 { 1122 1123 E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); 1124 switch (mode) { 1125 case ETHERSWITCH_VLAN_PORT: 1126 sc->vlan_mode = ETHERSWITCH_VLAN_PORT; 1127 etherswitch_info.es_nvlangroups = sc->num_ports; 1128 return (e6000sw_init_vlan(sc)); 1129 break; 1130 case ETHERSWITCH_VLAN_DOT1Q: 1131 sc->vlan_mode = ETHERSWITCH_VLAN_DOT1Q; 1132 etherswitch_info.es_nvlangroups = E6000SW_NUM_VLANS; 1133 return (e6000sw_init_vlan(sc)); 1134 break; 1135 default: 1136 return (EINVAL); 1137 } 1138 } 1139 1140 /* 1141 * Registers in this switch are divided into sections, specified in 1142 * documentation. So as to access any of them, section index and reg index 1143 * is necessary. etherswitchcfg uses only one variable, so indexes were 1144 * compressed into addr_reg: 32 * section_index + reg_index. 1145 */ 1146 static int 1147 e6000sw_readreg_wrapper(device_t dev, int addr_reg) 1148 { 1149 e6000sw_softc_t *sc; 1150 1151 sc = device_get_softc(dev); 1152 if ((addr_reg > (REG_GLOBAL2 * 32 + REG_NUM_MAX)) || 1153 (addr_reg < (REG_PORT(sc, 0) * 32))) { 1154 device_printf(dev, "Wrong register address.\n"); 1155 return (EINVAL); 1156 } 1157 1158 return (e6000sw_readreg(device_get_softc(dev), addr_reg / 32, 1159 addr_reg % 32)); 1160 } 1161 1162 static int 1163 e6000sw_writereg_wrapper(device_t dev, int addr_reg, int val) 1164 { 1165 e6000sw_softc_t *sc; 1166 1167 sc = device_get_softc(dev); 1168 if ((addr_reg > (REG_GLOBAL2 * 32 + REG_NUM_MAX)) || 1169 (addr_reg < (REG_PORT(sc, 0) * 32))) { 1170 device_printf(dev, "Wrong register address.\n"); 1171 return (EINVAL); 1172 } 1173 e6000sw_writereg(device_get_softc(dev), addr_reg / 32, 1174 addr_reg % 32, val); 1175 1176 return (0); 1177 } 1178 1179 /* 1180 * setvgroup/getvgroup called from etherswitchfcg need to be locked, 1181 * while internal calls do not. 1182 */ 1183 static int 1184 e6000sw_setvgroup_wrapper(device_t dev, etherswitch_vlangroup_t *vg) 1185 { 1186 e6000sw_softc_t *sc; 1187 int ret; 1188 1189 sc = device_get_softc(dev); 1190 E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED); 1191 1192 E6000SW_LOCK(sc); 1193 ret = e6000sw_setvgroup(dev, vg); 1194 E6000SW_UNLOCK(sc); 1195 1196 return (ret); 1197 } 1198 1199 static int 1200 e6000sw_getvgroup_wrapper(device_t dev, etherswitch_vlangroup_t *vg) 1201 { 1202 e6000sw_softc_t *sc; 1203 int ret; 1204 1205 sc = device_get_softc(dev); 1206 E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED); 1207 1208 E6000SW_LOCK(sc); 1209 ret = e6000sw_getvgroup(dev, vg); 1210 E6000SW_UNLOCK(sc); 1211 1212 return (ret); 1213 } 1214 1215 static int 1216 e6000sw_set_port_vlan(e6000sw_softc_t *sc, etherswitch_vlangroup_t *vg) 1217 { 1218 uint32_t port; 1219 1220 port = vg->es_vlangroup; 1221 if (port > sc->num_ports) 1222 return (EINVAL); 1223 1224 if (vg->es_member_ports != vg->es_untagged_ports) { 1225 device_printf(sc->dev, "Tagged ports not supported.\n"); 1226 return (EINVAL); 1227 } 1228 1229 e6000sw_port_vlan_assign(sc, port, 0, vg->es_untagged_ports); 1230 vg->es_vid = port | ETHERSWITCH_VID_VALID; 1231 1232 return (0); 1233 } 1234 1235 static int 1236 e6000sw_set_dot1q_vlan(e6000sw_softc_t *sc, etherswitch_vlangroup_t *vg) 1237 { 1238 int i, vlan; 1239 1240 vlan = vg->es_vid & ETHERSWITCH_VID_MASK; 1241 1242 /* Set VLAN to '0' removes it from table. */ 1243 if (vlan == 0) { 1244 e6000sw_vtu_update(sc, VTU_PURGE, 1245 sc->vlans[vg->es_vlangroup], 0, 0, 0); 1246 sc->vlans[vg->es_vlangroup] = 0; 1247 return (0); 1248 } 1249 1250 /* Is this VLAN already in table ? */ 1251 for (i = 0; i < etherswitch_info.es_nvlangroups; i++) 1252 if (i != vg->es_vlangroup && vlan == sc->vlans[i]) 1253 return (EINVAL); 1254 1255 sc->vlans[vg->es_vlangroup] = vlan; 1256 e6000sw_vtu_update(sc, 0, vlan, vg->es_vlangroup + 1, 1257 vg->es_member_ports & sc->ports_mask, 1258 vg->es_untagged_ports & sc->ports_mask); 1259 1260 return (0); 1261 } 1262 1263 static int 1264 e6000sw_setvgroup(device_t dev, etherswitch_vlangroup_t *vg) 1265 { 1266 e6000sw_softc_t *sc; 1267 1268 sc = device_get_softc(dev); 1269 E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); 1270 1271 if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) 1272 return (e6000sw_set_port_vlan(sc, vg)); 1273 else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) 1274 return (e6000sw_set_dot1q_vlan(sc, vg)); 1275 1276 return (EINVAL); 1277 } 1278 1279 static int 1280 e6000sw_get_port_vlan(e6000sw_softc_t *sc, etherswitch_vlangroup_t *vg) 1281 { 1282 uint32_t port, reg; 1283 1284 port = vg->es_vlangroup; 1285 if (port > sc->num_ports) 1286 return (EINVAL); 1287 1288 if (!e6000sw_is_portenabled(sc, port)) { 1289 vg->es_vid = port; 1290 return (0); 1291 } 1292 1293 reg = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_VLAN_MAP); 1294 vg->es_untagged_ports = vg->es_member_ports = reg & PORT_MASK(sc); 1295 vg->es_vid = port | ETHERSWITCH_VID_VALID; 1296 vg->es_fid = (reg & PORT_VLAN_MAP_FID_MASK) >> PORT_VLAN_MAP_FID; 1297 reg = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL1); 1298 vg->es_fid |= (reg & PORT_CONTROL1_FID_MASK) << 4; 1299 1300 return (0); 1301 } 1302 1303 static int 1304 e6000sw_get_dot1q_vlan(e6000sw_softc_t *sc, etherswitch_vlangroup_t *vg) 1305 { 1306 int i, port; 1307 uint32_t reg; 1308 1309 vg->es_fid = 0; 1310 vg->es_vid = sc->vlans[vg->es_vlangroup]; 1311 vg->es_untagged_ports = vg->es_member_ports = 0; 1312 if (vg->es_vid == 0) 1313 return (0); 1314 1315 if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { 1316 device_printf(sc->dev, "VTU unit is busy, cannot access\n"); 1317 return (EBUSY); 1318 } 1319 1320 e6000sw_writereg(sc, REG_GLOBAL, VTU_VID, vg->es_vid - 1); 1321 1322 reg = e6000sw_readreg(sc, REG_GLOBAL, VTU_OPERATION); 1323 reg &= ~VTU_OP_MASK; 1324 reg |= VTU_GET_NEXT | VTU_BUSY; 1325 e6000sw_writereg(sc, REG_GLOBAL, VTU_OPERATION, reg); 1326 if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { 1327 device_printf(sc->dev, "Timeout while reading\n"); 1328 return (EBUSY); 1329 } 1330 1331 reg = e6000sw_readreg(sc, REG_GLOBAL, VTU_VID); 1332 if (reg == VTU_VID_MASK || (reg & VTU_VID_VALID) == 0) 1333 return (EINVAL); 1334 if ((reg & VTU_VID_MASK) != vg->es_vid) 1335 return (EINVAL); 1336 1337 vg->es_vid |= ETHERSWITCH_VID_VALID; 1338 reg = e6000sw_readreg(sc, REG_GLOBAL, VTU_DATA); 1339 for (i = 0; i < sc->num_ports; i++) { 1340 if (i == VTU_PPREG(sc)) 1341 reg = e6000sw_readreg(sc, REG_GLOBAL, VTU_DATA2); 1342 port = (reg >> VTU_PORT(sc, i)) & VTU_PORT_MASK; 1343 if (port == VTU_PORT_UNTAGGED) { 1344 vg->es_untagged_ports |= (1 << i); 1345 vg->es_member_ports |= (1 << i); 1346 } else if (port == VTU_PORT_TAGGED) 1347 vg->es_member_ports |= (1 << i); 1348 } 1349 1350 return (0); 1351 } 1352 1353 static int 1354 e6000sw_getvgroup(device_t dev, etherswitch_vlangroup_t *vg) 1355 { 1356 e6000sw_softc_t *sc; 1357 1358 sc = device_get_softc(dev); 1359 E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); 1360 1361 if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) 1362 return (e6000sw_get_port_vlan(sc, vg)); 1363 else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) 1364 return (e6000sw_get_dot1q_vlan(sc, vg)); 1365 1366 return (EINVAL); 1367 } 1368 1369 static __inline struct mii_data* 1370 e6000sw_miiforphy(e6000sw_softc_t *sc, unsigned int phy) 1371 { 1372 1373 if (!e6000sw_is_phyport(sc, phy)) 1374 return (NULL); 1375 1376 return (device_get_softc(sc->miibus[phy])); 1377 } 1378 1379 static int 1380 e6000sw_ifmedia_upd(if_t ifp) 1381 { 1382 e6000sw_softc_t *sc; 1383 struct mii_data *mii; 1384 1385 sc = if_getsoftc(ifp); 1386 mii = e6000sw_miiforphy(sc, if_getdunit(ifp)); 1387 if (mii == NULL) 1388 return (ENXIO); 1389 mii_mediachg(mii); 1390 1391 return (0); 1392 } 1393 1394 static void 1395 e6000sw_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr) 1396 { 1397 e6000sw_softc_t *sc; 1398 struct mii_data *mii; 1399 1400 sc = if_getsoftc(ifp); 1401 mii = e6000sw_miiforphy(sc, if_getdunit(ifp)); 1402 1403 if (mii == NULL) 1404 return; 1405 1406 mii_pollstat(mii); 1407 ifmr->ifm_active = mii->mii_media_active; 1408 ifmr->ifm_status = mii->mii_media_status; 1409 } 1410 1411 static int 1412 e6000sw_smi_waitready(e6000sw_softc_t *sc, int phy) 1413 { 1414 int i; 1415 1416 for (i = 0; i < E6000SW_SMI_TIMEOUT; i++) { 1417 if ((MDIO_READ(sc->dev, phy, SMI_CMD) & SMI_CMD_BUSY) == 0) 1418 return (0); 1419 DELAY(1); 1420 } 1421 1422 return (1); 1423 } 1424 1425 static __inline uint32_t 1426 e6000sw_readreg(e6000sw_softc_t *sc, int addr, int reg) 1427 { 1428 1429 E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); 1430 1431 if (!MVSWITCH_MULTICHIP(sc)) 1432 return (MDIO_READ(sc->dev, addr, reg) & 0xffff); 1433 1434 if (e6000sw_smi_waitready(sc, sc->sw_addr)) { 1435 printf("e6000sw: readreg timeout\n"); 1436 return (0xffff); 1437 } 1438 MDIO_WRITE(sc->dev, sc->sw_addr, SMI_CMD, 1439 SMI_CMD_OP_C22_READ | (reg & SMI_CMD_REG_ADDR_MASK) | 1440 ((addr << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK)); 1441 if (e6000sw_smi_waitready(sc, sc->sw_addr)) { 1442 printf("e6000sw: readreg timeout\n"); 1443 return (0xffff); 1444 } 1445 1446 return (MDIO_READ(sc->dev, sc->sw_addr, SMI_DATA) & 0xffff); 1447 } 1448 1449 static __inline void 1450 e6000sw_writereg(e6000sw_softc_t *sc, int addr, int reg, int val) 1451 { 1452 1453 E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); 1454 1455 if (!MVSWITCH_MULTICHIP(sc)) { 1456 MDIO_WRITE(sc->dev, addr, reg, val); 1457 return; 1458 } 1459 1460 if (e6000sw_smi_waitready(sc, sc->sw_addr)) { 1461 printf("e6000sw: readreg timeout\n"); 1462 return; 1463 } 1464 MDIO_WRITE(sc->dev, sc->sw_addr, SMI_DATA, val); 1465 MDIO_WRITE(sc->dev, sc->sw_addr, SMI_CMD, 1466 SMI_CMD_OP_C22_WRITE | (reg & SMI_CMD_REG_ADDR_MASK) | 1467 ((addr << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK)); 1468 } 1469 1470 static __inline bool 1471 e6000sw_is_cpuport(e6000sw_softc_t *sc, int port) 1472 { 1473 1474 return ((sc->cpuports_mask & (1 << port)) ? true : false); 1475 } 1476 1477 static __inline bool 1478 e6000sw_is_fixedport(e6000sw_softc_t *sc, int port) 1479 { 1480 1481 return ((sc->fixed_mask & (1 << port)) ? true : false); 1482 } 1483 1484 static __inline bool 1485 e6000sw_is_fixed25port(e6000sw_softc_t *sc, int port) 1486 { 1487 1488 return ((sc->fixed25_mask & (1 << port)) ? true : false); 1489 } 1490 1491 static __inline bool 1492 e6000sw_is_phyport(e6000sw_softc_t *sc, int port) 1493 { 1494 uint32_t phy_mask; 1495 phy_mask = ~(sc->fixed_mask | sc->cpuports_mask); 1496 1497 return ((phy_mask & (1 << port)) ? true : false); 1498 } 1499 1500 static __inline bool 1501 e6000sw_is_portenabled(e6000sw_softc_t *sc, int port) 1502 { 1503 1504 return ((sc->ports_mask & (1 << port)) ? true : false); 1505 } 1506 1507 static __inline void 1508 e6000sw_set_pvid(e6000sw_softc_t *sc, int port, int pvid) 1509 { 1510 uint32_t reg; 1511 1512 reg = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_VID); 1513 reg &= ~PORT_VID_DEF_VID_MASK; 1514 reg |= (pvid & PORT_VID_DEF_VID_MASK); 1515 e6000sw_writereg(sc, REG_PORT(sc, port), PORT_VID, reg); 1516 } 1517 1518 static __inline int 1519 e6000sw_get_pvid(e6000sw_softc_t *sc, int port, int *pvid) 1520 { 1521 1522 if (pvid == NULL) 1523 return (ENXIO); 1524 1525 *pvid = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_VID) & 1526 PORT_VID_DEF_VID_MASK; 1527 1528 return (0); 1529 } 1530 1531 /* 1532 * Convert port status to ifmedia. 1533 */ 1534 static void 1535 e6000sw_update_ifmedia(uint16_t portstatus, u_int *media_status, u_int *media_active) 1536 { 1537 *media_active = IFM_ETHER; 1538 *media_status = IFM_AVALID; 1539 1540 if ((portstatus & PORT_STATUS_LINK_MASK) != 0) 1541 *media_status |= IFM_ACTIVE; 1542 else { 1543 *media_active |= IFM_NONE; 1544 return; 1545 } 1546 1547 switch (portstatus & PORT_STATUS_SPEED_MASK) { 1548 case PORT_STATUS_SPEED_10: 1549 *media_active |= IFM_10_T; 1550 break; 1551 case PORT_STATUS_SPEED_100: 1552 *media_active |= IFM_100_TX; 1553 break; 1554 case PORT_STATUS_SPEED_1000: 1555 *media_active |= IFM_1000_T; 1556 break; 1557 } 1558 1559 if ((portstatus & PORT_STATUS_DUPLEX_MASK) == 0) 1560 *media_active |= IFM_FDX; 1561 else 1562 *media_active |= IFM_HDX; 1563 } 1564 1565 static void 1566 e6000sw_tick(void *arg, int p __unused) 1567 { 1568 e6000sw_softc_t *sc; 1569 struct mii_data *mii; 1570 struct mii_softc *miisc; 1571 uint16_t portstatus; 1572 int port; 1573 1574 sc = arg; 1575 1576 E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED); 1577 1578 E6000SW_LOCK(sc); 1579 for (port = 0; port < sc->num_ports; port++) { 1580 /* Tick only on PHY ports */ 1581 if (!e6000sw_is_portenabled(sc, port) || 1582 !e6000sw_is_phyport(sc, port)) 1583 continue; 1584 1585 mii = e6000sw_miiforphy(sc, port); 1586 if (mii == NULL) 1587 continue; 1588 1589 portstatus = e6000sw_readreg(sc, REG_PORT(sc, port), 1590 PORT_STATUS); 1591 1592 e6000sw_update_ifmedia(portstatus, 1593 &mii->mii_media_status, &mii->mii_media_active); 1594 1595 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) { 1596 if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) 1597 != miisc->mii_inst) 1598 continue; 1599 mii_phy_update(miisc, MII_POLLSTAT); 1600 } 1601 } 1602 E6000SW_UNLOCK(sc); 1603 } 1604 1605 static void 1606 e6000sw_setup(device_t dev, e6000sw_softc_t *sc) 1607 { 1608 uint32_t atu_ctrl; 1609 1610 /* Set aging time. */ 1611 atu_ctrl = e6000sw_readreg(sc, REG_GLOBAL, ATU_CONTROL); 1612 atu_ctrl &= ~ATU_CONTROL_AGETIME_MASK; 1613 atu_ctrl |= E6000SW_DEFAULT_AGETIME << ATU_CONTROL_AGETIME; 1614 e6000sw_writereg(sc, REG_GLOBAL, ATU_CONTROL, atu_ctrl); 1615 1616 /* Send all with specific mac address to cpu port */ 1617 e6000sw_writereg(sc, REG_GLOBAL2, MGMT_EN_2x, MGMT_EN_ALL); 1618 e6000sw_writereg(sc, REG_GLOBAL2, MGMT_EN_0x, MGMT_EN_ALL); 1619 1620 /* Disable Remote Management */ 1621 e6000sw_writereg(sc, REG_GLOBAL, SWITCH_GLOBAL_CONTROL2, 0); 1622 1623 /* Disable loopback filter and flow control messages */ 1624 e6000sw_writereg(sc, REG_GLOBAL2, SWITCH_MGMT, 1625 SWITCH_MGMT_PRI_MASK | 1626 (1 << SWITCH_MGMT_RSVD2CPU) | 1627 SWITCH_MGMT_FC_PRI_MASK | 1628 (1 << SWITCH_MGMT_FORCEFLOW)); 1629 1630 e6000sw_atu_flush(dev, sc, NO_OPERATION); 1631 e6000sw_atu_mac_table(dev, sc, NULL, NO_OPERATION); 1632 e6000sw_set_atustat(dev, sc, 0, COUNT_ALL); 1633 } 1634 1635 static void 1636 e6000sw_set_atustat(device_t dev, e6000sw_softc_t *sc, int bin, int flag) 1637 { 1638 1639 e6000sw_readreg(sc, REG_GLOBAL2, ATU_STATS); 1640 e6000sw_writereg(sc, REG_GLOBAL2, ATU_STATS, (bin << ATU_STATS_BIN ) | 1641 (flag << ATU_STATS_FLAG)); 1642 } 1643 1644 static int 1645 e6000sw_atu_mac_table(device_t dev, e6000sw_softc_t *sc, struct atu_opt *atu, 1646 int flag) 1647 { 1648 uint16_t ret_opt; 1649 uint16_t ret_data; 1650 1651 if (flag == NO_OPERATION) 1652 return (0); 1653 else if ((flag & (LOAD_FROM_FIB | PURGE_FROM_FIB | GET_NEXT_IN_FIB | 1654 GET_VIOLATION_DATA | CLEAR_VIOLATION_DATA)) == 0) { 1655 device_printf(dev, "Wrong Opcode for ATU operation\n"); 1656 return (EINVAL); 1657 } 1658 1659 if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY)) { 1660 device_printf(dev, "ATU unit is busy, cannot access\n"); 1661 return (EBUSY); 1662 } 1663 1664 ret_opt = e6000sw_readreg(sc, REG_GLOBAL, ATU_OPERATION); 1665 if (flag & LOAD_FROM_FIB) { 1666 ret_data = e6000sw_readreg(sc, REG_GLOBAL, ATU_DATA); 1667 e6000sw_writereg(sc, REG_GLOBAL2, ATU_DATA, (ret_data & 1668 ~ENTRY_STATE)); 1669 } 1670 e6000sw_writereg(sc, REG_GLOBAL, ATU_MAC_ADDR01, atu->mac_01); 1671 e6000sw_writereg(sc, REG_GLOBAL, ATU_MAC_ADDR23, atu->mac_23); 1672 e6000sw_writereg(sc, REG_GLOBAL, ATU_MAC_ADDR45, atu->mac_45); 1673 e6000sw_writereg(sc, REG_GLOBAL, ATU_FID, atu->fid); 1674 1675 e6000sw_writereg(sc, REG_GLOBAL, ATU_OPERATION, 1676 (ret_opt | ATU_UNIT_BUSY | flag)); 1677 1678 if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY)) 1679 device_printf(dev, "Timeout while waiting ATU\n"); 1680 else if (flag & GET_NEXT_IN_FIB) { 1681 atu->mac_01 = e6000sw_readreg(sc, REG_GLOBAL, 1682 ATU_MAC_ADDR01); 1683 atu->mac_23 = e6000sw_readreg(sc, REG_GLOBAL, 1684 ATU_MAC_ADDR23); 1685 atu->mac_45 = e6000sw_readreg(sc, REG_GLOBAL, 1686 ATU_MAC_ADDR45); 1687 } 1688 1689 return (0); 1690 } 1691 1692 static int 1693 e6000sw_atu_flush(device_t dev, e6000sw_softc_t *sc, int flag) 1694 { 1695 uint32_t reg; 1696 1697 if (flag == NO_OPERATION) 1698 return (0); 1699 1700 if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY)) { 1701 device_printf(dev, "ATU unit is busy, cannot access\n"); 1702 return (EBUSY); 1703 } 1704 reg = e6000sw_readreg(sc, REG_GLOBAL, ATU_OPERATION); 1705 e6000sw_writereg(sc, REG_GLOBAL, ATU_OPERATION, 1706 (reg | ATU_UNIT_BUSY | flag)); 1707 if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY)) 1708 device_printf(dev, "Timeout while flushing ATU\n"); 1709 1710 return (0); 1711 } 1712 1713 static int 1714 e6000sw_vtu_flush(e6000sw_softc_t *sc) 1715 { 1716 1717 if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { 1718 device_printf(sc->dev, "VTU unit is busy, cannot access\n"); 1719 return (EBUSY); 1720 } 1721 1722 e6000sw_writereg(sc, REG_GLOBAL, VTU_OPERATION, VTU_FLUSH | VTU_BUSY); 1723 if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { 1724 device_printf(sc->dev, "Timeout while flushing VTU\n"); 1725 return (ETIMEDOUT); 1726 } 1727 1728 return (0); 1729 } 1730 1731 static int 1732 e6000sw_vtu_update(e6000sw_softc_t *sc, int purge, int vid, int fid, 1733 int members, int untagged) 1734 { 1735 int i, op; 1736 uint32_t data[2]; 1737 1738 if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { 1739 device_printf(sc->dev, "VTU unit is busy, cannot access\n"); 1740 return (EBUSY); 1741 } 1742 1743 *data = (vid & VTU_VID_MASK); 1744 if (purge == 0) 1745 *data |= VTU_VID_VALID; 1746 e6000sw_writereg(sc, REG_GLOBAL, VTU_VID, *data); 1747 1748 if (purge == 0) { 1749 data[0] = 0; 1750 data[1] = 0; 1751 for (i = 0; i < sc->num_ports; i++) { 1752 if ((untagged & (1 << i)) != 0) 1753 data[i / VTU_PPREG(sc)] |= 1754 VTU_PORT_UNTAGGED << VTU_PORT(sc, i); 1755 else if ((members & (1 << i)) != 0) 1756 data[i / VTU_PPREG(sc)] |= 1757 VTU_PORT_TAGGED << VTU_PORT(sc, i); 1758 else 1759 data[i / VTU_PPREG(sc)] |= 1760 VTU_PORT_DISCARD << VTU_PORT(sc, i); 1761 } 1762 e6000sw_writereg(sc, REG_GLOBAL, VTU_DATA, data[0]); 1763 e6000sw_writereg(sc, REG_GLOBAL, VTU_DATA2, data[1]); 1764 e6000sw_writereg(sc, REG_GLOBAL, VTU_FID, 1765 fid & VTU_FID_MASK(sc)); 1766 op = VTU_LOAD; 1767 } else 1768 op = VTU_PURGE; 1769 1770 e6000sw_writereg(sc, REG_GLOBAL, VTU_OPERATION, op | VTU_BUSY); 1771 if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { 1772 device_printf(sc->dev, "Timeout while flushing VTU\n"); 1773 return (ETIMEDOUT); 1774 } 1775 1776 return (0); 1777 } 1778