154359Sroberto/* $NetBSD: seeq8005.c,v 1.66 2020/01/30 04:56:11 thorpej Exp $ */ 2182007Sroberto 354359Sroberto/* 4182007Sroberto * Copyright (c) 2000, 2001 Ben Harris 554359Sroberto * Copyright (c) 1995-1998 Mark Brinicombe 6285612Sdelphij * All rights reserved. 7285612Sdelphij * 854359Sroberto * Redistribution and use in source and binary forms, with or without 9182007Sroberto * modification, are permitted provided that the following conditions 10182007Sroberto * are met: 11182007Sroberto * 1. Redistributions of source code must retain the above copyright 12182007Sroberto * notice, this list of conditions and the following disclaimer. 13182007Sroberto * 2. Redistributions in binary form must reproduce the above copyright 14182007Sroberto * notice, this list of conditions and the following disclaimer in the 15182007Sroberto * documentation and/or other materials provided with the distribution. 16182007Sroberto * 3. All advertising materials mentioning features or use of this software 17182007Sroberto * must display the following acknowledgement: 18182007Sroberto * This product includes software developed by Mark Brinicombe 19182007Sroberto * for the NetBSD Project. 20182007Sroberto * 4. The name of the company nor the name of the author may be used to 21182007Sroberto * endorse or promote products derived from this software without specific 22182007Sroberto * prior written permission. 23182007Sroberto * 24182007Sroberto * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25182007Sroberto * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26182007Sroberto * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27182007Sroberto * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 28182007Sroberto * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29182007Sroberto * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30182007Sroberto * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31182007Sroberto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32182007Sroberto * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3354359Sroberto * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3454359Sroberto * SUCH DAMAGE. 3554359Sroberto */ 3654359Sroberto/* 3754359Sroberto * seeq8005.c - SEEQ 8005 device driver 38182007Sroberto */ 3954359Sroberto/* 4054359Sroberto * This driver currently supports the following chips: 4154359Sroberto * SEEQ 8005 Advanced Ethernet Data Link Controller 4254359Sroberto * SEEQ 80C04 Ethernet Data Link Controller 4354359Sroberto * SEEQ 80C04A AutoDUPLEX CMOS Ethernet Data Link Controller 4454359Sroberto */ 4554359Sroberto/* 4654359Sroberto * More information on the 8004 and 8005 AEDLC controllers can be found in 4754359Sroberto * the SEEQ Technology Inc 1992 Data Comm Devices data book. 4854359Sroberto * 4954359Sroberto * This data book may no longer be available as these are rather old chips 5054359Sroberto * (1991 - 1993) 5154359Sroberto */ 5254359Sroberto/* 5354359Sroberto * This driver is based on the arm32 ea(4) driver, hence the names of many 5454359Sroberto * of the functions. 5554359Sroberto */ 5654359Sroberto/* 5754359Sroberto * Bugs/possible improvements: 5854359Sroberto * - Does not currently support DMA 5954359Sroberto * - Does not transmit multiple packets in one go 6054359Sroberto * - Does not support 8-bit busses 61285612Sdelphij */ 62285612Sdelphij 63285612Sdelphij#include <sys/cdefs.h> 64285612Sdelphij__KERNEL_RCSID(0, "$NetBSD: seeq8005.c,v 1.66 2020/01/30 04:56:11 thorpej Exp $"); 65285612Sdelphij 6654359Sroberto#include <sys/param.h> 6754359Sroberto#include <sys/systm.h> 6854359Sroberto#include <sys/endian.h> 6954359Sroberto#include <sys/errno.h> 7054359Sroberto#include <sys/ioctl.h> 7154359Sroberto#include <sys/mbuf.h> 7254359Sroberto#include <sys/socket.h> 7354359Sroberto#include <sys/syslog.h> 7454359Sroberto#include <sys/device.h> 7554359Sroberto 7654359Sroberto#include <net/if.h> 7754359Sroberto#include <net/if_dl.h> 7854359Sroberto#include <net/if_types.h> 7954359Sroberto#include <net/if_ether.h> 8054359Sroberto#include <net/if_media.h> 8154359Sroberto#include <net/bpf.h> 8254359Sroberto 8354359Sroberto#include <sys/rndsource.h> 8454359Sroberto 8554359Sroberto#include <sys/bus.h> 8654359Sroberto#include <sys/intr.h> 8754359Sroberto 8854359Sroberto#include <dev/ic/seeq8005reg.h> 8954359Sroberto#include <dev/ic/seeq8005var.h> 9054359Sroberto 9154359Sroberto/*#define SEEQ_DEBUG*/ 9254359Sroberto 9354359Sroberto/* for debugging convenience */ 9454359Sroberto#ifdef SEEQ8005_DEBUG 9554359Sroberto#define SEEQ_DEBUG_MISC 1 9654359Sroberto#define SEEQ_DEBUG_TX 2 9754359Sroberto#define SEEQ_DEBUG_RX 4 9854359Sroberto#define SEEQ_DEBUG_PKT 8 9954359Sroberto#define SEEQ_DEBUG_TXINT 16 10054359Sroberto#define SEEQ_DEBUG_RXINT 32 10154359Srobertoint seeq8005_debug = 0; 10254359Sroberto#define DPRINTF(f, x) { if (seeq8005_debug & (f)) printf x; } 10354359Sroberto#else 10454359Sroberto#define DPRINTF(f, x) 10554359Sroberto#endif 10654359Sroberto 10754359Sroberto#ifndef EA_TX_BUFFER_SIZE 108285612Sdelphij#define EA_TX_BUFFER_SIZE 0x800 /* (> ETHER_MAX_LEN) */ 109285612Sdelphij#endif 110285612Sdelphij#ifndef EA_TX_BUFFER_COUNT 111285612Sdelphij#define EA_TX_BUFFER_COUNT 1 /* (> 0) */ 112285612Sdelphij#endif 113285612Sdelphij 114285612Sdelphij#define SEEQ_READ16(sc, iot, ioh, reg) \ 11554359Sroberto ((sc)->sc_flags & SF_8BIT ? \ 11654359Sroberto (bus_space_read_1((iot), (ioh), (reg)) | \ 11754359Sroberto (bus_space_read_1((iot), (ioh), (reg) + 1) << 8)) : \ 11854359Sroberto (bus_space_read_2((iot), (ioh), (reg)))) 11954359Sroberto 12054359Sroberto#define SEEQ_WRITE16(sc, iot, ioh, reg, val) do { \ 12154359Sroberto if ((sc)->sc_flags & SF_8BIT) { \ 12254359Sroberto bus_space_write_1((iot), (ioh), (reg), (val) & 0xff); \ 12354359Sroberto bus_space_write_1((iot), (ioh), (reg) + 1, (val) >> 8); \ 12454359Sroberto } else \ 12554359Sroberto bus_space_write_2((iot), (ioh), (reg), (val)); \ 12654359Sroberto} while (/*CONSTCOND*/0) 12754359Sroberto 12854359Sroberto/* 12954359Sroberto * prototypes 13054359Sroberto */ 13154359Sroberto 13254359Srobertostatic int ea_init(struct ifnet *); 13354359Srobertostatic int ea_ioctl(struct ifnet *, u_long, void *); 13454359Srobertostatic void ea_start(struct ifnet *); 13554359Srobertostatic void ea_watchdog(struct ifnet *); 13654359Srobertostatic void ea_chipreset(struct seeq8005_softc *); 137285612Sdelphijstatic void ea_ramtest(struct seeq8005_softc *); 13854359Srobertostatic int ea_stoptx(struct seeq8005_softc *); 13954359Srobertostatic int ea_stoprx(struct seeq8005_softc *); 14054359Srobertostatic void ea_stop(struct ifnet *, int); 14154359Srobertostatic void ea_await_fifo_empty(struct seeq8005_softc *); 14254359Srobertostatic void ea_await_fifo_full(struct seeq8005_softc *); 14354359Srobertostatic void ea_writebuf(struct seeq8005_softc *, u_char *, int, size_t); 144285612Sdelphijstatic void ea_readbuf(struct seeq8005_softc *, u_char *, int, size_t); 14554359Srobertostatic void ea_select_buffer(struct seeq8005_softc *, int); 14654359Srobertostatic void ea_set_address(struct seeq8005_softc *, int, const uint8_t *); 14754359Srobertostatic void ea_read(struct seeq8005_softc *, int, int); 14854359Srobertostatic struct mbuf *ea_get(struct seeq8005_softc *, int, int, struct ifnet *); 14954359Srobertostatic void ea_txint(struct seeq8005_softc *); 15054359Srobertostatic void ea_rxint(struct seeq8005_softc *); 15154359Srobertostatic void ea_txpacket(struct seeq8005_softc *); 15254359Srobertostatic int ea_writembuf(struct seeq8005_softc *, struct mbuf *, int); 15354359Srobertostatic void ea_mc_reset(struct seeq8005_softc *); 15454359Srobertostatic void ea_mc_reset_8004(struct seeq8005_softc *); 155285612Sdelphijstatic void ea_mc_reset_8005(struct seeq8005_softc *); 15654359Srobertostatic int ea_mediachange(struct ifnet *); 15754359Srobertostatic void ea_mediastatus(struct ifnet *, struct ifmediareq *); 15854359Sroberto 15954359Srobertostatic u_char* padbuf = NULL; 16054359Sroberto 16154359Sroberto 16254359Sroberto/* 16354359Sroberto * Attach chip. 16454359Sroberto */ 16554359Sroberto 166285612Sdelphijvoid 16754359Srobertoseeq8005_attach(struct seeq8005_softc *sc, const uint8_t *myaddr, int *media, 16854359Sroberto int nmedia, int defmedia) 16954359Sroberto{ 170285612Sdelphij device_t dev = sc->sc_dev; 17154359Sroberto struct ifnet *ifp = &sc->sc_ethercom.ec_if; 17254359Sroberto bus_space_tag_t iot = sc->sc_iot; 17354359Sroberto bus_space_handle_t ioh = sc->sc_ioh; 17454359Sroberto u_int id; 17554359Sroberto 17654359Sroberto KASSERT(myaddr != NULL); 17754359Sroberto printf(" address %s", ether_sprintf(myaddr)); 17854359Sroberto 17954359Sroberto /* Stop the board. */ 18054359Sroberto 18154359Sroberto ea_chipreset(sc); 182182007Sroberto 183182007Sroberto /* Work out data bus width. */ 184182007Sroberto SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_PTR, 0x1234); 185182007Sroberto if (SEEQ_READ16(sc, iot, ioh, SEEQ_RX_PTR) != 0x1234) { 186182007Sroberto /* Try 8-bit mode */ 18754359Sroberto sc->sc_flags |= SF_8BIT; 18854359Sroberto SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_PTR, 0x1234); 18954359Sroberto if (SEEQ_READ16(sc, iot, ioh, SEEQ_RX_PTR) != 0x1234) { 19054359Sroberto aprint_normal("\n"); 19154359Sroberto aprint_error_dev(dev, 19254359Sroberto "Cannot determine data bus width\n"); 19354359Sroberto return; 19454359Sroberto } 195182007Sroberto } 19654359Sroberto 19754359Sroberto printf(", %d-bit", sc->sc_flags & SF_8BIT ? 8 : 16); 19854359Sroberto 19954359Sroberto /* Get the product ID */ 20054359Sroberto 20154359Sroberto ea_select_buffer(sc, SEEQ_BUFCODE_PRODUCTID); 20254359Sroberto id = SEEQ_READ16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN); 20354359Sroberto 20454359Sroberto switch (id & SEEQ_PRODUCTID_MASK) { 20554359Sroberto case SEEQ_PRODUCTID_8004: 20654359Sroberto sc->sc_variant = SEEQ_8004; 20754359Sroberto switch (id & SEEQ_PRODUCTID_REV_MASK) { 20854359Sroberto case SEEQ_PRODUCTID_REV_80C04: 20954359Sroberto printf(", SEEQ 80C04\n"); 21054359Sroberto break; 21154359Sroberto case SEEQ_PRODUCTID_REV_80C04A: 21254359Sroberto printf(", SEEQ 80C04A\n"); 21354359Sroberto break; 21454359Sroberto default: 21554359Sroberto /* Unknown SEEQ 8004 variants */ 21654359Sroberto printf(", SEEQ 8004 rev %x\n", 21754359Sroberto id & SEEQ_PRODUCTID_REV_MASK); 21854359Sroberto break; 21954359Sroberto } 22054359Sroberto break; 22154359Sroberto default: /* XXX */ 22254359Sroberto sc->sc_variant = SEEQ_8005; 22354359Sroberto printf(", SEEQ 8005\n"); 22454359Sroberto break; 22554359Sroberto } 22654359Sroberto 22754359Sroberto /* Both the 8004 and 8005 are designed for 64K Buffer memory */ 22854359Sroberto sc->sc_buffersize = SEEQ_MAX_BUFFER_SIZE; 22954359Sroberto 23054359Sroberto /* 23154359Sroberto * Set up tx and rx buffers. 23254359Sroberto * 23354359Sroberto * We set aside EA_TX_BUFFER_SIZE * EA_TX_BUFFER_COUNT for TX 23454359Sroberto * buffers and the rest for RX buffers 23554359Sroberto */ 23654359Sroberto sc->sc_tx_bufs = EA_TX_BUFFER_COUNT; 23754359Sroberto sc->sc_tx_bufsize = sc->sc_tx_bufs * EA_TX_BUFFER_SIZE; 23854359Sroberto sc->sc_rx_bufsize = sc->sc_buffersize - sc->sc_tx_bufsize; 239285612Sdelphij sc->sc_enabled = 0; 240285612Sdelphij 24154359Sroberto /* Test the RAM */ 24254359Sroberto ea_ramtest(sc); 24354359Sroberto 24454359Sroberto printf("%s: %dKB packet memory, txbuf=%dKB (%d buffers), rxbuf=%dKB", 245285612Sdelphij device_xname(dev), sc->sc_buffersize >> 10, 24654359Sroberto sc->sc_tx_bufsize >> 10, sc->sc_tx_bufs, sc->sc_rx_bufsize >> 10); 24754359Sroberto 24854359Sroberto if (padbuf == NULL) { 24954359Sroberto padbuf = malloc(ETHER_MIN_LEN - ETHER_CRC_LEN, M_DEVBUF, 25054359Sroberto M_ZERO | M_WAITOK); 25154359Sroberto } 25254359Sroberto 25354359Sroberto /* Initialise ifnet structure. */ 25454359Sroberto 25554359Sroberto strlcpy(ifp->if_xname, device_xname(dev), IFNAMSIZ); 25654359Sroberto ifp->if_softc = sc; 25754359Sroberto ifp->if_start = ea_start; 25854359Sroberto ifp->if_ioctl = ea_ioctl; 25954359Sroberto ifp->if_init = ea_init; 26054359Sroberto ifp->if_stop = ea_stop; 26154359Sroberto ifp->if_watchdog = ea_watchdog; 26254359Sroberto ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST; 26354359Sroberto if (sc->sc_variant == SEEQ_8004) 26454359Sroberto ifp->if_flags |= IFF_SIMPLEX; 26554359Sroberto IFQ_SET_READY(&ifp->if_snd); 26654359Sroberto 26754359Sroberto /* Initialize media goo. */ 268285612Sdelphij ifmedia_init(&sc->sc_media, 0, ea_mediachange, ea_mediastatus); 26954359Sroberto if (media != NULL) { 27054359Sroberto int i; 27154359Sroberto 27254359Sroberto for (i = 0; i < nmedia; i++) 27354359Sroberto ifmedia_add(&sc->sc_media, media[i], 0, NULL); 27454359Sroberto ifmedia_set(&sc->sc_media, defmedia); 27554359Sroberto } else { 276285612Sdelphij ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_MANUAL, 0, NULL); 27754359Sroberto ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_MANUAL); 27854359Sroberto } 27954359Sroberto 28054359Sroberto /* We can support 802.1Q VLAN-sized frames. */ 28154359Sroberto sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; 28254359Sroberto 28354359Sroberto /* Now we can attach the interface. */ 28454359Sroberto 28554359Sroberto if_attach(ifp); 28654359Sroberto ether_ifattach(ifp, myaddr); 28754359Sroberto 28854359Sroberto printf("\n"); 28954359Sroberto 29054359Sroberto /* After \n because it can print a line of its own. */ 29154359Sroberto rnd_attach_source(&sc->rnd_source, device_xname(dev), 29254359Sroberto RND_TYPE_NET, RND_FLAG_DEFAULT); 29354359Sroberto} 29454359Sroberto 29554359Sroberto/* 296285612Sdelphij * Media change callback. 29754359Sroberto */ 29854359Srobertostatic int 29954359Srobertoea_mediachange(struct ifnet *ifp) 30054359Sroberto{ 30154359Sroberto struct seeq8005_softc *sc = ifp->if_softc; 30254359Sroberto 30354359Sroberto if (sc->sc_mediachange) 30454359Sroberto return (*sc->sc_mediachange)(sc); 30554359Sroberto return EINVAL; 30654359Sroberto} 30754359Sroberto 30854359Sroberto/* 30954359Sroberto * Media status callback. 31054359Sroberto */ 31154359Srobertostatic void 31254359Srobertoea_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 31354359Sroberto{ 31454359Sroberto struct seeq8005_softc *sc = ifp->if_softc; 31554359Sroberto 31654359Sroberto if (sc->sc_enabled == 0) { 31754359Sroberto ifmr->ifm_active = IFM_ETHER | IFM_NONE; 31854359Sroberto ifmr->ifm_status = 0; 31954359Sroberto return; 32054359Sroberto } 32154359Sroberto 32254359Sroberto if (sc->sc_mediastatus) 32354359Sroberto (*sc->sc_mediastatus)(sc, ifmr); 32454359Sroberto} 32554359Sroberto 32654359Sroberto/* 32754359Sroberto * Test the RAM on the ethernet card. 32854359Sroberto */ 32954359Sroberto 33054359Srobertovoid 33154359Srobertoea_ramtest(struct seeq8005_softc *sc) 33254359Sroberto{ 33354359Sroberto bus_space_tag_t iot = sc->sc_iot; 33454359Sroberto bus_space_handle_t ioh = sc->sc_ioh; 33554359Sroberto int loop; 33654359Sroberto u_int sum = 0; 33754359Sroberto 33854359Sroberto /* 33954359Sroberto * Test the buffer memory on the board. 34054359Sroberto * Write simple pattens to it and read them back. 34154359Sroberto */ 34254359Sroberto 34354359Sroberto /* Set up the whole buffer RAM for writing */ 34454359Sroberto 34554359Sroberto ea_select_buffer(sc, SEEQ_BUFCODE_TX_EAP); 34654359Sroberto SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, (SEEQ_MAX_BUFFER_SIZE >> 8) - 1); 347285612Sdelphij SEEQ_WRITE16(sc, iot, ioh, SEEQ_TX_PTR, 0x0000); 348285612Sdelphij SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_PTR, SEEQ_MAX_BUFFER_SIZE - 2); 349285612Sdelphij 350285612Sdelphij#define SEEQ_RAMTEST_LOOP(value) \ 35154359Srobertodo { \ 35254359Sroberto /* Set the write start address and write a pattern */ \ 35354359Sroberto ea_writebuf(sc, NULL, 0x0000, 0); \ 354285612Sdelphij for (loop = 0; loop < SEEQ_MAX_BUFFER_SIZE; loop += 2) \ 35554359Sroberto SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, (value)); \ 356285612Sdelphij \ 35754359Sroberto /* Set the read start address and verify the pattern */ \ 35854359Sroberto ea_readbuf(sc, NULL, 0x0000, 0); \ 359285612Sdelphij for (loop = 0; loop < SEEQ_MAX_BUFFER_SIZE; loop += 2) \ 36054359Sroberto if (SEEQ_READ16(sc, iot, ioh, SEEQ_BUFWIN) != (value)) \ 36154359Sroberto ++sum; \ 36254359Sroberto} while (/*CONSTCOND*/0) 36354359Sroberto 36454359Sroberto SEEQ_RAMTEST_LOOP(loop); 36554359Sroberto SEEQ_RAMTEST_LOOP(loop ^ (SEEQ_MAX_BUFFER_SIZE - 1)); 36654359Sroberto SEEQ_RAMTEST_LOOP(0xaa55); 36754359Sroberto SEEQ_RAMTEST_LOOP(0x55aa); 36854359Sroberto 36954359Sroberto /* Report */ 37054359Sroberto 37154359Sroberto if (sum > 0) 37254359Sroberto aprint_error_dev(sc->sc_dev, 373285612Sdelphij "buffer RAM failed self test, %d faults\n", sum); 374285612Sdelphij} 375285612Sdelphij 376285612Sdelphij 377285612Sdelphij/* 378285612Sdelphij * Stop the tx interface. 379285612Sdelphij * 380285612Sdelphij * Returns 0 if the tx was already stopped or 1 if it was active 381285612Sdelphij */ 38254359Sroberto 383285612Sdelphijstatic int 384285612Sdelphijea_stoptx(struct seeq8005_softc *sc) 385285612Sdelphij{ 38654359Sroberto bus_space_tag_t iot = sc->sc_iot; 387285612Sdelphij bus_space_handle_t ioh = sc->sc_ioh; 388285612Sdelphij int timeout; 38954359Sroberto int status; 390285612Sdelphij 391285612Sdelphij DPRINTF(SEEQ_DEBUG_TX, ("ea_stoptx()\n")); 392285612Sdelphij 393285612Sdelphij sc->sc_enabled = 0; 394285612Sdelphij 395285612Sdelphij status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS); 396285612Sdelphij if (!(status & SEEQ_STATUS_TX_ON)) 39754359Sroberto return 0; 39854359Sroberto 39954359Sroberto /* Stop any tx and wait for confirmation */ 40054359Sroberto SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 40154359Sroberto sc->sc_command | SEEQ_CMD_TX_OFF); 40254359Sroberto 40354359Sroberto timeout = 20000; 404182007Sroberto do { 405182007Sroberto status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS); 406182007Sroberto delay(1); 407182007Sroberto } while ((status & SEEQ_STATUS_TX_ON) && --timeout > 0); 408182007Sroberto if (timeout == 0) 409182007Sroberto log(LOG_ERR, "%s: timeout waiting for tx termination\n", 410182007Sroberto device_xname(sc->sc_dev)); 41154359Sroberto 41254359Sroberto /* Clear any pending tx interrupt */ 41354359Sroberto SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 41454359Sroberto sc->sc_command | SEEQ_CMD_TX_INTACK); 41554359Sroberto return 1; 41654359Sroberto} 41754359Sroberto 41854359Sroberto 41954359Sroberto/* 42054359Sroberto * Stop the rx interface. 42154359Sroberto * 42254359Sroberto * Returns 0 if the tx was already stopped or 1 if it was active 42354359Sroberto */ 42454359Sroberto 42554359Srobertostatic int 42654359Srobertoea_stoprx(struct seeq8005_softc *sc) 42754359Sroberto{ 42854359Sroberto bus_space_tag_t iot = sc->sc_iot; 42954359Sroberto bus_space_handle_t ioh = sc->sc_ioh; 43054359Sroberto int timeout; 43154359Sroberto int status; 43254359Sroberto 433 DPRINTF(SEEQ_DEBUG_RX, ("ea_stoprx()\n")); 434 435 status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS); 436 if (!(status & SEEQ_STATUS_RX_ON)) 437 return 0; 438 439 /* Stop any rx and wait for confirmation */ 440 441 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 442 sc->sc_command | SEEQ_CMD_RX_OFF); 443 444 timeout = 20000; 445 do { 446 status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS); 447 delay(1); 448 } while ((status & SEEQ_STATUS_RX_ON) && --timeout > 0); 449 if (timeout == 0) 450 log(LOG_ERR, "%s: timeout waiting for rx termination\n", 451 device_xname(sc->sc_dev)); 452 453 /* Clear any pending rx interrupt */ 454 455 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 456 sc->sc_command | SEEQ_CMD_RX_INTACK); 457 return 1; 458} 459 460 461/* 462 * Stop interface. 463 * Stop all IO and shut the interface down 464 */ 465 466/* ARGSUSED */ 467static void 468ea_stop(struct ifnet *ifp, int disable) 469{ 470 struct seeq8005_softc *sc = ifp->if_softc; 471 bus_space_tag_t iot = sc->sc_iot; 472 bus_space_handle_t ioh = sc->sc_ioh; 473 474 DPRINTF(SEEQ_DEBUG_MISC, ("ea_stop()\n")); 475 476 /* Stop all IO */ 477 ea_stoptx(sc); 478 ea_stoprx(sc); 479 480 /* Disable rx and tx interrupts */ 481 sc->sc_command &= ~(SEEQ_CMD_RX_INTEN | SEEQ_CMD_TX_INTEN); 482 483 /* Clear any pending interrupts */ 484 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 485 sc->sc_command | SEEQ_CMD_RX_INTACK | SEEQ_CMD_TX_INTACK | 486 SEEQ_CMD_DMA_INTACK | SEEQ_CMD_BW_INTACK); 487 488 if (sc->sc_variant == SEEQ_8004) { 489 /* Put the chip to sleep */ 490 ea_select_buffer(sc, SEEQ_BUFCODE_CONFIG3); 491 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 492 sc->sc_config3 | SEEQ_CFG3_SLEEP); 493 } 494 495 /* Cancel any watchdog timer */ 496 sc->sc_ethercom.ec_if.if_timer = 0; 497} 498 499 500/* 501 * Reset the chip 502 * Following this the software registers are reset 503 */ 504 505static void 506ea_chipreset(struct seeq8005_softc *sc) 507{ 508 bus_space_tag_t iot = sc->sc_iot; 509 bus_space_handle_t ioh = sc->sc_ioh; 510 511 DPRINTF(SEEQ_DEBUG_MISC, ("ea_chipreset()\n")); 512 513 /* Reset the controller. Min of 4us delay here */ 514 515 /* 516 * This can be called before we know whether the chip is in 8- or 517 * 16-bit mode, so we do a reset in both modes. The 16-bit reset is 518 * harmless in 8-bit mode, so we do that second. 519 */ 520 521 /* In 16-bit mode, this will munge the PreamSelect bit. */ 522 bus_space_write_1(iot, ioh, SEEQ_CONFIG2 + 1, SEEQ_CFG2_RESET >> 8); 523 delay(4); 524 /* In 8-bit mode, this will zero the bottom half of config reg 2. */ 525 bus_space_write_2(iot, ioh, SEEQ_CONFIG2, SEEQ_CFG2_RESET); 526 delay(4); 527 528 sc->sc_command = 0; 529 sc->sc_config1 = 0; 530 sc->sc_config2 = 0; 531 sc->sc_config3 = 0; 532} 533 534 535/* 536 * If the DMA FIFO's in write mode, wait for it to empty. Needed when 537 * switching the FIFO from write to read. We also use it when changing 538 * the address for writes. 539 */ 540static void 541ea_await_fifo_empty(struct seeq8005_softc *sc) 542{ 543 bus_space_tag_t iot = sc->sc_iot; 544 bus_space_handle_t ioh = sc->sc_ioh; 545 int timeout; 546 547 timeout = 20000; 548 if ((SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS) & 549 SEEQ_STATUS_FIFO_DIR) != 0) 550 return; /* FIFO is reading anyway. */ 551 while (--timeout > 0) 552 if (SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS) & 553 SEEQ_STATUS_FIFO_EMPTY) 554 return; 555 log(LOG_ERR, "%s: DMA FIFO failed to empty\n", 556 device_xname(sc->sc_dev)); 557} 558 559/* 560 * Wait for the DMA FIFO to fill before reading from it. 561 */ 562static void 563ea_await_fifo_full(struct seeq8005_softc *sc) 564{ 565 bus_space_tag_t iot = sc->sc_iot; 566 bus_space_handle_t ioh = sc->sc_ioh; 567 int timeout; 568 569 timeout = 20000; 570 while (--timeout > 0) 571 if (SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS) & 572 SEEQ_STATUS_FIFO_FULL) 573 return; 574 log(LOG_ERR, "%s: DMA FIFO failed to fill\n", device_xname(sc->sc_dev)); 575} 576 577/* 578 * write to the buffer memory on the interface 579 * 580 * The buffer address is set to ADDR. 581 * If len != 0 then data is copied from the address starting at buf 582 * to the interface buffer. 583 * BUF must be usable as a uint16_t *. 584 * If LEN is odd, it must be safe to overwrite one extra byte. 585 */ 586 587static void 588ea_writebuf(struct seeq8005_softc *sc, u_char *buf, int addr, size_t len) 589{ 590 bus_space_tag_t iot = sc->sc_iot; 591 bus_space_handle_t ioh = sc->sc_ioh; 592 593 DPRINTF(SEEQ_DEBUG_MISC, ("writebuf: st=%04x\n", 594 SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS))); 595 596#ifdef DIAGNOSTIC 597 if (__predict_false(!ALIGNED_POINTER(buf, uint16_t))) 598 panic("%s: unaligned writebuf", device_xname(sc->sc_dev)); 599 if (__predict_false(addr >= SEEQ_MAX_BUFFER_SIZE)) 600 panic("%s: writebuf out of range", device_xname(sc->sc_dev)); 601#endif 602 603 if (addr != -1) { 604 ea_await_fifo_empty(sc); 605 606 ea_select_buffer(sc, SEEQ_BUFCODE_LOCAL_MEM); 607 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 608 sc->sc_command | SEEQ_CMD_FIFO_WRITE); 609 610 ea_await_fifo_empty(sc); 611 612 SEEQ_WRITE16(sc, iot, ioh, SEEQ_DMA_ADDR, addr); 613 } 614 615 if (len > 0) { 616 if (sc->sc_flags & SF_8BIT) 617 bus_space_write_multi_1(iot, ioh, SEEQ_BUFWIN, 618 (uint8_t *)buf, len); 619 else 620 bus_space_write_multi_2(iot, ioh, SEEQ_BUFWIN, 621 /* LINTED: alignment checked above */ 622 (uint16_t *)buf, len / 2); 623 } 624 if (!(sc->sc_flags & SF_8BIT) && len % 2) { 625 /* Write the last byte */ 626 bus_space_write_2(iot, ioh, SEEQ_BUFWIN, buf[len - 1]); 627 } 628 /* Leave FIFO to empty in the background */ 629} 630 631 632/* 633 * read from the buffer memory on the interface 634 * 635 * The buffer address is set to ADDR. 636 * If len != 0 then data is copied from the interface buffer to the 637 * address starting at buf. 638 * BUF must be usable as a uint16_t *. 639 * If LEN is odd, it must be safe to overwrite one extra byte. 640 */ 641 642static void 643ea_readbuf(struct seeq8005_softc *sc, u_char *buf, int addr, size_t len) 644{ 645 bus_space_tag_t iot = sc->sc_iot; 646 bus_space_handle_t ioh = sc->sc_ioh; 647 int runup; 648 649 DPRINTF(SEEQ_DEBUG_MISC, ("readbuf: st=%04x addr=%04x len=%d\n", 650 SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS), addr, len)); 651 652#ifdef DIAGNOSTIC 653 if (__predict_false(!ALIGNED_POINTER(buf, uint16_t))) 654 panic("%s: unaligned readbuf", device_xname(sc->sc_dev)); 655 if (__predict_false(addr >= SEEQ_MAX_BUFFER_SIZE)) 656 panic("%s: readbuf out of range", device_xname(sc->sc_dev)); 657#endif 658 659 if (addr != -1) { 660 /* 661 * SEEQ 80C04 bug: 662 * Starting reading from certain addresses seems to cause 663 * us to get bogus results, so we avoid them. 664 */ 665 runup = 0; 666 if (sc->sc_variant == SEEQ_8004 && 667 ((addr & 0x00ff) == 0x00ea || 668 (addr & 0x00ff) == 0x00ee || 669 (addr & 0x00ff) == 0x00f0)) 670 runup = (addr & 0x00ff) - 0x00e8; 671 672 ea_await_fifo_empty(sc); 673 674 ea_select_buffer(sc, SEEQ_BUFCODE_LOCAL_MEM); 675 676 /* 677 * 80C04 bug workaround. I found this in the old arm32 "eb" 678 * driver. I've no idea what it does, but it seems to stop 679 * the chip mangling data so often. 680 */ 681 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 682 sc->sc_command | SEEQ_CMD_FIFO_WRITE); 683 ea_await_fifo_empty(sc); 684 685 SEEQ_WRITE16(sc, iot, ioh, SEEQ_DMA_ADDR, addr - runup); 686 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 687 sc->sc_command | SEEQ_CMD_FIFO_READ); 688 689 ea_await_fifo_full(sc); 690 while (runup > 0) { 691 /* LINTED: Reading a volatile _does_ have an effect */ 692 (void)SEEQ_READ16(sc, iot, ioh, SEEQ_BUFWIN); 693 runup -= 2; 694 } 695 } 696 697 if (len > 0) { 698 if (sc->sc_flags & SF_8BIT) 699 bus_space_read_multi_1(iot, ioh, SEEQ_BUFWIN, 700 (uint8_t *)buf, len); 701 else 702 bus_space_read_multi_2(iot, ioh, SEEQ_BUFWIN, 703 /* LINTED: pointer alignment checked above */ 704 (uint16_t *)buf, len / 2); 705 } 706 if (!(sc->sc_flags & SF_8BIT) && len % 2) { 707 /* Read the last byte */ 708 buf[len - 1] = bus_space_read_2(iot, ioh, SEEQ_BUFWIN); 709 } 710} 711 712static void 713ea_select_buffer(struct seeq8005_softc *sc, int bufcode) 714{ 715 716 SEEQ_WRITE16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_CONFIG1, 717 sc->sc_config1 | bufcode); 718} 719 720/* Must be called at splnet */ 721static void 722ea_set_address(struct seeq8005_softc *sc, int which, const uint8_t *ea) 723{ 724 int i; 725 726 ea_select_buffer(sc, SEEQ_BUFCODE_STATION_ADDR0 + which); 727 for (i = 0; i < ETHER_ADDR_LEN; ++i) 728 SEEQ_WRITE16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN, ea[i]); 729} 730 731/* 732 * Initialize interface. 733 * 734 * This should leave the interface in a state for packet reception and 735 * transmission. 736 */ 737 738static int 739ea_init(struct ifnet *ifp) 740{ 741 struct seeq8005_softc *sc = ifp->if_softc; 742 bus_space_tag_t iot = sc->sc_iot; 743 bus_space_handle_t ioh = sc->sc_ioh; 744 int s; 745 746 DPRINTF(SEEQ_DEBUG_MISC, ("ea_init()\n")); 747 748 s = splnet(); 749 750 /* First, reset the board. */ 751 752 ea_chipreset(sc); 753 754 /* Set up defaults for the registers */ 755 756 sc->sc_command = 0; 757 sc->sc_config1 = 0; 758#if BYTE_ORDER == BIG_ENDIAN 759 sc->sc_config2 = SEEQ_CFG2_BYTESWAP; 760#else 761 sc->sc_config2 = 0; 762#endif 763 sc->sc_config3 = 0; 764 765 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, sc->sc_command); 766 SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG1, sc->sc_config1); 767 SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2); 768 if (sc->sc_variant == SEEQ_8004) { 769 ea_select_buffer(sc, SEEQ_BUFCODE_CONFIG3); 770 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, sc->sc_config3); 771 } 772 773 /* Write the station address - the receiver must be off */ 774 ea_set_address(sc, 0, (const uint8_t *)CLLADDR(ifp->if_sadl)); 775 776 /* Split board memory into Rx and Tx. */ 777 ea_select_buffer(sc, SEEQ_BUFCODE_TX_EAP); 778 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, (sc->sc_tx_bufsize>> 8) - 1); 779 780 if (sc->sc_variant == SEEQ_8004) { 781 /* Make the interface IFF_SIMPLEX. */ 782 sc->sc_config2 |= SEEQ_CFG2_RX_TX_DISABLE; 783 /* Enable reception of long packets (for vlan(4)). */ 784 sc->sc_config2 |= SEEQ_CFG2_PASS_LONGSHORT; 785 } 786 787 /* Configure rx. */ 788 ea_mc_reset(sc); 789 if (ifp->if_flags & IFF_PROMISC) 790 sc->sc_config1 = SEEQ_CFG1_PROMISCUOUS; 791 else if ((ifp->if_flags & IFF_ALLMULTI) || sc->sc_variant == SEEQ_8004) 792 sc->sc_config1 = SEEQ_CFG1_MULTICAST; 793 else 794 sc->sc_config1 = SEEQ_CFG1_BROADCAST; 795 sc->sc_config1 |= SEEQ_CFG1_STATION_ADDR0; 796 SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG1, sc->sc_config1); 797 798 /* Setup the Rx pointers */ 799 sc->sc_rx_ptr = sc->sc_tx_bufsize; 800 801 SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_PTR, sc->sc_rx_ptr); 802 SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_END, sc->sc_rx_ptr >> 8); 803 804 805 /* Place a NULL header at the beginning of the receive area */ 806 ea_writebuf(sc, NULL, sc->sc_rx_ptr, 0); 807 808 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 0x0000); 809 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 0x0000); 810 811 812 /* Configure TX. */ 813 DPRINTF(SEEQ_DEBUG_MISC, ("Configuring tx...\n")); 814 815 SEEQ_WRITE16(sc, iot, ioh, SEEQ_TX_PTR, 0x0000); 816 817 sc->sc_config2 |= SEEQ_CFG2_OUTPUT; 818 SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2); 819 820 /* Reset tx buffer pointers */ 821 sc->sc_tx_cur = 0; 822 sc->sc_tx_used = 0; 823 sc->sc_tx_next = 0; 824 825 /* Place a NULL header at the beginning of the transmit area */ 826 ea_writebuf(sc, NULL, 0x0000, 0); 827 828 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 0x0000); 829 SEEQ_WRITE16(sc, iot, ioh, SEEQ_BUFWIN, 0x0000); 830 831 sc->sc_command |= SEEQ_CMD_TX_INTEN; 832 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, sc->sc_command); 833 834 /* Turn on Rx */ 835 sc->sc_command |= SEEQ_CMD_RX_INTEN; 836 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 837 sc->sc_command | SEEQ_CMD_RX_ON); 838 839 /* TX_ON gets set by ea_txpacket when there's something to transmit. */ 840 841 842 /* Set flags appropriately. */ 843 ifp->if_flags |= IFF_RUNNING; 844 ifp->if_flags &= ~IFF_OACTIVE; 845 sc->sc_enabled = 1; 846 847 /* And start output. */ 848 ea_start(ifp); 849 850 splx(s); 851 return 0; 852} 853 854/* 855 * Start output on interface. Get datagrams from the queue and output them, 856 * giving the receiver a chance between datagrams. Call only from splnet or 857 * interrupt level! 858 */ 859 860static void 861ea_start(struct ifnet *ifp) 862{ 863 struct seeq8005_softc *sc = ifp->if_softc; 864 int s; 865 866 s = splnet(); 867 DPRINTF(SEEQ_DEBUG_TX, ("ea_start()...\n")); 868 869 /* 870 * Don't do anything if output is active. seeq8005intr() will call 871 * us (actually ea_txpacket()) back when the card's ready for more 872 * frames. 873 */ 874 if (ifp->if_flags & IFF_OACTIVE) { 875 splx(s); 876 return; 877 } 878 879 /* Mark interface as output active */ 880 881 ifp->if_flags |= IFF_OACTIVE; 882 883 /* tx packets */ 884 885 ea_txpacket(sc); 886 splx(s); 887} 888 889 890/* 891 * Transfer a packet to the interface buffer and start transmission 892 * 893 * Called at splnet() 894 */ 895 896static void 897ea_txpacket(struct seeq8005_softc *sc) 898{ 899 bus_space_tag_t iot = sc->sc_iot; 900 bus_space_handle_t ioh = sc->sc_ioh; 901 struct mbuf *m0; 902 struct ifnet *ifp; 903 904 ifp = &sc->sc_ethercom.ec_if; 905 906 /* Dequeue the next packet. */ 907 IFQ_DEQUEUE(&ifp->if_snd, m0); 908 909 /* If there's nothing to send, return. */ 910 if (m0 == NULL) { 911 ifp->if_flags &= ~IFF_OACTIVE; 912 sc->sc_config2 |= SEEQ_CFG2_OUTPUT; 913 SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2); 914 DPRINTF(SEEQ_DEBUG_TX, ("tx finished\n")); 915 return; 916 } 917 918 /* Give the packet to the bpf, if any. */ 919 bpf_mtap(ifp, m0, BPF_D_OUT); 920 921 DPRINTF(SEEQ_DEBUG_TX, ("Tx new packet\n")); 922 923 sc->sc_config2 &= ~SEEQ_CFG2_OUTPUT; 924 SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2); 925 926 ea_writembuf(sc, m0, 0x0000); 927 m_freem(m0); 928 929 SEEQ_WRITE16(sc, iot, ioh, SEEQ_TX_PTR, 0x0000); 930 931 /* Now transmit the datagram. */ 932 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 933 sc->sc_command | SEEQ_CMD_TX_ON); 934 935 /* Make sure we notice if the chip goes silent on us. */ 936 ifp->if_timer = 5; 937 938 DPRINTF(SEEQ_DEBUG_TX, 939 ("st=%04x\n", SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS))); 940 DPRINTF(SEEQ_DEBUG_TX, ("tx: queued\n")); 941} 942 943/* 944 * Copy a packet from an mbuf to the transmit buffer on the card. 945 * 946 * Puts a valid Tx header at the start of the packet, and a null header at 947 * the end. 948 */ 949static int 950ea_writembuf(struct seeq8005_softc *sc, struct mbuf *m0, int bufstart) 951{ 952 struct mbuf *m; 953 int len, nextpacket; 954 uint8_t hdr[4]; 955 956 /* 957 * Copy the datagram to the packet buffer. 958 */ 959 len = 0; 960 for (m = m0; m; m = m->m_next) { 961 if (m->m_len == 0) 962 continue; 963 ea_writebuf(sc, mtod(m, u_char *), bufstart + 4 + len, 964 m->m_len); 965 len += m->m_len; 966 } 967 968 if (len < ETHER_MIN_LEN) { 969 ea_writebuf(sc, padbuf, bufstart + 4 + len, 970 ETHER_MIN_LEN - len); 971 len = ETHER_MIN_LEN; 972 } 973 974 /* Follow it with a NULL packet header */ 975 memset(hdr, 0, 4); 976 ea_writebuf(sc, hdr, bufstart + 4 + len, 4); 977 978 /* Ok we now have a packet len bytes long in our packet buffer */ 979 DPRINTF(SEEQ_DEBUG_TX, ("ea_writembuf: length=%d\n", len)); 980 981 /* Write the packet header */ 982 nextpacket = bufstart + len + 4; 983 hdr[0] = (nextpacket >> 8) & 0xff; 984 hdr[1] = nextpacket & 0xff; 985 hdr[2] = SEEQ_PKTCMD_TX | SEEQ_PKTCMD_DATA_FOLLOWS | 986 SEEQ_TXCMD_XMIT_SUCCESS_INT | SEEQ_TXCMD_COLLISION_INT; 987 hdr[3] = 0; /* Status byte -- will be updated by hardware. */ 988 ea_writebuf(sc, hdr, bufstart, 4); 989 990 return len; 991} 992 993/* 994 * Ethernet controller interrupt. 995 */ 996 997int 998seeq8005intr(void *arg) 999{ 1000 struct seeq8005_softc *sc = arg; 1001 bus_space_tag_t iot = sc->sc_iot; 1002 bus_space_handle_t ioh = sc->sc_ioh; 1003 int status, handled; 1004 1005 handled = 0; 1006 1007 /* Get the controller status */ 1008 status = SEEQ_READ16(sc, iot, ioh, SEEQ_STATUS); 1009 1010 /* Tx interrupt ? */ 1011 if (status & SEEQ_STATUS_TX_INT) { 1012 handled = 1; 1013 1014 /* Acknowledge the interrupt */ 1015 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 1016 sc->sc_command | SEEQ_CMD_TX_INTACK); 1017 1018 ea_txint(sc); 1019 } 1020 1021 1022 /* Rx interrupt ? */ 1023 if (status & SEEQ_STATUS_RX_INT) { 1024 handled = 1; 1025 1026 /* Acknowledge the interrupt */ 1027 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 1028 sc->sc_command | SEEQ_CMD_RX_INTACK); 1029 1030 /* Processes the received packets */ 1031 ea_rxint(sc); 1032 } 1033 1034 if (handled) 1035 rnd_add_uint32(&sc->rnd_source, status); 1036 1037 return handled; 1038} 1039 1040static void 1041ea_txint(struct seeq8005_softc *sc) 1042{ 1043 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1044 bus_space_tag_t iot = sc->sc_iot; 1045 bus_space_handle_t ioh = sc->sc_ioh; 1046 uint8_t txhdr[4]; 1047 u_int txstatus; 1048 1049 ea_readbuf(sc, txhdr, 0x0000, 4); 1050 1051 DPRINTF(SEEQ_DEBUG_TX, ("txstatus=%02x %02x %02x %02x\n", 1052 txhdr[0], txhdr[1], txhdr[2], txhdr[3])); 1053 txstatus = txhdr[3]; 1054 1055 /* 1056 * If SEEQ_TXSTAT_COLLISION is set then we received at least 1057 * one collision. On the 8004 we can find out exactly how many 1058 * collisions occurred. 1059 * 1060 * The SEEQ_PKTSTAT_DONE will be set if the transmission has 1061 * completed. 1062 * 1063 * If SEEQ_TXSTAT_COLLISION16 is set then 16 collisions 1064 * occurred and the packet transmission was aborted. 1065 * This situation is untested as present. 1066 * 1067 * The SEEQ_TXSTAT_BABBLE is untested as it should only be set 1068 * when we deliberately transmit oversized packets (e.g. for 1069 * 802.1Q). 1070 */ 1071 if (txstatus & SEEQ_TXSTAT_COLLISION) { 1072 switch (sc->sc_variant) { 1073 case SEEQ_8004: { 1074 int colls; 1075 1076 /* 1077 * The 8004 contains a 4 bit collision count 1078 * in the status register. 1079 */ 1080#if 0 1081 /* This appears to be broken on 80C04.AE */ 1082 if_statadd(ifp, if_collisions, 1083 (txstatus >> SEEQ_TXSTAT_COLLISIONS_SHIFT) 1084 & SEEQ_TXSTAT_COLLISION_MASK; 1085#endif 1086 1087 /* Use the TX Collision register */ 1088 ea_select_buffer(sc, SEEQ_BUFCODE_TX_COLLS); 1089 colls = bus_space_read_1(iot, ioh, SEEQ_BUFWIN); 1090 if_statadd(ifp, if_collisions, colls); 1091 break; 1092 } 1093 case SEEQ_8005: 1094 /* We known there was at least 1 collision */ 1095 if_statinc(ifp, if_collisions); 1096 break; 1097 } 1098 } else if (txstatus & SEEQ_TXSTAT_COLLISION16) { 1099 printf("seeq_intr: col16 %x\n", txstatus); 1100 if_statadd2(ifp, if_collisions, 16, if_oerrors, 1); 1101 } 1102 1103 /* Have we completed transmission on the packet ? */ 1104 if (txstatus & SEEQ_PKTSTAT_DONE) { 1105 /* Clear watchdog timer. */ 1106 ifp->if_timer = 0; 1107 ifp->if_flags &= ~IFF_OACTIVE; 1108 1109 /* Update stats */ 1110 if_statinc(ifp, if_opackets); 1111 1112 /* Tx next packet */ 1113 1114 ea_txpacket(sc); 1115 } 1116} 1117 1118static void 1119ea_rxint(struct seeq8005_softc *sc) 1120{ 1121 bus_space_tag_t iot = sc->sc_iot; 1122 bus_space_handle_t ioh = sc->sc_ioh; 1123 u_int addr; 1124 int len; 1125 int ctrl; 1126 int ptr; 1127 int status; 1128 uint8_t rxhdr[4]; 1129 struct ifnet *ifp; 1130 1131 ifp = &sc->sc_ethercom.ec_if; 1132 1133 1134 /* We start from the last rx pointer position */ 1135 addr = sc->sc_rx_ptr; 1136 sc->sc_config2 &= ~SEEQ_CFG2_OUTPUT; 1137 SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2); 1138 1139 do { 1140 /* Read rx header */ 1141 ea_readbuf(sc, rxhdr, addr, 4); 1142 1143 /* Split the packet header */ 1144 ptr = (rxhdr[0] << 8) | rxhdr[1]; 1145 ctrl = rxhdr[2]; 1146 status = rxhdr[3]; 1147 1148 DPRINTF(SEEQ_DEBUG_RX, 1149 ("addr=%04x ptr=%04x ctrl=%02x status=%02x\n", 1150 addr, ptr, ctrl, status)); 1151 1152 /* Zero packet ptr ? then must be null header so exit */ 1153 if (ptr == 0) break; 1154 1155 /* Sanity-check the next-packet pointer and flags. */ 1156 if (__predict_false(ptr < sc->sc_tx_bufsize || 1157 (ctrl & SEEQ_PKTCMD_TX))) { 1158 if_statinc(ifp, if_ierrors); 1159 log(LOG_ERR, 1160 "%s: Rx chain corrupt at %04x (ptr = %04x)\n", 1161 device_xname(sc->sc_dev), addr, ptr); 1162 ea_init(ifp); 1163 return; 1164 } 1165 1166 /* Get packet length */ 1167 len = (ptr - addr) - 4; 1168 1169 if (len < 0) 1170 len += sc->sc_rx_bufsize; 1171 DPRINTF(SEEQ_DEBUG_RX, ("len=%04x\n", len)); 1172 1173 /* Has the packet rx completed ? if not then exit */ 1174 if ((status & SEEQ_PKTSTAT_DONE) == 0) 1175 break; 1176 1177 /* 1178 * Did we have any errors? then note error and go to 1179 * next packet 1180 */ 1181 if (__predict_false(status & 1182 (SEEQ_RXSTAT_CRC_ERROR | SEEQ_RXSTAT_DRIBBLE_ERROR | 1183 SEEQ_RXSTAT_SHORT_FRAME))) { 1184 if_statinc(ifp, if_ierrors); 1185 log(LOG_WARNING, 1186 "%s: rx packet error at %04x (err=%02x)\n", 1187 device_xname(sc->sc_dev), addr, status & 0x0f); 1188 /* XXX shouldn't need to reset if it's genuine. */ 1189 ea_init(ifp); 1190 return; 1191 } 1192 /* 1193 * Is the packet too big? We allow slightly oversize packets 1194 * for vlan(4) and tcpdump purposes, but the rest of the world 1195 * wants incoming packets in a single mbuf cluster. 1196 */ 1197 if (__predict_false(len > MCLBYTES)) { 1198 if_statinc(ifp, if_ierrors); 1199 log(LOG_ERR, 1200 "%s: rx packet size error at %04x (len=%d)\n", 1201 device_xname(sc->sc_dev), addr, len); 1202 ea_init(ifp); 1203 return; 1204 } 1205 1206 /* Pass data up to upper levels. */ 1207 ea_read(sc, addr + 4, len); 1208 1209 addr = ptr; 1210 } while (len != 0); 1211 1212 sc->sc_config2 |= SEEQ_CFG2_OUTPUT; 1213 SEEQ_WRITE16(sc, iot, ioh, SEEQ_CONFIG2, sc->sc_config2); 1214 1215 DPRINTF(SEEQ_DEBUG_RX, ("new rx ptr=%04x\n", addr)); 1216 1217 /* Store new rx pointer */ 1218 sc->sc_rx_ptr = addr; 1219 SEEQ_WRITE16(sc, iot, ioh, SEEQ_RX_END, sc->sc_rx_ptr >> 8); 1220 1221 /* Make sure the receiver is on */ 1222 SEEQ_WRITE16(sc, iot, ioh, SEEQ_COMMAND, 1223 sc->sc_command | SEEQ_CMD_RX_ON); 1224} 1225 1226 1227/* 1228 * Pass a packet up to the higher levels. 1229 */ 1230 1231static void 1232ea_read(struct seeq8005_softc *sc, int addr, int len) 1233{ 1234 struct mbuf *m; 1235 struct ifnet *ifp; 1236 1237 ifp = &sc->sc_ethercom.ec_if; 1238 1239 /* Pull packet off interface. */ 1240 m = ea_get(sc, addr, len, ifp); 1241 if (m == NULL) 1242 return; 1243 1244 if_percpuq_enqueue(ifp->if_percpuq, m); 1245} 1246 1247/* 1248 * Pull read data off a interface. Len is length of data, with local net 1249 * header stripped. We copy the data into mbufs. When full cluster sized 1250 * units are present we copy into clusters. 1251 */ 1252 1253struct mbuf * 1254ea_get(struct seeq8005_softc *sc, int addr, int totlen, struct ifnet *ifp) 1255{ 1256 struct mbuf *top, **mp, *m; 1257 int len; 1258 u_int cp, epkt; 1259 1260 cp = addr; 1261 epkt = cp + totlen; 1262 1263 MGETHDR(m, M_DONTWAIT, MT_DATA); 1264 if (m == NULL) 1265 return NULL; 1266 m_set_rcvif(m, ifp); 1267 m->m_pkthdr.len = totlen; 1268 m->m_len = MHLEN; 1269 top = NULL; 1270 mp = ⊤ 1271 1272 while (totlen > 0) { 1273 if (top) { 1274 MGET(m, M_DONTWAIT, MT_DATA); 1275 if (m == NULL) { 1276 m_freem(top); 1277 return NULL; 1278 } 1279 m->m_len = MLEN; 1280 } 1281 len = uimin(totlen, epkt - cp); 1282 if (len >= MINCLSIZE) { 1283 MCLGET(m, M_DONTWAIT); 1284 if (m->m_flags & M_EXT) 1285 m->m_len = len = uimin(len, MCLBYTES); 1286 else 1287 len = m->m_len; 1288 } else { 1289 /* 1290 * Place initial small packet/header at end of mbuf. 1291 */ 1292 if (len < m->m_len) { 1293 if (top == NULL && len + max_linkhdr <= m->m_len) 1294 m->m_data += max_linkhdr; 1295 m->m_len = len; 1296 } else 1297 len = m->m_len; 1298 } 1299 if (top == NULL) { 1300 /* Make sure the payload is aligned */ 1301 char *newdata = (char *) 1302 ALIGN((char*)m->m_data + 1303 sizeof(struct ether_header)) - 1304 sizeof(struct ether_header); 1305 len -= newdata - m->m_data; 1306 m->m_len = len; 1307 m->m_data = newdata; 1308 } 1309 ea_readbuf(sc, mtod(m, u_char *), 1310 cp < SEEQ_MAX_BUFFER_SIZE ? cp : cp - sc->sc_rx_bufsize, 1311 len); 1312 cp += len; 1313 *mp = m; 1314 mp = &m->m_next; 1315 totlen -= len; 1316 if (cp == epkt) 1317 cp = addr; 1318 } 1319 1320 return top; 1321} 1322 1323/* 1324 * Process an ioctl request. Mostly boilerplate. 1325 */ 1326static int 1327ea_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1328{ 1329 struct seeq8005_softc *sc = ifp->if_softc; 1330 int s, error = 0; 1331 1332 s = splnet(); 1333 switch (cmd) { 1334 1335 default: 1336 error = ether_ioctl(ifp, cmd, data); 1337 if (error == ENETRESET) { 1338 /* 1339 * Multicast list has changed; set the hardware filter 1340 * accordingly. 1341 */ 1342 if (ifp->if_flags & IFF_RUNNING) 1343 ea_mc_reset(sc); 1344 error = 0; 1345 } 1346 break; 1347 } 1348 1349 splx(s); 1350 return error; 1351} 1352 1353/* Must be called at splnet() */ 1354 1355static void 1356ea_mc_reset(struct seeq8005_softc *sc) 1357{ 1358 1359 switch (sc->sc_variant) { 1360 case SEEQ_8004: 1361 ea_mc_reset_8004(sc); 1362 return; 1363 case SEEQ_8005: 1364 ea_mc_reset_8005(sc); 1365 return; 1366 } 1367} 1368 1369static void 1370ea_mc_reset_8004(struct seeq8005_softc *sc) 1371{ 1372 struct ethercom *ec = &sc->sc_ethercom; 1373 struct ifnet *ifp = &ec->ec_if; 1374 struct ether_multi *enm; 1375 uint32_t crc; 1376 int i; 1377 struct ether_multistep step; 1378 uint8_t af[8]; 1379 1380 /* 1381 * Set up multicast address filter by passing all multicast addresses 1382 * through a crc generator, and then using bits 2 - 7 as an index 1383 * into the 64 bit logical address filter. The high order bits 1384 * selects the word, while the rest of the bits select the bit within 1385 * the word. 1386 */ 1387 1388 if (ifp->if_flags & IFF_PROMISC) { 1389 ifp->if_flags |= IFF_ALLMULTI; 1390 for (i = 0; i < 8; i++) 1391 af[i] = 0xff; 1392 return; 1393 } 1394 for (i = 0; i < 8; i++) 1395 af[i] = 0; 1396 1397 ETHER_LOCK(ec); 1398 ETHER_FIRST_MULTI(step, ec, enm); 1399 while (enm != NULL) { 1400 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1401 sizeof(enm->enm_addrlo)) != 0) { 1402 /* 1403 * We must listen to a range of multicast addresses. 1404 * For now, just accept all multicasts, rather than 1405 * trying to set only those filter bits needed to match 1406 * the range. (At this time, the only use of address 1407 * ranges is for IP multicast routing, for which the 1408 * range is big enough to require all bits set.) 1409 */ 1410 ifp->if_flags |= IFF_ALLMULTI; 1411 for (i = 0; i < 8; i++) 1412 af[i] = 0xff; 1413 break; 1414 } 1415 1416 crc = ether_crc32_be(enm->enm_addrlo, sizeof(enm->enm_addrlo)); 1417 1418 /* Just want the 6 most significant bits. */ 1419 crc = (crc >> 2) & 0x3f; 1420 1421 /* Turn on the corresponding bit in the filter. */ 1422 af[crc >> 3] |= 1 << (crc & 0x7); 1423 1424 ETHER_NEXT_MULTI(step, enm); 1425 } 1426 ETHER_UNLOCK(ec); 1427 ifp->if_flags &= ~IFF_ALLMULTI; 1428 1429 ea_select_buffer(sc, SEEQ_BUFCODE_MULTICAST); 1430 for (i = 0; i < 8; ++i) 1431 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 1432 SEEQ_BUFWIN, af[i]); 1433} 1434 1435static void 1436ea_mc_reset_8005(struct seeq8005_softc *sc) 1437{ 1438 struct ethercom *ec = &sc->sc_ethercom; 1439 struct ether_multi *enm; 1440 struct ether_multistep step; 1441 int naddr, maxaddrs; 1442 1443 naddr = 0; 1444 maxaddrs = 5; 1445 ETHER_LOCK(ec); 1446 ETHER_FIRST_MULTI(step, ec, enm); 1447 while (enm != NULL) { 1448 /* Have we got space? */ 1449 if (naddr >= maxaddrs || 1450 memcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) { 1451 ec->ec_if.if_flags |= IFF_ALLMULTI; 1452 ETHER_UNLOCK(ec); 1453 ea_ioctl(&ec->ec_if, SIOCSIFFLAGS, NULL); 1454 return; 1455 } 1456 ea_set_address(sc, 1 + naddr, enm->enm_addrlo); 1457 sc->sc_config1 |= SEEQ_CFG1_STATION_ADDR1 << naddr; 1458 naddr++; 1459 ETHER_NEXT_MULTI(step, enm); 1460 } 1461 ETHER_UNLOCK(ec); 1462 1463 for (; naddr < maxaddrs; naddr++) 1464 sc->sc_config1 &= ~(SEEQ_CFG1_STATION_ADDR1 << naddr); 1465 SEEQ_WRITE16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_CONFIG1, 1466 sc->sc_config1); 1467} 1468 1469/* 1470 * Device timeout routine. 1471 */ 1472 1473static void 1474ea_watchdog(struct ifnet *ifp) 1475{ 1476 struct seeq8005_softc *sc = ifp->if_softc; 1477 1478 log(LOG_ERR, "%s: lost Tx interrupt (status = 0x%04x)\n", 1479 device_xname(sc->sc_dev), 1480 SEEQ_READ16(sc, sc->sc_iot, sc->sc_ioh, SEEQ_STATUS)); 1481 if_statinc(ifp, if_oerrors); 1482 1483 /* Kick the interface */ 1484 1485 ea_init(ifp); 1486 1487 ifp->if_timer = 0; 1488} 1489 1490/* End of seeq8005.c */ 1491