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