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