Annotation of sys/dev/pci/if_lmc_common.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: if_lmc_common.c,v 1.11 2005/11/07 00:29:21 brad Exp $ */
! 2: /* $NetBSD: if_lmc_common.c,v 1.1 1999/03/25 03:32:43 explorer Exp $ */
! 3:
! 4: /*-
! 5: * Copyright (c) 1997-1999 LAN Media Corporation (LMC)
! 6: * All rights reserved. www.lanmedia.com
! 7: *
! 8: * This code is written by Michael Graff <graff@vix.com> for LMC.
! 9: * The code is derived from permitted modifications to software created
! 10: * by Matt Thomas (matt@3am-software.com).
! 11: *
! 12: * Redistribution and use in source and binary forms, with or without
! 13: * modification, are permitted provided that the following conditions
! 14: * are met:
! 15: * 1. Redistributions of source code must retain the above copyright
! 16: * notice, this list of conditions and the following disclaimer.
! 17: * 2. Redistributions in binary form must reproduce the above
! 18: * copyright notice, this list of conditions and the following disclaimer
! 19: * in the documentation and/or other materials provided with the
! 20: * distribution.
! 21: * 3. All marketing or advertising materials mentioning features or
! 22: * use of this software must display the following acknowledgement:
! 23: * This product includes software developed by LAN Media Corporation
! 24: * and its contributors.
! 25: * 4. Neither the name of LAN Media Corporation nor the names of its
! 26: * contributors may be used to endorse or promote products derived
! 27: * from this software without specific prior written permission.
! 28: *
! 29: * THIS SOFTWARE IS PROVIDED BY LAN MEDIA CORPORATION AND CONTRIBUTORS
! 30: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 31: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 32: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 33: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 34: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 35: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 36: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 37: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 38: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
! 39: * THE POSSIBILITY OF SUCH DAMAGE.
! 40: */
! 41:
! 42: /*-
! 43: * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
! 44: * All rights reserved.
! 45: *
! 46: * Redistribution and use in source and binary forms, with or without
! 47: * modification, are permitted provided that the following conditions
! 48: * are met:
! 49: * 1. Redistributions of source code must retain the above copyright
! 50: * notice, this list of conditions and the following disclaimer.
! 51: * 2. The name of the author may not be used to endorse or promote products
! 52: * derived from this software without specific prior written permission
! 53: *
! 54: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 55: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 56: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 57: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 58: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 59: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 60: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 61: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 62: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 63: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 64: */
! 65:
! 66: #include "bpfilter.h"
! 67:
! 68: #include <sys/param.h>
! 69: #include <sys/systm.h>
! 70: #include <sys/mbuf.h>
! 71: #include <sys/socket.h>
! 72: #include <sys/ioctl.h>
! 73: #include <sys/errno.h>
! 74: #include <sys/malloc.h>
! 75: #include <sys/kernel.h>
! 76: #include <sys/proc.h> /* only for declaration of wakeup() used by vm.h */
! 77: #include <sys/device.h>
! 78:
! 79: #include <dev/pci/pcidevs.h>
! 80:
! 81: #include <net/if.h>
! 82: #include <net/if_types.h>
! 83: #include <net/if_dl.h>
! 84: #include <net/netisr.h>
! 85:
! 86: #if NBPFILTER > 0
! 87: #include <net/bpf.h>
! 88: #endif
! 89:
! 90: #include <net/if_sppp.h>
! 91:
! 92: #include <machine/bus.h>
! 93:
! 94: #include <dev/pci/pcireg.h>
! 95: #include <dev/pci/pcivar.h>
! 96: #include <dev/ic/dc21040reg.h>
! 97:
! 98: #define d_length1 u.bd_length1
! 99: #define d_length2 u.bd_length2
! 100: #define d_flag u.bd_flag
! 101:
! 102: #include <dev/pci/if_lmc_types.h>
! 103: #include <dev/pci/if_lmcioctl.h>
! 104: #include <dev/pci/if_lmcvar.h>
! 105:
! 106: void
! 107: lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits)
! 108: {
! 109: sc->lmc_gpio_io &= ~bits;
! 110: LMC_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET | (sc->lmc_gpio_io));
! 111: }
! 112:
! 113: void
! 114: lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits)
! 115: {
! 116: sc->lmc_gpio_io |= bits;
! 117: LMC_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET | (sc->lmc_gpio_io));
! 118: }
! 119:
! 120: void
! 121: lmc_led_on(lmc_softc_t * const sc, u_int32_t led)
! 122: {
! 123: sc->lmc_miireg16 &= ~led;
! 124: lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
! 125: }
! 126:
! 127: void
! 128: lmc_led_off(lmc_softc_t * const sc, u_int32_t led)
! 129: {
! 130: sc->lmc_miireg16 |= led;
! 131: lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
! 132: }
! 133:
! 134: void
! 135: lmc_reset(lmc_softc_t * const sc)
! 136: {
! 137: sc->lmc_miireg16 |= LMC_MII16_FIFO_RESET;
! 138: lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
! 139:
! 140: sc->lmc_miireg16 &= ~LMC_MII16_FIFO_RESET;
! 141: lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
! 142:
! 143: /*
! 144: * make some of the GPIO pins be outputs
! 145: */
! 146: lmc_gpio_mkoutput(sc, LMC_GEP_DP | LMC_GEP_RESET);
! 147:
! 148: /*
! 149: * drive DP and RESET low to force configuration. This also forces
! 150: * the transmitter clock to be internal, but we expect to reset
! 151: * that later anyway.
! 152: */
! 153: sc->lmc_gpio &= ~(LMC_GEP_DP | LMC_GEP_RESET);
! 154: LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
! 155:
! 156: /*
! 157: * hold for more than 10 microseconds
! 158: */
! 159: DELAY(50);
! 160:
! 161: /*
! 162: * stop driving Xilinx-related signals
! 163: */
! 164: lmc_gpio_mkinput(sc, LMC_GEP_DP | LMC_GEP_RESET);
! 165:
! 166: /*
! 167: * busy wait for the chip to reset
! 168: */
! 169: while ((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_DP) == 0);
! 170:
! 171: /*
! 172: * Call media specific init routine
! 173: */
! 174: sc->lmc_media->init(sc);
! 175: }
! 176:
! 177: void
! 178: lmc_dec_reset(lmc_softc_t * const sc)
! 179: {
! 180: #ifndef __linux__
! 181: lmc_ringinfo_t *ri;
! 182: lmc_desc_t *di;
! 183: #endif
! 184: u_int32_t val;
! 185:
! 186: /*
! 187: * disable all interrupts
! 188: */
! 189: sc->lmc_intrmask = 0;
! 190: LMC_CSR_WRITE(sc, csr_intr, sc->lmc_intrmask);
! 191:
! 192: /*
! 193: * we are, obviously, down.
! 194: */
! 195: #ifndef __linux__
! 196: sc->lmc_flags &= ~(LMC_IFUP | LMC_MODEMOK);
! 197:
! 198: DP(("lmc_dec_reset\n"));
! 199: #endif
! 200:
! 201: /*
! 202: * Reset the chip with a software reset command.
! 203: * Wait 10 microseconds (actually 50 PCI cycles but at
! 204: * 33MHz that comes to two microseconds but wait a
! 205: * bit longer anyways)
! 206: */
! 207: LMC_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
! 208: DELAY(10);
! 209: sc->lmc_cmdmode = LMC_CSR_READ(sc, csr_command);
! 210:
! 211: /*
! 212: * We want:
! 213: * no ethernet address in frames we write
! 214: * disable padding (txdesc, padding disable)
! 215: * ignore runt frames (rdes0 bit 15)
! 216: * no receiver watchdog or transmitter jabber timer
! 217: * (csr15 bit 0,14 == 1)
! 218: * if using 16-bit CRC, turn off CRC (trans desc, crc disable)
! 219: */
! 220:
! 221: #ifndef TULIP_CMD_RECEIVEALL
! 222: #define TULIP_CMD_RECEIVEALL 0x40000000L
! 223: #endif
! 224:
! 225: sc->lmc_cmdmode |= ( TULIP_CMD_PROMISCUOUS
! 226: | TULIP_CMD_FULLDUPLEX
! 227: | TULIP_CMD_PASSBADPKT
! 228: | TULIP_CMD_NOHEARTBEAT
! 229: | TULIP_CMD_PORTSELECT
! 230: | TULIP_CMD_RECEIVEALL
! 231: | TULIP_CMD_MUSTBEONE
! 232: );
! 233: sc->lmc_cmdmode &= ~( TULIP_CMD_OPERMODE
! 234: | TULIP_CMD_THRESHOLDCTL
! 235: | TULIP_CMD_STOREFWD
! 236: | TULIP_CMD_TXTHRSHLDCTL
! 237: );
! 238:
! 239: LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
! 240:
! 241: /*
! 242: * disable receiver watchdog and transmit jabber
! 243: */
! 244: val = LMC_CSR_READ(sc, csr_sia_general);
! 245: val |= (TULIP_WATCHDOG_TXDISABLE | TULIP_WATCHDOG_RXDISABLE);
! 246: LMC_CSR_WRITE(sc, csr_sia_general, val);
! 247:
! 248: /*
! 249: * turn off those LEDs...
! 250: */
! 251: sc->lmc_miireg16 |= LMC_MII16_LED_ALL;
! 252: lmc_led_on(sc, LMC_MII16_LED0);
! 253:
! 254: #ifndef __linux__
! 255: /*
! 256: * reprogram the tx desc, rx desc, and PCI bus options
! 257: */
! 258: LMC_CSR_WRITE(sc, csr_txlist, sc->lmc_txdescmap->dm_segs[0].ds_addr);
! 259: LMC_CSR_WRITE(sc, csr_rxlist, sc->lmc_rxdescmap->dm_segs[0].ds_addr);
! 260: LMC_CSR_WRITE(sc, csr_busmode,
! 261: (1 << (LMC_BURSTSIZE(sc->lmc_unit) + 8))
! 262: |TULIP_BUSMODE_CACHE_ALIGN8
! 263: |TULIP_BUSMODE_READMULTIPLE);
! 264:
! 265: sc->lmc_txq.ifq_maxlen = LMC_TXDESCS;
! 266:
! 267: /*
! 268: * Free all the mbufs that were on the transmit ring.
! 269: */
! 270: for (;;) {
! 271: bus_dmamap_t map;
! 272: struct mbuf *m;
! 273:
! 274: IF_DEQUEUE(&sc->lmc_txq, m);
! 275: if (m == NULL)
! 276: break;
! 277: map = LMC_GETCTX(m, bus_dmamap_t);
! 278: bus_dmamap_unload(sc->lmc_dmatag, map);
! 279: sc->lmc_txmaps[sc->lmc_txmaps_free++] = map;
! 280: m_freem(m);
! 281: }
! 282:
! 283: /*
! 284: * reset descriptor state and reclaim all descriptors.
! 285: */
! 286: ri = &sc->lmc_txinfo;
! 287: ri->ri_nextin = ri->ri_nextout = ri->ri_first;
! 288: ri->ri_free = ri->ri_max;
! 289: for (di = ri->ri_first; di < ri->ri_last; di++)
! 290: di->d_status = 0;
! 291: bus_dmamap_sync(sc->lmc_dmatag, sc->lmc_txdescmap,
! 292: 0, sc->lmc_txdescmap->dm_mapsize,
! 293: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
! 294:
! 295: /*
! 296: * We need to collect all the mbufs were on the
! 297: * receive ring before we reinit it either to put
! 298: * them back on or to know if we have to allocate
! 299: * more.
! 300: */
! 301: ri = &sc->lmc_rxinfo;
! 302: ri->ri_nextin = ri->ri_nextout = ri->ri_first;
! 303: ri->ri_free = ri->ri_max;
! 304: for (di = ri->ri_first; di < ri->ri_last; di++) {
! 305: u_int32_t ctl = di->d_ctl;
! 306: di->d_status = 0;
! 307: di->d_ctl = LMC_CTL(LMC_CTL_FLGS(ctl),0,0);
! 308: di->d_addr1 = 0;
! 309: di->d_addr2 = 0;
! 310: }
! 311: bus_dmamap_sync(sc->lmc_dmatag, sc->lmc_rxdescmap,
! 312: 0, sc->lmc_rxdescmap->dm_mapsize,
! 313: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
! 314: for (;;) {
! 315: bus_dmamap_t map;
! 316: struct mbuf *m;
! 317: IF_DEQUEUE(&sc->lmc_rxq, m);
! 318: if (m == NULL)
! 319: break;
! 320: map = LMC_GETCTX(m, bus_dmamap_t);
! 321: bus_dmamap_unload(sc->lmc_dmatag, map);
! 322: sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
! 323: m_freem(m);
! 324: }
! 325: #endif
! 326: }
! 327:
! 328: void
! 329: lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base,
! 330: size_t csr_size)
! 331: {
! 332: sc->lmc_csrs.csr_busmode = csr_base + 0 * csr_size;
! 333: sc->lmc_csrs.csr_txpoll = csr_base + 1 * csr_size;
! 334: sc->lmc_csrs.csr_rxpoll = csr_base + 2 * csr_size;
! 335: sc->lmc_csrs.csr_rxlist = csr_base + 3 * csr_size;
! 336: sc->lmc_csrs.csr_txlist = csr_base + 4 * csr_size;
! 337: sc->lmc_csrs.csr_status = csr_base + 5 * csr_size;
! 338: sc->lmc_csrs.csr_command = csr_base + 6 * csr_size;
! 339: sc->lmc_csrs.csr_intr = csr_base + 7 * csr_size;
! 340: sc->lmc_csrs.csr_missed_frames = csr_base + 8 * csr_size;
! 341: sc->lmc_csrs.csr_9 = csr_base + 9 * csr_size;
! 342: sc->lmc_csrs.csr_10 = csr_base + 10 * csr_size;
! 343: sc->lmc_csrs.csr_11 = csr_base + 11 * csr_size;
! 344: sc->lmc_csrs.csr_12 = csr_base + 12 * csr_size;
! 345: sc->lmc_csrs.csr_13 = csr_base + 13 * csr_size;
! 346: sc->lmc_csrs.csr_14 = csr_base + 14 * csr_size;
! 347: sc->lmc_csrs.csr_15 = csr_base + 15 * csr_size;
! 348: }
CVSweb