Annotation of sys/dev/ic/re.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: re.c,v 1.74 2007/07/16 19:15:01 millert Exp $ */
! 2: /* $FreeBSD: if_re.c,v 1.31 2004/09/04 07:54:05 ru Exp $ */
! 3: /*
! 4: * Copyright (c) 1997, 1998-2003
! 5: * Bill Paul <wpaul@windriver.com>. All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed by Bill Paul.
! 18: * 4. Neither the name of the author nor the names of any co-contributors
! 19: * may be used to endorse or promote products derived from this software
! 20: * without specific prior written permission.
! 21: *
! 22: * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
! 23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 25: * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
! 26: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 27: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 28: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 29: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 30: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 31: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
! 32: * THE POSSIBILITY OF SUCH DAMAGE.
! 33: */
! 34:
! 35: /*
! 36: * RealTek 8139C+/8169/8169S/8110S PCI NIC driver
! 37: *
! 38: * Written by Bill Paul <wpaul@windriver.com>
! 39: * Senior Networking Software Engineer
! 40: * Wind River Systems
! 41: */
! 42:
! 43: /*
! 44: * This driver is designed to support RealTek's next generation of
! 45: * 10/100 and 10/100/1000 PCI ethernet controllers. There are currently
! 46: * seven devices in this family: the RTL8139C+, the RTL8169, the RTL8169S,
! 47: * RTL8110S, the RTL8168, the RTL8111 and the RTL8101E.
! 48: *
! 49: * The 8139C+ is a 10/100 ethernet chip. It is backwards compatible
! 50: * with the older 8139 family, however it also supports a special
! 51: * C+ mode of operation that provides several new performance enhancing
! 52: * features. These include:
! 53: *
! 54: * o Descriptor based DMA mechanism. Each descriptor represents
! 55: * a single packet fragment. Data buffers may be aligned on
! 56: * any byte boundary.
! 57: *
! 58: * o 64-bit DMA
! 59: *
! 60: * o TCP/IP checksum offload for both RX and TX
! 61: *
! 62: * o High and normal priority transmit DMA rings
! 63: *
! 64: * o VLAN tag insertion and extraction
! 65: *
! 66: * o TCP large send (segmentation offload)
! 67: *
! 68: * Like the 8139, the 8139C+ also has a built-in 10/100 PHY. The C+
! 69: * programming API is fairly straightforward. The RX filtering, EEPROM
! 70: * access and PHY access is the same as it is on the older 8139 series
! 71: * chips.
! 72: *
! 73: * The 8169 is a 64-bit 10/100/1000 gigabit ethernet MAC. It has almost the
! 74: * same programming API and feature set as the 8139C+ with the following
! 75: * differences and additions:
! 76: *
! 77: * o 1000Mbps mode
! 78: *
! 79: * o Jumbo frames
! 80: *
! 81: * o GMII and TBI ports/registers for interfacing with copper
! 82: * or fiber PHYs
! 83: *
! 84: * o RX and TX DMA rings can have up to 1024 descriptors
! 85: * (the 8139C+ allows a maximum of 64)
! 86: *
! 87: * o Slight differences in register layout from the 8139C+
! 88: *
! 89: * The TX start and timer interrupt registers are at different locations
! 90: * on the 8169 than they are on the 8139C+. Also, the status word in the
! 91: * RX descriptor has a slightly different bit layout. The 8169 does not
! 92: * have a built-in PHY. Most reference boards use a Marvell 88E1000 'Alaska'
! 93: * copper gigE PHY.
! 94: *
! 95: * The 8169S/8110S 10/100/1000 devices have built-in copper gigE PHYs
! 96: * (the 'S' stands for 'single-chip'). These devices have the same
! 97: * programming API as the older 8169, but also have some vendor-specific
! 98: * registers for the on-board PHY. The 8110S is a LAN-on-motherboard
! 99: * part designed to be pin-compatible with the RealTek 8100 10/100 chip.
! 100: *
! 101: * This driver takes advantage of the RX and TX checksum offload and
! 102: * VLAN tag insertion/extraction features. It also implements TX
! 103: * interrupt moderation using the timer interrupt registers, which
! 104: * significantly reduces TX interrupt load. There is also support
! 105: * for jumbo frames, however the 8169/8169S/8110S can not transmit
! 106: * jumbo frames larger than 7440, so the max MTU possible with this
! 107: * driver is 7422 bytes.
! 108: */
! 109:
! 110: #include "bpfilter.h"
! 111: #include "vlan.h"
! 112:
! 113: #include <sys/param.h>
! 114: #include <sys/endian.h>
! 115: #include <sys/systm.h>
! 116: #include <sys/sockio.h>
! 117: #include <sys/mbuf.h>
! 118: #include <sys/malloc.h>
! 119: #include <sys/kernel.h>
! 120: #include <sys/device.h>
! 121: #include <sys/timeout.h>
! 122: #include <sys/socket.h>
! 123:
! 124: #include <net/if.h>
! 125: #include <net/if_dl.h>
! 126: #include <net/if_media.h>
! 127:
! 128: #ifdef INET
! 129: #include <netinet/in.h>
! 130: #include <netinet/in_systm.h>
! 131: #include <netinet/in_var.h>
! 132: #include <netinet/ip.h>
! 133: #include <netinet/if_ether.h>
! 134: #endif
! 135:
! 136: #if NVLAN > 0
! 137: #include <net/if_types.h>
! 138: #include <net/if_vlan_var.h>
! 139: #endif
! 140:
! 141: #if NBPFILTER > 0
! 142: #include <net/bpf.h>
! 143: #endif
! 144:
! 145: #include <dev/mii/mii.h>
! 146: #include <dev/mii/miivar.h>
! 147:
! 148: #include <dev/pci/pcireg.h>
! 149: #include <dev/pci/pcivar.h>
! 150:
! 151: #include <dev/ic/rtl81x9reg.h>
! 152: #include <dev/ic/revar.h>
! 153:
! 154: #ifdef RE_DEBUG
! 155: int redebug = 0;
! 156: #define DPRINTF(x) do { if (redebug) printf x; } while (0)
! 157: #else
! 158: #define DPRINTF(x)
! 159: #endif
! 160:
! 161: static inline void re_set_bufaddr(struct rl_desc *, bus_addr_t);
! 162:
! 163: int re_encap(struct rl_softc *, struct mbuf *, int *);
! 164:
! 165: int re_newbuf(struct rl_softc *, int, struct mbuf *);
! 166: int re_rx_list_init(struct rl_softc *);
! 167: int re_tx_list_init(struct rl_softc *);
! 168: void re_rxeof(struct rl_softc *);
! 169: void re_txeof(struct rl_softc *);
! 170: void re_tick(void *);
! 171: void re_start(struct ifnet *);
! 172: int re_ioctl(struct ifnet *, u_long, caddr_t);
! 173: void re_watchdog(struct ifnet *);
! 174: int re_ifmedia_upd(struct ifnet *);
! 175: void re_ifmedia_sts(struct ifnet *, struct ifmediareq *);
! 176:
! 177: void re_eeprom_putbyte(struct rl_softc *, int);
! 178: void re_eeprom_getword(struct rl_softc *, int, u_int16_t *);
! 179: void re_read_eeprom(struct rl_softc *, caddr_t, int, int);
! 180:
! 181: int re_gmii_readreg(struct device *, int, int);
! 182: void re_gmii_writereg(struct device *, int, int, int);
! 183:
! 184: int re_miibus_readreg(struct device *, int, int);
! 185: void re_miibus_writereg(struct device *, int, int, int);
! 186: void re_miibus_statchg(struct device *);
! 187:
! 188: void re_setmulti(struct rl_softc *);
! 189: void re_setpromisc(struct rl_softc *);
! 190: void re_reset(struct rl_softc *);
! 191:
! 192: #ifdef RE_DIAG
! 193: int re_diag(struct rl_softc *);
! 194: #endif
! 195:
! 196: struct cfdriver re_cd = {
! 197: 0, "re", DV_IFNET
! 198: };
! 199:
! 200: #define EE_SET(x) \
! 201: CSR_WRITE_1(sc, RL_EECMD, \
! 202: CSR_READ_1(sc, RL_EECMD) | x)
! 203:
! 204: #define EE_CLR(x) \
! 205: CSR_WRITE_1(sc, RL_EECMD, \
! 206: CSR_READ_1(sc, RL_EECMD) & ~x)
! 207:
! 208: static const struct re_revision {
! 209: u_int32_t re_chipid;
! 210: const char *re_name;
! 211: } re_revisions[] = {
! 212: { RL_HWREV_8169, "RTL8169" },
! 213: { RL_HWREV_8110S, "RTL8110S" },
! 214: { RL_HWREV_8169S, "RTL8169S" },
! 215: { RL_HWREV_8169_8110SB, "RTL8169/8110SB" },
! 216: { RL_HWREV_8169_8110SCd, "RTL8169/8110SCd" },
! 217: { RL_HWREV_8168_SPIN1, "RTL8168 1" },
! 218: { RL_HWREV_8100E_SPIN1, "RTL8100E 1" },
! 219: { RL_HWREV_8101E, "RTL8101E" },
! 220: { RL_HWREV_8168_SPIN2, "RTL8168 2" },
! 221: { RL_HWREV_8168_SPIN3, "RTL8168 3" },
! 222: { RL_HWREV_8100E_SPIN2, "RTL8100E 2" },
! 223: { RL_HWREV_8139CPLUS, "RTL8139C+" },
! 224: { RL_HWREV_8101, "RTL8101" },
! 225: { RL_HWREV_8100, "RTL8100" },
! 226: { RL_HWREV_8169_8110SCe, "RTL8169/8110SCe" },
! 227:
! 228: { 0, NULL }
! 229: };
! 230:
! 231:
! 232: static inline void
! 233: re_set_bufaddr(struct rl_desc *d, bus_addr_t addr)
! 234: {
! 235: d->rl_bufaddr_lo = htole32((uint32_t)addr);
! 236: if (sizeof(bus_addr_t) == sizeof(uint64_t))
! 237: d->rl_bufaddr_hi = htole32((uint64_t)addr >> 32);
! 238: else
! 239: d->rl_bufaddr_hi = 0;
! 240: }
! 241:
! 242: /*
! 243: * Send a read command and address to the EEPROM, check for ACK.
! 244: */
! 245: void
! 246: re_eeprom_putbyte(struct rl_softc *sc, int addr)
! 247: {
! 248: int d, i;
! 249:
! 250: d = addr | (RL_9346_READ << sc->rl_eewidth);
! 251:
! 252: /*
! 253: * Feed in each bit and strobe the clock.
! 254: */
! 255:
! 256: for (i = 1 << (sc->rl_eewidth + 3); i; i >>= 1) {
! 257: if (d & i)
! 258: EE_SET(RL_EE_DATAIN);
! 259: else
! 260: EE_CLR(RL_EE_DATAIN);
! 261: DELAY(100);
! 262: EE_SET(RL_EE_CLK);
! 263: DELAY(150);
! 264: EE_CLR(RL_EE_CLK);
! 265: DELAY(100);
! 266: }
! 267: }
! 268:
! 269: /*
! 270: * Read a word of data stored in the EEPROM at address 'addr.'
! 271: */
! 272: void
! 273: re_eeprom_getword(struct rl_softc *sc, int addr, u_int16_t *dest)
! 274: {
! 275: int i;
! 276: u_int16_t word = 0;
! 277:
! 278: /*
! 279: * Send address of word we want to read.
! 280: */
! 281: re_eeprom_putbyte(sc, addr);
! 282:
! 283: /*
! 284: * Start reading bits from EEPROM.
! 285: */
! 286: for (i = 0x8000; i; i >>= 1) {
! 287: EE_SET(RL_EE_CLK);
! 288: DELAY(100);
! 289: if (CSR_READ_1(sc, RL_EECMD) & RL_EE_DATAOUT)
! 290: word |= i;
! 291: EE_CLR(RL_EE_CLK);
! 292: DELAY(100);
! 293: }
! 294:
! 295: *dest = word;
! 296: }
! 297:
! 298: /*
! 299: * Read a sequence of words from the EEPROM.
! 300: */
! 301: void
! 302: re_read_eeprom(struct rl_softc *sc, caddr_t dest, int off, int cnt)
! 303: {
! 304: int i;
! 305: u_int16_t word = 0, *ptr;
! 306:
! 307: CSR_SETBIT_1(sc, RL_EECMD, RL_EEMODE_PROGRAM);
! 308:
! 309: DELAY(100);
! 310:
! 311: for (i = 0; i < cnt; i++) {
! 312: CSR_SETBIT_1(sc, RL_EECMD, RL_EE_SEL);
! 313: re_eeprom_getword(sc, off + i, &word);
! 314: CSR_CLRBIT_1(sc, RL_EECMD, RL_EE_SEL);
! 315: ptr = (u_int16_t *)(dest + (i * 2));
! 316: *ptr = word;
! 317: }
! 318:
! 319: CSR_CLRBIT_1(sc, RL_EECMD, RL_EEMODE_PROGRAM);
! 320: }
! 321:
! 322: int
! 323: re_gmii_readreg(struct device *self, int phy, int reg)
! 324: {
! 325: struct rl_softc *sc = (struct rl_softc *)self;
! 326: u_int32_t rval;
! 327: int i;
! 328:
! 329: if (phy != 7)
! 330: return (0);
! 331:
! 332: /* Let the rgephy driver read the GMEDIASTAT register */
! 333:
! 334: if (reg == RL_GMEDIASTAT) {
! 335: rval = CSR_READ_1(sc, RL_GMEDIASTAT);
! 336: return (rval);
! 337: }
! 338:
! 339: CSR_WRITE_4(sc, RL_PHYAR, reg << 16);
! 340: DELAY(1000);
! 341:
! 342: for (i = 0; i < RL_TIMEOUT; i++) {
! 343: rval = CSR_READ_4(sc, RL_PHYAR);
! 344: if (rval & RL_PHYAR_BUSY)
! 345: break;
! 346: DELAY(100);
! 347: }
! 348:
! 349: if (i == RL_TIMEOUT) {
! 350: printf ("%s: PHY read failed\n", sc->sc_dev.dv_xname);
! 351: return (0);
! 352: }
! 353:
! 354: return (rval & RL_PHYAR_PHYDATA);
! 355: }
! 356:
! 357: void
! 358: re_gmii_writereg(struct device *dev, int phy, int reg, int data)
! 359: {
! 360: struct rl_softc *sc = (struct rl_softc *)dev;
! 361: u_int32_t rval;
! 362: int i;
! 363:
! 364: CSR_WRITE_4(sc, RL_PHYAR, (reg << 16) |
! 365: (data & RL_PHYAR_PHYDATA) | RL_PHYAR_BUSY);
! 366: DELAY(1000);
! 367:
! 368: for (i = 0; i < RL_TIMEOUT; i++) {
! 369: rval = CSR_READ_4(sc, RL_PHYAR);
! 370: if (!(rval & RL_PHYAR_BUSY))
! 371: break;
! 372: DELAY(100);
! 373: }
! 374:
! 375: if (i == RL_TIMEOUT)
! 376: printf ("%s: PHY write failed\n", sc->sc_dev.dv_xname);
! 377: }
! 378:
! 379: int
! 380: re_miibus_readreg(struct device *dev, int phy, int reg)
! 381: {
! 382: struct rl_softc *sc = (struct rl_softc *)dev;
! 383: u_int16_t rval = 0;
! 384: u_int16_t re8139_reg = 0;
! 385: int s;
! 386:
! 387: s = splnet();
! 388:
! 389: if (sc->rl_type == RL_8169) {
! 390: rval = re_gmii_readreg(dev, phy, reg);
! 391: splx(s);
! 392: return (rval);
! 393: }
! 394:
! 395: /* Pretend the internal PHY is only at address 0 */
! 396: if (phy) {
! 397: splx(s);
! 398: return (0);
! 399: }
! 400: switch(reg) {
! 401: case MII_BMCR:
! 402: re8139_reg = RL_BMCR;
! 403: break;
! 404: case MII_BMSR:
! 405: re8139_reg = RL_BMSR;
! 406: break;
! 407: case MII_ANAR:
! 408: re8139_reg = RL_ANAR;
! 409: break;
! 410: case MII_ANER:
! 411: re8139_reg = RL_ANER;
! 412: break;
! 413: case MII_ANLPAR:
! 414: re8139_reg = RL_LPAR;
! 415: break;
! 416: case MII_PHYIDR1:
! 417: case MII_PHYIDR2:
! 418: splx(s);
! 419: return (0);
! 420: /*
! 421: * Allow the rlphy driver to read the media status
! 422: * register. If we have a link partner which does not
! 423: * support NWAY, this is the register which will tell
! 424: * us the results of parallel detection.
! 425: */
! 426: case RL_MEDIASTAT:
! 427: rval = CSR_READ_1(sc, RL_MEDIASTAT);
! 428: splx(s);
! 429: return (rval);
! 430: default:
! 431: printf("%s: bad phy register %x\n", sc->sc_dev.dv_xname, reg);
! 432: splx(s);
! 433: return (0);
! 434: }
! 435: rval = CSR_READ_2(sc, re8139_reg);
! 436: if (sc->rl_type == RL_8139CPLUS && re8139_reg == RL_BMCR) {
! 437: /* 8139C+ has different bit layout. */
! 438: rval &= ~(BMCR_LOOP | BMCR_ISO);
! 439: }
! 440: splx(s);
! 441: return (rval);
! 442: }
! 443:
! 444: void
! 445: re_miibus_writereg(struct device *dev, int phy, int reg, int data)
! 446: {
! 447: struct rl_softc *sc = (struct rl_softc *)dev;
! 448: u_int16_t re8139_reg = 0;
! 449: int s;
! 450:
! 451: s = splnet();
! 452:
! 453: if (sc->rl_type == RL_8169) {
! 454: re_gmii_writereg(dev, phy, reg, data);
! 455: splx(s);
! 456: return;
! 457: }
! 458:
! 459: /* Pretend the internal PHY is only at address 0 */
! 460: if (phy) {
! 461: splx(s);
! 462: return;
! 463: }
! 464: switch(reg) {
! 465: case MII_BMCR:
! 466: re8139_reg = RL_BMCR;
! 467: if (sc->rl_type == RL_8139CPLUS) {
! 468: /* 8139C+ has different bit layout. */
! 469: data &= ~(BMCR_LOOP | BMCR_ISO);
! 470: }
! 471: break;
! 472: case MII_BMSR:
! 473: re8139_reg = RL_BMSR;
! 474: break;
! 475: case MII_ANAR:
! 476: re8139_reg = RL_ANAR;
! 477: break;
! 478: case MII_ANER:
! 479: re8139_reg = RL_ANER;
! 480: break;
! 481: case MII_ANLPAR:
! 482: re8139_reg = RL_LPAR;
! 483: break;
! 484: case MII_PHYIDR1:
! 485: case MII_PHYIDR2:
! 486: splx(s);
! 487: return;
! 488: break;
! 489: default:
! 490: printf("%s: bad phy register %x\n", sc->sc_dev.dv_xname, reg);
! 491: splx(s);
! 492: return;
! 493: }
! 494: CSR_WRITE_2(sc, re8139_reg, data);
! 495: splx(s);
! 496: }
! 497:
! 498: void
! 499: re_miibus_statchg(struct device *dev)
! 500: {
! 501: }
! 502:
! 503: /*
! 504: * Program the 64-bit multicast hash filter.
! 505: */
! 506: void
! 507: re_setmulti(struct rl_softc *sc)
! 508: {
! 509: struct ifnet *ifp;
! 510: int h = 0;
! 511: u_int32_t hashes[2] = { 0, 0 };
! 512: u_int32_t hwrev, rxfilt;
! 513: int mcnt = 0;
! 514: struct arpcom *ac = &sc->sc_arpcom;
! 515: struct ether_multi *enm;
! 516: struct ether_multistep step;
! 517:
! 518: ifp = &sc->sc_arpcom.ac_if;
! 519:
! 520: rxfilt = CSR_READ_4(sc, RL_RXCFG);
! 521:
! 522: if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
! 523: rxfilt |= RL_RXCFG_RX_MULTI;
! 524: CSR_WRITE_4(sc, RL_RXCFG, rxfilt);
! 525: CSR_WRITE_4(sc, RL_MAR0, 0xFFFFFFFF);
! 526: CSR_WRITE_4(sc, RL_MAR4, 0xFFFFFFFF);
! 527: return;
! 528: }
! 529:
! 530: /* first, zot all the existing hash bits */
! 531: CSR_WRITE_4(sc, RL_MAR0, 0);
! 532: CSR_WRITE_4(sc, RL_MAR4, 0);
! 533:
! 534: /* now program new ones */
! 535: ETHER_FIRST_MULTI(step, ac, enm);
! 536: while (enm != NULL) {
! 537: if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
! 538: ifp->if_flags |= IFF_ALLMULTI;
! 539: mcnt = MAX_NUM_MULTICAST_ADDRESSES;
! 540: }
! 541: if (mcnt == MAX_NUM_MULTICAST_ADDRESSES)
! 542: break;
! 543:
! 544: h = (ether_crc32_be(enm->enm_addrlo,
! 545: ETHER_ADDR_LEN) >> 26) & 0x0000003F;
! 546: if (h < 32)
! 547: hashes[0] |= (1 << h);
! 548: else
! 549: hashes[1] |= (1 << (h - 32));
! 550: mcnt++;
! 551: ETHER_NEXT_MULTI(step, enm);
! 552: }
! 553:
! 554: if (mcnt)
! 555: rxfilt |= RL_RXCFG_RX_MULTI;
! 556: else
! 557: rxfilt &= ~RL_RXCFG_RX_MULTI;
! 558:
! 559: CSR_WRITE_4(sc, RL_RXCFG, rxfilt);
! 560:
! 561: /*
! 562: * For some unfathomable reason, RealTek decided to reverse
! 563: * the order of the multicast hash registers in the PCI Express
! 564: * parts. This means we have to write the hash pattern in reverse
! 565: * order for those devices.
! 566: */
! 567: hwrev = CSR_READ_4(sc, RL_TXCFG) & RL_TXCFG_HWREV;
! 568: if (hwrev == RL_HWREV_8100E_SPIN1 || hwrev == RL_HWREV_8100E_SPIN2 ||
! 569: hwrev == RL_HWREV_8101E || hwrev == RL_HWREV_8168_SPIN1 ||
! 570: hwrev == RL_HWREV_8168_SPIN2) {
! 571: CSR_WRITE_4(sc, RL_MAR0, swap32(hashes[1]));
! 572: CSR_WRITE_4(sc, RL_MAR4, swap32(hashes[0]));
! 573: } else {
! 574: CSR_WRITE_4(sc, RL_MAR0, hashes[0]);
! 575: CSR_WRITE_4(sc, RL_MAR4, hashes[1]);
! 576: }
! 577: }
! 578:
! 579: void
! 580: re_setpromisc(struct rl_softc *sc)
! 581: {
! 582: struct ifnet *ifp;
! 583: u_int32_t rxcfg = 0;
! 584:
! 585: ifp = &sc->sc_arpcom.ac_if;
! 586:
! 587: rxcfg = CSR_READ_4(sc, RL_RXCFG);
! 588: if (ifp->if_flags & IFF_PROMISC)
! 589: rxcfg |= RL_RXCFG_RX_ALLPHYS;
! 590: else
! 591: rxcfg &= ~RL_RXCFG_RX_ALLPHYS;
! 592: CSR_WRITE_4(sc, RL_RXCFG, rxcfg);
! 593: }
! 594:
! 595: void
! 596: re_reset(struct rl_softc *sc)
! 597: {
! 598: int i;
! 599:
! 600: CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RESET);
! 601:
! 602: for (i = 0; i < RL_TIMEOUT; i++) {
! 603: DELAY(10);
! 604: if (!(CSR_READ_1(sc, RL_COMMAND) & RL_CMD_RESET))
! 605: break;
! 606: }
! 607: if (i == RL_TIMEOUT)
! 608: printf("%s: reset never completed!\n", sc->sc_dev.dv_xname);
! 609:
! 610: CSR_WRITE_1(sc, 0x82, 1);
! 611: }
! 612:
! 613: #ifdef RE_DIAG
! 614:
! 615: /*
! 616: * The following routine is designed to test for a defect on some
! 617: * 32-bit 8169 cards. Some of these NICs have the REQ64# and ACK64#
! 618: * lines connected to the bus, however for a 32-bit only card, they
! 619: * should be pulled high. The result of this defect is that the
! 620: * NIC will not work right if you plug it into a 64-bit slot: DMA
! 621: * operations will be done with 64-bit transfers, which will fail
! 622: * because the 64-bit data lines aren't connected.
! 623: *
! 624: * There's no way to work around this (short of talking a soldering
! 625: * iron to the board), however we can detect it. The method we use
! 626: * here is to put the NIC into digital loopback mode, set the receiver
! 627: * to promiscuous mode, and then try to send a frame. We then compare
! 628: * the frame data we sent to what was received. If the data matches,
! 629: * then the NIC is working correctly, otherwise we know the user has
! 630: * a defective NIC which has been mistakenly plugged into a 64-bit PCI
! 631: * slot. In the latter case, there's no way the NIC can work correctly,
! 632: * so we print out a message on the console and abort the device attach.
! 633: */
! 634:
! 635: int
! 636: re_diag(struct rl_softc *sc)
! 637: {
! 638: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
! 639: struct mbuf *m0;
! 640: struct ether_header *eh;
! 641: struct rl_rxsoft *rxs;
! 642: struct rl_desc *cur_rx;
! 643: bus_dmamap_t dmamap;
! 644: u_int16_t status;
! 645: u_int32_t rxstat;
! 646: int total_len, i, s, error = 0, phyaddr;
! 647: u_int8_t dst[] = { 0x00, 'h', 'e', 'l', 'l', 'o' };
! 648: u_int8_t src[] = { 0x00, 'w', 'o', 'r', 'l', 'd' };
! 649:
! 650: DPRINTF(("inside re_diag\n"));
! 651: /* Allocate a single mbuf */
! 652:
! 653: MGETHDR(m0, M_DONTWAIT, MT_DATA);
! 654: if (m0 == NULL)
! 655: return (ENOBUFS);
! 656:
! 657: /*
! 658: * Initialize the NIC in test mode. This sets the chip up
! 659: * so that it can send and receive frames, but performs the
! 660: * following special functions:
! 661: * - Puts receiver in promiscuous mode
! 662: * - Enables digital loopback mode
! 663: * - Leaves interrupts turned off
! 664: */
! 665:
! 666: ifp->if_flags |= IFF_PROMISC;
! 667: sc->rl_testmode = 1;
! 668: re_reset(sc);
! 669: re_init(ifp);
! 670: sc->rl_link = 1;
! 671: if (sc->rl_type == RL_8169)
! 672: phyaddr = 1;
! 673: else
! 674: phyaddr = 0;
! 675:
! 676: re_miibus_writereg((struct device *)sc, phyaddr, MII_BMCR,
! 677: BMCR_RESET);
! 678: for (i = 0; i < RL_TIMEOUT; i++) {
! 679: status = re_miibus_readreg((struct device *)sc,
! 680: phyaddr, MII_BMCR);
! 681: if (!(status & BMCR_RESET))
! 682: break;
! 683: }
! 684:
! 685: re_miibus_writereg((struct device *)sc, phyaddr, MII_BMCR,
! 686: BMCR_LOOP);
! 687: CSR_WRITE_2(sc, RL_ISR, RL_INTRS);
! 688:
! 689: DELAY(100000);
! 690:
! 691: /* Put some data in the mbuf */
! 692:
! 693: eh = mtod(m0, struct ether_header *);
! 694: bcopy ((char *)&dst, eh->ether_dhost, ETHER_ADDR_LEN);
! 695: bcopy ((char *)&src, eh->ether_shost, ETHER_ADDR_LEN);
! 696: eh->ether_type = htons(ETHERTYPE_IP);
! 697: m0->m_pkthdr.len = m0->m_len = ETHER_MIN_LEN - ETHER_CRC_LEN;
! 698:
! 699: /*
! 700: * Queue the packet, start transmission.
! 701: */
! 702:
! 703: CSR_WRITE_2(sc, RL_ISR, 0xFFFF);
! 704: s = splnet();
! 705: IFQ_ENQUEUE(&ifp->if_snd, m0, NULL, error);
! 706: re_start(ifp);
! 707: splx(s);
! 708: m0 = NULL;
! 709:
! 710: DPRINTF(("re_diag: transmission started\n"));
! 711:
! 712: /* Wait for it to propagate through the chip */
! 713:
! 714: DELAY(100000);
! 715: for (i = 0; i < RL_TIMEOUT; i++) {
! 716: status = CSR_READ_2(sc, RL_ISR);
! 717: CSR_WRITE_2(sc, RL_ISR, status);
! 718: if ((status & (RL_ISR_TIMEOUT_EXPIRED|RL_ISR_RX_OK)) ==
! 719: (RL_ISR_TIMEOUT_EXPIRED|RL_ISR_RX_OK))
! 720: break;
! 721: DELAY(10);
! 722: }
! 723: if (i == RL_TIMEOUT) {
! 724: printf("%s: diagnostic failed, failed to receive packet "
! 725: "in loopback mode\n", sc->sc_dev.dv_xname);
! 726: error = EIO;
! 727: goto done;
! 728: }
! 729:
! 730: /*
! 731: * The packet should have been dumped into the first
! 732: * entry in the RX DMA ring. Grab it from there.
! 733: */
! 734:
! 735: rxs = &sc->rl_ldata.rl_rxsoft[0];
! 736: dmamap = rxs->rxs_dmamap;
! 737: bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
! 738: BUS_DMASYNC_POSTREAD);
! 739: bus_dmamap_unload(sc->sc_dmat, dmamap);
! 740:
! 741: m0 = rxs->rxs_mbuf;
! 742: rxs->rxs_mbuf = NULL;
! 743: eh = mtod(m0, struct ether_header *);
! 744:
! 745: RL_RXDESCSYNC(sc, 0, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
! 746: cur_rx = &sc->rl_ldata.rl_rx_list[0];
! 747: rxstat = letoh32(cur_rx->rl_cmdstat);
! 748: total_len = rxstat & sc->rl_rxlenmask;
! 749:
! 750: if (total_len != ETHER_MIN_LEN) {
! 751: printf("%s: diagnostic failed, received short packet\n",
! 752: sc->sc_dev.dv_xname);
! 753: error = EIO;
! 754: goto done;
! 755: }
! 756:
! 757: DPRINTF(("re_diag: packet received\n"));
! 758:
! 759: /* Test that the received packet data matches what we sent. */
! 760:
! 761: if (bcmp((char *)&eh->ether_dhost, (char *)&dst, ETHER_ADDR_LEN) ||
! 762: bcmp((char *)&eh->ether_shost, (char *)&src, ETHER_ADDR_LEN) ||
! 763: ntohs(eh->ether_type) != ETHERTYPE_IP) {
! 764: printf("%s: WARNING, DMA FAILURE!\n", sc->sc_dev.dv_xname);
! 765: printf("%s: expected TX data: %s",
! 766: sc->sc_dev.dv_xname, ether_sprintf(dst));
! 767: printf("/%s/0x%x\n", ether_sprintf(src), ETHERTYPE_IP);
! 768: printf("%s: received RX data: %s",
! 769: sc->sc_dev.dv_xname,
! 770: ether_sprintf(eh->ether_dhost));
! 771: printf("/%s/0x%x\n", ether_sprintf(eh->ether_shost),
! 772: ntohs(eh->ether_type));
! 773: printf("%s: You may have a defective 32-bit NIC plugged "
! 774: "into a 64-bit PCI slot.\n", sc->sc_dev.dv_xname);
! 775: printf("%s: Please re-install the NIC in a 32-bit slot "
! 776: "for proper operation.\n", sc->sc_dev.dv_xname);
! 777: printf("%s: Read the re(4) man page for more details.\n",
! 778: sc->sc_dev.dv_xname);
! 779: error = EIO;
! 780: }
! 781:
! 782: done:
! 783: /* Turn interface off, release resources */
! 784:
! 785: sc->rl_testmode = 0;
! 786: sc->rl_link = 0;
! 787: ifp->if_flags &= ~IFF_PROMISC;
! 788: re_stop(ifp, 1);
! 789: if (m0 != NULL)
! 790: m_freem(m0);
! 791: DPRINTF(("leaving re_diag\n"));
! 792:
! 793: return (error);
! 794: }
! 795:
! 796: #endif
! 797:
! 798: #ifdef __armish__
! 799: /*
! 800: * Thecus N2100 doesn't store the full mac address in eeprom
! 801: * so we read the old mac address from the device before the reset
! 802: * in hopes that the proper mac address is already there.
! 803: */
! 804: union {
! 805: u_int32_t eaddr_word[2];
! 806: u_char eaddr[ETHER_ADDR_LEN];
! 807: } boot_eaddr;
! 808: int boot_eaddr_valid;
! 809: #endif /* __armish__ */
! 810: /*
! 811: * Attach the interface. Allocate softc structures, do ifmedia
! 812: * setup and ethernet/BPF attach.
! 813: */
! 814: int
! 815: re_attach(struct rl_softc *sc, const char *intrstr)
! 816: {
! 817: u_char eaddr[ETHER_ADDR_LEN];
! 818: u_int16_t as[ETHER_ADDR_LEN / 2];
! 819: struct ifnet *ifp;
! 820: u_int16_t re_did = 0;
! 821: int error = 0, i;
! 822: u_int32_t hwrev;
! 823: const struct re_revision *rr;
! 824: const char *re_name = NULL;
! 825:
! 826: /* Reset the adapter. */
! 827: re_reset(sc);
! 828:
! 829: sc->rl_eewidth = RL_9356_ADDR_LEN;
! 830: re_read_eeprom(sc, (caddr_t)&re_did, 0, 1);
! 831: if (re_did != 0x8129)
! 832: sc->rl_eewidth = RL_9346_ADDR_LEN;
! 833:
! 834: /*
! 835: * Get station address from the EEPROM.
! 836: */
! 837: re_read_eeprom(sc, (caddr_t)as, RL_EE_EADDR, 3);
! 838: for (i = 0; i < ETHER_ADDR_LEN / 2; i++)
! 839: as[i] = letoh16(as[i]);
! 840: bcopy(as, eaddr, sizeof(eaddr));
! 841: #ifdef __armish__
! 842: /*
! 843: * On the Thecus N2100, the MAC address in the EEPROM is
! 844: * always 00:14:fd:10:00:00. The proper MAC address is stored
! 845: * in flash. Fortunately RedBoot configures the proper MAC
! 846: * address (for the first onboard interface) which we can read
! 847: * from the IDR.
! 848: */
! 849: if (eaddr[0] == 0x00 && eaddr[1] == 0x14 && eaddr[2] == 0xfd &&
! 850: eaddr[3] == 0x10 && eaddr[4] == 0x00 && eaddr[5] == 0x00) {
! 851: if (boot_eaddr_valid == 0) {
! 852: boot_eaddr.eaddr_word[1] = letoh32(CSR_READ_4(sc, RL_IDR4));
! 853: boot_eaddr.eaddr_word[0] = letoh32(CSR_READ_4(sc, RL_IDR0));
! 854: boot_eaddr_valid = 1;
! 855: }
! 856:
! 857: bcopy(boot_eaddr.eaddr, eaddr, sizeof(eaddr));
! 858: eaddr[5] += sc->sc_dev.dv_unit;
! 859: }
! 860: #endif
! 861:
! 862: /*
! 863: * Set RX length mask, TX poll request register
! 864: * and TX descriptor count.
! 865: */
! 866: if (sc->rl_type == RL_8169) {
! 867: sc->rl_rxlenmask = RL_RDESC_STAT_GFRAGLEN;
! 868: sc->rl_txstart = RL_GTXSTART;
! 869: sc->rl_ldata.rl_tx_desc_cnt = RL_TX_DESC_CNT_8169;
! 870: } else {
! 871: sc->rl_rxlenmask = RL_RDESC_STAT_FRAGLEN;
! 872: sc->rl_txstart = RL_TXSTART;
! 873: sc->rl_ldata.rl_tx_desc_cnt = RL_TX_DESC_CNT_8139;
! 874: }
! 875:
! 876: bcopy(eaddr, (char *)&sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
! 877:
! 878: hwrev = CSR_READ_4(sc, RL_TXCFG) & RL_TXCFG_HWREV;
! 879: for (rr = re_revisions; rr->re_name != NULL; rr++) {
! 880: if (rr->re_chipid == hwrev)
! 881: re_name = rr->re_name;
! 882: }
! 883:
! 884: if (re_name == NULL)
! 885: printf(": unknown ASIC (0x%04x)", hwrev >> 16);
! 886: else
! 887: printf(": %s (0x%04x)", re_name, hwrev >> 16);
! 888:
! 889: printf(", %s, address %s\n", intrstr,
! 890: ether_sprintf(sc->sc_arpcom.ac_enaddr));
! 891:
! 892: if (sc->rl_ldata.rl_tx_desc_cnt >
! 893: PAGE_SIZE / sizeof(struct rl_desc)) {
! 894: sc->rl_ldata.rl_tx_desc_cnt =
! 895: PAGE_SIZE / sizeof(struct rl_desc);
! 896: }
! 897:
! 898: /* Allocate DMA'able memory for the TX ring */
! 899: if ((error = bus_dmamem_alloc(sc->sc_dmat, RL_TX_LIST_SZ(sc),
! 900: RL_RING_ALIGN, 0, &sc->rl_ldata.rl_tx_listseg, 1,
! 901: &sc->rl_ldata.rl_tx_listnseg, BUS_DMA_NOWAIT)) != 0) {
! 902: printf("%s: can't allocate tx listseg, error = %d\n",
! 903: sc->sc_dev.dv_xname, error);
! 904: goto fail_0;
! 905: }
! 906:
! 907: /* Load the map for the TX ring. */
! 908: if ((error = bus_dmamem_map(sc->sc_dmat, &sc->rl_ldata.rl_tx_listseg,
! 909: sc->rl_ldata.rl_tx_listnseg, RL_TX_LIST_SZ(sc),
! 910: (caddr_t *)&sc->rl_ldata.rl_tx_list,
! 911: BUS_DMA_COHERENT | BUS_DMA_NOWAIT)) != 0) {
! 912: printf("%s: can't map tx list, error = %d\n",
! 913: sc->sc_dev.dv_xname, error);
! 914: goto fail_1;
! 915: }
! 916: memset(sc->rl_ldata.rl_tx_list, 0, RL_TX_LIST_SZ(sc));
! 917:
! 918: if ((error = bus_dmamap_create(sc->sc_dmat, RL_TX_LIST_SZ(sc), 1,
! 919: RL_TX_LIST_SZ(sc), 0, 0,
! 920: &sc->rl_ldata.rl_tx_list_map)) != 0) {
! 921: printf("%s: can't create tx list map, error = %d\n",
! 922: sc->sc_dev.dv_xname, error);
! 923: goto fail_2;
! 924: }
! 925:
! 926: if ((error = bus_dmamap_load(sc->sc_dmat,
! 927: sc->rl_ldata.rl_tx_list_map, sc->rl_ldata.rl_tx_list,
! 928: RL_TX_LIST_SZ(sc), NULL, BUS_DMA_NOWAIT)) != 0) {
! 929: printf("%s: can't load tx list, error = %d\n",
! 930: sc->sc_dev.dv_xname, error);
! 931: goto fail_3;
! 932: }
! 933:
! 934: /* Create DMA maps for TX buffers */
! 935: for (i = 0; i < RL_TX_QLEN; i++) {
! 936: error = bus_dmamap_create(sc->sc_dmat,
! 937: RL_JUMBO_FRAMELEN,
! 938: RL_TX_DESC_CNT(sc) - RL_NTXDESC_RSVD, RL_TDESC_CMD_FRAGLEN,
! 939: 0, 0, &sc->rl_ldata.rl_txq[i].txq_dmamap);
! 940: if (error) {
! 941: printf("%s: can't create DMA map for TX\n",
! 942: sc->sc_dev.dv_xname);
! 943: goto fail_4;
! 944: }
! 945: }
! 946:
! 947: /* Allocate DMA'able memory for the RX ring */
! 948: if ((error = bus_dmamem_alloc(sc->sc_dmat, RL_RX_DMAMEM_SZ,
! 949: RL_RING_ALIGN, 0, &sc->rl_ldata.rl_rx_listseg, 1,
! 950: &sc->rl_ldata.rl_rx_listnseg, BUS_DMA_NOWAIT)) != 0) {
! 951: printf("%s: can't allocate rx listnseg, error = %d\n",
! 952: sc->sc_dev.dv_xname, error);
! 953: goto fail_4;
! 954: }
! 955:
! 956: /* Load the map for the RX ring. */
! 957: if ((error = bus_dmamem_map(sc->sc_dmat, &sc->rl_ldata.rl_rx_listseg,
! 958: sc->rl_ldata.rl_rx_listnseg, RL_RX_DMAMEM_SZ,
! 959: (caddr_t *)&sc->rl_ldata.rl_rx_list,
! 960: BUS_DMA_COHERENT | BUS_DMA_NOWAIT)) != 0) {
! 961: printf("%s: can't map rx list, error = %d\n",
! 962: sc->sc_dev.dv_xname, error);
! 963: goto fail_5;
! 964:
! 965: }
! 966: memset(sc->rl_ldata.rl_rx_list, 0, RL_RX_DMAMEM_SZ);
! 967:
! 968: if ((error = bus_dmamap_create(sc->sc_dmat, RL_RX_DMAMEM_SZ, 1,
! 969: RL_RX_DMAMEM_SZ, 0, 0,
! 970: &sc->rl_ldata.rl_rx_list_map)) != 0) {
! 971: printf("%s: can't create rx list map, error = %d\n",
! 972: sc->sc_dev.dv_xname, error);
! 973: goto fail_6;
! 974: }
! 975:
! 976: if ((error = bus_dmamap_load(sc->sc_dmat,
! 977: sc->rl_ldata.rl_rx_list_map, sc->rl_ldata.rl_rx_list,
! 978: RL_RX_DMAMEM_SZ, NULL, BUS_DMA_NOWAIT)) != 0) {
! 979: printf("%s: can't load rx list, error = %d\n",
! 980: sc->sc_dev.dv_xname, error);
! 981: goto fail_7;
! 982: }
! 983:
! 984: /* Create DMA maps for RX buffers */
! 985: for (i = 0; i < RL_RX_DESC_CNT; i++) {
! 986: error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
! 987: 0, 0, &sc->rl_ldata.rl_rxsoft[i].rxs_dmamap);
! 988: if (error) {
! 989: printf("%s: can't create DMA map for RX\n",
! 990: sc->sc_dev.dv_xname);
! 991: goto fail_8;
! 992: }
! 993: }
! 994:
! 995: ifp = &sc->sc_arpcom.ac_if;
! 996: ifp->if_softc = sc;
! 997: strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
! 998: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
! 999: ifp->if_ioctl = re_ioctl;
! 1000: ifp->if_start = re_start;
! 1001: ifp->if_watchdog = re_watchdog;
! 1002: ifp->if_init = re_init;
! 1003: if (sc->rl_type == RL_8169)
! 1004: ifp->if_hardmtu = RL_JUMBO_MTU;
! 1005: IFQ_SET_MAXLEN(&ifp->if_snd, RL_TX_QLEN);
! 1006: IFQ_SET_READY(&ifp->if_snd);
! 1007:
! 1008: ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_CSUM_IPv4 |
! 1009: IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
! 1010:
! 1011: #if NVLAN > 0
! 1012: ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
! 1013: #endif
! 1014:
! 1015: timeout_set(&sc->timer_handle, re_tick, sc);
! 1016:
! 1017: /* Do MII setup */
! 1018: sc->sc_mii.mii_ifp = ifp;
! 1019: sc->sc_mii.mii_readreg = re_miibus_readreg;
! 1020: sc->sc_mii.mii_writereg = re_miibus_writereg;
! 1021: sc->sc_mii.mii_statchg = re_miibus_statchg;
! 1022: ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, re_ifmedia_upd,
! 1023: re_ifmedia_sts);
! 1024: mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
! 1025: MII_OFFSET_ANY, MIIF_DOPAUSE);
! 1026: if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
! 1027: printf("%s: no PHY found!\n", sc->sc_dev.dv_xname);
! 1028: ifmedia_add(&sc->sc_mii.mii_media,
! 1029: IFM_ETHER|IFM_NONE, 0, NULL);
! 1030: ifmedia_set(&sc->sc_mii.mii_media,
! 1031: IFM_ETHER|IFM_NONE);
! 1032: } else
! 1033: ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
! 1034:
! 1035: /*
! 1036: * Call MI attach routine.
! 1037: */
! 1038: re_reset(sc);
! 1039: if_attach(ifp);
! 1040: ether_ifattach(ifp);
! 1041:
! 1042: #ifdef RE_DIAG
! 1043: /*
! 1044: * Perform hardware diagnostic on the original RTL8169.
! 1045: * Some 32-bit cards were incorrectly wired and would
! 1046: * malfunction if plugged into a 64-bit slot.
! 1047: */
! 1048: if (sc->rl_type == RL_8169) {
! 1049: error = re_diag(sc);
! 1050: if (error) {
! 1051: printf("%s: attach aborted due to hardware diag failure\n",
! 1052: sc->sc_dev.dv_xname);
! 1053: ether_ifdetach(ifp);
! 1054: goto fail_8;
! 1055: }
! 1056: }
! 1057: #endif
! 1058:
! 1059: return (0);
! 1060:
! 1061: fail_8:
! 1062: /* Destroy DMA maps for RX buffers. */
! 1063: for (i = 0; i < RL_RX_DESC_CNT; i++) {
! 1064: if (sc->rl_ldata.rl_rxsoft[i].rxs_dmamap != NULL)
! 1065: bus_dmamap_destroy(sc->sc_dmat,
! 1066: sc->rl_ldata.rl_rxsoft[i].rxs_dmamap);
! 1067: }
! 1068:
! 1069: /* Free DMA'able memory for the RX ring. */
! 1070: bus_dmamap_unload(sc->sc_dmat, sc->rl_ldata.rl_rx_list_map);
! 1071: fail_7:
! 1072: bus_dmamap_destroy(sc->sc_dmat, sc->rl_ldata.rl_rx_list_map);
! 1073: fail_6:
! 1074: bus_dmamem_unmap(sc->sc_dmat,
! 1075: (caddr_t)sc->rl_ldata.rl_rx_list, RL_RX_DMAMEM_SZ);
! 1076: fail_5:
! 1077: bus_dmamem_free(sc->sc_dmat,
! 1078: &sc->rl_ldata.rl_rx_listseg, sc->rl_ldata.rl_rx_listnseg);
! 1079:
! 1080: fail_4:
! 1081: /* Destroy DMA maps for TX buffers. */
! 1082: for (i = 0; i < RL_TX_QLEN; i++) {
! 1083: if (sc->rl_ldata.rl_txq[i].txq_dmamap != NULL)
! 1084: bus_dmamap_destroy(sc->sc_dmat,
! 1085: sc->rl_ldata.rl_txq[i].txq_dmamap);
! 1086: }
! 1087:
! 1088: /* Free DMA'able memory for the TX ring. */
! 1089: bus_dmamap_unload(sc->sc_dmat, sc->rl_ldata.rl_tx_list_map);
! 1090: fail_3:
! 1091: bus_dmamap_destroy(sc->sc_dmat, sc->rl_ldata.rl_tx_list_map);
! 1092: fail_2:
! 1093: bus_dmamem_unmap(sc->sc_dmat,
! 1094: (caddr_t)sc->rl_ldata.rl_tx_list, RL_TX_LIST_SZ(sc));
! 1095: fail_1:
! 1096: bus_dmamem_free(sc->sc_dmat,
! 1097: &sc->rl_ldata.rl_tx_listseg, sc->rl_ldata.rl_tx_listnseg);
! 1098: fail_0:
! 1099: return (1);
! 1100: }
! 1101:
! 1102:
! 1103: int
! 1104: re_newbuf(struct rl_softc *sc, int idx, struct mbuf *m)
! 1105: {
! 1106: struct mbuf *n = NULL;
! 1107: bus_dmamap_t map;
! 1108: struct rl_desc *d;
! 1109: struct rl_rxsoft *rxs;
! 1110: u_int32_t cmdstat;
! 1111: int error;
! 1112:
! 1113: if (m == NULL) {
! 1114: MGETHDR(n, M_DONTWAIT, MT_DATA);
! 1115: if (n == NULL)
! 1116: return (ENOBUFS);
! 1117:
! 1118: MCLGET(n, M_DONTWAIT);
! 1119: if (!(n->m_flags & M_EXT)) {
! 1120: m_freem(n);
! 1121: return (ENOBUFS);
! 1122: }
! 1123: m = n;
! 1124: } else
! 1125: m->m_data = m->m_ext.ext_buf;
! 1126:
! 1127: /*
! 1128: * Initialize mbuf length fields and fixup
! 1129: * alignment so that the frame payload is
! 1130: * longword aligned on strict alignment archs.
! 1131: */
! 1132: m->m_len = m->m_pkthdr.len = RE_RX_DESC_BUFLEN;
! 1133: m->m_data += RE_ETHER_ALIGN;
! 1134:
! 1135: rxs = &sc->rl_ldata.rl_rxsoft[idx];
! 1136: map = rxs->rxs_dmamap;
! 1137: error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m,
! 1138: BUS_DMA_READ|BUS_DMA_NOWAIT);
! 1139:
! 1140: if (error)
! 1141: goto out;
! 1142:
! 1143: bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
! 1144: BUS_DMASYNC_PREREAD);
! 1145:
! 1146: d = &sc->rl_ldata.rl_rx_list[idx];
! 1147: RL_RXDESCSYNC(sc, idx, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
! 1148: cmdstat = letoh32(d->rl_cmdstat);
! 1149: RL_RXDESCSYNC(sc, idx, BUS_DMASYNC_PREREAD);
! 1150: if (cmdstat & RL_RDESC_STAT_OWN) {
! 1151: printf("%s: tried to map busy RX descriptor\n",
! 1152: sc->sc_dev.dv_xname);
! 1153: goto out;
! 1154: }
! 1155:
! 1156: rxs->rxs_mbuf = m;
! 1157:
! 1158: d->rl_vlanctl = 0;
! 1159: cmdstat = map->dm_segs[0].ds_len;
! 1160: if (idx == (RL_RX_DESC_CNT - 1))
! 1161: cmdstat |= RL_RDESC_CMD_EOR;
! 1162: re_set_bufaddr(d, map->dm_segs[0].ds_addr);
! 1163: d->rl_cmdstat = htole32(cmdstat);
! 1164: RL_RXDESCSYNC(sc, idx, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
! 1165: cmdstat |= RL_RDESC_CMD_OWN;
! 1166: d->rl_cmdstat = htole32(cmdstat);
! 1167: RL_RXDESCSYNC(sc, idx, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
! 1168:
! 1169: return (0);
! 1170: out:
! 1171: if (n != NULL)
! 1172: m_freem(n);
! 1173: return (ENOMEM);
! 1174: }
! 1175:
! 1176:
! 1177: int
! 1178: re_tx_list_init(struct rl_softc *sc)
! 1179: {
! 1180: int i;
! 1181:
! 1182: memset(sc->rl_ldata.rl_tx_list, 0, RL_TX_LIST_SZ(sc));
! 1183: for (i = 0; i < RL_TX_QLEN; i++) {
! 1184: sc->rl_ldata.rl_txq[i].txq_mbuf = NULL;
! 1185: }
! 1186:
! 1187: bus_dmamap_sync(sc->sc_dmat,
! 1188: sc->rl_ldata.rl_tx_list_map, 0,
! 1189: sc->rl_ldata.rl_tx_list_map->dm_mapsize,
! 1190: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
! 1191: sc->rl_ldata.rl_txq_prodidx = 0;
! 1192: sc->rl_ldata.rl_txq_considx = 0;
! 1193: sc->rl_ldata.rl_tx_free = RL_TX_DESC_CNT(sc);
! 1194: sc->rl_ldata.rl_tx_nextfree = 0;
! 1195:
! 1196: return (0);
! 1197: }
! 1198:
! 1199: int
! 1200: re_rx_list_init(struct rl_softc *sc)
! 1201: {
! 1202: int i;
! 1203:
! 1204: memset((char *)sc->rl_ldata.rl_rx_list, 0, RL_RX_LIST_SZ);
! 1205:
! 1206: for (i = 0; i < RL_RX_DESC_CNT; i++) {
! 1207: if (re_newbuf(sc, i, NULL) == ENOBUFS)
! 1208: return (ENOBUFS);
! 1209: }
! 1210:
! 1211: sc->rl_ldata.rl_rx_prodidx = 0;
! 1212: sc->rl_head = sc->rl_tail = NULL;
! 1213:
! 1214: return (0);
! 1215: }
! 1216:
! 1217: /*
! 1218: * RX handler for C+ and 8169. For the gigE chips, we support
! 1219: * the reception of jumbo frames that have been fragmented
! 1220: * across multiple 2K mbuf cluster buffers.
! 1221: */
! 1222: void
! 1223: re_rxeof(struct rl_softc *sc)
! 1224: {
! 1225: struct mbuf *m;
! 1226: struct ifnet *ifp;
! 1227: int i, total_len;
! 1228: struct rl_desc *cur_rx;
! 1229: struct rl_rxsoft *rxs;
! 1230: u_int32_t rxstat;
! 1231:
! 1232: ifp = &sc->sc_arpcom.ac_if;
! 1233:
! 1234: for (i = sc->rl_ldata.rl_rx_prodidx;; i = RL_NEXT_RX_DESC(sc, i)) {
! 1235: cur_rx = &sc->rl_ldata.rl_rx_list[i];
! 1236: RL_RXDESCSYNC(sc, i,
! 1237: BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
! 1238: rxstat = letoh32(cur_rx->rl_cmdstat);
! 1239: RL_RXDESCSYNC(sc, i, BUS_DMASYNC_PREREAD);
! 1240: if ((rxstat & RL_RDESC_STAT_OWN) != 0)
! 1241: break;
! 1242: total_len = rxstat & sc->rl_rxlenmask;
! 1243: rxs = &sc->rl_ldata.rl_rxsoft[i];
! 1244: m = rxs->rxs_mbuf;
! 1245:
! 1246: /* Invalidate the RX mbuf and unload its map */
! 1247:
! 1248: bus_dmamap_sync(sc->sc_dmat,
! 1249: rxs->rxs_dmamap, 0, rxs->rxs_dmamap->dm_mapsize,
! 1250: BUS_DMASYNC_POSTREAD);
! 1251: bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
! 1252:
! 1253: if (!(rxstat & RL_RDESC_STAT_EOF)) {
! 1254: m->m_len = RE_RX_DESC_BUFLEN;
! 1255: if (sc->rl_head == NULL)
! 1256: sc->rl_head = sc->rl_tail = m;
! 1257: else {
! 1258: m->m_flags &= ~M_PKTHDR;
! 1259: sc->rl_tail->m_next = m;
! 1260: sc->rl_tail = m;
! 1261: }
! 1262: re_newbuf(sc, i, NULL);
! 1263: continue;
! 1264: }
! 1265:
! 1266: /*
! 1267: * NOTE: for the 8139C+, the frame length field
! 1268: * is always 12 bits in size, but for the gigE chips,
! 1269: * it is 13 bits (since the max RX frame length is 16K).
! 1270: * Unfortunately, all 32 bits in the status word
! 1271: * were already used, so to make room for the extra
! 1272: * length bit, RealTek took out the 'frame alignment
! 1273: * error' bit and shifted the other status bits
! 1274: * over one slot. The OWN, EOR, FS and LS bits are
! 1275: * still in the same places. We have already extracted
! 1276: * the frame length and checked the OWN bit, so rather
! 1277: * than using an alternate bit mapping, we shift the
! 1278: * status bits one space to the right so we can evaluate
! 1279: * them using the 8169 status as though it was in the
! 1280: * same format as that of the 8139C+.
! 1281: */
! 1282: if (sc->rl_type == RL_8169)
! 1283: rxstat >>= 1;
! 1284:
! 1285: /*
! 1286: * if total_len > 2^13-1, both _RXERRSUM and _GIANT will be
! 1287: * set, but if CRC is clear, it will still be a valid frame.
! 1288: */
! 1289: if (rxstat & RL_RDESC_STAT_RXERRSUM && !(total_len > 8191 &&
! 1290: (rxstat & RL_RDESC_STAT_ERRS) == RL_RDESC_STAT_GIANT)) {
! 1291: ifp->if_ierrors++;
! 1292: /*
! 1293: * If this is part of a multi-fragment packet,
! 1294: * discard all the pieces.
! 1295: */
! 1296: if (sc->rl_head != NULL) {
! 1297: m_freem(sc->rl_head);
! 1298: sc->rl_head = sc->rl_tail = NULL;
! 1299: }
! 1300: re_newbuf(sc, i, m);
! 1301: continue;
! 1302: }
! 1303:
! 1304: /*
! 1305: * If allocating a replacement mbuf fails,
! 1306: * reload the current one.
! 1307: */
! 1308:
! 1309: if (re_newbuf(sc, i, NULL)) {
! 1310: ifp->if_ierrors++;
! 1311: if (sc->rl_head != NULL) {
! 1312: m_freem(sc->rl_head);
! 1313: sc->rl_head = sc->rl_tail = NULL;
! 1314: }
! 1315: re_newbuf(sc, i, m);
! 1316: continue;
! 1317: }
! 1318:
! 1319: if (sc->rl_head != NULL) {
! 1320: m->m_len = total_len % RE_RX_DESC_BUFLEN;
! 1321: if (m->m_len == 0)
! 1322: m->m_len = RE_RX_DESC_BUFLEN;
! 1323: /*
! 1324: * Special case: if there's 4 bytes or less
! 1325: * in this buffer, the mbuf can be discarded:
! 1326: * the last 4 bytes is the CRC, which we don't
! 1327: * care about anyway.
! 1328: */
! 1329: if (m->m_len <= ETHER_CRC_LEN) {
! 1330: sc->rl_tail->m_len -=
! 1331: (ETHER_CRC_LEN - m->m_len);
! 1332: m_freem(m);
! 1333: } else {
! 1334: m->m_len -= ETHER_CRC_LEN;
! 1335: m->m_flags &= ~M_PKTHDR;
! 1336: sc->rl_tail->m_next = m;
! 1337: }
! 1338: m = sc->rl_head;
! 1339: sc->rl_head = sc->rl_tail = NULL;
! 1340: m->m_pkthdr.len = total_len - ETHER_CRC_LEN;
! 1341: } else
! 1342: m->m_pkthdr.len = m->m_len =
! 1343: (total_len - ETHER_CRC_LEN);
! 1344:
! 1345: ifp->if_ipackets++;
! 1346: m->m_pkthdr.rcvif = ifp;
! 1347:
! 1348: /* Do RX checksumming */
! 1349:
! 1350: /* Check IP header checksum */
! 1351: if ((rxstat & RL_RDESC_STAT_PROTOID) &&
! 1352: !(rxstat & RL_RDESC_STAT_IPSUMBAD))
! 1353: m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
! 1354:
! 1355: /* Check TCP/UDP checksum */
! 1356: if ((RL_TCPPKT(rxstat) &&
! 1357: !(rxstat & RL_RDESC_STAT_TCPSUMBAD)) ||
! 1358: (RL_UDPPKT(rxstat) &&
! 1359: !(rxstat & RL_RDESC_STAT_UDPSUMBAD)))
! 1360: m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
! 1361:
! 1362: #if NBPFILTER > 0
! 1363: if (ifp->if_bpf)
! 1364: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
! 1365: #endif
! 1366: ether_input_mbuf(ifp, m);
! 1367: }
! 1368:
! 1369: sc->rl_ldata.rl_rx_prodidx = i;
! 1370: }
! 1371:
! 1372: void
! 1373: re_txeof(struct rl_softc *sc)
! 1374: {
! 1375: struct ifnet *ifp;
! 1376: struct rl_txq *txq;
! 1377: uint32_t txstat;
! 1378: int idx, descidx;
! 1379:
! 1380: ifp = &sc->sc_arpcom.ac_if;
! 1381:
! 1382: for (idx = sc->rl_ldata.rl_txq_considx;; idx = RL_NEXT_TXQ(sc, idx)) {
! 1383: txq = &sc->rl_ldata.rl_txq[idx];
! 1384:
! 1385: if (txq->txq_mbuf == NULL) {
! 1386: KASSERT(idx == sc->rl_ldata.rl_txq_prodidx);
! 1387: break;
! 1388: }
! 1389:
! 1390: descidx = txq->txq_descidx;
! 1391: RL_TXDESCSYNC(sc, descidx,
! 1392: BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
! 1393: txstat =
! 1394: letoh32(sc->rl_ldata.rl_tx_list[descidx].rl_cmdstat);
! 1395: RL_TXDESCSYNC(sc, descidx, BUS_DMASYNC_PREREAD);
! 1396: KASSERT((txstat & RL_TDESC_CMD_EOF) != 0);
! 1397: if (txstat & RL_TDESC_CMD_OWN)
! 1398: break;
! 1399:
! 1400: sc->rl_ldata.rl_tx_free += txq->txq_nsegs;
! 1401: KASSERT(sc->rl_ldata.rl_tx_free <= RL_TX_DESC_CNT(sc));
! 1402: bus_dmamap_sync(sc->sc_dmat, txq->txq_dmamap,
! 1403: 0, txq->txq_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
! 1404: bus_dmamap_unload(sc->sc_dmat, txq->txq_dmamap);
! 1405: m_freem(txq->txq_mbuf);
! 1406: txq->txq_mbuf = NULL;
! 1407:
! 1408: if (txstat & (RL_TDESC_STAT_EXCESSCOL | RL_TDESC_STAT_COLCNT))
! 1409: ifp->if_collisions++;
! 1410: if (txstat & RL_TDESC_STAT_TXERRSUM)
! 1411: ifp->if_oerrors++;
! 1412: else
! 1413: ifp->if_opackets++;
! 1414: }
! 1415:
! 1416: sc->rl_ldata.rl_txq_considx = idx;
! 1417:
! 1418: if (sc->rl_ldata.rl_tx_free > RL_NTXDESC_RSVD)
! 1419: ifp->if_flags &= ~IFF_OACTIVE;
! 1420:
! 1421: if (sc->rl_ldata.rl_tx_free < RL_TX_DESC_CNT(sc)) {
! 1422: /*
! 1423: * Some chips will ignore a second TX request issued while an
! 1424: * existing transmission is in progress. If the transmitter goes
! 1425: * idle but there are still packets waiting to be sent, we need
! 1426: * to restart the channel here to flush them out. This only
! 1427: * seems to be required with the PCIe devices.
! 1428: */
! 1429: CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START);
! 1430:
! 1431: /*
! 1432: * If not all descriptors have been released reaped yet,
! 1433: * reload the timer so that we will eventually get another
! 1434: * interrupt that will cause us to re-enter this routine.
! 1435: * This is done in case the transmitter has gone idle.
! 1436: */
! 1437: CSR_WRITE_4(sc, RL_TIMERCNT, 1);
! 1438: } else
! 1439: ifp->if_timer = 0;
! 1440: }
! 1441:
! 1442: void
! 1443: re_tick(void *xsc)
! 1444: {
! 1445: struct rl_softc *sc = xsc;
! 1446: struct mii_data *mii;
! 1447: struct ifnet *ifp;
! 1448: int s;
! 1449:
! 1450: ifp = &sc->sc_arpcom.ac_if;
! 1451: mii = &sc->sc_mii;
! 1452:
! 1453: s = splnet();
! 1454:
! 1455: mii_tick(mii);
! 1456: if (sc->rl_link) {
! 1457: if (!(mii->mii_media_status & IFM_ACTIVE))
! 1458: sc->rl_link = 0;
! 1459: } else {
! 1460: if (mii->mii_media_status & IFM_ACTIVE &&
! 1461: IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
! 1462: sc->rl_link = 1;
! 1463: if (!IFQ_IS_EMPTY(&ifp->if_snd))
! 1464: re_start(ifp);
! 1465: }
! 1466: }
! 1467: splx(s);
! 1468:
! 1469: timeout_add(&sc->timer_handle, hz);
! 1470: }
! 1471:
! 1472: int
! 1473: re_intr(void *arg)
! 1474: {
! 1475: struct rl_softc *sc = arg;
! 1476: struct ifnet *ifp;
! 1477: u_int16_t status;
! 1478: int claimed = 0;
! 1479:
! 1480: ifp = &sc->sc_arpcom.ac_if;
! 1481:
! 1482: if (!(ifp->if_flags & IFF_UP))
! 1483: return (0);
! 1484:
! 1485: for (;;) {
! 1486:
! 1487: status = CSR_READ_2(sc, RL_ISR);
! 1488: /* If the card has gone away the read returns 0xffff. */
! 1489: if (status == 0xffff)
! 1490: break;
! 1491: if (status)
! 1492: CSR_WRITE_2(sc, RL_ISR, status);
! 1493:
! 1494: if ((status & RL_INTRS_CPLUS) == 0)
! 1495: break;
! 1496:
! 1497: if (status & (RL_ISR_RX_OK | RL_ISR_RX_ERR)) {
! 1498: re_rxeof(sc);
! 1499: claimed = 1;
! 1500: }
! 1501:
! 1502: if (status & (RL_ISR_TIMEOUT_EXPIRED | RL_ISR_TX_ERR |
! 1503: RL_ISR_TX_DESC_UNAVAIL)) {
! 1504: re_txeof(sc);
! 1505: claimed = 1;
! 1506: }
! 1507:
! 1508: if (status & RL_ISR_SYSTEM_ERR) {
! 1509: re_reset(sc);
! 1510: re_init(ifp);
! 1511: claimed = 1;
! 1512: }
! 1513:
! 1514: if (status & RL_ISR_LINKCHG) {
! 1515: timeout_del(&sc->timer_handle);
! 1516: re_tick(sc);
! 1517: claimed = 1;
! 1518: }
! 1519: }
! 1520:
! 1521: if (claimed && !IFQ_IS_EMPTY(&ifp->if_snd))
! 1522: re_start(ifp);
! 1523:
! 1524: return (claimed);
! 1525: }
! 1526:
! 1527: int
! 1528: re_encap(struct rl_softc *sc, struct mbuf *m, int *idx)
! 1529: {
! 1530: bus_dmamap_t map;
! 1531: int error, seg, nsegs, uidx, startidx, curidx, lastidx, pad;
! 1532: struct rl_desc *d;
! 1533: u_int32_t cmdstat, rl_flags = 0;
! 1534: struct rl_txq *txq;
! 1535: #if NVLAN > 0
! 1536: struct ifvlan *ifv = NULL;
! 1537:
! 1538: if ((m->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
! 1539: m->m_pkthdr.rcvif != NULL)
! 1540: ifv = m->m_pkthdr.rcvif->if_softc;
! 1541: #endif
! 1542:
! 1543: if (sc->rl_ldata.rl_tx_free <= RL_NTXDESC_RSVD)
! 1544: return (EFBIG);
! 1545:
! 1546: /*
! 1547: * Set up checksum offload. Note: checksum offload bits must
! 1548: * appear in all descriptors of a multi-descriptor transmit
! 1549: * attempt. This is according to testing done with an 8169
! 1550: * chip. This is a requirement.
! 1551: */
! 1552:
! 1553: /*
! 1554: * Set RL_TDESC_CMD_IPCSUM if any checksum offloading
! 1555: * is requested. Otherwise, RL_TDESC_CMD_TCPCSUM/
! 1556: * RL_TDESC_CMD_UDPCSUM does not take affect.
! 1557: */
! 1558:
! 1559: if ((m->m_pkthdr.csum_flags &
! 1560: (M_IPV4_CSUM_OUT|M_TCPV4_CSUM_OUT|M_UDPV4_CSUM_OUT)) != 0) {
! 1561: rl_flags |= RL_TDESC_CMD_IPCSUM;
! 1562: if (m->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT)
! 1563: rl_flags |= RL_TDESC_CMD_TCPCSUM;
! 1564: if (m->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT)
! 1565: rl_flags |= RL_TDESC_CMD_UDPCSUM;
! 1566: }
! 1567:
! 1568: txq = &sc->rl_ldata.rl_txq[*idx];
! 1569: map = txq->txq_dmamap;
! 1570: error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m,
! 1571: BUS_DMA_WRITE|BUS_DMA_NOWAIT);
! 1572: if (error) {
! 1573: /* XXX try to defrag if EFBIG? */
! 1574: printf("%s: can't map mbuf (error %d)\n",
! 1575: sc->sc_dev.dv_xname, error);
! 1576: return (error);
! 1577: }
! 1578:
! 1579: nsegs = map->dm_nsegs;
! 1580: pad = 0;
! 1581: if (m->m_pkthdr.len <= RL_IP4CSUMTX_PADLEN &&
! 1582: (rl_flags & RL_TDESC_CMD_IPCSUM) != 0) {
! 1583: pad = 1;
! 1584: nsegs++;
! 1585: }
! 1586:
! 1587: if (nsegs > sc->rl_ldata.rl_tx_free - RL_NTXDESC_RSVD) {
! 1588: error = EFBIG;
! 1589: goto fail_unload;
! 1590: }
! 1591:
! 1592: /*
! 1593: * Make sure that the caches are synchronized before we
! 1594: * ask the chip to start DMA for the packet data.
! 1595: */
! 1596: bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
! 1597: BUS_DMASYNC_PREWRITE);
! 1598:
! 1599: /*
! 1600: * Map the segment array into descriptors. Note that we set the
! 1601: * start-of-frame and end-of-frame markers for either TX or RX, but
! 1602: * they really only have meaning in the TX case. (In the RX case,
! 1603: * it's the chip that tells us where packets begin and end.)
! 1604: * We also keep track of the end of the ring and set the
! 1605: * end-of-ring bits as needed, and we set the ownership bits
! 1606: * in all except the very first descriptor. (The caller will
! 1607: * set this descriptor later when it start transmission or
! 1608: * reception.)
! 1609: */
! 1610: curidx = startidx = sc->rl_ldata.rl_tx_nextfree;
! 1611: lastidx = -1;
! 1612: for (seg = 0; seg < map->dm_nsegs;
! 1613: seg++, curidx = RL_NEXT_TX_DESC(sc, curidx)) {
! 1614: d = &sc->rl_ldata.rl_tx_list[curidx];
! 1615: RL_TXDESCSYNC(sc, curidx,
! 1616: BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
! 1617: cmdstat = letoh32(d->rl_cmdstat);
! 1618: RL_TXDESCSYNC(sc, curidx, BUS_DMASYNC_PREREAD);
! 1619: if (cmdstat & RL_TDESC_STAT_OWN) {
! 1620: printf("%s: tried to map busy TX descriptor\n",
! 1621: sc->sc_dev.dv_xname);
! 1622: for (; seg > 0; seg --) {
! 1623: uidx = (curidx + RL_TX_DESC_CNT(sc) - seg) %
! 1624: RL_TX_DESC_CNT(sc);
! 1625: sc->rl_ldata.rl_tx_list[uidx].rl_cmdstat = 0;
! 1626: RL_TXDESCSYNC(sc, uidx,
! 1627: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
! 1628: }
! 1629: error = ENOBUFS;
! 1630: goto fail_unload;
! 1631: }
! 1632:
! 1633: d->rl_vlanctl = 0;
! 1634: re_set_bufaddr(d, map->dm_segs[seg].ds_addr);
! 1635: cmdstat = rl_flags | map->dm_segs[seg].ds_len;
! 1636: if (seg == 0)
! 1637: cmdstat |= RL_TDESC_CMD_SOF;
! 1638: else
! 1639: cmdstat |= RL_TDESC_CMD_OWN;
! 1640: if (curidx == (RL_TX_DESC_CNT(sc) - 1))
! 1641: cmdstat |= RL_TDESC_CMD_EOR;
! 1642: if (seg == nsegs - 1) {
! 1643: cmdstat |= RL_TDESC_CMD_EOF;
! 1644: lastidx = curidx;
! 1645: }
! 1646: d->rl_cmdstat = htole32(cmdstat);
! 1647: RL_TXDESCSYNC(sc, curidx,
! 1648: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
! 1649: }
! 1650: if (pad) {
! 1651: bus_addr_t paddaddr;
! 1652:
! 1653: d = &sc->rl_ldata.rl_tx_list[curidx];
! 1654: d->rl_vlanctl = 0;
! 1655: paddaddr = RL_TXPADDADDR(sc);
! 1656: re_set_bufaddr(d, paddaddr);
! 1657: cmdstat = rl_flags |
! 1658: RL_TDESC_CMD_OWN | RL_TDESC_CMD_EOF |
! 1659: (RL_IP4CSUMTX_PADLEN + 1 - m->m_pkthdr.len);
! 1660: if (curidx == (RL_TX_DESC_CNT(sc) - 1))
! 1661: cmdstat |= RL_TDESC_CMD_EOR;
! 1662: d->rl_cmdstat = htole32(cmdstat);
! 1663: RL_TXDESCSYNC(sc, curidx,
! 1664: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
! 1665: lastidx = curidx;
! 1666: curidx = RL_NEXT_TX_DESC(sc, curidx);
! 1667: }
! 1668: KASSERT(lastidx != -1);
! 1669:
! 1670: /*
! 1671: * Set up hardware VLAN tagging. Note: vlan tag info must
! 1672: * appear in the first descriptor of a multi-descriptor
! 1673: * transmission attempt.
! 1674: */
! 1675:
! 1676: #if NVLAN > 0
! 1677: if (ifv != NULL) {
! 1678: sc->rl_ldata.rl_tx_list[startidx].rl_vlanctl =
! 1679: htole32(swap16(ifv->ifv_tag) |
! 1680: RL_TDESC_VLANCTL_TAG);
! 1681: }
! 1682: #endif
! 1683:
! 1684: /* Transfer ownership of packet to the chip. */
! 1685:
! 1686: sc->rl_ldata.rl_tx_list[startidx].rl_cmdstat |=
! 1687: htole32(RL_TDESC_CMD_OWN);
! 1688: RL_TXDESCSYNC(sc, startidx, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
! 1689:
! 1690: /* update info of TX queue and descriptors */
! 1691: txq->txq_mbuf = m;
! 1692: txq->txq_descidx = lastidx;
! 1693: txq->txq_nsegs = nsegs;
! 1694:
! 1695: sc->rl_ldata.rl_tx_free -= nsegs;
! 1696: sc->rl_ldata.rl_tx_nextfree = curidx;
! 1697:
! 1698: *idx = RL_NEXT_TXQ(sc, *idx);
! 1699:
! 1700: return (0);
! 1701:
! 1702: fail_unload:
! 1703: bus_dmamap_unload(sc->sc_dmat, map);
! 1704:
! 1705: return (error);
! 1706: }
! 1707:
! 1708: /*
! 1709: * Main transmit routine for C+ and gigE NICs.
! 1710: */
! 1711:
! 1712: void
! 1713: re_start(struct ifnet *ifp)
! 1714: {
! 1715: struct rl_softc *sc;
! 1716: int idx, queued = 0;
! 1717:
! 1718: sc = ifp->if_softc;
! 1719:
! 1720: if (!sc->rl_link || ifp->if_flags & IFF_OACTIVE)
! 1721: return;
! 1722:
! 1723: idx = sc->rl_ldata.rl_txq_prodidx;
! 1724: for (;;) {
! 1725: struct mbuf *m;
! 1726: int error;
! 1727:
! 1728: IFQ_POLL(&ifp->if_snd, m);
! 1729: if (m == NULL)
! 1730: break;
! 1731:
! 1732: if (sc->rl_ldata.rl_txq[idx].txq_mbuf != NULL) {
! 1733: KASSERT(idx == sc->rl_ldata.rl_txq_considx);
! 1734: ifp->if_flags |= IFF_OACTIVE;
! 1735: break;
! 1736: }
! 1737:
! 1738: error = re_encap(sc, m, &idx);
! 1739: if (error == EFBIG &&
! 1740: sc->rl_ldata.rl_tx_free == RL_TX_DESC_CNT(sc)) {
! 1741: IFQ_DEQUEUE(&ifp->if_snd, m);
! 1742: m_freem(m);
! 1743: ifp->if_oerrors++;
! 1744: continue;
! 1745: }
! 1746: if (error) {
! 1747: ifp->if_flags |= IFF_OACTIVE;
! 1748: break;
! 1749: }
! 1750:
! 1751: IFQ_DEQUEUE(&ifp->if_snd, m);
! 1752: queued++;
! 1753:
! 1754: #if NBPFILTER > 0
! 1755: /*
! 1756: * If there's a BPF listener, bounce a copy of this frame
! 1757: * to him.
! 1758: */
! 1759: if (ifp->if_bpf)
! 1760: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
! 1761: #endif
! 1762: }
! 1763:
! 1764: if (queued == 0) {
! 1765: if (sc->rl_ldata.rl_tx_free != RL_TX_DESC_CNT(sc))
! 1766: CSR_WRITE_4(sc, RL_TIMERCNT, 1);
! 1767: return;
! 1768: }
! 1769:
! 1770: sc->rl_ldata.rl_txq_prodidx = idx;
! 1771:
! 1772: CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START);
! 1773:
! 1774: /*
! 1775: * Use the countdown timer for interrupt moderation.
! 1776: * 'TX done' interrupts are disabled. Instead, we reset the
! 1777: * countdown timer, which will begin counting until it hits
! 1778: * the value in the TIMERINT register, and then trigger an
! 1779: * interrupt. Each time we write to the TIMERCNT register,
! 1780: * the timer count is reset to 0.
! 1781: */
! 1782: CSR_WRITE_4(sc, RL_TIMERCNT, 1);
! 1783:
! 1784: /*
! 1785: * Set a timeout in case the chip goes out to lunch.
! 1786: */
! 1787: ifp->if_timer = 5;
! 1788: }
! 1789:
! 1790: int
! 1791: re_init(struct ifnet *ifp)
! 1792: {
! 1793: struct rl_softc *sc = ifp->if_softc;
! 1794: u_int32_t rxcfg = 0;
! 1795: int s;
! 1796: union {
! 1797: u_int32_t align_dummy;
! 1798: u_char eaddr[ETHER_ADDR_LEN];
! 1799: } eaddr;
! 1800:
! 1801: s = splnet();
! 1802:
! 1803: /*
! 1804: * Cancel pending I/O and free all RX/TX buffers.
! 1805: */
! 1806: re_stop(ifp, 0);
! 1807:
! 1808: /*
! 1809: * Enable C+ RX and TX mode, as well as RX checksum offload.
! 1810: * We must configure the C+ register before all others.
! 1811: */
! 1812: CSR_WRITE_2(sc, RL_CPLUS_CMD, RL_CPLUSCMD_RXENB|
! 1813: RL_CPLUSCMD_TXENB|RL_CPLUSCMD_PCI_MRW|
! 1814: RL_CPLUSCMD_RXCSUM_ENB);
! 1815:
! 1816: /*
! 1817: * Init our MAC address. Even though the chipset
! 1818: * documentation doesn't mention it, we need to enter "Config
! 1819: * register write enable" mode to modify the ID registers.
! 1820: */
! 1821: bcopy(sc->sc_arpcom.ac_enaddr, eaddr.eaddr, ETHER_ADDR_LEN);
! 1822: CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_WRITECFG);
! 1823: CSR_WRITE_4(sc, RL_IDR4,
! 1824: htole32(*(u_int32_t *)(&eaddr.eaddr[4])));
! 1825: CSR_WRITE_4(sc, RL_IDR0,
! 1826: htole32(*(u_int32_t *)(&eaddr.eaddr[0])));
! 1827: CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
! 1828:
! 1829: /*
! 1830: * For C+ mode, initialize the RX descriptors and mbufs.
! 1831: */
! 1832: re_rx_list_init(sc);
! 1833: re_tx_list_init(sc);
! 1834:
! 1835: /*
! 1836: * Load the addresses of the RX and TX lists into the chip.
! 1837: */
! 1838: CSR_WRITE_4(sc, RL_RXLIST_ADDR_HI,
! 1839: RL_ADDR_HI(sc->rl_ldata.rl_rx_list_map->dm_segs[0].ds_addr));
! 1840: CSR_WRITE_4(sc, RL_RXLIST_ADDR_LO,
! 1841: RL_ADDR_LO(sc->rl_ldata.rl_rx_list_map->dm_segs[0].ds_addr));
! 1842:
! 1843: CSR_WRITE_4(sc, RL_TXLIST_ADDR_HI,
! 1844: RL_ADDR_HI(sc->rl_ldata.rl_tx_list_map->dm_segs[0].ds_addr));
! 1845: CSR_WRITE_4(sc, RL_TXLIST_ADDR_LO,
! 1846: RL_ADDR_LO(sc->rl_ldata.rl_tx_list_map->dm_segs[0].ds_addr));
! 1847:
! 1848: /*
! 1849: * Enable transmit and receive.
! 1850: */
! 1851: CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB);
! 1852:
! 1853: /*
! 1854: * Set the initial TX and RX configuration.
! 1855: */
! 1856: if (sc->rl_testmode) {
! 1857: if (sc->rl_type == RL_8169)
! 1858: CSR_WRITE_4(sc, RL_TXCFG,
! 1859: RL_TXCFG_CONFIG|RL_LOOPTEST_ON);
! 1860: else
! 1861: CSR_WRITE_4(sc, RL_TXCFG,
! 1862: RL_TXCFG_CONFIG|RL_LOOPTEST_ON_CPLUS);
! 1863: } else
! 1864: CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG);
! 1865:
! 1866: CSR_WRITE_1(sc, RL_EARLY_TX_THRESH, 16);
! 1867:
! 1868: CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG);
! 1869:
! 1870: /* Set the individual bit to receive frames for this host only. */
! 1871: rxcfg = CSR_READ_4(sc, RL_RXCFG);
! 1872: rxcfg |= RL_RXCFG_RX_INDIV;
! 1873:
! 1874: /*
! 1875: * Set capture broadcast bit to capture broadcast frames.
! 1876: */
! 1877: if (ifp->if_flags & IFF_BROADCAST)
! 1878: rxcfg |= RL_RXCFG_RX_BROAD;
! 1879: else
! 1880: rxcfg &= ~RL_RXCFG_RX_BROAD;
! 1881:
! 1882: CSR_WRITE_4(sc, RL_RXCFG, rxcfg);
! 1883:
! 1884: /* Set promiscuous mode. */
! 1885: re_setpromisc(sc);
! 1886:
! 1887: /*
! 1888: * Program the multicast filter, if necessary.
! 1889: */
! 1890: re_setmulti(sc);
! 1891:
! 1892: /*
! 1893: * Enable interrupts.
! 1894: */
! 1895: if (sc->rl_testmode)
! 1896: CSR_WRITE_2(sc, RL_IMR, 0);
! 1897: else
! 1898: CSR_WRITE_2(sc, RL_IMR, RL_INTRS_CPLUS);
! 1899: CSR_WRITE_2(sc, RL_ISR, RL_INTRS_CPLUS);
! 1900:
! 1901: /* Start RX/TX process. */
! 1902: CSR_WRITE_4(sc, RL_MISSEDPKT, 0);
! 1903: #ifdef notdef
! 1904: /* Enable receiver and transmitter. */
! 1905: CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB);
! 1906: #endif
! 1907:
! 1908: /*
! 1909: * Initialize the timer interrupt register so that
! 1910: * a timer interrupt will be generated once the timer
! 1911: * reaches a certain number of ticks. The timer is
! 1912: * reloaded on each transmit. This gives us TX interrupt
! 1913: * moderation, which dramatically improves TX frame rate.
! 1914: */
! 1915: if (sc->rl_type == RL_8169)
! 1916: CSR_WRITE_4(sc, RL_TIMERINT_8169, 0x800);
! 1917: else
! 1918: CSR_WRITE_4(sc, RL_TIMERINT, 0x400);
! 1919:
! 1920: /*
! 1921: * For 8169 gigE NICs, set the max allowed RX packet
! 1922: * size so we can receive jumbo frames.
! 1923: */
! 1924: if (sc->rl_type == RL_8169)
! 1925: CSR_WRITE_2(sc, RL_MAXRXPKTLEN, 16383);
! 1926:
! 1927: if (sc->rl_testmode)
! 1928: return (0);
! 1929:
! 1930: mii_mediachg(&sc->sc_mii);
! 1931:
! 1932: CSR_WRITE_1(sc, RL_CFG1, CSR_READ_1(sc, RL_CFG1) | RL_CFG1_DRVLOAD);
! 1933:
! 1934: ifp->if_flags |= IFF_RUNNING;
! 1935: ifp->if_flags &= ~IFF_OACTIVE;
! 1936:
! 1937: splx(s);
! 1938:
! 1939: sc->rl_link = 0;
! 1940:
! 1941: timeout_add(&sc->timer_handle, hz);
! 1942:
! 1943: return (0);
! 1944: }
! 1945:
! 1946: /*
! 1947: * Set media options.
! 1948: */
! 1949: int
! 1950: re_ifmedia_upd(struct ifnet *ifp)
! 1951: {
! 1952: struct rl_softc *sc;
! 1953:
! 1954: sc = ifp->if_softc;
! 1955:
! 1956: return (mii_mediachg(&sc->sc_mii));
! 1957: }
! 1958:
! 1959: /*
! 1960: * Report current media status.
! 1961: */
! 1962: void
! 1963: re_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
! 1964: {
! 1965: struct rl_softc *sc;
! 1966:
! 1967: sc = ifp->if_softc;
! 1968:
! 1969: mii_pollstat(&sc->sc_mii);
! 1970: ifmr->ifm_active = sc->sc_mii.mii_media_active;
! 1971: ifmr->ifm_status = sc->sc_mii.mii_media_status;
! 1972: }
! 1973:
! 1974: int
! 1975: re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
! 1976: {
! 1977: struct rl_softc *sc = ifp->if_softc;
! 1978: struct ifreq *ifr = (struct ifreq *) data;
! 1979: struct ifaddr *ifa = (struct ifaddr *)data;
! 1980: int s, error = 0;
! 1981:
! 1982: s = splnet();
! 1983:
! 1984: if ((error = ether_ioctl(ifp, &sc->sc_arpcom, command,
! 1985: data)) > 0) {
! 1986: splx(s);
! 1987: return (error);
! 1988: }
! 1989:
! 1990: switch(command) {
! 1991: case SIOCSIFADDR:
! 1992: ifp->if_flags |= IFF_UP;
! 1993: if (!(ifp->if_flags & IFF_RUNNING))
! 1994: re_init(ifp);
! 1995: #ifdef INET
! 1996: if (ifa->ifa_addr->sa_family == AF_INET)
! 1997: arp_ifinit(&sc->sc_arpcom, ifa);
! 1998: #endif /* INET */
! 1999: break;
! 2000: case SIOCSIFMTU:
! 2001: if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
! 2002: error = EINVAL;
! 2003: else if (ifp->if_mtu != ifr->ifr_mtu)
! 2004: ifp->if_mtu = ifr->ifr_mtu;
! 2005: break;
! 2006: case SIOCSIFFLAGS:
! 2007: if (ifp->if_flags & IFF_UP) {
! 2008: if (ifp->if_flags & IFF_RUNNING &&
! 2009: ((ifp->if_flags ^ sc->if_flags) &
! 2010: IFF_PROMISC)) {
! 2011: re_setpromisc(sc);
! 2012: } else {
! 2013: if (!(ifp->if_flags & IFF_RUNNING))
! 2014: re_init(ifp);
! 2015: }
! 2016: } else {
! 2017: if (ifp->if_flags & IFF_RUNNING)
! 2018: re_stop(ifp, 1);
! 2019: }
! 2020: sc->if_flags = ifp->if_flags;
! 2021: break;
! 2022: case SIOCADDMULTI:
! 2023: case SIOCDELMULTI:
! 2024: error = (command == SIOCADDMULTI) ?
! 2025: ether_addmulti(ifr, &sc->sc_arpcom) :
! 2026: ether_delmulti(ifr, &sc->sc_arpcom);
! 2027: if (error == ENETRESET) {
! 2028: /*
! 2029: * Multicast list has changed; set the hardware
! 2030: * filter accordingly.
! 2031: */
! 2032: if (ifp->if_flags & IFF_RUNNING)
! 2033: re_setmulti(sc);
! 2034: error = 0;
! 2035: }
! 2036: break;
! 2037: case SIOCGIFMEDIA:
! 2038: case SIOCSIFMEDIA:
! 2039: error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command);
! 2040: break;
! 2041: default:
! 2042: error = EINVAL;
! 2043: break;
! 2044: }
! 2045:
! 2046: splx(s);
! 2047:
! 2048: return (error);
! 2049: }
! 2050:
! 2051: void
! 2052: re_watchdog(struct ifnet *ifp)
! 2053: {
! 2054: struct rl_softc *sc;
! 2055: int s;
! 2056:
! 2057: sc = ifp->if_softc;
! 2058: s = splnet();
! 2059: printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
! 2060: ifp->if_oerrors++;
! 2061:
! 2062: re_txeof(sc);
! 2063: re_rxeof(sc);
! 2064:
! 2065: re_init(ifp);
! 2066:
! 2067: splx(s);
! 2068: }
! 2069:
! 2070: /*
! 2071: * Stop the adapter and free any mbufs allocated to the
! 2072: * RX and TX lists.
! 2073: */
! 2074: void
! 2075: re_stop(struct ifnet *ifp, int disable)
! 2076: {
! 2077: struct rl_softc *sc;
! 2078: int i;
! 2079:
! 2080: sc = ifp->if_softc;
! 2081:
! 2082: ifp->if_timer = 0;
! 2083: sc->rl_link = 0;
! 2084:
! 2085: timeout_del(&sc->timer_handle);
! 2086: ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
! 2087:
! 2088: mii_down(&sc->sc_mii);
! 2089:
! 2090: CSR_WRITE_1(sc, RL_COMMAND, 0x00);
! 2091: CSR_WRITE_2(sc, RL_IMR, 0x0000);
! 2092: CSR_WRITE_2(sc, RL_ISR, 0xFFFF);
! 2093:
! 2094: if (sc->rl_head != NULL) {
! 2095: m_freem(sc->rl_head);
! 2096: sc->rl_head = sc->rl_tail = NULL;
! 2097: }
! 2098:
! 2099: /* Free the TX list buffers. */
! 2100: for (i = 0; i < RL_TX_QLEN; i++) {
! 2101: if (sc->rl_ldata.rl_txq[i].txq_mbuf != NULL) {
! 2102: bus_dmamap_unload(sc->sc_dmat,
! 2103: sc->rl_ldata.rl_txq[i].txq_dmamap);
! 2104: m_freem(sc->rl_ldata.rl_txq[i].txq_mbuf);
! 2105: sc->rl_ldata.rl_txq[i].txq_mbuf = NULL;
! 2106: }
! 2107: }
! 2108:
! 2109: /* Free the RX list buffers. */
! 2110: for (i = 0; i < RL_RX_DESC_CNT; i++) {
! 2111: if (sc->rl_ldata.rl_rxsoft[i].rxs_mbuf != NULL) {
! 2112: bus_dmamap_unload(sc->sc_dmat,
! 2113: sc->rl_ldata.rl_rxsoft[i].rxs_dmamap);
! 2114: m_freem(sc->rl_ldata.rl_rxsoft[i].rxs_mbuf);
! 2115: sc->rl_ldata.rl_rxsoft[i].rxs_mbuf = NULL;
! 2116: }
! 2117: }
! 2118: }
CVSweb