1 /* 2 * Copyright (c) 2008 The DragonFly Project. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 3. Neither the name of The DragonFly Project nor the names of its 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific, prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * $FreeBSD-4.7: /usr/src/sys/pci/silan.c,v 1.0 2003/01/10 gaoyonghong $ 32 */ 33 34 #include <sys/param.h> 35 #include <sys/bus.h> 36 #include <sys/endian.h> 37 #include <sys/kernel.h> 38 #include <sys/interrupt.h> 39 #include <sys/malloc.h> 40 #include <sys/mbuf.h> 41 #include <sys/resource.h> 42 #include <sys/rman.h> 43 #include <sys/socket.h> 44 #include <sys/sockio.h> 45 #include <sys/systm.h> 46 47 #include "pcidevs.h" 48 #include <bus/pci/pcireg.h> 49 #include <bus/pci/pcivar.h> 50 51 #include <machine/clock.h> 52 53 #include <net/bpf.h> 54 #include <net/ethernet.h> 55 #include <net/ifq_var.h> 56 #include <net/if.h> 57 #include <net/if_arp.h> 58 #include <net/if_dl.h> 59 #include <net/if_media.h> 60 #include <net/if_var.h> 61 62 #include <vm/pmap.h> 63 #include <vm/vm.h> 64 65 #include "if_slnreg.h" 66 #include "if_slnvar.h" 67 68 /* Default to using PIO access for netcard driver */ 69 #define SL_USEIOSPACE 70 71 #ifdef SLN_DEBUG 72 #define PDEBUG(fmt, args...) kprintf("%s: " fmt "\n" , __func__ , ## args) 73 #else 74 #define PDEBUG(fmt, args...) 75 #endif 76 77 static const struct sln_dev { 78 uint16_t vid; 79 uint16_t did; 80 const char *desc; 81 } sln_devs[] = { 82 {PCI_VENDOR_SILAN, PCI_PRODUCT_SILAN_SC92031, 83 "Silan SC92031 Fast Ethernet" }, 84 {PCI_VENDOR_SILAN, PCI_PRODUCT_SILAN_8139D, 85 "Silan Rsltek 8139D Fast Ethernet" }, 86 {0, 0, NULL} 87 }; 88 89 static int sln_probe(device_t); 90 static int sln_attach(device_t); 91 static int sln_detach(device_t); 92 static int sln_shutdown(device_t); 93 static int sln_suspend(device_t); 94 static int sln_resume(device_t); 95 96 static void sln_reset(struct sln_softc *); 97 static void sln_init(void *); 98 99 static void sln_tx(struct ifnet *, struct ifaltq_subque *); 100 static void sln_rx(struct sln_softc *); 101 static void sln_tx_intr(struct sln_softc *); 102 static void sln_media_intr(struct sln_softc *); 103 static void sln_interrupt(void *); 104 static int sln_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *); 105 static void sln_stop(struct sln_softc *); 106 static void sln_watchdog(struct ifnet *); 107 108 static int sln_media_upd(struct ifnet *); 109 110 static void sln_media_stat(struct ifnet *, struct ifmediareq *); 111 static void sln_mii_cmd(struct sln_softc *, uint32_t, u_long *); 112 static void sln_media_cfg(struct sln_softc *); 113 static void sln_mac_cfg(struct sln_softc *); 114 static uint32_t sln_ether_crc32(caddr_t); 115 static void sln_set_multi(struct sln_softc *); 116 static void sln_init_tx(struct sln_softc *); 117 static void sln_tick(void *); 118 119 #ifdef SL_USEIOSPACE 120 #define SL_RID SL_PCI_IOAD 121 #define SL_RES SYS_RES_IOPORT 122 #else 123 #define SL_RID SL_PCI_MEMAD 124 #define SL_RES SYS_RES_MEMORY 125 #endif 126 127 static device_method_t sln_methods[] = { 128 DEVMETHOD(device_probe, sln_probe), 129 DEVMETHOD(device_attach, sln_attach), 130 DEVMETHOD(device_detach, sln_detach), 131 DEVMETHOD(device_shutdown, sln_shutdown), 132 DEVMETHOD(device_suspend, sln_suspend), 133 DEVMETHOD(device_resume, sln_resume), 134 135 DEVMETHOD(bus_print_child, bus_generic_print_child), 136 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 137 138 DEVMETHOD_END 139 }; 140 141 static driver_t sln_driver = { 142 "sln", 143 sln_methods, 144 sizeof(struct sln_softc) 145 }; 146 147 static devclass_t sln_devclass; 148 149 DRIVER_MODULE(sln, pci, sln_driver, sln_devclass, NULL, NULL); 150 151 static int 152 sln_probe(struct device *dev) 153 { 154 const struct sln_dev *d; 155 uint16_t did, vid; 156 157 vid = pci_get_vendor(dev); 158 did = pci_get_device(dev); 159 160 for (d = sln_devs; d->desc != NULL; d++) { 161 if (vid == d->vid && did == d->did) { 162 device_set_desc(dev, d->desc); 163 return 0; 164 } 165 } 166 return ENXIO; 167 } 168 169 /* the chip reset */ 170 static void 171 sln_reset(struct sln_softc *sc) 172 { 173 SLN_WRITE_4(sc, SL_CFG0, SL_SOFT_RESET); 174 DELAY(200000); 175 SLN_WRITE_4(sc, SL_CFG0, 0x0); 176 DELAY(10000); 177 } 178 179 /* Attach the interface. Allocate softc structures */ 180 static int 181 sln_attach(device_t dev) 182 { 183 struct sln_softc *sc = device_get_softc(dev); 184 struct ifnet *ifp = &sc->arpcom.ac_if; 185 unsigned char eaddr[ETHER_ADDR_LEN]; 186 int rid; 187 int error = 0; 188 189 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 190 191 /* TODO: power state change */ 192 193 pci_enable_busmaster(dev); 194 195 rid = SL_RID; 196 sc->sln_res = bus_alloc_resource_any(dev, SL_RES, &rid, RF_ACTIVE); 197 if (sc->sln_res == NULL) { 198 device_printf(dev, "couldn't map ports/memory\n"); 199 error = ENXIO; 200 goto fail; 201 } 202 sc->sln_bustag = rman_get_bustag(sc->sln_res); 203 sc->sln_bushandle = rman_get_bushandle(sc->sln_res); 204 205 /* alloc pci irq */ 206 rid = 0; 207 sc->sln_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 208 RF_SHAREABLE | RF_ACTIVE); 209 if (sc->sln_irq == NULL) { 210 device_printf(dev, "couldn't map interrupt\n"); 211 bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res); 212 error = ENXIO; 213 goto fail; 214 } 215 216 /* Get MAC address */ 217 ((uint32_t *)(&eaddr))[0] = be32toh(SLN_READ_4(sc, SL_MAC_ADDR0)); 218 ((uint16_t *)(&eaddr))[2] = be16toh(SLN_READ_4(sc, SL_MAC_ADDR1)); 219 220 /* alloc rx buffer space */ 221 sc->sln_bufdata.sln_rx_buf = contigmalloc(SL_RX_BUFLEN, 222 M_DEVBUF, M_WAITOK, 0, 0xffffffff, PAGE_SIZE, 0); 223 if (sc->sln_bufdata.sln_rx_buf == NULL) { 224 device_printf(dev, "no memory for rx buffers!\n"); 225 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sln_irq); 226 bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res); 227 error = ENXIO; 228 goto fail; 229 } 230 callout_init(&sc->sln_state); 231 232 ifp->if_softc = sc; 233 ifp->if_mtu = ETHERMTU; 234 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 235 ifp->if_init = sln_init; 236 ifp->if_start = sln_tx; 237 ifp->if_ioctl = sln_ioctl; 238 ifp->if_watchdog = sln_watchdog; 239 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN); 240 ifq_set_ready(&ifp->if_snd); 241 242 /* initial media */ 243 ifmedia_init(&sc->ifmedia, 0, sln_media_upd, sln_media_stat); 244 245 /* supported media types */ 246 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL); 247 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T, 0, NULL); 248 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_HDX, 0, NULL); 249 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL); 250 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX, 0, NULL); 251 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_HDX, 0, NULL); 252 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL); 253 254 /* Choose a default media. */ 255 ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO); 256 257 ether_ifattach(ifp, eaddr, NULL); 258 259 ifq_set_cpuid(&ifp->if_snd, rman_get_cpuid(sc->sln_irq)); 260 261 error = bus_setup_intr(dev, sc->sln_irq, INTR_MPSAFE, sln_interrupt, sc, 262 &sc->sln_intrhand, ifp->if_serializer); 263 if (error) { 264 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sln_irq); 265 bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res); 266 ether_ifdetach(ifp); 267 device_printf(dev, "couldn't set up irq\n"); 268 goto fail; 269 } 270 271 return 0; 272 fail: 273 return error; 274 } 275 276 /* Stop the adapter and free any mbufs allocated to the RX and TX buffers */ 277 static void 278 sln_stop(struct sln_softc *sc) 279 { 280 struct ifnet *ifp = &sc->arpcom.ac_if; 281 int i; 282 283 ASSERT_SERIALIZED(ifp->if_serializer); 284 285 ifp->if_timer = 0; 286 callout_stop(&sc->sln_state); 287 288 /* disable Tx/Rx */ 289 sc->txcfg &= ~SL_TXCFG_EN; 290 sc->rxcfg &= ~SL_RXCFG_EN; 291 SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg); 292 SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg); 293 294 /* Clear interrupt */ 295 SLN_WRITE_4(sc, SL_INT_MASK, 0); 296 SLN_READ_4(sc, SL_INT_STATUS); 297 298 /* Free the TX list buffers */ 299 for (i = 0; i < SL_TXD_CNT; i++) { 300 if (sc->sln_bufdata.sln_tx_buf[i] != NULL) { 301 m_freem(sc->sln_bufdata.sln_tx_buf[i]); 302 sc->sln_bufdata.sln_tx_buf[i] = NULL; 303 SLN_WRITE_4(sc, SL_TSAD0 + i * 4, 0); 304 } 305 } 306 307 ifp->if_flags &= ~IFF_RUNNING; 308 ifq_clr_oactive(&ifp->if_snd); 309 } 310 311 static int 312 sln_detach(device_t dev) 313 { 314 struct sln_softc *sc = device_get_softc(dev); 315 struct ifnet *ifp = &sc->arpcom.ac_if; 316 317 lwkt_serialize_enter(ifp->if_serializer); 318 sln_stop(sc); 319 bus_teardown_intr(dev, sc->sln_irq, sc->sln_intrhand); 320 lwkt_serialize_exit(ifp->if_serializer); 321 322 ether_ifdetach(ifp); 323 324 bus_generic_detach(dev); 325 326 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sln_irq); 327 bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res); 328 329 contigfree(sc->sln_bufdata.sln_rx_buf, SL_RX_BUFLEN, M_DEVBUF); 330 331 return 0; 332 } 333 334 static int 335 sln_media_upd(struct ifnet *ifp) 336 { 337 struct sln_softc *sc = ifp->if_softc; 338 struct ifmedia *ifm = &sc->ifmedia; 339 340 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) 341 return EINVAL; 342 343 if (ifp->if_flags & IFF_UP) 344 sln_init(sc); 345 346 return 0; 347 } 348 349 static void 350 sln_media_stat(struct ifnet *ifp, struct ifmediareq *ifmr) 351 { 352 struct sln_softc *sc = ifp->if_softc; 353 u_long phys[2]; 354 uint32_t temp; 355 356 ifmr->ifm_status = IFM_AVALID; 357 ifmr->ifm_active = IFM_ETHER; 358 359 phys[0] = SL_MII_STAT; 360 sln_mii_cmd(sc, SL_MII0_READ, phys); 361 362 if (phys[1] & SL_MIISTAT_LINK) 363 ifmr->ifm_status |= IFM_ACTIVE; 364 365 temp = SLN_READ_4(sc, SL_PHY_CTRL); 366 367 if ((temp & (SL_PHYCTL_DUX | SL_PHYCTL_SPD100 | SL_PHYCTL_SPD10)) == 0x60800000) 368 ifmr->ifm_active |= IFM_AUTO; 369 else if ((temp & (SL_PHYCTL_DUX | SL_PHYCTL_SPD100)) == 0x40800000) 370 ifmr->ifm_active |= IFM_100_TX | IFM_FDX; 371 else if ((temp & SL_PHYCTL_SPD100) == 0x40000000) 372 ifmr->ifm_active |= IFM_100_TX | IFM_HDX; 373 else if ((temp & (SL_PHYCTL_DUX | SL_PHYCTL_SPD10)) == 0x20800000) 374 ifmr->ifm_active |= IFM_10_T | IFM_FDX; 375 else if ((temp & SL_PHYCTL_SPD10) == 0x20000000) 376 ifmr->ifm_active |= IFM_10_T | IFM_HDX; 377 378 sln_mii_cmd(sc, SL_MII0_SCAN, phys); 379 } 380 381 /* command selected in MII command register */ 382 static void 383 sln_mii_cmd(struct sln_softc *sc, uint32_t cmd, u_long *phys) 384 { 385 uint32_t mii_status; 386 387 SLN_WRITE_4(sc, SL_MII_CMD0, SL_MII0_DIVEDER); 388 389 do { 390 mii_status = 0; 391 DELAY(10); 392 mii_status = SLN_READ_4(sc, SL_MII_STATUS); 393 } while (mii_status & SL_MIISTAT_BUSY); 394 395 switch (cmd) { 396 case SL_MII0_SCAN: 397 SLN_WRITE_4(sc, SL_MII_CMD1, 0x1 << 6); 398 SLN_WRITE_4(sc, SL_MII_CMD0, SL_MII0_DIVEDER | SL_MII0_SCAN); 399 break; 400 401 case SL_MII0_READ: 402 SLN_WRITE_4(sc, SL_MII_CMD1, phys[0] << 6); 403 SLN_WRITE_4(sc, SL_MII_CMD0, SL_MII0_DIVEDER | SL_MII0_READ); 404 break; 405 406 default: /* WRITE */ 407 SLN_WRITE_4(sc, SL_MII_CMD1, phys[0] << 6 | phys[1] << 11); 408 SLN_WRITE_4(sc, SL_MII_CMD0, SL_MII0_DIVEDER | SL_MII0_WRITE); 409 break; 410 } 411 412 do { 413 DELAY(10); 414 mii_status = SLN_READ_4(sc, SL_MII_STATUS); 415 } while (mii_status & SL_MIISTAT_BUSY); 416 417 if (SL_MII0_READ == cmd) 418 phys[1] = (mii_status >> 13) & 0xffff; 419 } 420 421 /* Set media speed and duplex mode */ 422 static void 423 sln_media_cfg(struct sln_softc *sc) 424 { 425 u_long phys[2]; 426 uint32_t mediatype; 427 uint32_t temp; 428 429 mediatype = (&sc->ifmedia)->ifm_cur->ifm_media; 430 431 temp = SLN_READ_4(sc, SL_PHY_CTRL); 432 temp &= ~(SL_PHYCTL_DUX | SL_PHYCTL_SPD100 | SL_PHYCTL_SPD10); 433 temp |= (SL_PHYCTL_ANE | SL_PHYCTL_RESET); 434 435 /************************************************/ 436 /* currently set media word by selected media */ 437 /* */ 438 /* IFM_ETHER = 0x00000020 */ 439 /* IFM_AUTO=0, IFM_10_T=3, IFM_100_TX=6 */ 440 /* IFM_FDX=0x00100000 IFM_HDX=0x00200000 */ 441 /************************************************/ 442 switch (mediatype) { 443 case 0x00000020: 444 PDEBUG(" autoselet supported\n"); 445 temp |= (SL_PHYCTL_DUX | SL_PHYCTL_SPD100 | SL_PHYCTL_SPD10); 446 sc->ifmedia.ifm_media = IFM_ETHER | IFM_AUTO; 447 ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO); 448 break; 449 case 0x23: 450 case 0x00200023: 451 PDEBUG(" 10Mbps half_duplex supported\n"); 452 temp |= SL_PHYCTL_SPD10; 453 sc->ifmedia.ifm_media = IFM_ETHER | IFM_10_T | IFM_HDX; 454 ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_HDX); 455 break; 456 457 case 0x00100023: 458 PDEBUG("10Mbps full_duplex supported\n"); 459 temp |= (SL_PHYCTL_SPD10 | SL_PHYCTL_DUX); 460 sc->ifmedia.ifm_media = IFM_ETHER | IFM_10_T | IFM_FDX; 461 ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX); 462 break; 463 464 case 0x26: 465 case 0x00200026: 466 PDEBUG("100Mbps half_duplex supported\n"); 467 temp |= SL_PHYCTL_SPD100; 468 sc->ifmedia.ifm_media = IFM_ETHER | IFM_100_TX | IFM_HDX; 469 ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_HDX); 470 break; 471 472 case 0x00100026: 473 PDEBUG("100Mbps full_duplex supported\n"); 474 temp |= (SL_PHYCTL_SPD100 | SL_PHYCTL_DUX); 475 sc->ifmedia.ifm_media = IFM_ETHER | IFM_100_TX | IFM_FDX; 476 ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_FDX); 477 break; 478 479 default: 480 break; 481 } 482 483 SLN_WRITE_4(sc, SL_PHY_CTRL, temp); 484 485 DELAY(10000); 486 temp &= ~SL_PHYCTL_RESET; 487 SLN_WRITE_4(sc, SL_PHY_CTRL, temp); 488 489 DELAY(1000); 490 phys[0] = SL_MII_JAB; 491 phys[1] = SL_PHY_16_JAB_ENB | SL_PHY_16_PORT_ENB; 492 sln_mii_cmd(sc, SL_MII0_WRITE, phys); 493 494 sc->connect = 0; 495 sln_mii_cmd(sc, SL_MII0_SCAN, phys); 496 } 497 498 static void 499 sln_mac_cfg(struct sln_softc *sc) 500 { 501 struct ifnet *ifp = &sc->arpcom.ac_if; 502 u_long flowcfg = 0; 503 504 /* Set the initial TX/RX/Flow Control configuration */ 505 sc->rxcfg = SL_RXCFG_LOW_THRESHOLD | SL_RXCFG_HIGH_THRESHOLD; 506 sc->txcfg = TX_CFG_DEFAULT; 507 508 if (sc->txenablepad) 509 sc->txcfg |= 0x20000000; 510 511 if (sc->media_speed == IFM_10_T) 512 sc->txcfg |= SL_TXCFG_DATARATE; 513 514 if (sc->media_duplex == IFM_FDX) { 515 sc->rxcfg |= SL_RXCFG_FULLDX; 516 sc->txcfg |= SL_TXCFG_FULLDX; 517 flowcfg = SL_FLOWCTL_FULLDX | SL_FLOWCTL_EN; 518 } else { 519 sc->rxcfg &= ~SL_RXCFG_FULLDX; 520 sc->txcfg &= ~SL_TXCFG_FULLDX; 521 } 522 523 /* if promiscuous mode, set the allframes bit. */ 524 if (ifp->if_flags & IFF_PROMISC) 525 sc->rxcfg |= (SL_RXCFG_EN | SL_RXCFG_RCV_SMALL | SL_RXCFG_RCV_HUGE | SL_RXCFG_RCV_ERR | SL_RXCFG_RCV_BROAD | SL_RXCFG_RCV_MULTI | SL_RXCFG_RCV_ALL); 526 else 527 sc->rxcfg &= ~(SL_RXCFG_EN | SL_RXCFG_RCV_SMALL | SL_RXCFG_RCV_HUGE | SL_RXCFG_RCV_ERR | SL_RXCFG_RCV_BROAD | SL_RXCFG_RCV_MULTI | SL_RXCFG_RCV_ALL); 528 529 /* Set capture broadcast bit to capture broadcast frames */ 530 if (ifp->if_flags & IFF_BROADCAST) 531 sc->rxcfg |= SL_RXCFG_EN | SL_RXCFG_RCV_BROAD; 532 else 533 sc->rxcfg &= ~(SL_RXCFG_EN | SL_RXCFG_RCV_BROAD); 534 535 /* Program the multicast filter, if necessary */ 536 sln_set_multi(sc); 537 538 SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg); 539 SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg); 540 SLN_WRITE_4(sc, SL_FLOW_CTRL, flowcfg); 541 } 542 543 static u_char shade_map[] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 544 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf }; 545 546 /* Calculate CRC32 of a multicast group address */ 547 static uint32_t 548 sln_ether_crc32(caddr_t addr) 549 { 550 uint32_t crc, crcr; 551 int i, j; 552 unsigned char data = 0; 553 /* Compute CRC for the address value. */ 554 555 crc = 0xFFFFFFFF; /* initial value */ 556 557 for (i = ETHER_ADDR_LEN; i > 0; i--) { 558 data = *addr++; 559 560 for (j = 0; j < 8; j++) { 561 if (((data & 0x1) ^ (crc & 0x1)) != 0) { 562 crc >>= 1; 563 crc ^= 0xEDB88320; 564 } else { 565 crc >>= 1; 566 } 567 data >>= 1; 568 } 569 } 570 571 crcr = shade_map[crc >> 28]; 572 crcr |= (shade_map[(crc >> 24) & 0xf] << 4); 573 crcr |= (shade_map[(crc >> 20) & 0xf] << 8); 574 crcr |= (shade_map[(crc >> 16) & 0xf] << 12); 575 crcr |= (shade_map[(crc >> 12) & 0xf] << 16); 576 crcr |= (shade_map[(crc >> 8) & 0xf] << 20); 577 crcr |= (shade_map[(crc >> 4) & 0xf] << 24); 578 crcr |= (shade_map[crc & 0xf] << 28); 579 580 return crcr; 581 } 582 583 /* Program the 64-bit multicast hash filter */ 584 static void 585 sln_set_multi(struct sln_softc *sc) 586 { 587 struct ifnet *ifp = &sc->arpcom.ac_if; 588 uint32_t crc = 0; 589 uint32_t mc_g[2] = {0, 0}; 590 struct ifmultiaddr *ifma; 591 int j; 592 593 if (ifp->if_flags & IFF_PROMISC) { 594 kprintf("Promisc mode is enabled\n"); 595 sc->rxcfg |= SL_RXCFG_EN | SL_RXCFG_RCV_MULTI; 596 mc_g[0] = mc_g[1] = 0xFFFFFFFF; 597 } else if (ifp->if_flags & IFF_ALLMULTI) { 598 kprintf("Allmulti mode is enabled\n"); 599 sc->rxcfg |= SL_RXCFG_EN | SL_RXCFG_RCV_MULTI; 600 mc_g[0] = mc_g[1] = 0xFFFFFFFF; 601 } else if (ifp->if_flags & IFF_MULTICAST) { 602 kprintf("Multicast mode is enabled\n"); 603 sc->rxcfg |= SL_RXCFG_EN | SL_RXCFG_RCV_MULTI; 604 605 /* first, zero all the existing hash bits */ 606 mc_g[0] = mc_g[1] = 0; 607 608 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 609 j = 0; 610 611 if ((ifma->ifma_addr->sa_family) != AF_LINK) 612 continue; 613 614 crc = ~sln_ether_crc32(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); 615 crc >>= 24; 616 617 if (crc & 0x1) 618 j |= 0x2; 619 if (crc & 0x2) 620 j |= 0x1; 621 if (crc & 0x10) 622 j |= 0x20; 623 if (crc & 0x20) 624 j |= 0x10; 625 if (crc & 0x40) 626 j |= 0x8; 627 if (crc & 0x80) 628 j |= 0x4; 629 630 if (j > 31) 631 mc_g[0] |= (0x1 << (j - 32)); 632 else 633 mc_g[1] |= (0x1 << j); 634 } 635 } else { 636 sc->rxcfg &= ~(SL_RXCFG_EN | SL_RXCFG_RCV_MULTI); 637 } 638 639 SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg); 640 SLN_WRITE_4(sc, SL_MULTI_GROUP0, mc_g[0]); 641 SLN_WRITE_4(sc, SL_MULTI_GROUP1, mc_g[1]); 642 } 643 644 /* Initialize the TX/Rx descriptors */ 645 static void 646 sln_init_tx(struct sln_softc *sc) 647 { 648 int i; 649 650 sc->sln_bufdata.cur_tx = 0; 651 sc->sln_bufdata.dirty_tx = 0; 652 653 for (i = 0; i < SL_TXD_CNT; i++) { 654 sc->sln_bufdata.sln_tx_buf[i] = NULL; 655 SLN_WRITE_4(sc, SL_TSAD0 + (i * 4), 0); 656 } 657 } 658 659 /* Software & Hardware Initialize */ 660 static void 661 sln_init(void *x) 662 { 663 struct sln_softc *sc = x; 664 struct ifnet *ifp = &sc->arpcom.ac_if; 665 666 PDEBUG("sln_init\n"); 667 668 ASSERT_SERIALIZED(ifp->if_serializer); 669 670 sln_stop(sc); 671 672 /* soft reset the chip */ 673 sln_reset(sc); 674 675 /* disable interrupt */ 676 SLN_WRITE_4(sc, SL_INT_MASK, 0); 677 678 /* SLN_WRITE_4(sc, SL_MII_CMD0, SL_MII0_DIVEDER); */ 679 680 /* clear multicast address */ 681 SLN_WRITE_4(sc, SL_MULTI_GROUP0, 0); 682 SLN_WRITE_4(sc, SL_MULTI_GROUP1, 0); 683 684 /* Init the RX buffer start address register. */ 685 SLN_WRITE_4(sc, SL_RBSA, vtophys(sc->sln_bufdata.sln_rx_buf)); 686 sc->sln_bufdata.dirty_rx = vtophys(sc->sln_bufdata.sln_rx_buf); 687 688 /* Init TX descriptors. */ 689 sln_init_tx(sc); 690 691 /* configure RX buffer size */ 692 if (sc->tx_early_ctrl && sc->rx_early_ctrl) 693 SLN_WRITE_4(sc, SL_CFG1, SL_EARLY_RX | SL_EARLY_TX | SL_RXBUF_64 | SL_RXFIFO_1024BYTES); 694 else if (sc->tx_early_ctrl) 695 SLN_WRITE_4(sc, SL_CFG1, SL_EARLY_TX | SL_RXBUF_64); 696 else if (sc->rx_early_ctrl) 697 SLN_WRITE_4(sc, SL_CFG1, SL_EARLY_RX | SL_RXBUF_64 | SL_RXFIFO_1024BYTES); 698 else 699 SLN_WRITE_4(sc, SL_CFG1, SL_RXBUF_64); 700 701 /* MII media configuration */ 702 sln_media_cfg(sc); 703 704 if (sc->connect) { 705 /* Enable transmit and receive */ 706 sc->rxcfg |= SL_RXCFG_EN; 707 sc->txcfg |= SL_TXCFG_EN; 708 } else { 709 sc->rxcfg &= ~SL_RXCFG_EN; 710 sc->txcfg &= ~SL_TXCFG_EN; 711 } 712 713 SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg); 714 SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg); 715 716 /* Enable interrupts */ 717 SLN_WRITE_4(sc, SL_INT_MASK, SL_INRTS); 718 719 sc->suspended = 0; 720 721 ifp->if_flags |= IFF_RUNNING; 722 ifq_clr_oactive(&ifp->if_snd); 723 724 callout_reset(&sc->sln_state, hz, sln_tick, sc); 725 } 726 727 /* Transmit Packet */ 728 static void 729 sln_tx(struct ifnet *ifp, struct ifaltq_subque *ifsq) 730 { 731 struct sln_softc *sc = ifp->if_softc; 732 struct mbuf *m_head = NULL; 733 struct mbuf *m_new = NULL; 734 int entry; 735 736 ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq); 737 ASSERT_SERIALIZED(ifp->if_serializer); 738 739 if (!sc->connect) { 740 ifq_purge(&ifp->if_snd); 741 return; 742 } 743 744 if ((ifp->if_flags & IFF_RUNNING) == 0 || ifq_is_oactive(&ifp->if_snd)) 745 return; 746 747 while (SL_CUR_TXBUF(sc) == NULL) { /* SL_CUR_TXBUF(x) = x->sln_bufdata.sln_tx_buf[x->sln_bufdata.cur_tx] */ 748 entry = sc->sln_bufdata.cur_tx; 749 750 m_head = ifq_dequeue(&ifp->if_snd); 751 if (m_head == NULL) 752 break; 753 754 MGETHDR(m_new, M_NOWAIT, MT_DATA); 755 if (m_new == NULL) { 756 if_printf(ifp, "no memory for tx descriptor"); 757 m_freem(m_head); 758 break; 759 } 760 if ((m_head->m_pkthdr.len > MHLEN) || (60 > MHLEN)) { 761 MCLGET(m_new, M_NOWAIT); 762 if (!(m_new->m_flags & M_EXT)) { 763 m_freem(m_new); 764 m_freem(m_head); 765 if_printf(ifp, "no memory for tx descriptor"); 766 break; 767 } 768 } 769 m_copydata(m_head, 0, m_head->m_pkthdr.len, mtod(m_new, caddr_t)); 770 m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len; 771 m_freem(m_head); 772 m_head = m_new; 773 SL_CUR_TXBUF(sc) = m_head; 774 775 /* 776 * if there's a BPF listener, bounce a copy of this frame to 777 * him 778 */ 779 BPF_MTAP(ifp, SL_CUR_TXBUF(sc)); 780 781 /* Transmit the frame */ 782 SLN_WRITE_4(sc, ((entry * 4) + SL_TSAD0), 783 vtophys(mtod(SL_CUR_TXBUF(sc), caddr_t))); 784 785 /* calculate length of the frame */ 786 if ((SL_CUR_TXBUF(sc)->m_pkthdr.len < 60) && (!sc->txenablepad)) { 787 memset(mtod(m_head, char *)+m_head->m_pkthdr.len, 0x20, 60 - m_head->m_pkthdr.len); 788 SLN_WRITE_4(sc, (entry * 4) + SL_TSD0, 60); 789 } else if (SL_CUR_TXBUF(sc)->m_pkthdr.len < 100) 790 SLN_WRITE_4(sc, (entry * 4) + SL_TSD0, SL_CUR_TXBUF(sc)->m_pkthdr.len); 791 else if (SL_CUR_TXBUF(sc)->m_pkthdr.len < 300) 792 SLN_WRITE_4(sc, (entry * 4) + SL_TSD0, 0x30000 | SL_CUR_TXBUF(sc)->m_pkthdr.len); 793 else 794 SLN_WRITE_4(sc, (entry * 4) + SL_TSD0, 0x50000 | SL_CUR_TXBUF(sc)->m_pkthdr.len); 795 sc->sln_bufdata.cur_tx = (entry + 1) % SL_TXD_CNT; 796 797 PDEBUG("Queue tx packet size %d to tx-descriptor %d.\n", m_head->m_pkthdr.len, entry); 798 } 799 800 /* Tx buffer chain full */ 801 if (SL_CUR_TXBUF(sc) != NULL) 802 ifq_set_oactive(&ifp->if_snd); 803 804 /* Set a timeout in case the chip goes out to lunch */ 805 ifp->if_timer = 5; 806 } 807 808 /* Receive Data handler */ 809 static void 810 sln_rx(struct sln_softc *sc) 811 { 812 struct mbuf *m; 813 struct ifnet *ifp = &sc->arpcom.ac_if; 814 uint32_t rxstat = 0; 815 uint32_t rx_offset; 816 caddr_t rx_bufpos = NULL; 817 uint32_t cur_rx = 0; 818 uint32_t dirty_rx; 819 long rx_len; 820 u_long rx_space; 821 u_long rx_size = 0; 822 u_long rx_size_align = 0; 823 u_long pkt_size = 0; 824 825 cur_rx = SLN_READ_4(sc, SL_RBW_PTR); 826 dirty_rx = sc->sln_bufdata.dirty_rx; 827 828 /* 829 * cur_rx is only 17 bits in the RxBufWPtr register. if cur_rx can be 830 * used in physical space, we need to change it to 32 bits physical 831 * address 832 */ 833 cur_rx |= vtophys(sc->sln_bufdata.sln_rx_buf) & (~(u_long) (SL_RX_BUFLEN - 1)); 834 835 if (cur_rx < vtophys(sc->sln_bufdata.sln_rx_buf)) 836 cur_rx += SL_RX_BUFLEN; 837 838 if (cur_rx >= dirty_rx) 839 rx_len = (long)(cur_rx - dirty_rx); 840 else 841 rx_len = SL_RX_BUFLEN - (long)(dirty_rx - cur_rx); 842 843 if ((rx_len > SL_RX_BUFLEN) || (rx_len < 0)) { 844 if_printf(ifp, "rx len is fail\n"); 845 return; 846 } 847 if (rx_len == 0) 848 return; 849 850 rx_offset = (dirty_rx - vtophys(sc->sln_bufdata.sln_rx_buf)) & (u_long) (SL_RX_BUFLEN - 1); 851 852 while (rx_len > 0) { 853 #ifdef SLN_DEBUG 854 u_long ipkts; 855 #endif 856 857 rx_bufpos = sc->sln_bufdata.sln_rx_buf + rx_offset; 858 rxstat = *(uint32_t *) rx_bufpos; 859 rx_size = (rxstat >> 20) & 0x0FFF; 860 rx_size_align = (rx_size + 3) & ~3; /* for 4 bytes aligned */ 861 pkt_size = rx_size - ETHER_CRC_LEN; /* Omit the four octet 862 * CRC from the length. */ 863 864 PDEBUG("rx len: %ld rx frame size:%ld rx state:0x%x\n", rx_len, rx_size, rxstat); 865 866 /* errors receive packets caculatation */ 867 if (rxstat == 0 || rx_size < 16 || !(rxstat & SL_RXSTAT_RXOK)) { 868 IFNET_STAT_INC(ifp, ierrors, 1); 869 870 if (!(rxstat & SL_RXSTAT_RXOK)) 871 if_printf(ifp, "receiver ok error\n"); 872 873 if (!(rxstat & SL_RXSTAT_CRCOK)) 874 if_printf(ifp, "crc error\n"); 875 876 if (rxstat & SL_RXSTAT_ALIGNERR) 877 if_printf(ifp, "frame alignment error\n"); 878 879 if (rxstat & (SL_RXSTAT_HUGEFRM | SL_RXSTAT_SMALLFRM)) 880 if_printf(ifp, "received frame length is error\n"); 881 882 break; 883 } 884 rx_len -= (long)(rx_size_align + 4); /* 4 bytes for receive 885 * frame head */ 886 887 if (rx_len < 0) { 888 kprintf("rx packets len is too small\n"); 889 break; 890 } 891 #ifdef SLN_PDEBUG 892 caddr_t p = NULL; 893 894 if_printf(ifp, "rx frame content\n"); 895 p = rx_bufpos; 896 for (i = 0; i < 30; i++, p++) { 897 if (i % 10 == 0) 898 kprintf("\n"); 899 if_printf(ifp, "%x ", (u_char)*p); 900 } 901 if_printf(ifp, "\n"); 902 #endif 903 /* No errors; receive the packet. */ 904 if (rx_bufpos == (sc->sln_bufdata.sln_rx_buf + SL_RX_BUFLEN)) 905 rx_bufpos = sc->sln_bufdata.sln_rx_buf; 906 907 rx_bufpos = rx_bufpos + 4; /* 4 bytes for receive frame 908 * header */ 909 rx_space = (u_long)((sc->sln_bufdata.sln_rx_buf + SL_RX_BUFLEN) - rx_bufpos); 910 911 if (pkt_size > rx_space) { 912 m = m_devget(rx_bufpos - 2, pkt_size + 2, 0, ifp, NULL); /* 2 for etherer head 913 * align */ 914 915 if (m == NULL) { 916 IFNET_STAT_INC(ifp, ierrors, 1); 917 if_printf(ifp, 918 "out of mbufs, tried to copy %ld bytes\n", 919 rx_space); 920 } else { 921 m_adj(m, 2); 922 m_copyback(m, rx_space, pkt_size - rx_space, sc->sln_bufdata.sln_rx_buf); 923 } 924 } else { 925 m = m_devget(rx_bufpos - 2, pkt_size + 2, 0, ifp, NULL); 926 927 if (m == NULL) { 928 u_long ierr; 929 930 IFNET_STAT_INC(ifp, ierrors, 1); 931 if_printf(ifp, 932 "out of mbufs, tried to copy %ld bytes\n", 933 pkt_size); 934 935 IFNET_STAT_GET(ifp, ierrors, ierr); 936 if_printf(ifp, "ierrors = %lu\n", ierr); 937 } else { 938 m_adj(m, 2); 939 } 940 } 941 942 IFNET_STAT_INC(ifp, ipackets, 1); 943 #ifdef SLN_DEBUG 944 IFNET_STAT_GET(ifp, ipackets, ipkts); 945 PDEBUG("ipackets = %lu\n", ipkts); 946 #endif 947 948 ifp->if_input(ifp, m, NULL, -1); 949 950 rx_offset = (rx_offset + rx_size + 4) & (u_long) (SL_RX_BUFLEN - 1); /* 4 bytes for receive 951 * frame head */ 952 } 953 954 sc->sln_bufdata.dirty_rx = cur_rx; 955 956 SLN_WRITE_4(sc, SL_RBR_PTR, cur_rx); 957 } 958 959 /* Transmit OK/ERR handler */ 960 static void 961 sln_tx_intr(struct sln_softc *sc) 962 { 963 struct ifnet *ifp = &sc->arpcom.ac_if; 964 uint32_t txstat; 965 int entry; 966 967 do { 968 entry = sc->sln_bufdata.dirty_tx; 969 txstat = SLN_READ_4(sc, SL_TSD0 + entry * 4); 970 971 if (!(txstat & (SL_TXSD_TOK | SL_TXSD_TUN | SL_TXSD_TABT))) 972 break; /* It still hasn't been sent */ 973 974 if (SL_DIRTY_TXBUF(sc) != NULL) { /* SL_DIRTY_TXBUF(x) = 975 * x->sln_bufdata.sln_tx_ 976 * buf[x->sln_bufdata.dir 977 * ty_tx] */ 978 m_freem(SL_DIRTY_TXBUF(sc)); 979 SL_DIRTY_TXBUF(sc) = NULL; 980 } 981 if (txstat & SL_TXSD_TOK) { 982 #ifdef SLN_DEBUG 983 u_long opkts; 984 #endif 985 986 IFNET_STAT_INC(ifp, opackets, 1); 987 IFNET_STAT_INC(ifp, obytes, txstat & SL_TXSD_LENMASK); 988 #ifdef SLN_DEBUG 989 IFNET_STAT_GET(ifp, opackets, opkts); 990 PDEBUG("opackets = %lu\n", opkts); 991 #endif 992 IFNET_STAT_INC(ifp, collisions, 993 (txstat & SL_TXSD_NCC) >> 22); 994 } else { 995 IFNET_STAT_INC(ifp, oerrors, 1); 996 if ((txstat & (SL_TXSD_TABT | SL_TXSD_OWC))) { 997 sc->txcfg = TX_CFG_DEFAULT; 998 999 if (sc->txenablepad) 1000 sc->txcfg |= 0x20000000; 1001 1002 SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg); 1003 } 1004 } 1005 PDEBUG("tx done descriprtor %x\n", entry); 1006 sc->sln_bufdata.dirty_tx = (entry + 1) % SL_TXD_CNT; 1007 1008 ifq_clr_oactive(&ifp->if_snd); 1009 } while (sc->sln_bufdata.dirty_tx != sc->sln_bufdata.cur_tx); 1010 1011 if (sc->sln_bufdata.dirty_tx == sc->sln_bufdata.cur_tx) 1012 ifp->if_timer = 0; 1013 else 1014 ifp->if_timer = 5; 1015 } 1016 1017 static void 1018 sln_media_intr(struct sln_softc *sc) 1019 { 1020 u_long phys[2]; 1021 struct ifnet *ifp = &sc->arpcom.ac_if; 1022 1023 phys[0] = SL_MII_STAT; 1024 sln_mii_cmd(sc, SL_MII0_READ, phys); 1025 1026 PDEBUG("mii_stat:0x%lx\n", phys[1]); 1027 1028 if (0 == (phys[1] & SL_MIISTAT_LINK)) { 1029 kprintf("media is unconnect,linked down,or uncompatible\n"); 1030 sc->connect = 0; 1031 sln_mii_cmd(sc, SL_MII0_SCAN, phys); 1032 /* disable tx/rx */ 1033 sc->txcfg &= ~SL_TXCFG_EN; 1034 sc->rxcfg &= ~SL_RXCFG_EN; 1035 SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg); 1036 SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg); 1037 1038 return; 1039 } 1040 /* Link is good. Report modes and set duplex mode. */ 1041 PDEBUG("media is connecting---> "); 1042 sc->connect = 1; 1043 1044 phys[0] = SL_MII_STAT_OUTPUT; 1045 sln_mii_cmd(sc, SL_MII0_READ, phys); 1046 sc->media_duplex = ((phys[1] & 0x0004) == 0) ? IFM_HDX : IFM_FDX; 1047 sc->media_speed = ((phys[1] & 0x0002) == 0) ? IFM_10_T : IFM_100_TX; 1048 1049 if_printf(ifp, "media option:%dM %s-duplex\n", 1050 sc->media_speed == 0x6 ? 100 : 10, 1051 sc->media_duplex == 0x100000 ? "full" : "half"); 1052 1053 sln_mii_cmd(sc, SL_MII0_SCAN, phys); 1054 1055 sln_mac_cfg(sc); 1056 1057 /* Enable tx/rx */ 1058 sc->rxcfg |= SL_RXCFG_EN; 1059 sc->txcfg |= SL_TXCFG_EN; 1060 SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg); 1061 SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg); 1062 } 1063 1064 /* Interrupt Handler */ 1065 static void 1066 sln_interrupt(void *arg) 1067 { 1068 struct sln_softc *sc = arg; 1069 struct ifnet *ifp = &sc->arpcom.ac_if; 1070 uint32_t int_status; 1071 1072 ASSERT_SERIALIZED(ifp->if_serializer); 1073 1074 if (sc->suspended || (ifp->if_flags & IFF_RUNNING) == 0) 1075 return; 1076 1077 /* Disable interrupts. */ 1078 SLN_WRITE_4(sc, SL_INT_MASK, 0); 1079 1080 int_status = SLN_READ_4(sc, SL_INT_STATUS); 1081 1082 if ((int_status == 0xffffffff) || (int_status & SL_INRTS) == 0) 1083 goto back; 1084 1085 int_status = int_status & SL_INRTS; 1086 PDEBUG("int_status = 0x%x\n", int_status); 1087 1088 while (0 != int_status) { 1089 if (int_status & SL_INT_ROK) 1090 sln_rx(sc); 1091 1092 if (int_status & SL_INT_TOK) 1093 sln_tx_intr(sc); 1094 1095 if (int_status & SL_INT_RBO) { 1096 IFNET_STAT_INC(ifp, ierrors, 1); 1097 PDEBUG("rx buffer is overflow\n"); 1098 } 1099 1100 if (int_status & (SL_INT_LINKFAIL | SL_INT_LINKOK)) 1101 sln_media_intr(sc); 1102 1103 int_status = SLN_READ_4(sc, SL_INT_STATUS); 1104 } 1105 1106 /* Data in Tx buffer waiting for transimission */ 1107 if (!ifq_is_empty(&ifp->if_snd)) 1108 if_devstart(ifp); 1109 back: 1110 /* Re-enable interrupts. */ 1111 SLN_WRITE_4(sc, SL_INT_MASK, SL_INRTS); 1112 } 1113 1114 static void 1115 sln_tick(void *x) 1116 { 1117 struct sln_softc *sc = x; 1118 1119 callout_reset(&sc->sln_state, hz, sln_tick, sc); 1120 } 1121 1122 static int 1123 sln_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr) 1124 { 1125 struct sln_softc *sc = ifp->if_softc; 1126 struct ifreq *ifr = (struct ifreq *)data; 1127 int error = 0; 1128 1129 ASSERT_SERIALIZED(ifp->if_serializer); 1130 1131 switch (cmd) { 1132 case SIOCSIFFLAGS: 1133 if (ifp->if_flags & IFF_UP) { 1134 if ((ifp->if_flags & IFF_RUNNING) == 0) 1135 sln_init(sc); 1136 } else { 1137 if (ifp->if_flags & IFF_RUNNING) 1138 sln_stop(sc); 1139 } 1140 break; 1141 case SIOCADDMULTI: 1142 case SIOCDELMULTI: 1143 sln_set_multi(sc); 1144 break; 1145 case SIOCGIFMEDIA: 1146 case SIOCSIFMEDIA: 1147 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd); 1148 break; 1149 default: 1150 error = ether_ioctl(ifp, cmd, data); 1151 break; 1152 } 1153 return error; 1154 } 1155 1156 static void 1157 sln_watchdog(struct ifnet *ifp) 1158 { 1159 struct sln_softc *sc = ifp->if_softc; 1160 1161 ASSERT_SERIALIZED(ifp->if_serializer); 1162 1163 if_printf(ifp, "watchdog timeout!\n"); 1164 IFNET_STAT_INC(ifp, oerrors, 1); 1165 1166 sln_tx_intr(sc); 1167 sln_rx(sc); 1168 sln_init(sc); 1169 1170 if (!ifq_is_empty(&ifp->if_snd)) 1171 if_devstart(ifp); 1172 } 1173 1174 /* Stop all chip I/O */ 1175 static int 1176 sln_shutdown(device_t dev) 1177 { 1178 struct sln_softc *sc = device_get_softc(dev); 1179 struct ifnet *ifp = &sc->arpcom.ac_if; 1180 1181 lwkt_serialize_enter(ifp->if_serializer); 1182 sln_stop(sc); 1183 lwkt_serialize_exit(ifp->if_serializer); 1184 1185 return 0; 1186 } 1187 1188 /* device suspend routine */ 1189 static int 1190 sln_suspend(device_t dev) 1191 { 1192 struct sln_softc *sc = device_get_softc(dev); 1193 struct ifnet *ifp = &sc->arpcom.ac_if; 1194 1195 lwkt_serialize_enter(ifp->if_serializer); 1196 sln_stop(sc); 1197 sc->suspended = 1; 1198 lwkt_serialize_exit(ifp->if_serializer); 1199 1200 return 0; 1201 } 1202 1203 /* device resume routine */ 1204 static int 1205 sln_resume(device_t dev) 1206 { 1207 struct sln_softc *sc = device_get_softc(dev); 1208 struct ifnet *ifp = &sc->arpcom.ac_if; 1209 1210 lwkt_serialize_enter(ifp->if_serializer); 1211 if (ifp->if_flags & IFF_UP) 1212 sln_init(sc); 1213 sc->suspended = 0; 1214 lwkt_serialize_exit(ifp->if_serializer); 1215 1216 return 0; 1217 } 1218