1 /*- 2 * Copyright (c) 2016 Hiroki Mori 3 * Copyright (c) 2013 Luiz Otavio O Souza. 4 * Copyright (c) 2011-2012 Stefan Bethke. 5 * Copyright (c) 2012 Adrian Chadd. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 /* 33 * This is Micrel KSZ8995MA driver code. KSZ8995MA use SPI bus on control. 34 * This code development on @SRCHACK's ksz8995ma board and FON2100 with 35 * gpiospi. 36 * etherswitchcfg command port option support addtag, ingress, striptag, 37 * dropuntagged. 38 */ 39 40 #include <sys/param.h> 41 #include <sys/bus.h> 42 #include <sys/errno.h> 43 #include <sys/kernel.h> 44 #include <sys/lock.h> 45 #include <sys/malloc.h> 46 #include <sys/module.h> 47 #include <sys/mutex.h> 48 #include <sys/socket.h> 49 #include <sys/sockio.h> 50 #include <sys/sysctl.h> 51 #include <sys/systm.h> 52 53 #include <net/if.h> 54 #include <net/if_var.h> 55 #include <net/ethernet.h> 56 #include <net/if_media.h> 57 #include <net/if_types.h> 58 59 #include <machine/bus.h> 60 #include <dev/mii/mii.h> 61 #include <dev/mii/miivar.h> 62 63 #include <dev/etherswitch/etherswitch.h> 64 65 #include <dev/spibus/spi.h> 66 67 #include "spibus_if.h" 68 #include "miibus_if.h" 69 #include "etherswitch_if.h" 70 71 #define KSZ8995MA_SPI_READ 0x03 72 #define KSZ8995MA_SPI_WRITE 0x02 73 74 #define KSZ8995MA_CID0 0x00 75 #define KSZ8995MA_CID1 0x01 76 77 #define KSZ8995MA_GC0 0x02 78 #define KSZ8995MA_GC1 0x03 79 #define KSZ8995MA_GC2 0x04 80 #define KSZ8995MA_GC3 0x05 81 82 #define KSZ8995MA_PORT_SIZE 0x10 83 84 #define KSZ8995MA_PC0_BASE 0x10 85 #define KSZ8995MA_PC1_BASE 0x11 86 #define KSZ8995MA_PC2_BASE 0x12 87 #define KSZ8995MA_PC3_BASE 0x13 88 #define KSZ8995MA_PC4_BASE 0x14 89 #define KSZ8995MA_PC5_BASE 0x15 90 #define KSZ8995MA_PC6_BASE 0x16 91 #define KSZ8995MA_PC7_BASE 0x17 92 #define KSZ8995MA_PC8_BASE 0x18 93 #define KSZ8995MA_PC9_BASE 0x19 94 #define KSZ8995MA_PC10_BASE 0x1a 95 #define KSZ8995MA_PC11_BASE 0x1b 96 #define KSZ8995MA_PC12_BASE 0x1c 97 #define KSZ8995MA_PC13_BASE 0x1d 98 99 #define KSZ8995MA_PS0_BASE 0x1e 100 101 #define KSZ8995MA_PC14_BASE 0x1f 102 103 #define KSZ8995MA_IAC0 0x6e 104 #define KSZ8995MA_IAC1 0x6f 105 #define KSZ8995MA_IDR8 0x70 106 #define KSZ8995MA_IDR7 0x71 107 #define KSZ8995MA_IDR6 0x72 108 #define KSZ8995MA_IDR5 0x73 109 #define KSZ8995MA_IDR4 0x74 110 #define KSZ8995MA_IDR3 0x75 111 #define KSZ8995MA_IDR2 0x76 112 #define KSZ8995MA_IDR1 0x77 113 #define KSZ8995MA_IDR0 0x78 114 115 #define KSZ8995MA_FAMILI_ID 0x95 116 #define KSZ8995MA_CHIP_ID 0x00 117 #define KSZ8995MA_CHIP_ID_MASK 0xf0 118 #define KSZ8995MA_START 0x01 119 #define KSZ8995MA_VLAN_ENABLE 0x80 120 #define KSZ8995MA_TAG_INS 0x04 121 #define KSZ8995MA_TAG_RM 0x02 122 #define KSZ8995MA_INGR_FILT 0x40 123 #define KSZ8995MA_DROP_NONPVID 0x20 124 125 #define KSZ8995MA_PDOWN 0x08 126 #define KSZ8995MA_STARTNEG 0x20 127 128 #define KSZ8995MA_MII_STAT 0x7808 129 #define KSZ8995MA_MII_PHYID_H 0x0022 130 #define KSZ8995MA_MII_PHYID_L 0x1450 131 #define KSZ8995MA_MII_AA 0x0401 132 133 #define KSZ8995MA_VLAN_TABLE_VALID 0x20 134 #define KSZ8995MA_VLAN_TABLE_READ 0x14 135 #define KSZ8995MA_VLAN_TABLE_WRITE 0x04 136 137 #define KSZ8995MA_MAX_PORT 5 138 139 MALLOC_DECLARE(M_KSZ8995MA); 140 MALLOC_DEFINE(M_KSZ8995MA, "ksz8995ma", "ksz8995ma data structures"); 141 142 struct ksz8995ma_softc { 143 struct mtx sc_mtx; /* serialize access to softc */ 144 device_t sc_dev; 145 int vlan_mode; 146 int media; /* cpu port media */ 147 int cpuport; /* which PHY is connected to the CPU */ 148 int phymask; /* PHYs we manage */ 149 int numports; /* number of ports */ 150 int ifpport[KSZ8995MA_MAX_PORT]; 151 int *portphy; 152 char **ifname; 153 device_t **miibus; 154 struct ifnet **ifp; 155 struct callout callout_tick; 156 etherswitch_info_t info; 157 }; 158 159 #define KSZ8995MA_LOCK(_sc) \ 160 mtx_lock(&(_sc)->sc_mtx) 161 #define KSZ8995MA_UNLOCK(_sc) \ 162 mtx_unlock(&(_sc)->sc_mtx) 163 #define KSZ8995MA_LOCK_ASSERT(_sc, _what) \ 164 mtx_assert(&(_sc)->sc_mtx, (_what)) 165 #define KSZ8995MA_TRYLOCK(_sc) \ 166 mtx_trylock(&(_sc)->sc_mtx) 167 168 #if defined(DEBUG) 169 #define DPRINTF(dev, args...) device_printf(dev, args) 170 #else 171 #define DPRINTF(dev, args...) 172 #endif 173 174 static inline int ksz8995ma_portforphy(struct ksz8995ma_softc *, int); 175 static void ksz8995ma_tick(void *); 176 static int ksz8995ma_ifmedia_upd(struct ifnet *); 177 static void ksz8995ma_ifmedia_sts(struct ifnet *, struct ifmediareq *); 178 static int ksz8995ma_readreg(device_t dev, int addr); 179 static int ksz8995ma_writereg(device_t dev, int addr, int value); 180 static void ksz8995ma_portvlanreset(device_t dev); 181 182 static int 183 ksz8995ma_probe(device_t dev) 184 { 185 int id0, id1; 186 struct ksz8995ma_softc *sc; 187 188 sc = device_get_softc(dev); 189 bzero(sc, sizeof(*sc)); 190 191 id0 = ksz8995ma_readreg(dev, KSZ8995MA_CID0); 192 id1 = ksz8995ma_readreg(dev, KSZ8995MA_CID1); 193 if (bootverbose) 194 device_printf(dev,"Chip Identifier Register %x %x\n", id0, id1); 195 196 /* check Product Code */ 197 if (id0 != KSZ8995MA_FAMILI_ID || (id1 & KSZ8995MA_CHIP_ID_MASK) != 198 KSZ8995MA_CHIP_ID) { 199 return (ENXIO); 200 } 201 202 device_set_desc_copy(dev, "Micrel KSZ8995MA SPI switch driver"); 203 return (BUS_PROBE_DEFAULT); 204 } 205 206 static int 207 ksz8995ma_attach_phys(struct ksz8995ma_softc *sc) 208 { 209 int phy, port, err; 210 char name[IFNAMSIZ]; 211 212 port = 0; 213 err = 0; 214 /* PHYs need an interface, so we generate a dummy one */ 215 snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(sc->sc_dev)); 216 for (phy = 0; phy < sc->numports; phy++) { 217 if (phy == sc->cpuport) 218 continue; 219 if (((1 << phy) & sc->phymask) == 0) 220 continue; 221 sc->ifpport[phy] = port; 222 sc->portphy[port] = phy; 223 sc->ifp[port] = if_alloc(IFT_ETHER); 224 sc->ifp[port]->if_softc = sc; 225 sc->ifp[port]->if_flags |= IFF_UP | IFF_BROADCAST | 226 IFF_DRV_RUNNING | IFF_SIMPLEX; 227 if_initname(sc->ifp[port], name, port); 228 sc->miibus[port] = malloc(sizeof(device_t), M_KSZ8995MA, 229 M_WAITOK | M_ZERO); 230 if (sc->miibus[port] == NULL) { 231 err = ENOMEM; 232 goto failed; 233 } 234 err = mii_attach(sc->sc_dev, sc->miibus[port], sc->ifp[port], 235 ksz8995ma_ifmedia_upd, ksz8995ma_ifmedia_sts, \ 236 BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0); 237 DPRINTF(sc->sc_dev, "%s attached to pseudo interface %s\n", 238 device_get_nameunit(*sc->miibus[port]), 239 sc->ifp[port]->if_xname); 240 if (err != 0) { 241 device_printf(sc->sc_dev, 242 "attaching PHY %d failed\n", 243 phy); 244 goto failed; 245 } 246 ++port; 247 } 248 sc->info.es_nports = port; 249 if (sc->cpuport != -1) { 250 /* cpu port is MAC5 on ksz8995ma */ 251 sc->ifpport[sc->cpuport] = port; 252 sc->portphy[port] = sc->cpuport; 253 ++sc->info.es_nports; 254 } 255 256 return (0); 257 258 failed: 259 for (phy = 0; phy < sc->numports; phy++) { 260 if (((1 << phy) & sc->phymask) == 0) 261 continue; 262 port = ksz8995ma_portforphy(sc, phy); 263 if (sc->miibus[port] != NULL) 264 device_delete_child(sc->sc_dev, (*sc->miibus[port])); 265 if (sc->ifp[port] != NULL) 266 if_free(sc->ifp[port]); 267 if (sc->ifname[port] != NULL) 268 free(sc->ifname[port], M_KSZ8995MA); 269 if (sc->miibus[port] != NULL) 270 free(sc->miibus[port], M_KSZ8995MA); 271 } 272 return (err); 273 } 274 275 static int 276 ksz8995ma_attach(device_t dev) 277 { 278 struct ksz8995ma_softc *sc; 279 int err, reg; 280 281 err = 0; 282 sc = device_get_softc(dev); 283 284 sc->sc_dev = dev; 285 mtx_init(&sc->sc_mtx, "ksz8995ma", NULL, MTX_DEF); 286 strlcpy(sc->info.es_name, device_get_desc(dev), 287 sizeof(sc->info.es_name)); 288 289 /* KSZ8995MA Defaults */ 290 sc->numports = KSZ8995MA_MAX_PORT; 291 sc->phymask = (1 << (KSZ8995MA_MAX_PORT + 1)) - 1; 292 sc->cpuport = -1; 293 sc->media = 100; 294 295 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 296 "cpuport", &sc->cpuport); 297 298 sc->info.es_nvlangroups = 16; 299 sc->info.es_vlan_caps = ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOT1Q; 300 301 sc->ifp = malloc(sizeof(struct ifnet *) * sc->numports, M_KSZ8995MA, 302 M_WAITOK | M_ZERO); 303 sc->ifname = malloc(sizeof(char *) * sc->numports, M_KSZ8995MA, 304 M_WAITOK | M_ZERO); 305 sc->miibus = malloc(sizeof(device_t *) * sc->numports, M_KSZ8995MA, 306 M_WAITOK | M_ZERO); 307 sc->portphy = malloc(sizeof(int) * sc->numports, M_KSZ8995MA, 308 M_WAITOK | M_ZERO); 309 310 if (sc->ifp == NULL || sc->ifname == NULL || sc->miibus == NULL || 311 sc->portphy == NULL) { 312 err = ENOMEM; 313 goto failed; 314 } 315 316 /* 317 * Attach the PHYs and complete the bus enumeration. 318 */ 319 err = ksz8995ma_attach_phys(sc); 320 if (err != 0) 321 goto failed; 322 323 bus_generic_probe(dev); 324 bus_enumerate_hinted_children(dev); 325 err = bus_generic_attach(dev); 326 if (err != 0) 327 goto failed; 328 329 callout_init(&sc->callout_tick, 0); 330 331 ksz8995ma_tick(sc); 332 333 /* start switch */ 334 sc->vlan_mode = 0; 335 reg = ksz8995ma_readreg(dev, KSZ8995MA_GC3); 336 ksz8995ma_writereg(dev, KSZ8995MA_GC3, 337 reg & ~KSZ8995MA_VLAN_ENABLE); 338 ksz8995ma_portvlanreset(dev); 339 ksz8995ma_writereg(dev, KSZ8995MA_CID1, KSZ8995MA_START); 340 341 return (0); 342 343 failed: 344 if (sc->portphy != NULL) 345 free(sc->portphy, M_KSZ8995MA); 346 if (sc->miibus != NULL) 347 free(sc->miibus, M_KSZ8995MA); 348 if (sc->ifname != NULL) 349 free(sc->ifname, M_KSZ8995MA); 350 if (sc->ifp != NULL) 351 free(sc->ifp, M_KSZ8995MA); 352 353 return (err); 354 } 355 356 static int 357 ksz8995ma_detach(device_t dev) 358 { 359 struct ksz8995ma_softc *sc; 360 int i, port; 361 362 sc = device_get_softc(dev); 363 364 callout_drain(&sc->callout_tick); 365 366 for (i = 0; i < KSZ8995MA_MAX_PORT; i++) { 367 if (((1 << i) & sc->phymask) == 0) 368 continue; 369 port = ksz8995ma_portforphy(sc, i); 370 if (sc->miibus[port] != NULL) 371 device_delete_child(dev, (*sc->miibus[port])); 372 if (sc->ifp[port] != NULL) 373 if_free(sc->ifp[port]); 374 free(sc->ifname[port], M_KSZ8995MA); 375 free(sc->miibus[port], M_KSZ8995MA); 376 } 377 378 free(sc->portphy, M_KSZ8995MA); 379 free(sc->miibus, M_KSZ8995MA); 380 free(sc->ifname, M_KSZ8995MA); 381 free(sc->ifp, M_KSZ8995MA); 382 383 bus_generic_detach(dev); 384 mtx_destroy(&sc->sc_mtx); 385 386 return (0); 387 } 388 389 /* 390 * Convert PHY number to port number. 391 */ 392 static inline int 393 ksz8995ma_portforphy(struct ksz8995ma_softc *sc, int phy) 394 { 395 396 return (sc->ifpport[phy]); 397 } 398 399 static inline struct mii_data * 400 ksz8995ma_miiforport(struct ksz8995ma_softc *sc, int port) 401 { 402 403 if (port < 0 || port > sc->numports) 404 return (NULL); 405 if (port == sc->cpuport) 406 return (NULL); 407 return (device_get_softc(*sc->miibus[port])); 408 } 409 410 static inline struct ifnet * 411 ksz8995ma_ifpforport(struct ksz8995ma_softc *sc, int port) 412 { 413 414 if (port < 0 || port > sc->numports) 415 return (NULL); 416 return (sc->ifp[port]); 417 } 418 419 /* 420 * Poll the status for all PHYs. 421 */ 422 static void 423 ksz8995ma_miipollstat(struct ksz8995ma_softc *sc) 424 { 425 int i, port; 426 struct mii_data *mii; 427 struct mii_softc *miisc; 428 429 KSZ8995MA_LOCK_ASSERT(sc, MA_NOTOWNED); 430 431 for (i = 0; i < KSZ8995MA_MAX_PORT; i++) { 432 if (i == sc->cpuport) 433 continue; 434 if (((1 << i) & sc->phymask) == 0) 435 continue; 436 port = ksz8995ma_portforphy(sc, i); 437 if ((*sc->miibus[port]) == NULL) 438 continue; 439 mii = device_get_softc(*sc->miibus[port]); 440 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) { 441 if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) != 442 miisc->mii_inst) 443 continue; 444 ukphy_status(miisc); 445 mii_phy_update(miisc, MII_POLLSTAT); 446 } 447 } 448 } 449 450 static void 451 ksz8995ma_tick(void *arg) 452 { 453 struct ksz8995ma_softc *sc; 454 455 sc = arg; 456 457 ksz8995ma_miipollstat(sc); 458 callout_reset(&sc->callout_tick, hz, ksz8995ma_tick, sc); 459 } 460 461 static void 462 ksz8995ma_lock(device_t dev) 463 { 464 struct ksz8995ma_softc *sc; 465 466 sc = device_get_softc(dev); 467 468 KSZ8995MA_LOCK_ASSERT(sc, MA_NOTOWNED); 469 KSZ8995MA_LOCK(sc); 470 } 471 472 static void 473 ksz8995ma_unlock(device_t dev) 474 { 475 struct ksz8995ma_softc *sc; 476 477 sc = device_get_softc(dev); 478 479 KSZ8995MA_LOCK_ASSERT(sc, MA_OWNED); 480 KSZ8995MA_UNLOCK(sc); 481 } 482 483 static etherswitch_info_t * 484 ksz8995ma_getinfo(device_t dev) 485 { 486 struct ksz8995ma_softc *sc; 487 488 sc = device_get_softc(dev); 489 490 return (&sc->info); 491 } 492 493 static int 494 ksz8995ma_getport(device_t dev, etherswitch_port_t *p) 495 { 496 struct ksz8995ma_softc *sc; 497 struct mii_data *mii; 498 struct ifmediareq *ifmr; 499 int phy, err; 500 int tag1, tag2, portreg; 501 502 sc = device_get_softc(dev); 503 ifmr = &p->es_ifmr; 504 505 if (p->es_port < 0 || p->es_port >= sc->numports) 506 return (ENXIO); 507 508 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { 509 tag1 = ksz8995ma_readreg(dev, KSZ8995MA_PC3_BASE + 510 KSZ8995MA_PORT_SIZE * p->es_port); 511 tag2 = ksz8995ma_readreg(dev, KSZ8995MA_PC4_BASE + 512 KSZ8995MA_PORT_SIZE * p->es_port); 513 p->es_pvid = (tag1 & 0x0f) << 8 | tag2; 514 515 portreg = ksz8995ma_readreg(dev, KSZ8995MA_PC0_BASE + 516 KSZ8995MA_PORT_SIZE * p->es_port); 517 if (portreg & KSZ8995MA_TAG_INS) 518 p->es_flags |= ETHERSWITCH_PORT_ADDTAG; 519 if (portreg & KSZ8995MA_TAG_RM) 520 p->es_flags |= ETHERSWITCH_PORT_STRIPTAG; 521 522 portreg = ksz8995ma_readreg(dev, KSZ8995MA_PC2_BASE + 523 KSZ8995MA_PORT_SIZE * p->es_port); 524 if (portreg & KSZ8995MA_DROP_NONPVID) 525 p->es_flags |= ETHERSWITCH_PORT_DROPUNTAGGED; 526 if (portreg & KSZ8995MA_INGR_FILT) 527 p->es_flags |= ETHERSWITCH_PORT_INGRESS; 528 } 529 530 phy = sc->portphy[p->es_port]; 531 mii = ksz8995ma_miiforport(sc, p->es_port); 532 if (sc->cpuport != -1 && phy == sc->cpuport) { 533 /* fill in fixed values for CPU port */ 534 p->es_flags |= ETHERSWITCH_PORT_CPU; 535 ifmr->ifm_count = 0; 536 if (sc->media == 100) 537 ifmr->ifm_current = ifmr->ifm_active = 538 IFM_ETHER | IFM_100_TX | IFM_FDX; 539 else 540 ifmr->ifm_current = ifmr->ifm_active = 541 IFM_ETHER | IFM_1000_T | IFM_FDX; 542 ifmr->ifm_mask = 0; 543 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID; 544 } else if (mii != NULL) { 545 err = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, 546 &mii->mii_media, SIOCGIFMEDIA); 547 if (err) 548 return (err); 549 } else { 550 return (ENXIO); 551 } 552 553 return (0); 554 } 555 556 static int 557 ksz8995ma_setport(device_t dev, etherswitch_port_t *p) 558 { 559 struct ksz8995ma_softc *sc; 560 struct mii_data *mii; 561 struct ifmedia *ifm; 562 struct ifnet *ifp; 563 int phy, err; 564 int portreg; 565 566 sc = device_get_softc(dev); 567 568 if (p->es_port < 0 || p->es_port >= sc->numports) 569 return (ENXIO); 570 571 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { 572 ksz8995ma_writereg(dev, KSZ8995MA_PC4_BASE + 573 KSZ8995MA_PORT_SIZE * p->es_port, p->es_pvid & 0xff); 574 portreg = ksz8995ma_readreg(dev, KSZ8995MA_PC3_BASE + 575 KSZ8995MA_PORT_SIZE * p->es_port); 576 ksz8995ma_writereg(dev, KSZ8995MA_PC3_BASE + 577 KSZ8995MA_PORT_SIZE * p->es_port, 578 (portreg & 0xf0) | ((p->es_pvid >> 8) & 0x0f)); 579 580 portreg = ksz8995ma_readreg(dev, KSZ8995MA_PC0_BASE + 581 KSZ8995MA_PORT_SIZE * p->es_port); 582 if (p->es_flags & ETHERSWITCH_PORT_ADDTAG) 583 portreg |= KSZ8995MA_TAG_INS; 584 else 585 portreg &= ~KSZ8995MA_TAG_INS; 586 if (p->es_flags & ETHERSWITCH_PORT_STRIPTAG) 587 portreg |= KSZ8995MA_TAG_RM; 588 else 589 portreg &= ~KSZ8995MA_TAG_RM; 590 ksz8995ma_writereg(dev, KSZ8995MA_PC0_BASE + 591 KSZ8995MA_PORT_SIZE * p->es_port, portreg); 592 593 portreg = ksz8995ma_readreg(dev, KSZ8995MA_PC2_BASE + 594 KSZ8995MA_PORT_SIZE * p->es_port); 595 if (p->es_flags & ETHERSWITCH_PORT_DROPUNTAGGED) 596 portreg |= KSZ8995MA_DROP_NONPVID; 597 else 598 portreg &= ~KSZ8995MA_DROP_NONPVID; 599 if (p->es_flags & ETHERSWITCH_PORT_INGRESS) 600 portreg |= KSZ8995MA_INGR_FILT; 601 else 602 portreg &= ~KSZ8995MA_INGR_FILT; 603 ksz8995ma_writereg(dev, KSZ8995MA_PC2_BASE + 604 KSZ8995MA_PORT_SIZE * p->es_port, portreg); 605 } 606 607 phy = sc->portphy[p->es_port]; 608 mii = ksz8995ma_miiforport(sc, p->es_port); 609 if (phy != sc->cpuport) { 610 if (mii == NULL) 611 return (ENXIO); 612 ifp = ksz8995ma_ifpforport(sc, p->es_port); 613 ifm = &mii->mii_media; 614 err = ifmedia_ioctl(ifp, &p->es_ifr, ifm, SIOCSIFMEDIA); 615 } 616 return (0); 617 } 618 619 static int 620 ksz8995ma_getvgroup(device_t dev, etherswitch_vlangroup_t *vg) 621 { 622 int data0, data1, data2; 623 int vlantab; 624 struct ksz8995ma_softc *sc; 625 626 sc = device_get_softc(dev); 627 628 if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) { 629 if (vg->es_vlangroup < sc->numports) { 630 vg->es_vid = ETHERSWITCH_VID_VALID; 631 vg->es_vid |= vg->es_vlangroup; 632 data0 = ksz8995ma_readreg(dev, KSZ8995MA_PC1_BASE + 633 KSZ8995MA_PORT_SIZE * vg->es_vlangroup); 634 vg->es_member_ports = data0 & 0x1f; 635 vg->es_untagged_ports = vg->es_member_ports; 636 vg->es_fid = 0; 637 } else { 638 vg->es_vid = 0; 639 } 640 } else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { 641 ksz8995ma_writereg(dev, KSZ8995MA_IAC0, 642 KSZ8995MA_VLAN_TABLE_READ); 643 ksz8995ma_writereg(dev, KSZ8995MA_IAC1, vg->es_vlangroup); 644 data2 = ksz8995ma_readreg(dev, KSZ8995MA_IDR2); 645 data1 = ksz8995ma_readreg(dev, KSZ8995MA_IDR1); 646 data0 = ksz8995ma_readreg(dev, KSZ8995MA_IDR0); 647 vlantab = data2 << 16 | data1 << 8 | data0; 648 if (data2 & KSZ8995MA_VLAN_TABLE_VALID) { 649 vg->es_vid = ETHERSWITCH_VID_VALID; 650 vg->es_vid |= vlantab & 0xfff; 651 vg->es_member_ports = (vlantab >> 16) & 0x1f; 652 vg->es_untagged_ports = vg->es_member_ports; 653 vg->es_fid = (vlantab >> 12) & 0x0f; 654 } else { 655 vg->es_fid = 0; 656 } 657 } 658 659 return (0); 660 } 661 662 static int 663 ksz8995ma_setvgroup(device_t dev, etherswitch_vlangroup_t *vg) 664 { 665 struct ksz8995ma_softc *sc; 666 int data0; 667 668 sc = device_get_softc(dev); 669 670 if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) { 671 data0 = ksz8995ma_readreg(dev, KSZ8995MA_PC1_BASE + 672 KSZ8995MA_PORT_SIZE * vg->es_vlangroup); 673 ksz8995ma_writereg(dev, KSZ8995MA_PC1_BASE + 674 KSZ8995MA_PORT_SIZE * vg->es_vlangroup, 675 (data0 & 0xe0) | (vg->es_member_ports & 0x1f)); 676 } else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { 677 if (vg->es_member_ports != 0) { 678 ksz8995ma_writereg(dev, KSZ8995MA_IDR2, 679 KSZ8995MA_VLAN_TABLE_VALID | 680 (vg->es_member_ports & 0x1f)); 681 ksz8995ma_writereg(dev, KSZ8995MA_IDR1, 682 vg->es_fid << 4 | vg->es_vid >> 8); 683 ksz8995ma_writereg(dev, KSZ8995MA_IDR0, 684 vg->es_vid & 0xff); 685 } else { 686 ksz8995ma_writereg(dev, KSZ8995MA_IDR2, 0); 687 ksz8995ma_writereg(dev, KSZ8995MA_IDR1, 0); 688 ksz8995ma_writereg(dev, KSZ8995MA_IDR0, 0); 689 } 690 ksz8995ma_writereg(dev, KSZ8995MA_IAC0, 691 KSZ8995MA_VLAN_TABLE_WRITE); 692 ksz8995ma_writereg(dev, KSZ8995MA_IAC1, vg->es_vlangroup); 693 } 694 695 return (0); 696 } 697 698 static int 699 ksz8995ma_getconf(device_t dev, etherswitch_conf_t *conf) 700 { 701 struct ksz8995ma_softc *sc; 702 703 sc = device_get_softc(dev); 704 705 /* Return the VLAN mode. */ 706 conf->cmd = ETHERSWITCH_CONF_VLAN_MODE; 707 conf->vlan_mode = sc->vlan_mode; 708 709 return (0); 710 } 711 712 static void 713 ksz8995ma_portvlanreset(device_t dev) 714 { 715 int i, data; 716 struct ksz8995ma_softc *sc; 717 718 sc = device_get_softc(dev); 719 720 for (i = 0; i < sc->numports; ++i) { 721 data = ksz8995ma_readreg(dev, KSZ8995MA_PC1_BASE + 722 KSZ8995MA_PORT_SIZE * i); 723 ksz8995ma_writereg(dev, KSZ8995MA_PC1_BASE + 724 KSZ8995MA_PORT_SIZE * i, (data & 0xe0) | 0x1f); 725 } 726 } 727 728 static int 729 ksz8995ma_setconf(device_t dev, etherswitch_conf_t *conf) 730 { 731 int reg; 732 struct ksz8995ma_softc *sc; 733 734 sc = device_get_softc(dev); 735 736 if ((conf->cmd & ETHERSWITCH_CONF_VLAN_MODE) == 0) 737 return (0); 738 739 if (conf->vlan_mode == ETHERSWITCH_VLAN_PORT) { 740 sc->vlan_mode = ETHERSWITCH_VLAN_PORT; 741 reg = ksz8995ma_readreg(dev, KSZ8995MA_GC3); 742 ksz8995ma_writereg(dev, KSZ8995MA_GC3, 743 reg & ~KSZ8995MA_VLAN_ENABLE); 744 ksz8995ma_portvlanreset(dev); 745 } else if (conf->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { 746 sc->vlan_mode = ETHERSWITCH_VLAN_DOT1Q; 747 reg = ksz8995ma_readreg(dev, KSZ8995MA_GC3); 748 ksz8995ma_writereg(dev, KSZ8995MA_GC3, 749 reg | KSZ8995MA_VLAN_ENABLE); 750 } else { 751 sc->vlan_mode = 0; 752 reg = ksz8995ma_readreg(dev, KSZ8995MA_GC3); 753 ksz8995ma_writereg(dev, KSZ8995MA_GC3, 754 reg & ~KSZ8995MA_VLAN_ENABLE); 755 ksz8995ma_portvlanreset(dev); 756 } 757 return (0); 758 } 759 760 static void 761 ksz8995ma_statchg(device_t dev) 762 { 763 764 DPRINTF(dev, "%s\n", __func__); 765 } 766 767 static int 768 ksz8995ma_ifmedia_upd(struct ifnet *ifp) 769 { 770 struct ksz8995ma_softc *sc; 771 struct mii_data *mii; 772 773 sc = ifp->if_softc; 774 mii = ksz8995ma_miiforport(sc, ifp->if_dunit); 775 776 DPRINTF(sc->sc_dev, "%s\n", __func__); 777 if (mii == NULL) 778 return (ENXIO); 779 mii_mediachg(mii); 780 return (0); 781 } 782 783 static void 784 ksz8995ma_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 785 { 786 struct ksz8995ma_softc *sc; 787 struct mii_data *mii; 788 789 sc = ifp->if_softc; 790 mii = ksz8995ma_miiforport(sc, ifp->if_dunit); 791 792 DPRINTF(sc->sc_dev, "%s\n", __func__); 793 794 if (mii == NULL) 795 return; 796 mii_pollstat(mii); 797 ifmr->ifm_active = mii->mii_media_active; 798 ifmr->ifm_status = mii->mii_media_status; 799 } 800 801 static int 802 ksz8995ma_readphy(device_t dev, int phy, int reg) 803 { 804 int portreg; 805 806 /* 807 * This is no mdio/mdc connection code. 808 * simulate MIIM Registers via the SPI interface 809 */ 810 if (reg == MII_BMSR) { 811 portreg = ksz8995ma_readreg(dev, KSZ8995MA_PS0_BASE + 812 KSZ8995MA_PORT_SIZE * phy); 813 return (KSZ8995MA_MII_STAT | 814 (portreg & 0x20 ? BMSR_LINK : 0x00) | 815 (portreg & 0x40 ? BMSR_ACOMP : 0x00)); 816 } else if (reg == MII_PHYIDR1) { 817 return (KSZ8995MA_MII_PHYID_H); 818 } else if (reg == MII_PHYIDR2) { 819 return (KSZ8995MA_MII_PHYID_L); 820 } else if (reg == MII_ANAR) { 821 portreg = ksz8995ma_readreg(dev, KSZ8995MA_PC12_BASE + 822 KSZ8995MA_PORT_SIZE * phy); 823 return (KSZ8995MA_MII_AA | (portreg & 0x0f) << 5); 824 } else if (reg == MII_ANLPAR) { 825 portreg = ksz8995ma_readreg(dev, KSZ8995MA_PS0_BASE + 826 KSZ8995MA_PORT_SIZE * phy); 827 return (((portreg & 0x0f) << 5) | 0x01); 828 } 829 830 return (0); 831 } 832 833 static int 834 ksz8995ma_writephy(device_t dev, int phy, int reg, int data) 835 { 836 int portreg; 837 838 /* 839 * This is no mdio/mdc connection code. 840 * simulate MIIM Registers via the SPI interface 841 */ 842 if (reg == MII_BMCR) { 843 portreg = ksz8995ma_readreg(dev, KSZ8995MA_PC13_BASE + 844 KSZ8995MA_PORT_SIZE * phy); 845 if (data & BMCR_PDOWN) 846 portreg |= KSZ8995MA_PDOWN; 847 else 848 portreg &= ~KSZ8995MA_PDOWN; 849 if (data & BMCR_STARTNEG) 850 portreg |= KSZ8995MA_STARTNEG; 851 else 852 portreg &= ~KSZ8995MA_STARTNEG; 853 ksz8995ma_writereg(dev, KSZ8995MA_PC13_BASE + 854 KSZ8995MA_PORT_SIZE * phy, portreg); 855 } else if (reg == MII_ANAR) { 856 portreg = ksz8995ma_readreg(dev, KSZ8995MA_PC12_BASE + 857 KSZ8995MA_PORT_SIZE * phy); 858 portreg &= 0xf; 859 portreg |= ((data >> 5) & 0x0f); 860 ksz8995ma_writereg(dev, KSZ8995MA_PC12_BASE + 861 KSZ8995MA_PORT_SIZE * phy, portreg); 862 } 863 return (0); 864 } 865 866 static int 867 ksz8995ma_readreg(device_t dev, int addr) 868 { 869 uint8_t txBuf[8], rxBuf[8]; 870 struct spi_command cmd; 871 int err; 872 873 memset(&cmd, 0, sizeof(cmd)); 874 memset(txBuf, 0, sizeof(txBuf)); 875 memset(rxBuf, 0, sizeof(rxBuf)); 876 877 /* read spi */ 878 txBuf[0] = KSZ8995MA_SPI_READ; 879 txBuf[1] = addr; 880 cmd.tx_cmd = &txBuf; 881 cmd.rx_cmd = &rxBuf; 882 cmd.tx_cmd_sz = 3; 883 cmd.rx_cmd_sz = 3; 884 err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); 885 if (err) 886 return(0); 887 888 return (rxBuf[2]); 889 } 890 891 static int 892 ksz8995ma_writereg(device_t dev, int addr, int value) 893 { 894 uint8_t txBuf[8], rxBuf[8]; 895 struct spi_command cmd; 896 int err; 897 898 memset(&cmd, 0, sizeof(cmd)); 899 memset(txBuf, 0, sizeof(txBuf)); 900 memset(rxBuf, 0, sizeof(rxBuf)); 901 902 /* write spi */ 903 txBuf[0] = KSZ8995MA_SPI_WRITE; 904 txBuf[1] = addr; 905 txBuf[2] = value; 906 cmd.tx_cmd = &txBuf; 907 cmd.rx_cmd = &rxBuf; 908 cmd.tx_cmd_sz = 3; 909 cmd.rx_cmd_sz = 3; 910 err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); 911 if (err) 912 return(0); 913 914 return (0); 915 } 916 917 static device_method_t ksz8995ma_methods[] = { 918 /* Device interface */ 919 DEVMETHOD(device_probe, ksz8995ma_probe), 920 DEVMETHOD(device_attach, ksz8995ma_attach), 921 DEVMETHOD(device_detach, ksz8995ma_detach), 922 923 /* bus interface */ 924 DEVMETHOD(bus_add_child, device_add_child_ordered), 925 926 /* MII interface */ 927 DEVMETHOD(miibus_readreg, ksz8995ma_readphy), 928 DEVMETHOD(miibus_writereg, ksz8995ma_writephy), 929 DEVMETHOD(miibus_statchg, ksz8995ma_statchg), 930 931 /* etherswitch interface */ 932 DEVMETHOD(etherswitch_lock, ksz8995ma_lock), 933 DEVMETHOD(etherswitch_unlock, ksz8995ma_unlock), 934 DEVMETHOD(etherswitch_getinfo, ksz8995ma_getinfo), 935 DEVMETHOD(etherswitch_readreg, ksz8995ma_readreg), 936 DEVMETHOD(etherswitch_writereg, ksz8995ma_writereg), 937 DEVMETHOD(etherswitch_readphyreg, ksz8995ma_readphy), 938 DEVMETHOD(etherswitch_writephyreg, ksz8995ma_writephy), 939 DEVMETHOD(etherswitch_getport, ksz8995ma_getport), 940 DEVMETHOD(etherswitch_setport, ksz8995ma_setport), 941 DEVMETHOD(etherswitch_getvgroup, ksz8995ma_getvgroup), 942 DEVMETHOD(etherswitch_setvgroup, ksz8995ma_setvgroup), 943 DEVMETHOD(etherswitch_setconf, ksz8995ma_setconf), 944 DEVMETHOD(etherswitch_getconf, ksz8995ma_getconf), 945 946 DEVMETHOD_END 947 }; 948 949 DEFINE_CLASS_0(ksz8995ma, ksz8995ma_driver, ksz8995ma_methods, 950 sizeof(struct ksz8995ma_softc)); 951 static devclass_t ksz8995ma_devclass; 952 953 DRIVER_MODULE(ksz8995ma, spibus, ksz8995ma_driver, ksz8995ma_devclass, 0, 0); 954 DRIVER_MODULE(miibus, ksz8995ma, miibus_driver, miibus_devclass, 0, 0); 955 DRIVER_MODULE(etherswitch, ksz8995ma, etherswitch_driver, etherswitch_devclass, 956 0, 0); 957 MODULE_VERSION(ksz8995ma, 1); 958 MODULE_DEPEND(ksz8995ma, spibus, 1, 1, 1); /* XXX which versions? */ 959 MODULE_DEPEND(ksz8995ma, miibus, 1, 1, 1); /* XXX which versions? */ 960 MODULE_DEPEND(ksz8995ma, etherswitch, 1, 1, 1); /* XXX which versions? */ 961