1 /* $NetBSD: lan9118.c,v 1.14 2010/04/05 07:19:35 joerg Exp $ */ 2 /* 3 * Copyright (c) 2008 KIYOHARA Takashi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #include <sys/cdefs.h> 28 __KERNEL_RCSID(0, "$NetBSD: lan9118.c,v 1.14 2010/04/05 07:19:35 joerg Exp $"); 29 30 /* 31 * The LAN9118 Family 32 * * The LAN9118 is targeted for 32-bit applications requiring high 33 * performance, and provides the highest level of performance possible for 34 * a non-PCI 10/100 Ethernet controller. 35 * 36 * * The LAN9117 is designed to provide the highest level of performance 37 * possible for 16-bit applications. It also has an external MII interface, 38 * which can be used to attach an external PHY. 39 * 40 * * The LAN9116 and LAN9115 are designed for performance-sensitive 41 * applications with less intensive performance requirements. The LAN9116 42 * is for 32-bit host processors, while the LAN9115 is for 16-bit 43 * applications, which may also require an external PHY. Both devices 44 * deliver superior levels of performance. 45 * 46 * The LAN9218 Family 47 * Also support HP Auto-MDIX. 48 */ 49 50 #include "rnd.h" 51 52 #include <sys/param.h> 53 #include <sys/callout.h> 54 #include <sys/device.h> 55 #include <sys/errno.h> 56 #include <sys/bus.h> 57 #include <sys/ioctl.h> 58 #include <sys/kernel.h> 59 #include <sys/proc.h> 60 #include <sys/systm.h> 61 62 #include <net/if.h> 63 #include <net/if_ether.h> 64 #include <net/if_media.h> 65 66 #include <dev/mii/mii.h> 67 #include <dev/mii/miivar.h> 68 69 #include <net/bpf.h> 70 #if NRND > 0 71 #include <sys/rnd.h> 72 #endif 73 74 #include <dev/ic/lan9118reg.h> 75 #include <dev/ic/lan9118var.h> 76 77 78 #ifdef SMSH_DEBUG 79 #define DPRINTF(x) if (smsh_debug) printf x 80 #define DPRINTFN(n,x) if (smsh_debug >= (n)) printf x 81 int smsh_debug = SMSH_DEBUG; 82 #else 83 #define DPRINTF(x) 84 #define DPRINTFN(n,x) 85 #endif 86 87 88 static void lan9118_start(struct ifnet *); 89 static int lan9118_ioctl(struct ifnet *, u_long, void *); 90 static int lan9118_init(struct ifnet *); 91 static void lan9118_stop(struct ifnet *, int); 92 static void lan9118_watchdog(struct ifnet *); 93 94 static int lan9118_ifm_change(struct ifnet *); 95 static void lan9118_ifm_status(struct ifnet *, struct ifmediareq *); 96 97 static int lan9118_miibus_readreg(device_t, int, int); 98 static void lan9118_miibus_writereg(device_t, int, int, int); 99 static void lan9118_miibus_statchg(device_t); 100 101 static uint16_t lan9118_mii_readreg(struct lan9118_softc *, int, int); 102 static void lan9118_mii_writereg(struct lan9118_softc *, int, int, uint16_t); 103 static uint32_t lan9118_mac_readreg(struct lan9118_softc *, int); 104 static void lan9118_mac_writereg(struct lan9118_softc *, int, uint32_t); 105 106 static void lan9118_set_filter(struct lan9118_softc *); 107 static void lan9118_rxintr(struct lan9118_softc *); 108 static void lan9118_txintr(struct lan9118_softc *); 109 110 static void lan9118_tick(void *); 111 112 /* This values refer from Linux's smc911x.c */ 113 static uint32_t afc_cfg[] = { 114 /* 0 */ 0x00000000, 115 /* 1 */ 0x00000000, 116 /* 2 */ 0x008c4600 | LAN9118_AFC_CFG_BACK_DUR(10) | 117 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 118 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 119 /* 3 */ 0x00824100 | LAN9118_AFC_CFG_BACK_DUR(9) | 120 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 121 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 122 /* 4 */ 0x00783c00 | LAN9118_AFC_CFG_BACK_DUR(9) | 123 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 124 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 125 /* 5 */ 0x006e3700 | LAN9118_AFC_CFG_BACK_DUR(8) | 126 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 127 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 128 /* 6 */ 0x00643200 | LAN9118_AFC_CFG_BACK_DUR(8) | 129 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 130 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 131 /* 7 */ 0x005a2d00 | LAN9118_AFC_CFG_BACK_DUR(7) | 132 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 133 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 134 /* 8 */ 0x00502800 | LAN9118_AFC_CFG_BACK_DUR(7) | 135 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 136 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 137 /* 9 */ 0x00462300 | LAN9118_AFC_CFG_BACK_DUR(6) | 138 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 139 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 140 /* a */ 0x003c1e00 | LAN9118_AFC_CFG_BACK_DUR(6) | 141 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 142 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 143 /* b */ 0x00321900 | LAN9118_AFC_CFG_BACK_DUR(5) | 144 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 145 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 146 /* c */ 0x00241200 | LAN9118_AFC_CFG_BACK_DUR(4) | 147 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 148 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 149 /* d */ 0x00150700 | LAN9118_AFC_CFG_BACK_DUR(3) | 150 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 151 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 152 /* e */ 0x00060300 | LAN9118_AFC_CFG_BACK_DUR(2) | 153 LAN9118_AFC_CFG_FCMULT | LAN9118_AFC_CFG_FCBRD | 154 LAN9118_AFC_CFG_FCADD | LAN9118_AFC_CFG_FCANY, 155 /* f */ 0x00000000, 156 }; 157 158 159 int 160 lan9118_attach(struct lan9118_softc *sc) 161 { 162 struct ifnet *ifp = &sc->sc_ec.ec_if; 163 uint32_t val; 164 int timo, i; 165 166 if (sc->sc_flags & LAN9118_FLAGS_SWAP) 167 /* byte swap mode */ 168 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_WORD_SWAP, 169 0xffffffff); 170 val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_BYTE_TEST); 171 if (val != LAN9118_BYTE_TEST_VALUE) { 172 aprint_error(": failed to detect chip\n"); 173 return EINVAL; 174 } 175 176 val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_ID_REV); 177 sc->sc_id = LAN9118_ID_REV_ID(val); 178 sc->sc_rev = LAN9118_ID_REV_REV(val); 179 180 #define LAN9xxx_ID(id) \ 181 (IS_LAN9118(id) ? (id) : (IS_LAN9218(id) ? ((id) >> 4) + 0x100 : (id) & 0xfff)) 182 183 aprint_normal(": SMSC LAN9%03x Rev %d\n", 184 LAN9xxx_ID(sc->sc_id), sc->sc_rev); 185 186 if (sc->sc_flags & LAN9118_FLAGS_SWAP) 187 aprint_normal_dev(sc->sc_dev, "byte swap mode\n"); 188 189 timo = 3 * 1000 * 1000; /* XXXX 3sec */ 190 do { 191 val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 192 LAN9118_MAC_CSR_CMD); 193 if (!(val & LAN9118_MAC_CSR_CMD_BUSY)) 194 break; 195 delay(100); 196 } while (timo -= 100); 197 if (timo <= 0) 198 aprint_error_dev(sc->sc_dev, "%s: command busy\n", __func__); 199 if (!(sc->sc_flags & LAN9118_FLAGS_NO_EEPROM)) { 200 /* Read auto-loaded MAC address */ 201 val = lan9118_mac_readreg(sc, LAN9118_ADDRL); 202 sc->sc_enaddr[3] = (val >> 24) & 0xff; 203 sc->sc_enaddr[2] = (val >> 16) & 0xff; 204 sc->sc_enaddr[1] = (val >> 8) & 0xff; 205 sc->sc_enaddr[0] = val & 0xff; 206 val = lan9118_mac_readreg(sc, LAN9118_ADDRH); 207 sc->sc_enaddr[5] = (val >> 8) & 0xff; 208 sc->sc_enaddr[4] = val & 0xff; 209 } 210 aprint_normal_dev(sc->sc_dev, "MAC address %s\n", 211 ether_sprintf(sc->sc_enaddr)); 212 213 KASSERT(LAN9118_TX_FIF_SZ >= 2 && LAN9118_TX_FIF_SZ < 15); 214 sc->sc_afc_cfg = afc_cfg[LAN9118_TX_FIF_SZ]; 215 216 /* Initialize the ifnet structure. */ 217 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 218 ifp->if_softc = sc; 219 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 220 ifp->if_start = lan9118_start; 221 ifp->if_ioctl = lan9118_ioctl; 222 ifp->if_init = lan9118_init; 223 ifp->if_stop = lan9118_stop; 224 ifp->if_watchdog = lan9118_watchdog; 225 IFQ_SET_READY(&ifp->if_snd); 226 227 #if 0 /* Not support 802.1Q VLAN-sized frames yet. */ 228 sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU; 229 #endif 230 231 ifmedia_init(&sc->sc_mii.mii_media, 0, 232 lan9118_ifm_change, lan9118_ifm_status); 233 sc->sc_mii.mii_ifp = ifp; 234 sc->sc_mii.mii_readreg = lan9118_miibus_readreg; 235 sc->sc_mii.mii_writereg = lan9118_miibus_writereg; 236 sc->sc_mii.mii_statchg = lan9118_miibus_statchg; 237 238 /* 239 * Number of instance of Internal PHY is always 0. External PHY 240 * number that above. 241 */ 242 mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, 1, MII_OFFSET_ANY, 0); 243 244 if (sc->sc_id == LAN9118_ID_9115 || sc->sc_id == LAN9118_ID_9117 || 245 sc->sc_id == LAN9218_ID_9215 || sc->sc_id == LAN9218_ID_9217) { 246 if (bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG) & 247 LAN9118_HW_CFG_EXT_PHY_DET) { 248 /* 249 * We always have a internal PHY at phy1. 250 * In addition, external PHY is attached. 251 */ 252 DPRINTFN(1, ("%s: detect External PHY\n", __func__)); 253 254 /* Switch MII and SMI */ 255 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 256 LAN9118_HW_CFG, 257 LAN9118_HW_CFG_MBO | 258 LAN9118_HW_CFG_PHY_CLK_SEL_CD); 259 delay(1); /* Wait 5 cycle */ 260 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 261 LAN9118_HW_CFG, 262 LAN9118_HW_CFG_MBO | 263 LAN9118_HW_CFG_PHY_CLK_SEL_EMII | 264 LAN9118_HW_CFG_SMI_SEL | 265 LAN9118_HW_CFG_EXT_PHY_EN); 266 delay(1); /* Once wait more 5 cycle */ 267 268 /* Call mii_attach, avoid at phy1. */ 269 mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, 270 0, MII_OFFSET_ANY, 0); 271 for (i = 2; i < MII_NPHY; i++) 272 mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, 273 i, MII_OFFSET_ANY, 0); 274 } 275 } 276 277 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO); 278 279 /* Attach the interface. */ 280 if_attach(ifp); 281 ether_ifattach(ifp, sc->sc_enaddr); 282 283 callout_init(&sc->sc_tick, 0); 284 285 #if NRND > 0 286 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 287 RND_TYPE_NET, 0); 288 #endif 289 return 0; 290 } 291 292 int 293 lan9118_intr(void *arg) 294 { 295 struct lan9118_softc *sc = (struct lan9118_softc *)arg; 296 struct ifnet *ifp = &sc->sc_ec.ec_if; 297 uint32_t int_sts, int_en, datum = 0; 298 int handled = 0; 299 300 for (;;) { 301 int_sts = 302 bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_STS); 303 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_STS, 304 int_sts); 305 int_en = 306 bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_EN); 307 308 DPRINTFN(3, ("%s: int_sts=0x%x, int_en=0x%x\n", 309 __func__, int_sts, int_en)); 310 311 if (!(int_sts & int_en)) 312 break; 313 datum = int_sts; 314 315 #if 0 /* not yet... */ 316 if (int_sts & LAN9118_INT_PHY_INT) { /* PHY */ 317 /* Shall we need? */ 318 } 319 if (int_sts & LAN9118_INT_PME_INT) { /*Power Management Event*/ 320 /* not yet... */ 321 } 322 #endif 323 if (int_sts & LAN9118_INT_RXE) { 324 ifp->if_ierrors++; 325 aprint_error_ifnet(ifp, "Receive Error\n"); 326 } 327 if (int_sts & LAN9118_INT_TSFL) /* TX Status FIFO Level */ 328 lan9118_txintr(sc); 329 if (int_sts & LAN9118_INT_RXDF_INT) { 330 ifp->if_ierrors++; 331 aprint_error_ifnet(ifp, "RX Dropped Frame Interrupt\n"); 332 } 333 if (int_sts & LAN9118_INT_RSFF) { 334 ifp->if_ierrors++; 335 aprint_error_ifnet(ifp, "RX Status FIFO Full\n"); 336 } 337 if (int_sts & LAN9118_INT_RSFL) /* RX Status FIFO Level */ 338 lan9118_rxintr(sc); 339 } 340 341 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 342 lan9118_start(ifp); 343 344 #if NRND > 0 345 if (RND_ENABLED(&sc->rnd_source)) 346 rnd_add_uint32(&sc->rnd_source, datum); 347 #endif 348 349 return handled; 350 } 351 352 353 static void 354 lan9118_start(struct ifnet *ifp) 355 { 356 struct lan9118_softc *sc = ifp->if_softc; 357 struct mbuf *m0, *m; 358 unsigned tdfree, totlen, dso; 359 uint32_t txa, txb; 360 uint8_t *p; 361 int n; 362 363 DPRINTFN(3, ("%s\n", __func__)); 364 365 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 366 return; 367 368 totlen = 0; 369 for (;;) { 370 IFQ_POLL(&ifp->if_snd, m0); 371 if (m0 == NULL) 372 break; 373 374 tdfree = LAN9118_TX_FIFO_INF_TDFREE(bus_space_read_4(sc->sc_iot, 375 sc->sc_ioh, LAN9118_TX_FIFO_INF)); 376 if (tdfree < 2036) { 377 /* 378 * 2036 is the possible maximum FIFO consumption 379 * for the most fragmented frame. 380 */ 381 ifp->if_flags |= IFF_OACTIVE; 382 break; 383 } 384 385 IFQ_DEQUEUE(&ifp->if_snd, m0); 386 387 /* 388 * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET. 389 */ 390 391 /* 392 * Check mbuf chain -- "middle" buffers must be >= 4 bytes 393 * and maximum # of buffers is 86. 394 */ 395 m = m0; 396 n = 0; 397 while (m) { 398 if (m->m_len < 4 || ++n > 86) { 399 /* Copy mbuf chain. */ 400 MGETHDR(m, M_DONTWAIT, MT_DATA); 401 if (m == NULL) 402 goto discard; /* discard packet */ 403 MCLGET(m, M_DONTWAIT); 404 if ((m->m_flags & M_EXT) == 0) { 405 m_freem(m); 406 goto discard; /* discard packet */ 407 } 408 m_copydata(m0, 0, m0->m_pkthdr.len, 409 mtod(m, void *)); 410 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len; 411 m_freem(m0); 412 m0 = m; 413 break; 414 } 415 m = m->m_next; 416 } 417 418 m = m0; 419 totlen = m->m_pkthdr.len; 420 p = mtod(m, uint8_t *); 421 dso = (unsigned)p & 0x3; 422 txa = 423 LAN9118_TXC_A_BEA_4B | 424 LAN9118_TXC_A_DSO(dso) | 425 LAN9118_TXC_A_FS | 426 LAN9118_TXC_A_BS(m->m_len); 427 txb = LAN9118_TXC_B_PL(totlen); 428 while (m->m_next != NULL) { 429 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 430 LAN9118_TXDFIFOP, txa); 431 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 432 LAN9118_TXDFIFOP, txb); 433 bus_space_write_multi_4(sc->sc_iot, sc->sc_ioh, 434 LAN9118_TXDFIFOP, (uint32_t *)(p - dso), 435 (m->m_len + dso + 3) >> 2); 436 437 m = m->m_next; 438 p = mtod(m, uint8_t *); 439 dso = (unsigned)p & 0x3; 440 txa = 441 LAN9118_TXC_A_BEA_4B | 442 LAN9118_TXC_A_DSO(dso) | 443 LAN9118_TXC_A_BS(m->m_len); 444 } 445 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_TXDFIFOP, 446 txa | LAN9118_TXC_A_LS); 447 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_TXDFIFOP, 448 txb); 449 bus_space_write_multi_4(sc->sc_iot, sc->sc_ioh, 450 LAN9118_TXDFIFOP, (uint32_t *)(p - dso), 451 (m->m_len + dso + 3) >> 2); 452 453 discard: 454 /* 455 * Pass the packet to any BPF listeners. 456 */ 457 bpf_mtap(ifp, m0); 458 459 m_freem(m0); 460 } 461 if (totlen > 0) 462 ifp->if_timer = 5; 463 } 464 465 static int 466 lan9118_ioctl(struct ifnet *ifp, u_long command, void *data) 467 { 468 struct lan9118_softc *sc = ifp->if_softc; 469 struct ifreq *ifr = data; 470 struct mii_data *mii = &sc->sc_mii; 471 int s, error = 0; 472 473 s = splnet(); 474 475 switch (command) { 476 case SIOCSIFFLAGS: 477 DPRINTFN(2, ("%s: IFFLAGS\n", __func__)); 478 if ((error = ifioctl_common(ifp, command, data)) != 0) 479 break; 480 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 481 case IFF_RUNNING: 482 lan9118_stop(ifp, 0); 483 break; 484 case IFF_UP: 485 lan9118_init(ifp); 486 break; 487 case IFF_UP|IFF_RUNNING: 488 lan9118_set_filter(sc); 489 break; 490 default: 491 break; 492 } 493 error = 0; 494 break; 495 496 case SIOCGIFMEDIA: 497 case SIOCSIFMEDIA: 498 DPRINTFN(2, ("%s: MEDIA\n", __func__)); 499 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 500 break; 501 502 default: 503 DPRINTFN(2, ("%s: ETHER\n", __func__)); 504 error = ether_ioctl(ifp, command, data); 505 if (error == ENETRESET) { 506 if (ifp->if_flags & IFF_RUNNING) { 507 lan9118_set_filter(sc); 508 DPRINTFN(2, ("%s set_filter called\n", 509 __func__)); 510 } 511 error = 0; 512 } 513 break; 514 } 515 516 splx(s); 517 518 return error; 519 } 520 521 static int 522 lan9118_init(struct ifnet *ifp) 523 { 524 struct lan9118_softc *sc = ifp->if_softc; 525 struct ifmedia *ifm = &sc->sc_mii.mii_media; 526 uint32_t reg, hw_cfg, mac_cr; 527 int timo, s; 528 529 DPRINTFN(2, ("%s\n", __func__)); 530 531 s = splnet(); 532 533 /* wait for PMT_CTRL[READY] */ 534 timo = mstohz(5000); /* XXXX 5sec */ 535 while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_PMT_CTRL) & 536 LAN9118_PMT_CTRL_READY)) { 537 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_BYTE_TEST, 538 0xbad0c0de); 539 tsleep(&sc, PRIBIO, "lan9118_pmt_ready", 1); 540 if (--timo <= 0) { 541 splx(s); 542 return EBUSY; 543 } 544 } 545 546 /* Soft Reset */ 547 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG, 548 LAN9118_HW_CFG_SRST); 549 do { 550 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG); 551 if (reg & LAN9118_HW_CFG_SRST_TO) { 552 aprint_error_dev(sc->sc_dev, 553 "soft reset timeouted out\n"); 554 splx(s); 555 return ETIMEDOUT; 556 } 557 } while (reg & LAN9118_HW_CFG_SRST); 558 559 /* Set MAC and PHY CSRs */ 560 561 if (sc->sc_flags & LAN9118_FLAGS_SWAP) 562 /* need byte swap */ 563 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_WORD_SWAP, 564 0xffffffff); 565 566 while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_E2P_CMD) & 567 LAN9118_E2P_CMD_EPCB); 568 if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_E2P_CMD) & 569 LAN9118_E2P_CMD_MACAL)) { 570 lan9118_mac_writereg(sc, LAN9118_ADDRL, 571 sc->sc_enaddr[0] | 572 sc->sc_enaddr[1] << 8 | 573 sc->sc_enaddr[2] << 16 | 574 sc->sc_enaddr[3] << 24); 575 lan9118_mac_writereg(sc, LAN9118_ADDRH, 576 sc->sc_enaddr[4] | sc->sc_enaddr[5] << 8); 577 } 578 579 if (ifm->ifm_media & IFM_FLOW) { 580 lan9118_mac_writereg(sc, LAN9118_FLOW, 581 LAN9118_FLOW_FCPT(1) | LAN9118_FLOW_FCEN); 582 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_AFC_CFG, 583 sc->sc_afc_cfg); 584 } 585 586 lan9118_ifm_change(ifp); 587 hw_cfg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG); 588 hw_cfg &= ~LAN9118_HW_CFG_TX_FIF_MASK; 589 hw_cfg |= LAN9118_HW_CFG_TX_FIF_SZ(LAN9118_TX_FIF_SZ); 590 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG, hw_cfg); 591 592 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_GPIO_CFG, 593 LAN9118_GPIO_CFG_LEDX_EN(2) | 594 LAN9118_GPIO_CFG_LEDX_EN(1) | 595 LAN9118_GPIO_CFG_LEDX_EN(0) | 596 LAN9118_GPIO_CFG_GPIOBUFN(2) | 597 LAN9118_GPIO_CFG_GPIOBUFN(1) | 598 LAN9118_GPIO_CFG_GPIOBUFN(0)); 599 600 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_IRQ_CFG, 601 LAN9118_IRQ_CFG_IRQ_EN); 602 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_STS, 603 bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_STS)); 604 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_FIFO_INT, 605 LAN9118_FIFO_INT_TXSL(0) | LAN9118_FIFO_INT_RXSL(0)); 606 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_EN, 607 #if 0 /* not yet... */ 608 LAN9118_INT_PHY_INT | /* PHY */ 609 LAN9118_INT_PME_INT | /* Power Management Event */ 610 #endif 611 LAN9118_INT_RXE | /* Receive Error */ 612 LAN9118_INT_TSFL | /* TX Status FIFO Level */ 613 LAN9118_INT_RXDF_INT| /* RX Dropped Frame Interrupt */ 614 LAN9118_INT_RSFF | /* RX Status FIFO Full */ 615 LAN9118_INT_RSFL); /* RX Status FIFO Level */ 616 617 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_RX_CFG, 618 LAN9118_RX_CFG_RXDOFF(2)); 619 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_TX_CFG, 620 LAN9118_TX_CFG_TX_ON); 621 mac_cr = lan9118_mac_readreg(sc, LAN9118_MAC_CR); 622 lan9118_mac_writereg(sc, LAN9118_MAC_CR, 623 mac_cr | LAN9118_MAC_CR_TXEN | LAN9118_MAC_CR_RXEN); 624 625 lan9118_set_filter(sc); 626 627 ifp->if_flags |= IFF_RUNNING; 628 ifp->if_flags &= ~IFF_OACTIVE; 629 630 callout_reset(&sc->sc_tick, hz, lan9118_tick, sc); 631 632 splx(s); 633 634 return 0; 635 } 636 637 static void 638 lan9118_stop(struct ifnet *ifp, int disable) 639 { 640 struct lan9118_softc *sc = ifp->if_softc; 641 uint32_t cr; 642 643 DPRINTFN(2, ("%s\n", __func__)); 644 645 /* Disable IRQ */ 646 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_EN, 0); 647 648 /* Stopping transmitter */ 649 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_TX_CFG, 650 LAN9118_TX_CFG_STOP_TX); 651 while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_TX_CFG) & 652 (LAN9118_TX_CFG_TX_ON | LAN9118_TX_CFG_STOP_TX)); 653 654 /* Purge TX Status/Data FIFOs */ 655 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_TX_CFG, 656 LAN9118_TX_CFG_TXS_DUMP | LAN9118_TX_CFG_TXD_DUMP); 657 658 /* Stopping receiver, also clear TXEN */ 659 cr = lan9118_mac_readreg(sc, LAN9118_MAC_CR); 660 cr &= ~(LAN9118_MAC_CR_TXEN | LAN9118_MAC_CR_RXEN); 661 lan9118_mac_writereg(sc, LAN9118_MAC_CR, cr); 662 while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_STS) & 663 LAN9118_INT_RXSTOP_INT)); 664 665 /* Clear RX Status/Data FIFOs */ 666 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_RX_CFG, 667 LAN9118_RX_CFG_RX_DUMP); 668 669 callout_stop(&sc->sc_tick); 670 } 671 672 static void 673 lan9118_watchdog(struct ifnet *ifp) 674 { 675 struct lan9118_softc *sc = ifp->if_softc; 676 677 /* 678 * Reclaim first as there is a possibility of losing Tx completion 679 * interrupts. 680 */ 681 lan9118_txintr(sc); 682 683 aprint_error_ifnet(ifp, "watchdog timeout\n"); 684 ifp->if_oerrors++; 685 686 lan9118_init(ifp); 687 } 688 689 690 static int 691 lan9118_ifm_change(struct ifnet *ifp) 692 { 693 struct lan9118_softc *sc = ifp->if_softc; 694 struct mii_data *mii = &sc->sc_mii; 695 struct ifmedia *ifm = &mii->mii_media; 696 struct ifmedia_entry *ife = ifm->ifm_cur; 697 uint32_t pmt_ctrl; 698 699 DPRINTFN(3, ("%s: ifm inst %d\n", __func__, IFM_INST(ife->ifm_media))); 700 701 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG, 702 LAN9118_HW_CFG_MBO | LAN9118_HW_CFG_PHY_CLK_SEL_CD); 703 delay(1); /* Wait 5 cycle */ 704 705 if (IFM_INST(ife->ifm_media) != 0) { 706 /* Use External PHY */ 707 708 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG, 709 LAN9118_HW_CFG_MBO | 710 LAN9118_HW_CFG_PHY_CLK_SEL_EMII | 711 LAN9118_HW_CFG_SMI_SEL | 712 LAN9118_HW_CFG_EXT_PHY_EN); 713 delay(1); 714 return mii_mediachg(&sc->sc_mii); 715 } 716 717 /* Setup Internal PHY */ 718 719 mii->mii_media_status = IFM_AVALID; 720 mii->mii_media_active = IFM_ETHER; 721 722 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG, 723 LAN9118_HW_CFG_MBO | 724 LAN9118_HW_CFG_PHY_CLK_SEL_IPHY); 725 delay(1); 726 727 /* Reset PHY */ 728 pmt_ctrl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_PMT_CTRL); 729 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_PMT_CTRL, 730 pmt_ctrl | LAN9118_PMT_CTRL_PHY_RST); 731 while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_PMT_CTRL) & 732 LAN9118_PMT_CTRL_PHY_RST); 733 734 mii_mediachg(&sc->sc_mii); 735 return 0; 736 } 737 738 static void 739 lan9118_ifm_status(struct ifnet *ifp, struct ifmediareq *ifmr) 740 { 741 struct lan9118_softc *sc = ifp->if_softc; 742 struct mii_data *mii = &sc->sc_mii; 743 744 DPRINTFN(3, ("%s\n", __func__)); 745 746 mii_pollstat(mii); 747 ifmr->ifm_active = mii->mii_media_active; 748 ifmr->ifm_status = mii->mii_media_status; 749 } 750 751 752 static int 753 lan9118_miibus_readreg(device_t dev, int phy, int reg) 754 { 755 756 return lan9118_mii_readreg(device_private(dev), phy, reg); 757 } 758 static void 759 lan9118_miibus_writereg(device_t dev, int phy, int reg, int val) 760 { 761 762 lan9118_mii_writereg(device_private(dev), phy, reg, val); 763 } 764 765 static void 766 lan9118_miibus_statchg(device_t dev) 767 { 768 struct lan9118_softc *sc = device_private(dev); 769 u_int cr; 770 771 cr = lan9118_mac_readreg(sc, LAN9118_MAC_CR); 772 if (IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) { 773 cr &= ~LAN9118_MAC_CR_RCVOWN; 774 cr |= LAN9118_MAC_CR_FDPX; 775 } else { 776 cr |= LAN9118_MAC_CR_RCVOWN; 777 cr &= ~LAN9118_MAC_CR_FDPX; 778 } 779 lan9118_mac_writereg(sc, LAN9118_MAC_CR, cr); 780 } 781 782 783 static uint16_t 784 lan9118_mii_readreg(struct lan9118_softc *sc, int phy, int reg) 785 { 786 uint32_t acc; 787 788 while (lan9118_mac_readreg(sc, LAN9118_MII_ACC) & 789 LAN9118_MII_ACC_MIIBZY); 790 acc = LAN9118_MII_ACC_PHYA(phy) | LAN9118_MII_ACC_MIIRINDA(reg); 791 lan9118_mac_writereg(sc, LAN9118_MII_ACC, acc); 792 while (lan9118_mac_readreg(sc, LAN9118_MII_ACC) & 793 LAN9118_MII_ACC_MIIBZY); 794 return lan9118_mac_readreg(sc, LAN9118_MII_DATA); 795 } 796 797 static void 798 lan9118_mii_writereg(struct lan9118_softc *sc, int phy, int reg, uint16_t val) 799 { 800 uint32_t acc; 801 802 while (lan9118_mac_readreg(sc, LAN9118_MII_ACC) & 803 LAN9118_MII_ACC_MIIBZY); 804 acc = LAN9118_MII_ACC_PHYA(phy) | LAN9118_MII_ACC_MIIRINDA(reg) | 805 LAN9118_MII_ACC_MIIWNR; 806 lan9118_mac_writereg(sc, LAN9118_MII_DATA, val); 807 lan9118_mac_writereg(sc, LAN9118_MII_ACC, acc); 808 while (lan9118_mac_readreg(sc, LAN9118_MII_ACC) & 809 LAN9118_MII_ACC_MIIBZY); 810 } 811 812 static uint32_t 813 lan9118_mac_readreg(struct lan9118_softc *sc, int reg) 814 { 815 uint32_t cmd; 816 int timo = 3 * 1000 * 1000; /* XXXX: 3sec */ 817 818 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_MAC_CSR_CMD, 819 LAN9118_MAC_CSR_CMD_BUSY | LAN9118_MAC_CSR_CMD_R | reg); 820 do { 821 cmd = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 822 LAN9118_MAC_CSR_CMD); 823 if (!(cmd & LAN9118_MAC_CSR_CMD_BUSY)) 824 break; 825 delay(100); 826 } while (timo -= 100); 827 if (timo <= 0) 828 aprint_error_dev(sc->sc_dev, "%s: command busy\n", __func__); 829 return bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_MAC_CSR_DATA); 830 } 831 832 static void 833 lan9118_mac_writereg(struct lan9118_softc *sc, int reg, uint32_t val) 834 { 835 uint32_t cmd; 836 int timo = 3 * 1000 * 1000; /* XXXX: 3sec */ 837 838 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_MAC_CSR_DATA, val); 839 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_MAC_CSR_CMD, 840 LAN9118_MAC_CSR_CMD_BUSY | LAN9118_MAC_CSR_CMD_W | reg); 841 do { 842 cmd = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 843 LAN9118_MAC_CSR_CMD); 844 if (!(cmd & LAN9118_MAC_CSR_CMD_BUSY)) 845 break; 846 delay(100); 847 } while (timo -= 100); 848 if (timo <= 0) 849 aprint_error_dev(sc->sc_dev, "%s: command busy\n", __func__); 850 } 851 852 853 static void 854 lan9118_set_filter(struct lan9118_softc *sc) 855 { 856 struct ether_multistep step; 857 struct ether_multi *enm; 858 struct ifnet *ifp = &sc->sc_ec.ec_if; 859 uint32_t mac_cr, h, hashes[2] = { 0, 0 }; 860 861 mac_cr = lan9118_mac_readreg(sc, LAN9118_MAC_CR); 862 if (ifp->if_flags & IFF_PROMISC) { 863 lan9118_mac_writereg(sc, LAN9118_MAC_CR, 864 mac_cr | LAN9118_MAC_CR_PRMS); 865 return; 866 } 867 868 mac_cr &= ~(LAN9118_MAC_CR_PRMS | LAN9118_MAC_CR_MCPAS | 869 LAN9118_MAC_CR_BCAST | LAN9118_MAC_CR_HPFILT); 870 if (!(ifp->if_flags & IFF_BROADCAST)) 871 mac_cr |= LAN9118_MAC_CR_BCAST; 872 873 if (ifp->if_flags & IFF_ALLMULTI) 874 mac_cr |= LAN9118_MAC_CR_MCPAS; 875 else { 876 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm); 877 while (enm != NULL) { 878 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 879 ETHER_ADDR_LEN) != 0) { 880 /* 881 * We must listen to a range of multicast 882 * addresses. For now, just accept all 883 * multicasts, rather than trying to set 884 * only those filter bits needed to match 885 * the range. (At this time, the only use 886 * of address ranges is for IP multicast 887 * routing, for which the range is big enough 888 * to require all bits set.) 889 */ 890 ifp->if_flags |= IFF_ALLMULTI; 891 mac_cr |= LAN9118_MAC_CR_MCPAS; 892 break; 893 } 894 h = ether_crc32_le(enm->enm_addrlo, 895 ETHER_ADDR_LEN) >> 26; 896 hashes[h >> 5] |= 1 << (h & 0x1f); 897 898 mac_cr |= LAN9118_MAC_CR_HPFILT; 899 ETHER_NEXT_MULTI(step, enm); 900 } 901 if (mac_cr & LAN9118_MAC_CR_HPFILT) { 902 lan9118_mac_writereg(sc, LAN9118_HASHH, hashes[1]); 903 lan9118_mac_writereg(sc, LAN9118_HASHL, hashes[0]); 904 } 905 } 906 lan9118_mac_writereg(sc, LAN9118_MAC_CR, mac_cr); 907 return; 908 } 909 910 static void 911 lan9118_rxintr(struct lan9118_softc *sc) 912 { 913 struct ifnet *ifp = &sc->sc_ec.ec_if; 914 struct mbuf *m; 915 uint32_t rx_fifo_inf, rx_status; 916 int pktlen; 917 const int pad = ETHER_HDR_LEN % sizeof(uint32_t); 918 919 DPRINTFN(3, ("%s\n", __func__)); 920 921 for (;;) { 922 rx_fifo_inf = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 923 LAN9118_RX_FIFO_INF); 924 if (LAN9118_RX_FIFO_INF_RXSUSED(rx_fifo_inf) == 0) 925 break; 926 927 rx_status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 928 LAN9118_RXSFIFOP); 929 pktlen = LAN9118_RXS_PKTLEN(rx_status); 930 DPRINTFN(3, ("%s: rx_status=0x%x(pktlen %d)\n", 931 __func__, rx_status, pktlen)); 932 if (rx_status & (LAN9118_RXS_ES | LAN9118_RXS_LENERR | 933 LAN9118_RXS_RWTO | LAN9118_RXS_MIIERR | LAN9118_RXS_DBIT)) { 934 if (rx_status & LAN9118_RXS_LENERR) 935 aprint_error_dev(sc->sc_dev, "Length Error\n"); 936 if (rx_status & LAN9118_RXS_RUNTF) 937 aprint_error_dev(sc->sc_dev, "Runt Frame\n"); 938 if (rx_status & LAN9118_RXS_FTL) 939 aprint_error_dev(sc->sc_dev, 940 "Frame Too Long\n"); 941 if (rx_status & LAN9118_RXS_RWTO) 942 aprint_error_dev(sc->sc_dev, 943 "Receive Watchdog time-out\n"); 944 if (rx_status & LAN9118_RXS_MIIERR) 945 aprint_error_dev(sc->sc_dev, "MII Error\n"); 946 if (rx_status & LAN9118_RXS_DBIT) 947 aprint_error_dev(sc->sc_dev, "Drabbling Bit\n"); 948 if (rx_status & LAN9118_RXS_COLS) 949 aprint_error_dev(sc->sc_dev, 950 "Collision Seen\n"); 951 if (rx_status & LAN9118_RXS_CRCERR) 952 aprint_error_dev(sc->sc_dev, "CRC Error\n"); 953 954 dropit: 955 ifp->if_ierrors++; 956 /* 957 * Receive Data FIFO Fast Forward 958 * When performing a fast-forward, there must be at 959 * least 4 DWORDs of data in the RX data FIFO for the 960 * packet being discarded. 961 */ 962 if (pktlen >= 4 * sizeof(uint32_t)) { 963 uint32_t rx_dp_ctl; 964 965 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 966 LAN9118_RX_DP_CTL, 967 LAN9118_RX_DP_CTL_RX_FFWD); 968 /* DP_FFWD bit is self clearing */ 969 do { 970 rx_dp_ctl = bus_space_read_4(sc->sc_iot, 971 sc->sc_ioh, LAN9118_RX_DP_CTL); 972 } while (rx_dp_ctl & LAN9118_RX_DP_CTL_RX_FFWD); 973 } else { 974 /* For less than 4 DWORDs do not use RX_FFWD. */ 975 uint32_t garbage[4]; 976 977 bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh, 978 LAN9118_RXDFIFOP, garbage, 979 roundup(pktlen, 4) >> 2); 980 } 981 continue; 982 } 983 984 MGETHDR(m, M_DONTWAIT, MT_DATA); 985 if (m == NULL) 986 goto dropit; 987 if (pktlen > (MHLEN - pad)) { 988 MCLGET(m, M_DONTWAIT); 989 if ((m->m_flags & M_EXT) == 0) { 990 m_freem(m); 991 goto dropit; 992 } 993 } 994 995 /* STRICT_ALIGNMENT */ 996 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_RX_CFG, 997 LAN9118_RX_CFG_RXEA_4B | LAN9118_RX_CFG_RXDOFF(pad)); 998 bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh, LAN9118_RXDFIFOP, 999 mtod(m, uint32_t *), 1000 roundup(pad + pktlen, sizeof(uint32_t)) >> 2); 1001 m->m_data += pad; 1002 1003 ifp->if_ipackets++; 1004 m->m_pkthdr.rcvif = ifp; 1005 m->m_pkthdr.len = m->m_len = (pktlen - ETHER_CRC_LEN); 1006 1007 /* 1008 * Pass this up to any BPF listeners, but only 1009 * pass if up the stack if it's for us. 1010 */ 1011 bpf_mtap(ifp, m); 1012 1013 /* Pass it on. */ 1014 (*ifp->if_input)(ifp, m); 1015 } 1016 } 1017 1018 static void 1019 lan9118_txintr(struct lan9118_softc *sc) 1020 { 1021 struct ifnet *ifp = &sc->sc_ec.ec_if; 1022 uint32_t tx_fifo_inf, tx_status; 1023 int fdx = IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX; 1024 int tdfree; 1025 1026 DPRINTFN(3, ("%s\n", __func__)); 1027 1028 for (;;) { 1029 tx_fifo_inf = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 1030 LAN9118_TX_FIFO_INF); 1031 if (LAN9118_TX_FIFO_INF_TXSUSED(tx_fifo_inf) == 0) 1032 break; 1033 1034 tx_status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 1035 LAN9118_TXSFIFOP); 1036 DPRINTFN(3, ("%s: tx_status=0x%x\n", __func__, tx_status)); 1037 if (tx_status & LAN9118_TXS_ES) { 1038 if (tx_status & LAN9118_TXS_LOC) 1039 aprint_error_dev(sc->sc_dev, 1040 "Loss Of Carrier\n"); 1041 if ((tx_status & LAN9118_TXS_NC) && !fdx) 1042 aprint_error_dev(sc->sc_dev, "No Carrier\n"); 1043 if (tx_status & LAN9118_TXS_LCOL) 1044 aprint_error_dev(sc->sc_dev, 1045 "Late Collision\n"); 1046 if (tx_status & LAN9118_TXS_ECOL) { 1047 /* Rearch 16 collision */ 1048 ifp->if_collisions += 16; 1049 aprint_error_dev(sc->sc_dev, 1050 "Excessive Collision\n"); 1051 } 1052 if (LAN9118_TXS_COLCNT(tx_status) != 0) 1053 aprint_error_dev(sc->sc_dev, 1054 "Collision Count: %d\n", 1055 LAN9118_TXS_COLCNT(tx_status)); 1056 if (tx_status & LAN9118_TXS_ED) 1057 aprint_error_dev(sc->sc_dev, 1058 "Excessive Deferral\n"); 1059 if (tx_status & LAN9118_TXS_DEFERRED) 1060 aprint_error_dev(sc->sc_dev, "Deferred\n"); 1061 ifp->if_oerrors++; 1062 } else 1063 ifp->if_opackets++; 1064 } 1065 1066 tdfree = LAN9118_TX_FIFO_INF_TDFREE(tx_fifo_inf); 1067 if (tdfree == LAN9118_TX_DATA_FIFO_SIZE) 1068 /* FIFO empty */ 1069 ifp->if_timer = 0; 1070 if (tdfree >= 2036) 1071 /* 1072 * 2036 is the possible maximum FIFO consumption 1073 * for the most fragmented frame. 1074 */ 1075 ifp->if_flags &= ~IFF_OACTIVE; 1076 } 1077 1078 void 1079 lan9118_tick(void *v) 1080 { 1081 struct lan9118_softc *sc = v; 1082 int s; 1083 1084 s = splnet(); 1085 mii_tick(&sc->sc_mii); 1086 callout_schedule(&sc->sc_tick, hz); 1087 splx(s); 1088 } 1089