1 /* $NetBSD: lan9118.c,v 1.13 2010/01/19 22:06:24 pooka 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.13 2010/01/19 22:06:24 pooka 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 if (ifp->if_bpf) 458 bpf_ops->bpf_mtap(ifp->if_bpf, m0); 459 460 m_freem(m0); 461 } 462 if (totlen > 0) 463 ifp->if_timer = 5; 464 } 465 466 static int 467 lan9118_ioctl(struct ifnet *ifp, u_long command, void *data) 468 { 469 struct lan9118_softc *sc = ifp->if_softc; 470 struct ifreq *ifr = data; 471 struct mii_data *mii = &sc->sc_mii; 472 int s, error = 0; 473 474 s = splnet(); 475 476 switch (command) { 477 case SIOCSIFFLAGS: 478 DPRINTFN(2, ("%s: IFFLAGS\n", __func__)); 479 if ((error = ifioctl_common(ifp, command, data)) != 0) 480 break; 481 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 482 case IFF_RUNNING: 483 lan9118_stop(ifp, 0); 484 break; 485 case IFF_UP: 486 lan9118_init(ifp); 487 break; 488 case IFF_UP|IFF_RUNNING: 489 lan9118_set_filter(sc); 490 break; 491 default: 492 break; 493 } 494 error = 0; 495 break; 496 497 case SIOCGIFMEDIA: 498 case SIOCSIFMEDIA: 499 DPRINTFN(2, ("%s: MEDIA\n", __func__)); 500 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 501 break; 502 503 default: 504 DPRINTFN(2, ("%s: ETHER\n", __func__)); 505 error = ether_ioctl(ifp, command, data); 506 if (error == ENETRESET) { 507 if (ifp->if_flags & IFF_RUNNING) { 508 lan9118_set_filter(sc); 509 DPRINTFN(2, ("%s set_filter called\n", 510 __func__)); 511 } 512 error = 0; 513 } 514 break; 515 } 516 517 splx(s); 518 519 return error; 520 } 521 522 static int 523 lan9118_init(struct ifnet *ifp) 524 { 525 struct lan9118_softc *sc = ifp->if_softc; 526 struct ifmedia *ifm = &sc->sc_mii.mii_media; 527 uint32_t reg, hw_cfg, mac_cr; 528 int timo, s; 529 530 DPRINTFN(2, ("%s\n", __func__)); 531 532 s = splnet(); 533 534 /* wait for PMT_CTRL[READY] */ 535 timo = mstohz(5000); /* XXXX 5sec */ 536 while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_PMT_CTRL) & 537 LAN9118_PMT_CTRL_READY)) { 538 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_BYTE_TEST, 539 0xbad0c0de); 540 tsleep(&sc, PRIBIO, "lan9118_pmt_ready", 1); 541 if (--timo <= 0) { 542 splx(s); 543 return EBUSY; 544 } 545 } 546 547 /* Soft Reset */ 548 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG, 549 LAN9118_HW_CFG_SRST); 550 do { 551 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG); 552 if (reg & LAN9118_HW_CFG_SRST_TO) { 553 aprint_error_dev(sc->sc_dev, 554 "soft reset timeouted out\n"); 555 splx(s); 556 return ETIMEDOUT; 557 } 558 } while (reg & LAN9118_HW_CFG_SRST); 559 560 /* Set MAC and PHY CSRs */ 561 562 if (sc->sc_flags & LAN9118_FLAGS_SWAP) 563 /* need byte swap */ 564 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_WORD_SWAP, 565 0xffffffff); 566 567 while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_E2P_CMD) & 568 LAN9118_E2P_CMD_EPCB); 569 if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_E2P_CMD) & 570 LAN9118_E2P_CMD_MACAL)) { 571 lan9118_mac_writereg(sc, LAN9118_ADDRL, 572 sc->sc_enaddr[0] | 573 sc->sc_enaddr[1] << 8 | 574 sc->sc_enaddr[2] << 16 | 575 sc->sc_enaddr[3] << 24); 576 lan9118_mac_writereg(sc, LAN9118_ADDRH, 577 sc->sc_enaddr[4] | sc->sc_enaddr[5] << 8); 578 } 579 580 if (ifm->ifm_media & IFM_FLOW) { 581 lan9118_mac_writereg(sc, LAN9118_FLOW, 582 LAN9118_FLOW_FCPT(1) | LAN9118_FLOW_FCEN); 583 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_AFC_CFG, 584 sc->sc_afc_cfg); 585 } 586 587 lan9118_ifm_change(ifp); 588 hw_cfg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG); 589 hw_cfg &= ~LAN9118_HW_CFG_TX_FIF_MASK; 590 hw_cfg |= LAN9118_HW_CFG_TX_FIF_SZ(LAN9118_TX_FIF_SZ); 591 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG, hw_cfg); 592 593 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_GPIO_CFG, 594 LAN9118_GPIO_CFG_LEDX_EN(2) | 595 LAN9118_GPIO_CFG_LEDX_EN(1) | 596 LAN9118_GPIO_CFG_LEDX_EN(0) | 597 LAN9118_GPIO_CFG_GPIOBUFN(2) | 598 LAN9118_GPIO_CFG_GPIOBUFN(1) | 599 LAN9118_GPIO_CFG_GPIOBUFN(0)); 600 601 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_IRQ_CFG, 602 LAN9118_IRQ_CFG_IRQ_EN); 603 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_STS, 604 bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_STS)); 605 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_FIFO_INT, 606 LAN9118_FIFO_INT_TXSL(0) | LAN9118_FIFO_INT_RXSL(0)); 607 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_EN, 608 #if 0 /* not yet... */ 609 LAN9118_INT_PHY_INT | /* PHY */ 610 LAN9118_INT_PME_INT | /* Power Management Event */ 611 #endif 612 LAN9118_INT_RXE | /* Receive Error */ 613 LAN9118_INT_TSFL | /* TX Status FIFO Level */ 614 LAN9118_INT_RXDF_INT| /* RX Dropped Frame Interrupt */ 615 LAN9118_INT_RSFF | /* RX Status FIFO Full */ 616 LAN9118_INT_RSFL); /* RX Status FIFO Level */ 617 618 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_RX_CFG, 619 LAN9118_RX_CFG_RXDOFF(2)); 620 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_TX_CFG, 621 LAN9118_TX_CFG_TX_ON); 622 mac_cr = lan9118_mac_readreg(sc, LAN9118_MAC_CR); 623 lan9118_mac_writereg(sc, LAN9118_MAC_CR, 624 mac_cr | LAN9118_MAC_CR_TXEN | LAN9118_MAC_CR_RXEN); 625 626 lan9118_set_filter(sc); 627 628 ifp->if_flags |= IFF_RUNNING; 629 ifp->if_flags &= ~IFF_OACTIVE; 630 631 callout_reset(&sc->sc_tick, hz, lan9118_tick, sc); 632 633 splx(s); 634 635 return 0; 636 } 637 638 static void 639 lan9118_stop(struct ifnet *ifp, int disable) 640 { 641 struct lan9118_softc *sc = ifp->if_softc; 642 uint32_t cr; 643 644 DPRINTFN(2, ("%s\n", __func__)); 645 646 /* Disable IRQ */ 647 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_EN, 0); 648 649 /* Stopping transmitter */ 650 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_TX_CFG, 651 LAN9118_TX_CFG_STOP_TX); 652 while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_TX_CFG) & 653 (LAN9118_TX_CFG_TX_ON | LAN9118_TX_CFG_STOP_TX)); 654 655 /* Purge TX Status/Data FIFOs */ 656 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_TX_CFG, 657 LAN9118_TX_CFG_TXS_DUMP | LAN9118_TX_CFG_TXD_DUMP); 658 659 /* Stopping receiver, also clear TXEN */ 660 cr = lan9118_mac_readreg(sc, LAN9118_MAC_CR); 661 cr &= ~(LAN9118_MAC_CR_TXEN | LAN9118_MAC_CR_RXEN); 662 lan9118_mac_writereg(sc, LAN9118_MAC_CR, cr); 663 while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_INT_STS) & 664 LAN9118_INT_RXSTOP_INT)); 665 666 /* Clear RX Status/Data FIFOs */ 667 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_RX_CFG, 668 LAN9118_RX_CFG_RX_DUMP); 669 670 callout_stop(&sc->sc_tick); 671 } 672 673 static void 674 lan9118_watchdog(struct ifnet *ifp) 675 { 676 struct lan9118_softc *sc = ifp->if_softc; 677 678 /* 679 * Reclaim first as there is a possibility of losing Tx completion 680 * interrupts. 681 */ 682 lan9118_txintr(sc); 683 684 aprint_error_ifnet(ifp, "watchdog timeout\n"); 685 ifp->if_oerrors++; 686 687 lan9118_init(ifp); 688 } 689 690 691 static int 692 lan9118_ifm_change(struct ifnet *ifp) 693 { 694 struct lan9118_softc *sc = ifp->if_softc; 695 struct mii_data *mii = &sc->sc_mii; 696 struct ifmedia *ifm = &mii->mii_media; 697 struct ifmedia_entry *ife = ifm->ifm_cur; 698 uint32_t pmt_ctrl; 699 700 DPRINTFN(3, ("%s: ifm inst %d\n", __func__, IFM_INST(ife->ifm_media))); 701 702 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG, 703 LAN9118_HW_CFG_MBO | LAN9118_HW_CFG_PHY_CLK_SEL_CD); 704 delay(1); /* Wait 5 cycle */ 705 706 if (IFM_INST(ife->ifm_media) != 0) { 707 /* Use External PHY */ 708 709 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG, 710 LAN9118_HW_CFG_MBO | 711 LAN9118_HW_CFG_PHY_CLK_SEL_EMII | 712 LAN9118_HW_CFG_SMI_SEL | 713 LAN9118_HW_CFG_EXT_PHY_EN); 714 delay(1); 715 return mii_mediachg(&sc->sc_mii); 716 } 717 718 /* Setup Internal PHY */ 719 720 mii->mii_media_status = IFM_AVALID; 721 mii->mii_media_active = IFM_ETHER; 722 723 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_HW_CFG, 724 LAN9118_HW_CFG_MBO | 725 LAN9118_HW_CFG_PHY_CLK_SEL_IPHY); 726 delay(1); 727 728 /* Reset PHY */ 729 pmt_ctrl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_PMT_CTRL); 730 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_PMT_CTRL, 731 pmt_ctrl | LAN9118_PMT_CTRL_PHY_RST); 732 while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_PMT_CTRL) & 733 LAN9118_PMT_CTRL_PHY_RST); 734 735 mii_mediachg(&sc->sc_mii); 736 return 0; 737 } 738 739 static void 740 lan9118_ifm_status(struct ifnet *ifp, struct ifmediareq *ifmr) 741 { 742 struct lan9118_softc *sc = ifp->if_softc; 743 struct mii_data *mii = &sc->sc_mii; 744 745 DPRINTFN(3, ("%s\n", __func__)); 746 747 mii_pollstat(mii); 748 ifmr->ifm_active = mii->mii_media_active; 749 ifmr->ifm_status = mii->mii_media_status; 750 } 751 752 753 static int 754 lan9118_miibus_readreg(device_t dev, int phy, int reg) 755 { 756 757 return lan9118_mii_readreg(device_private(dev), phy, reg); 758 } 759 static void 760 lan9118_miibus_writereg(device_t dev, int phy, int reg, int val) 761 { 762 763 lan9118_mii_writereg(device_private(dev), phy, reg, val); 764 } 765 766 static void 767 lan9118_miibus_statchg(device_t dev) 768 { 769 struct lan9118_softc *sc = device_private(dev); 770 u_int cr; 771 772 cr = lan9118_mac_readreg(sc, LAN9118_MAC_CR); 773 if (IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) { 774 cr &= ~LAN9118_MAC_CR_RCVOWN; 775 cr |= LAN9118_MAC_CR_FDPX; 776 } else { 777 cr |= LAN9118_MAC_CR_RCVOWN; 778 cr &= ~LAN9118_MAC_CR_FDPX; 779 } 780 lan9118_mac_writereg(sc, LAN9118_MAC_CR, cr); 781 } 782 783 784 static uint16_t 785 lan9118_mii_readreg(struct lan9118_softc *sc, int phy, int reg) 786 { 787 uint32_t acc; 788 789 while (lan9118_mac_readreg(sc, LAN9118_MII_ACC) & 790 LAN9118_MII_ACC_MIIBZY); 791 acc = LAN9118_MII_ACC_PHYA(phy) | LAN9118_MII_ACC_MIIRINDA(reg); 792 lan9118_mac_writereg(sc, LAN9118_MII_ACC, acc); 793 while (lan9118_mac_readreg(sc, LAN9118_MII_ACC) & 794 LAN9118_MII_ACC_MIIBZY); 795 return lan9118_mac_readreg(sc, LAN9118_MII_DATA); 796 } 797 798 static void 799 lan9118_mii_writereg(struct lan9118_softc *sc, int phy, int reg, uint16_t val) 800 { 801 uint32_t acc; 802 803 while (lan9118_mac_readreg(sc, LAN9118_MII_ACC) & 804 LAN9118_MII_ACC_MIIBZY); 805 acc = LAN9118_MII_ACC_PHYA(phy) | LAN9118_MII_ACC_MIIRINDA(reg) | 806 LAN9118_MII_ACC_MIIWNR; 807 lan9118_mac_writereg(sc, LAN9118_MII_DATA, val); 808 lan9118_mac_writereg(sc, LAN9118_MII_ACC, acc); 809 while (lan9118_mac_readreg(sc, LAN9118_MII_ACC) & 810 LAN9118_MII_ACC_MIIBZY); 811 } 812 813 static uint32_t 814 lan9118_mac_readreg(struct lan9118_softc *sc, int reg) 815 { 816 uint32_t cmd; 817 int timo = 3 * 1000 * 1000; /* XXXX: 3sec */ 818 819 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_MAC_CSR_CMD, 820 LAN9118_MAC_CSR_CMD_BUSY | LAN9118_MAC_CSR_CMD_R | reg); 821 do { 822 cmd = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 823 LAN9118_MAC_CSR_CMD); 824 if (!(cmd & LAN9118_MAC_CSR_CMD_BUSY)) 825 break; 826 delay(100); 827 } while (timo -= 100); 828 if (timo <= 0) 829 aprint_error_dev(sc->sc_dev, "%s: command busy\n", __func__); 830 return bus_space_read_4(sc->sc_iot, sc->sc_ioh, LAN9118_MAC_CSR_DATA); 831 } 832 833 static void 834 lan9118_mac_writereg(struct lan9118_softc *sc, int reg, uint32_t val) 835 { 836 uint32_t cmd; 837 int timo = 3 * 1000 * 1000; /* XXXX: 3sec */ 838 839 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_MAC_CSR_DATA, val); 840 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_MAC_CSR_CMD, 841 LAN9118_MAC_CSR_CMD_BUSY | LAN9118_MAC_CSR_CMD_W | reg); 842 do { 843 cmd = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 844 LAN9118_MAC_CSR_CMD); 845 if (!(cmd & LAN9118_MAC_CSR_CMD_BUSY)) 846 break; 847 delay(100); 848 } while (timo -= 100); 849 if (timo <= 0) 850 aprint_error_dev(sc->sc_dev, "%s: command busy\n", __func__); 851 } 852 853 854 static void 855 lan9118_set_filter(struct lan9118_softc *sc) 856 { 857 struct ether_multistep step; 858 struct ether_multi *enm; 859 struct ifnet *ifp = &sc->sc_ec.ec_if; 860 uint32_t mac_cr, h, hashes[2] = { 0, 0 }; 861 862 mac_cr = lan9118_mac_readreg(sc, LAN9118_MAC_CR); 863 if (ifp->if_flags & IFF_PROMISC) { 864 lan9118_mac_writereg(sc, LAN9118_MAC_CR, 865 mac_cr | LAN9118_MAC_CR_PRMS); 866 return; 867 } 868 869 mac_cr &= ~(LAN9118_MAC_CR_PRMS | LAN9118_MAC_CR_MCPAS | 870 LAN9118_MAC_CR_BCAST | LAN9118_MAC_CR_HPFILT); 871 if (!(ifp->if_flags & IFF_BROADCAST)) 872 mac_cr |= LAN9118_MAC_CR_BCAST; 873 874 if (ifp->if_flags & IFF_ALLMULTI) 875 mac_cr |= LAN9118_MAC_CR_MCPAS; 876 else { 877 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm); 878 while (enm != NULL) { 879 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 880 ETHER_ADDR_LEN) != 0) { 881 /* 882 * We must listen to a range of multicast 883 * addresses. For now, just accept all 884 * multicasts, rather than trying to set 885 * only those filter bits needed to match 886 * the range. (At this time, the only use 887 * of address ranges is for IP multicast 888 * routing, for which the range is big enough 889 * to require all bits set.) 890 */ 891 ifp->if_flags |= IFF_ALLMULTI; 892 mac_cr |= LAN9118_MAC_CR_MCPAS; 893 break; 894 } 895 h = ether_crc32_le(enm->enm_addrlo, 896 ETHER_ADDR_LEN) >> 26; 897 hashes[h >> 5] |= 1 << (h & 0x1f); 898 899 mac_cr |= LAN9118_MAC_CR_HPFILT; 900 ETHER_NEXT_MULTI(step, enm); 901 } 902 if (mac_cr & LAN9118_MAC_CR_HPFILT) { 903 lan9118_mac_writereg(sc, LAN9118_HASHH, hashes[1]); 904 lan9118_mac_writereg(sc, LAN9118_HASHL, hashes[0]); 905 } 906 } 907 lan9118_mac_writereg(sc, LAN9118_MAC_CR, mac_cr); 908 return; 909 } 910 911 static void 912 lan9118_rxintr(struct lan9118_softc *sc) 913 { 914 struct ifnet *ifp = &sc->sc_ec.ec_if; 915 struct mbuf *m; 916 uint32_t rx_fifo_inf, rx_status; 917 int pktlen; 918 const int pad = ETHER_HDR_LEN % sizeof(uint32_t); 919 920 DPRINTFN(3, ("%s\n", __func__)); 921 922 for (;;) { 923 rx_fifo_inf = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 924 LAN9118_RX_FIFO_INF); 925 if (LAN9118_RX_FIFO_INF_RXSUSED(rx_fifo_inf) == 0) 926 break; 927 928 rx_status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 929 LAN9118_RXSFIFOP); 930 pktlen = LAN9118_RXS_PKTLEN(rx_status); 931 DPRINTFN(3, ("%s: rx_status=0x%x(pktlen %d)\n", 932 __func__, rx_status, pktlen)); 933 if (rx_status & (LAN9118_RXS_ES | LAN9118_RXS_LENERR | 934 LAN9118_RXS_RWTO | LAN9118_RXS_MIIERR | LAN9118_RXS_DBIT)) { 935 if (rx_status & LAN9118_RXS_LENERR) 936 aprint_error_dev(sc->sc_dev, "Length Error\n"); 937 if (rx_status & LAN9118_RXS_RUNTF) 938 aprint_error_dev(sc->sc_dev, "Runt Frame\n"); 939 if (rx_status & LAN9118_RXS_FTL) 940 aprint_error_dev(sc->sc_dev, 941 "Frame Too Long\n"); 942 if (rx_status & LAN9118_RXS_RWTO) 943 aprint_error_dev(sc->sc_dev, 944 "Receive Watchdog time-out\n"); 945 if (rx_status & LAN9118_RXS_MIIERR) 946 aprint_error_dev(sc->sc_dev, "MII Error\n"); 947 if (rx_status & LAN9118_RXS_DBIT) 948 aprint_error_dev(sc->sc_dev, "Drabbling Bit\n"); 949 if (rx_status & LAN9118_RXS_COLS) 950 aprint_error_dev(sc->sc_dev, 951 "Collision Seen\n"); 952 if (rx_status & LAN9118_RXS_CRCERR) 953 aprint_error_dev(sc->sc_dev, "CRC Error\n"); 954 955 dropit: 956 ifp->if_ierrors++; 957 /* 958 * Receive Data FIFO Fast Forward 959 * When performing a fast-forward, there must be at 960 * least 4 DWORDs of data in the RX data FIFO for the 961 * packet being discarded. 962 */ 963 if (pktlen >= 4 * sizeof(uint32_t)) { 964 uint32_t rx_dp_ctl; 965 966 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 967 LAN9118_RX_DP_CTL, 968 LAN9118_RX_DP_CTL_RX_FFWD); 969 /* DP_FFWD bit is self clearing */ 970 do { 971 rx_dp_ctl = bus_space_read_4(sc->sc_iot, 972 sc->sc_ioh, LAN9118_RX_DP_CTL); 973 } while (rx_dp_ctl & LAN9118_RX_DP_CTL_RX_FFWD); 974 } else { 975 /* For less than 4 DWORDs do not use RX_FFWD. */ 976 uint32_t garbage[4]; 977 978 bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh, 979 LAN9118_RXDFIFOP, garbage, 980 roundup(pktlen, 4) >> 2); 981 } 982 continue; 983 } 984 985 MGETHDR(m, M_DONTWAIT, MT_DATA); 986 if (m == NULL) 987 goto dropit; 988 if (pktlen > (MHLEN - pad)) { 989 MCLGET(m, M_DONTWAIT); 990 if ((m->m_flags & M_EXT) == 0) { 991 m_freem(m); 992 goto dropit; 993 } 994 } 995 996 /* STRICT_ALIGNMENT */ 997 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LAN9118_RX_CFG, 998 LAN9118_RX_CFG_RXEA_4B | LAN9118_RX_CFG_RXDOFF(pad)); 999 bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh, LAN9118_RXDFIFOP, 1000 mtod(m, uint32_t *), 1001 roundup(pad + pktlen, sizeof(uint32_t)) >> 2); 1002 m->m_data += pad; 1003 1004 ifp->if_ipackets++; 1005 m->m_pkthdr.rcvif = ifp; 1006 m->m_pkthdr.len = m->m_len = (pktlen - ETHER_CRC_LEN); 1007 1008 /* 1009 * Pass this up to any BPF listeners, but only 1010 * pass if up the stack if it's for us. 1011 */ 1012 if (ifp->if_bpf) 1013 bpf_ops->bpf_mtap(ifp->if_bpf, m); 1014 1015 /* Pass it on. */ 1016 (*ifp->if_input)(ifp, m); 1017 } 1018 } 1019 1020 static void 1021 lan9118_txintr(struct lan9118_softc *sc) 1022 { 1023 struct ifnet *ifp = &sc->sc_ec.ec_if; 1024 uint32_t tx_fifo_inf, tx_status; 1025 int fdx = IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX; 1026 int tdfree; 1027 1028 DPRINTFN(3, ("%s\n", __func__)); 1029 1030 for (;;) { 1031 tx_fifo_inf = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 1032 LAN9118_TX_FIFO_INF); 1033 if (LAN9118_TX_FIFO_INF_TXSUSED(tx_fifo_inf) == 0) 1034 break; 1035 1036 tx_status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 1037 LAN9118_TXSFIFOP); 1038 DPRINTFN(3, ("%s: tx_status=0x%x\n", __func__, tx_status)); 1039 if (tx_status & LAN9118_TXS_ES) { 1040 if (tx_status & LAN9118_TXS_LOC) 1041 aprint_error_dev(sc->sc_dev, 1042 "Loss Of Carrier\n"); 1043 if ((tx_status & LAN9118_TXS_NC) && !fdx) 1044 aprint_error_dev(sc->sc_dev, "No Carrier\n"); 1045 if (tx_status & LAN9118_TXS_LCOL) 1046 aprint_error_dev(sc->sc_dev, 1047 "Late Collision\n"); 1048 if (tx_status & LAN9118_TXS_ECOL) { 1049 /* Rearch 16 collision */ 1050 ifp->if_collisions += 16; 1051 aprint_error_dev(sc->sc_dev, 1052 "Excessive Collision\n"); 1053 } 1054 if (LAN9118_TXS_COLCNT(tx_status) != 0) 1055 aprint_error_dev(sc->sc_dev, 1056 "Collision Count: %d\n", 1057 LAN9118_TXS_COLCNT(tx_status)); 1058 if (tx_status & LAN9118_TXS_ED) 1059 aprint_error_dev(sc->sc_dev, 1060 "Excessive Deferral\n"); 1061 if (tx_status & LAN9118_TXS_DEFERRED) 1062 aprint_error_dev(sc->sc_dev, "Deferred\n"); 1063 ifp->if_oerrors++; 1064 } else 1065 ifp->if_opackets++; 1066 } 1067 1068 tdfree = LAN9118_TX_FIFO_INF_TDFREE(tx_fifo_inf); 1069 if (tdfree == LAN9118_TX_DATA_FIFO_SIZE) 1070 /* FIFO empty */ 1071 ifp->if_timer = 0; 1072 if (tdfree >= 2036) 1073 /* 1074 * 2036 is the possible maximum FIFO consumption 1075 * for the most fragmented frame. 1076 */ 1077 ifp->if_flags &= ~IFF_OACTIVE; 1078 } 1079 1080 void 1081 lan9118_tick(void *v) 1082 { 1083 struct lan9118_softc *sc = v; 1084 int s; 1085 1086 s = splnet(); 1087 mii_tick(&sc->sc_mii); 1088 callout_schedule(&sc->sc_tick, hz); 1089 splx(s); 1090 } 1091