summaryrefslogtreecommitdiffstats
path: root/sys/dev/tx
diff options
context:
space:
mode:
authorsemenu <semenu@FreeBSD.org>2002-10-22 00:57:51 +0000
committersemenu <semenu@FreeBSD.org>2002-10-22 00:57:51 +0000
commit44d9c31ef8ebcd6a1e87ee23fee797da3666a850 (patch)
treed6330d5e29e1005bb54d3586c8d50fb50b593d23 /sys/dev/tx
parentc7b342f47ccfa38cb1cb558555d2e23f7f14eb30 (diff)
downloadFreeBSD-src-44d9c31ef8ebcd6a1e87ee23fee797da3666a850.zip
FreeBSD-src-44d9c31ef8ebcd6a1e87ee23fee797da3666a850.tar.gz
Remove the OpenBSD comatibility stuff. Many changes to be more style(9)
compilant. Split two pieces if code into separate functions to do not exceed line length due to indentation.
Diffstat (limited to 'sys/dev/tx')
-rw-r--r--sys/dev/tx/if_tx.c900
-rw-r--r--sys/dev/tx/if_txreg.h11
-rw-r--r--sys/dev/tx/if_txvar.h65
3 files changed, 355 insertions, 621 deletions
diff --git a/sys/dev/tx/if_tx.c b/sys/dev/tx/if_tx.c
index faf4841..1c18cec 100644
--- a/sys/dev/tx/if_tx.c
+++ b/sys/dev/tx/if_tx.c
@@ -1,6 +1,3 @@
-/* $OpenBSD: if_tx.c,v 1.9.2.1 2000/02/21 22:29:13 niklas Exp $ */
-/* $FreeBSD$ */
-
/*-
* Copyright (c) 1997 Semen Ustimenko (semenu@FreeBSD.org)
* All rights reserved.
@@ -25,12 +22,19 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $FreeBSD$
*/
/*
- * EtherPower II 10/100 Fast Ethernet (tx0)
- * (aka SMC9432TX based on SMC83c170 EPIC chip)
- *
+ * EtherPower II 10/100 Fast Ethernet (SMC 9432 serie)
+ *
+ * These cards are based on SMC83c17x (EPIC) chip and one of the various
+ * PHYs (QS6612, AC101 and LXT970 were seen). The media support depends on
+ * card model. All cards support 10baseT/UTP and 100baseTX half- and full-
+ * duplex (SMB9432TX). SMC9432BTX also supports 10baseT/BNC. SMC9432FTX also
+ * supports fibre optics.
+ *
* Thanks are going to Steve Bauer and Jason Wright.
*/
@@ -43,9 +47,6 @@
#include <sys/socket.h>
#include <sys/queue.h>
-#if defined(__FreeBSD__)
-#define NBPFILTER 1
-
#include <net/if.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
@@ -56,12 +57,13 @@
#include <net/if_vlan_var.h>
-#include <vm/vm.h> /* for vtophys */
-#include <vm/pmap.h> /* for vtophys */
+#include <vm/vm.h> /* for vtophys */
+#include <vm/pmap.h> /* for vtophys */
#include <machine/bus_memio.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <machine/resource.h>
+#include <machine/clock.h> /* for DELAY */
#include <sys/bus.h>
#include <sys/rman.h>
@@ -78,65 +80,12 @@
#include <dev/tx/if_txreg.h>
#include <dev/tx/if_txvar.h>
-#else /* __OpenBSD__ */
-#include "bpfilter.h"
-
-#define NVLAN 0 /* not sure if/how OpenBSD supports VLANs */
-
-#include <sys/device.h>
-
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/if_types.h>
-#include <net/if_media.h>
-
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-#endif
-
-#ifdef IPX
-#include <netipx/ipx.h>
-#include <netipx/ipx_if.h>
-#endif
-
-#ifdef NS
-#include <netns/ns.h>
-#include <netns/ns_if.h>
-#endif
-
-#if NBPFILTER > 0
-#include <net/bpf.h>
-#endif
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-
-#include <dev/mii/mii.h>
-#include <dev/mii/miivar.h>
-#include <dev/mii/miidevs.h>
-#include <dev/mii/lxtphyreg.h>
-
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcidevs.h>
-
-#include <dev/pci/if_txvar.h>
-#endif
MODULE_DEPEND(tx, miibus, 1, 1, 1);
-#if defined(__FreeBSD__)
-#define EPIC_INTR_RET_TYPE void
-#else /* __OpenBSD__ */
-#define EPIC_INTR_RET_TYPE int
-#endif
-
static int epic_ifioctl(register struct ifnet *, u_long, caddr_t);
-static EPIC_INTR_RET_TYPE epic_intr(void *);
+static void epic_intr(void *);
+static void epic_tx_underrun(epic_softc_t *);
static int epic_common_attach(epic_softc_t *);
static void epic_ifstart(struct ifnet *);
static void epic_ifwatchdog(struct ifnet *);
@@ -148,6 +97,7 @@ static void epic_tx_done(epic_softc_t *);
static int epic_init_rings(epic_softc_t *);
static void epic_free_rings(epic_softc_t *);
static void epic_stop_activity(epic_softc_t *);
+static int epic_queue_last_packet(epic_softc_t *);
static void epic_start_activity(epic_softc_t *);
static void epic_set_rx_mode(epic_softc_t *);
static void epic_set_tx_mode(epic_softc_t *);
@@ -171,180 +121,18 @@ static void epic_miibus_mediainit(device_t);
static int epic_ifmedia_upd(struct ifnet *);
static void epic_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-/* -------------------------------------------------------------------------
- OS-specific part
- ------------------------------------------------------------------------- */
-
-#if defined(__OpenBSD__)
-/* -----------------------------OpenBSD------------------------------------- */
-
-int epic_openbsd_probe(struct device *,void *,void *);
-void epic_openbsd_attach(struct device *, struct device *, void *);
-void epic_openbsd_shutdown(void *);
-
-struct cfattach tx_ca = {
- sizeof(epic_softc_t), epic_openbsd_probe, epic_openbsd_attach
-};
-struct cfdriver tx_cd = {
- NULL,"tx",DV_IFNET
-};
-
-/* Synopsis: Check if device id corresponds with SMC83C170 id. */
-int
-epic_openbsd_probe(
- struct device *parent,
- void *match,
- void *aux )
-{
- struct pci_attach_args *pa = aux;
- if( PCI_VENDOR(pa->pa_id) != SMC_VENDORID )
- return 0;
-
- if( PCI_PRODUCT(pa->pa_id) == SMC_DEVICEID_83C170 )
- return 1;
-
- return 0;
-}
-
-void
-epic_openbsd_attach(
- struct device *parent,
- struct device *self,
- void *aux )
-{
- epic_softc_t *sc = (epic_softc_t*)self;
- struct pci_attach_args *pa = aux;
- pci_chipset_tag_t pc = pa->pa_pc;
- pci_intr_handle_t ih;
- const char *intrstr = NULL;
- struct ifnet *ifp;
- bus_addr_t iobase;
- bus_size_t iosize;
- int i;
- u_int32_t command;
-
- command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
- command |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
- PCI_COMMAND_MASTER_ENABLE;
- pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
- command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
-
-#ifdef EPIC_USEIOSPACE
- if (!(command & PCI_COMMAND_IO_ENABLE)) {
- printf(": failed to enable I/O ports\n");
- return;
- }
- if( pci_io_find(pc, pa->pa_tag, PCI_BASEIO, &iobase, &iosize)) {
- printf(": can't find i/o space\n");
- return;
- }
- if( bus_space_map(pa->pa_iot, iobase, iosize, 0, &sc->sc_sh)) {
- printf(": can't map i/o space\n");
- return;
- }
- sc->sc_st = pa->pa_iot;
-#else
- if (!(command & PCI_COMMAND_MEM_ENABLE)) {
- printf(": failed to enable memory mapping\n");
- return;
- }
- if( pci_mem_find(pc, pa->pa_tag, PCI_BASEMEM, &iobase, &iosize, NULL)) {
- printf(": can't find mem space\n");
- return;
- }
- if( bus_space_map(pa->pa_memt, iobase, iosize, 0, &sc->sc_sh)) {
- printf(": can't map i/o space\n");
- return;
- }
- sc->sc_st = pa->pa_memt;
-#endif
-
- ifp = &sc->sc_if;
- bcopy(sc->dev.dv_xname, ifp->if_xname,IFNAMSIZ);
- ifp->if_softc = sc;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_ioctl = epic_ifioctl;
- ifp->if_start = epic_ifstart;
- ifp->if_watchdog = epic_ifwatchdog;
-
- /* Do common attach procedure */
- if( epic_common_attach(sc) ) return;
-
- /* Map interrupt */
- if( pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin,
- pa->pa_intrline, &ih)) {
- printf(": can't map interrupt\n");
- return;
- }
- intrstr = pci_intr_string(pc, ih);
- sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, epic_intr, sc,
- self->dv_xname);
-
- if( NULL == sc->sc_ih ) {
- printf(": can't establish interrupt");
- if( intrstr )printf(" at %s",intrstr);
- printf("\n");
- return;
- }
- printf(": %s",intrstr);
-
- /* Display some info */
- printf(" address %s",ether_sprintf(sc->sc_macaddr));
-
- /* Init ifmedia interface */
- ifmedia_init(&sc->sc_mii.mii_media, 0,
- epic_ifmedia_upd, epic_ifmedia_sts);
- sc->sc_mii.mii_ifp = ifp;
- sc->sc_mii.mii_readreg = epic_miibus_readreg;
- sc->sc_mii.mii_writereg = epic_miibus_writereg;
- sc->sc_mii.mii_statchg = epic_miibus_statchg;
- mii_phy_probe(self, &sc->sc_mii, 0xffffffff);
- if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
- ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE,0,NULL);
- ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
- } else
- ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
-
- /* Attach os interface and bpf */
- if_attach(ifp);
- ether_ifattach(ifp);
-#if NBPFILTER > 0
- bpfattach(&sc->sc_if.if_bpf, ifp, DLT_EN10MB,
- sizeof(struct ether_header));
-#endif
-
- /* Set shutdown routine to stop DMA process */
- shutdownhook_establish(epic_openbsd_shutdown, sc);
- printf("\n");
-}
-
-/* Simple call epic_stop() */
-void
-epic_openbsd_shutdown(
- void *sc)
-{
- epic_stop(sc);
-}
-
-#else /* __FreeBSD__ */
-/* -----------------------------FreeBSD------------------------------------- */
-
-static int epic_freebsd_probe(device_t);
-static int epic_freebsd_attach(device_t);
-static void epic_freebsd_shutdown(device_t);
-static int epic_freebsd_detach(device_t);
+static int epic_probe(device_t);
+static int epic_attach(device_t);
+static void epic_shutdown(device_t);
+static int epic_detach(device_t);
static struct epic_type *epic_devtype(device_t);
static device_method_t epic_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, epic_freebsd_probe),
- DEVMETHOD(device_attach, epic_freebsd_attach),
- DEVMETHOD(device_detach, epic_freebsd_detach),
- DEVMETHOD(device_shutdown, epic_freebsd_shutdown),
-
- /* bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+ /* Device interface */
+ DEVMETHOD(device_probe, epic_probe),
+ DEVMETHOD(device_attach, epic_attach),
+ DEVMETHOD(device_detach, epic_detach),
+ DEVMETHOD(device_shutdown, epic_shutdown),
/* MII interface */
DEVMETHOD(miibus_readreg, epic_miibus_readreg),
@@ -356,9 +144,9 @@ static device_method_t epic_methods[] = {
};
static driver_t epic_driver = {
- "tx",
- epic_methods,
- sizeof(epic_softc_t)
+ "tx",
+ epic_methods,
+ sizeof(epic_softc_t)
};
static devclass_t epic_devclass;
@@ -368,12 +156,12 @@ DRIVER_MODULE(miibus, tx, miibus_driver, miibus_devclass, 0, 0);
static struct epic_type epic_devs[] = {
{ SMC_VENDORID, SMC_DEVICEID_83C170,
- "SMC EtherPower II 10/100" },
+ "SMC EtherPower II 10/100" },
{ 0, 0, NULL }
};
static int
-epic_freebsd_probe(dev)
+epic_probe(dev)
device_t dev;
{
struct epic_type *t;
@@ -415,11 +203,11 @@ epic_devtype(dev)
#endif
/*
- * Do FreeBSD-specific attach routine, like map registers, alloc softc
- * structure and etc.
+ * Attach routine: map registers, allocate softc, rings and descriptors.
+ * Reset to known state.
*/
static int
-epic_freebsd_attach(dev)
+epic_attach(dev)
device_t dev;
{
struct ifnet *ifp;
@@ -434,7 +222,7 @@ epic_freebsd_attach(dev)
unit = device_get_unit(dev);
/* Preinitialize softc structure */
- bzero(sc, sizeof(epic_softc_t));
+ bzero(sc, sizeof(epic_softc_t));
sc->unit = unit;
sc->dev = dev;
@@ -460,13 +248,13 @@ epic_freebsd_attach(dev)
command = pci_read_config(dev, PCIR_COMMAND, 4);
#if defined(EPIC_USEIOSPACE)
- if (!(command & PCIM_CMD_PORTEN)) {
+ if ((command & PCIM_CMD_PORTEN) == 0) {
device_printf(dev, "failed to enable I/O mapping!\n");
error = ENXIO;
goto fail;
}
#else
- if (!(command & PCIM_CMD_MEMEN)) {
+ if ((command & PCIM_CMD_MEMEN) == 0) {
device_printf(dev, "failed to enable memory mapping!\n");
error = ENXIO;
goto fail;
@@ -514,13 +302,14 @@ epic_freebsd_attach(dev)
bus_teardown_intr(dev, sc->irq, sc->sc_ih);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
bus_release_resource(dev, EPIC_RES, EPIC_RID, sc->res);
+ error = ENXIO;
goto fail;
}
/* Do ifmedia setup */
if (mii_phy_probe(dev, &sc->miibus,
epic_ifmedia_upd, epic_ifmedia_sts)) {
- device_printf(dev, "MII without any PHY!?\n");
+ device_printf(dev, "ERROR! MII without any PHY!?\n");
bus_teardown_intr(dev, sc->irq, sc->sc_ih);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
bus_release_resource(dev, EPIC_RES, EPIC_RID, sc->res);
@@ -534,12 +323,12 @@ epic_freebsd_attach(dev)
/* board type and ... */
printf(" type ");
for(i=0x2c;i<0x32;i++) {
- tmp = epic_read_eeprom( sc, i );
- if( ' ' == (u_int8_t)tmp ) break;
- printf("%c",(u_int8_t)tmp);
+ tmp = epic_read_eeprom(sc, i);
+ if (' ' == (u_int8_t)tmp) break;
+ printf("%c", (u_int8_t)tmp);
tmp >>= 8;
- if( ' ' == (u_int8_t)tmp ) break;
- printf("%c",(u_int8_t)tmp);
+ if (' ' == (u_int8_t)tmp) break;
+ printf("%c", (u_int8_t)tmp);
}
printf("\n");
@@ -558,7 +347,7 @@ fail:
* Detach driver and free resources
*/
static int
-epic_freebsd_detach(dev)
+epic_detach(dev)
device_t dev;
{
struct ifnet *ifp;
@@ -598,7 +387,7 @@ epic_freebsd_detach(dev)
* get confused by errant DMAs when rebooting.
*/
static void
-epic_freebsd_shutdown(dev)
+epic_shutdown(dev)
device_t dev;
{
epic_softc_t *sc;
@@ -609,14 +398,9 @@ epic_freebsd_shutdown(dev)
return;
}
-#endif /* __OpenBSD__ */
-
-/* ------------------------------------------------------------------------
- OS-independing part
- ------------------------------------------------------------------------ */
/*
- * This is if_ioctl handler.
+ * This is if_ioctl handler.
*/
static int
epic_ifioctl(ifp, command, data)
@@ -632,16 +416,15 @@ epic_ifioctl(ifp, command, data)
x = splimp();
switch (command) {
-#if defined(__FreeBSD__)
case SIOCSIFADDR:
case SIOCGIFADDR:
error = ether_ioctl(ifp, command, data);
break;
case SIOCSIFMTU:
- if (ifp->if_mtu == ifr->ifr_mtu)
+ if (ifp->if_mtu == ifr->ifr_mtu)
break;
- /* XXX Though the datasheet doesn't imply any
+ /* XXX Though the datasheet doesn't imply any
* limitations on RX and TX sizes beside max 64Kb
* DMA transfer, seems we can't send more then 1600
* data bytes per ethernet packet. (Transmitter hangs
@@ -654,42 +437,6 @@ epic_ifioctl(ifp, command, data)
} else
error = EINVAL;
break;
-#else /* __OpenBSD__ */
- case SIOCSIFADDR: {
- struct ifaddr *ifa = (struct ifaddr *)data;
-
- ifp->if_flags |= IFF_UP;
- switch(ifa->ifa_addr->sa_family) {
-#if INET
- case AF_INET:
- epic_stop(sc);
- epic_init(sc);
- arp_ifinit(&sc->arpcom,ifa);
- break;
-#endif
-#if NS
- case AF_NS: {
- register struct ns_addr * ina = &IA_SNS(ifa)->sns_addr;
-
- if( ns_nullhost(*ina) )
- ina->x_host =
- *(union ns_host *) LLADDR(ifp->if_sadl);
- else
- bcopy(ina->x_host.c_host, LLADDR(ifp->if_sadl),
- ifp->if_addrlen);
-
- epic_stop(sc);
- epic_init(sc);
- break;
- }
-#endif
- default:
- epic_stop(sc);
- epic_init(sc);
- break;
- }
- }
-#endif /* __FreeBSD__ */
case SIOCSIFFLAGS:
/*
@@ -717,20 +464,8 @@ epic_ifioctl(ifp, command, data)
case SIOCADDMULTI:
case SIOCDELMULTI:
- /* Update out multicast list */
-#if defined(__FreeBSD__) && __FreeBSD_version >= 300000
epic_set_mc_table(sc);
error = 0;
-#else
- error = (command == SIOCADDMULTI) ?
- ether_addmulti((struct ifreq *)data, &sc->arpcom) :
- ether_delmulti((struct ifreq *)data, &sc->arpcom);
-
- if (error == ENETRESET) {
- epic_set_mc_table(sc);
- error = 0;
- }
-#endif
break;
case SIOCSIFMEDIA:
@@ -766,7 +501,7 @@ epic_common_attach(sc)
M_DEVBUF, M_NOWAIT | M_ZERO);
if (sc->tx_flist == NULL || sc->tx_desc == NULL || sc->rx_desc == NULL){
- device_printf(sc->dev, "Failed to malloc memory\n");
+ device_printf(sc->dev, "failed to malloc memory\n");
if (sc->tx_flist) free(sc->tx_flist, M_DEVBUF);
if (sc->tx_desc) free(sc->tx_desc, M_DEVBUF);
if (sc->rx_desc) free(sc->rx_desc, M_DEVBUF);
@@ -774,7 +509,7 @@ epic_common_attach(sc)
}
/* Bring the chip out of low-power mode. */
- CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET);
+ CSR_WRITE_4(sc, GENCTL, GENCTL_SOFT_RESET);
DELAY(500);
/* Workaround for Application Note 7-15 */
@@ -798,8 +533,8 @@ epic_common_attach(sc)
sc->cardvend = pci_read_config(sc->dev, PCIR_SUBVEND_0, 2);
sc->cardid = pci_read_config(sc->dev, PCIR_SUBDEV_0, 2);
- if (sc->cardvend != SMC_VENDORID)
- printf(EPIC_FORMAT ": unknown card vendor 0x%04x\n", EPIC_ARGS(sc), sc->cardvend);
+ if (sc->cardvend != SMC_VENDORID)
+ device_printf(sc->dev, "unknown card vendor %04xh\n", sc->cardvend);
return 0;
}
@@ -821,63 +556,61 @@ epic_ifstart(ifp)
register struct mbuf *m;
register int i;
- while( sc->pending_txs < TX_RING_SIZE ){
+ while (sc->pending_txs < TX_RING_SIZE) {
buf = sc->tx_buffer + sc->cur_tx;
desc = sc->tx_desc + sc->cur_tx;
flist = sc->tx_flist + sc->cur_tx;
/* Get next packet to send */
- IF_DEQUEUE( &ifp->if_snd, m0 );
+ IF_DEQUEUE(&ifp->if_snd, m0);
/* If nothing to send, return */
- if( NULL == m0 ) return;
+ if (NULL == m0) return;
/* Fill fragments list */
- for( m=m0, i=0;
+ for (m = m0, i = 0;
(NULL != m) && (i < EPIC_MAX_FRAGS);
- m = m->m_next, i++ ) {
- flist->frag[i].fraglen = m->m_len;
- flist->frag[i].fragaddr = vtophys( mtod(m, caddr_t) );
+ m = m->m_next, i++) {
+ flist->frag[i].fraglen = m->m_len;
+ flist->frag[i].fragaddr = vtophys(mtod(m, caddr_t));
}
flist->numfrags = i;
/* If packet was more than EPIC_MAX_FRAGS parts, */
/* recopy packet to new allocated mbuf cluster */
- if( NULL != m ){
+ if (NULL != m) {
EPIC_MGETCLUSTER(m);
- if( NULL == m ){
+ if (NULL == m) {
m_freem(m0);
ifp->if_oerrors++;
continue;
}
- m_copydata( m0, 0, m0->m_pkthdr.len, mtod(m,caddr_t) );
- flist->frag[0].fraglen =
+ m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
+ flist->frag[0].fraglen =
m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
m->m_pkthdr.rcvif = ifp;
flist->numfrags = 1;
- flist->frag[0].fragaddr = vtophys( mtod(m, caddr_t) );
+ flist->frag[0].fragaddr = vtophys(mtod(m, caddr_t));
m_freem(m0);
m0 = m;
}
buf->mbuf = m0;
sc->pending_txs++;
- sc->cur_tx = ( sc->cur_tx + 1 ) & TX_RING_MASK;
+ sc->cur_tx = (sc->cur_tx + 1) & TX_RING_MASK;
desc->control = 0x01;
- desc->txlength =
+ desc->txlength =
max(m0->m_pkthdr.len,ETHER_MIN_LEN-ETHER_CRC_LEN);
desc->status = 0x8000;
- CSR_WRITE_4( sc, COMMAND, COMMAND_TXQUEUED );
+ CSR_WRITE_4(sc, COMMAND, COMMAND_TXQUEUED);
/* Set watchdog timer */
ifp->if_timer = 8;
-#if NBPFILTER > 0
- if( ifp->if_bpf )
- bpf_mtap( EPIC_BPFTAP_ARG(ifp), m0 );
-#endif
+ if (ifp->if_bpf)
+ bpf_mtap(ifp, m0);
}
ifp->if_flags |= IFF_OACTIVE;
@@ -899,30 +632,31 @@ epic_rx_done(sc)
struct mbuf *m;
struct ether_header *eh;
- while( !(sc->rx_desc[sc->cur_rx].status & 0x8000) ) {
+ while ((sc->rx_desc[sc->cur_rx].status & 0x8000) == 0) {
buf = sc->rx_buffer + sc->cur_rx;
desc = sc->rx_desc + sc->cur_rx;
/* Switch to next descriptor */
sc->cur_rx = (sc->cur_rx+1) & RX_RING_MASK;
- /* Check for errors, this should happend */
- /* only if SAVE_ERRORED_PACKETS is set, */
- /* normaly rx errors generate RXE interrupt */
- if( !(desc->status & 1) ) {
- dprintf((EPIC_FORMAT ": Rx error status: 0x%x\n",EPIC_ARGS(sc),desc->status));
+ /*
+ * Check for RX errors. This should only happen if
+ * SAVE_ERRORED_PACKETS is set. RX errors generate
+ * RXE interrupt usually.
+ */
+ if ((desc->status & 1) == 0) {
sc->sc_if.if_ierrors++;
desc->status = 0x8000;
continue;
}
- /* Save packet length and mbuf contained packet */
+ /* Save packet length and mbuf contained packet */
len = desc->rxlength - ETHER_CRC_LEN;
m = buf->mbuf;
/* Try to get mbuf cluster */
- EPIC_MGETCLUSTER( buf->mbuf );
- if( NULL == buf->mbuf ) {
+ EPIC_MGETCLUSTER(buf->mbuf);
+ if (NULL == buf->mbuf) {
buf->mbuf = m;
desc->status = 0x8000;
sc->sc_if.if_ierrors++;
@@ -930,38 +664,30 @@ epic_rx_done(sc)
}
/* Point to new mbuf, and give descriptor to chip */
- desc->bufaddr = vtophys( mtod( buf->mbuf, caddr_t ) );
+ desc->bufaddr = vtophys(mtod(buf->mbuf, caddr_t));
desc->status = 0x8000;
/* First mbuf in packet holds the ethernet and packet headers */
- eh = mtod( m, struct ether_header * );
+ eh = mtod(m, struct ether_header *);
m->m_pkthdr.rcvif = &(sc->sc_if);
m->m_pkthdr.len = m->m_len = len;
-#if !defined(__FreeBSD__)
-#if NBPFILTER > 0
- /* Give mbuf to BPFILTER */
- if( sc->sc_if.if_bpf )
- bpf_mtap( EPIC_BPFTAP_ARG(&sc->sc_if), m );
-#endif /* NBPFILTER > 0 */
-#endif /* !__FreeBSD__ */
-
/* Second mbuf holds packet ifself */
m->m_pkthdr.len = m->m_len = len - sizeof(struct ether_header);
- m->m_data += sizeof( struct ether_header );
+ m->m_data += sizeof(struct ether_header);
/* Give mbuf to OS */
ether_input(&sc->sc_if, eh, m);
/* Successfuly received frame */
sc->sc_if.if_ipackets++;
- }
+ }
return;
}
/*
- * Synopsis: Do last phase of transmission. I.e. if desc is
+ * Synopsis: Do last phase of transmission. I.e. if desc is
* transmitted, decrease pending_txs counter, free mbuf contained
* packet, switch to next descriptor and repeat until no packets
* are pending or descriptor is not transmitted yet.
@@ -974,88 +700,80 @@ epic_tx_done(sc)
struct epic_tx_desc *desc;
u_int16_t status;
- while( sc->pending_txs > 0 ){
+ while (sc->pending_txs > 0) {
buf = sc->tx_buffer + sc->dirty_tx;
desc = sc->tx_desc + sc->dirty_tx;
status = desc->status;
/* If packet is not transmitted, thou followed */
/* packets are not transmitted too */
- if( status & 0x8000 ) break;
+ if (status & 0x8000) break;
/* Packet is transmitted. Switch to next and */
/* free mbuf */
sc->pending_txs--;
sc->dirty_tx = (sc->dirty_tx + 1) & TX_RING_MASK;
- m_freem( buf->mbuf );
+ m_freem(buf->mbuf);
buf->mbuf = NULL;
/* Check for errors and collisions */
- if( status & 0x0001 ) sc->sc_if.if_opackets++;
+ if (status & 0x0001) sc->sc_if.if_opackets++;
else sc->sc_if.if_oerrors++;
sc->sc_if.if_collisions += (status >> 8) & 0x1F;
-#if defined(EPIC_DEBUG)
- if( (status & 0x1001) == 0x1001 )
- dprintf((EPIC_FORMAT ": frame not transmitted due collisions\n",EPIC_ARGS(sc)));
+#if defined(EPIC_DIAG)
+ if ((status & 0x1001) == 0x1001)
+ device_printf(sc->dev, "Tx ERROR: excessive coll. number\n");
#endif
}
- if( sc->pending_txs < TX_RING_SIZE )
+ if (sc->pending_txs < TX_RING_SIZE)
sc->sc_if.if_flags &= ~IFF_OACTIVE;
}
/*
* Interrupt function
*/
-static EPIC_INTR_RET_TYPE
+static void
epic_intr(arg)
void *arg;
{
epic_softc_t * sc = (epic_softc_t *) arg;
- int status,i=4;
-#if defined(__OpenBSD__)
- int claimed = 0;
+ int status, i = 4;
+
+ while (i-- && ((status = CSR_READ_4(sc, INTSTAT)) & INTSTAT_INT_ACTV)) {
+ CSR_WRITE_4(sc, INTSTAT, status);
+
+ if (status & (INTSTAT_RQE|INTSTAT_RCC|INTSTAT_OVW)) {
+ epic_rx_done(sc);
+ if (status & (INTSTAT_RQE|INTSTAT_OVW)) {
+#if defined(EPIC_DIAG)
+ if (status & INTSTAT_OVW)
+ device_printf(sc->dev, "RX buffer overflow\n");
+ if (status & INTSTAT_RQE)
+ device_printf(sc->dev, "RX FIFO overflow\n");
#endif
+ if ((CSR_READ_4(sc, COMMAND) & COMMAND_RXQUEUED) == 0)
+ CSR_WRITE_4(sc, COMMAND, COMMAND_RXQUEUED);
+ sc->sc_if.if_ierrors++;
+ }
+ }
- while( i-- && ((status = CSR_READ_4(sc, INTSTAT)) & INTSTAT_INT_ACTV) ){
-#if defined(__OpenBSD__)
- claimed = 1;
-#endif
- CSR_WRITE_4( sc, INTSTAT, status );
-
- if( status & (INTSTAT_RQE|INTSTAT_RCC|INTSTAT_OVW) ) {
- epic_rx_done( sc );
- if( status & (INTSTAT_RQE|INTSTAT_OVW) ){
-#if defined(EPIC_DEBUG)
- if( status & INTSTAT_OVW )
- printf(EPIC_FORMAT ": RX buffer overflow\n",EPIC_ARGS(sc));
- if( status & INTSTAT_RQE )
- printf(EPIC_FORMAT ": RX FIFO overflow\n",EPIC_ARGS(sc));
-#endif
- if( !(CSR_READ_4( sc, COMMAND ) & COMMAND_RXQUEUED) )
- CSR_WRITE_4( sc, COMMAND, COMMAND_RXQUEUED );
- sc->sc_if.if_ierrors++;
- }
- }
-
- if( status & (INTSTAT_TXC|INTSTAT_TCC|INTSTAT_TQE) ) {
- epic_tx_done( sc );
- if(!(sc->sc_if.if_flags & IFF_OACTIVE) &&
- sc->sc_if.if_snd.ifq_head )
- epic_ifstart( &sc->sc_if );
+ if (status & (INTSTAT_TXC|INTSTAT_TCC|INTSTAT_TQE)) {
+ epic_tx_done(sc);
+ if (sc->sc_if.if_snd.ifq_head != NULL)
+ epic_ifstart(&sc->sc_if);
}
- /* Check for errors */
- if( status & (INTSTAT_FATAL|INTSTAT_PMA|INTSTAT_PTA|
- INTSTAT_APE|INTSTAT_DPE|INTSTAT_TXU|INTSTAT_RXE) ){
- if( status & (INTSTAT_FATAL|INTSTAT_PMA|INTSTAT_PTA|
- INTSTAT_APE|INTSTAT_DPE) ){
- printf(EPIC_FORMAT ": PCI fatal error occured (%s%s%s%s)\n",
- EPIC_ARGS(sc),
- (status&INTSTAT_PMA)?"PMA":"",
- (status&INTSTAT_PTA)?" PTA":"",
- (status&INTSTAT_APE)?" APE":"",
- (status&INTSTAT_DPE)?" DPE":""
+ /* Check for rare errors */
+ if (status & (INTSTAT_FATAL|INTSTAT_PMA|INTSTAT_PTA|
+ INTSTAT_APE|INTSTAT_DPE|INTSTAT_TXU|INTSTAT_RXE)) {
+ if (status & (INTSTAT_FATAL|INTSTAT_PMA|INTSTAT_PTA|
+ INTSTAT_APE|INTSTAT_DPE)) {
+ device_printf(sc->dev, "PCI fatal errors occured: %s%s%s%s\n",
+ (status&INTSTAT_PMA)?"PMA ":"",
+ (status&INTSTAT_PTA)?"PTA ":"",
+ (status&INTSTAT_APE)?"APE ":"",
+ (status&INTSTAT_DPE)?"DPE":""
);
epic_stop(sc);
@@ -1065,41 +783,60 @@ epic_intr(arg)
}
if (status & INTSTAT_RXE) {
- dprintf((EPIC_FORMAT ": CRC/Alignment error\n",EPIC_ARGS(sc)));
+#if defined(EPIC_DIAG)
+ device_printf(sc->dev, "CRC/Alignment error\n");
+#endif
sc->sc_if.if_ierrors++;
}
- /* Tx FIFO underflow. Increase tx threshold, */
- /* if it grown above 2048, disable EARLY_TX */
if (status & INTSTAT_TXU) {
- if( sc->tx_threshold > 0x800 ) {
- sc->txcon &= ~TXCON_EARLY_TRANSMIT_ENABLE;
- dprintf((EPIC_FORMAT ": TX underrun error, early tx disabled\n",EPIC_ARGS(sc)));
- } else {
- sc->tx_threshold += 0x40;
- dprintf((EPIC_FORMAT ": TX underrun error, tx threshold increased to %d\n",EPIC_ARGS(sc),sc->tx_threshold));
- }
-
- CSR_WRITE_4(sc, COMMAND, COMMAND_TXUGO | COMMAND_TXQUEUED);
- epic_stop_activity(sc);
- epic_set_tx_mode(sc);
- epic_start_activity(sc);
+ epic_tx_underrun(sc);
sc->sc_if.if_oerrors++;
}
}
}
- /* If no packets are pending, thus no timeouts */
- if( sc->pending_txs == 0 ) sc->sc_if.if_timer = 0;
+ /* If no packets are pending, then no timeouts */
+ if (sc->pending_txs == 0) sc->sc_if.if_timer = 0;
+
+ return;
+}
-#if defined(__OpenBSD__)
- return claimed;
+/*
+ * Handle the TX underrun error: increase the TX threshold
+ * and restart the transmitter.
+ */
+static void
+epic_tx_underrun(sc)
+ epic_softc_t *sc;
+{
+ if (sc->tx_threshold > TRANSMIT_THRESHOLD_MAX) {
+ sc->txcon &= ~TXCON_EARLY_TRANSMIT_ENABLE;
+#if defined(EPIC_DIAG)
+ device_printf(sc->dev, "Tx UNDERRUN: early TX disabled\n");
+#endif
+ } else {
+ sc->tx_threshold += 0x40;
+#if defined(EPIC_DIAG)
+ device_printf(sc->dev, "Tx UNDERRUN: TX threshold increased to %d\n",
+ sc->tx_threshold);
#endif
+ }
+
+ /* We must set TXUGO to reset the stuck transmitter */
+ CSR_WRITE_4(sc, COMMAND, COMMAND_TXUGO);
+
+ /* Update the TX threshold */
+ epic_stop_activity(sc);
+ epic_set_tx_mode(sc);
+ epic_start_activity(sc);
+
+ return;
}
/*
* Synopsis: This one is called if packets wasn't transmitted
- * during timeout. Try to deallocate transmitted packets, and
+ * during timeout. Try to deallocate transmitted packets, and
* if success continue to work.
*/
static void
@@ -1111,27 +848,26 @@ epic_ifwatchdog(ifp)
x = splimp();
- printf(EPIC_FORMAT ": device timeout %d packets, ",
- EPIC_ARGS(sc),sc->pending_txs);
+ device_printf(sc->dev, "device timeout %d packets\n", sc->pending_txs);
/* Try to finish queued packets */
- epic_tx_done( sc );
+ epic_tx_done(sc);
/* If not successful */
- if( sc->pending_txs > 0 ){
+ if (sc->pending_txs > 0) {
ifp->if_oerrors+=sc->pending_txs;
/* Reinitialize board */
- printf("reinitialization\n");
+ device_printf(sc->dev, "reinitialization\n");
epic_stop(sc);
epic_init(sc);
- } else
- printf("seems we can continue normaly\n");
+ } else
+ device_printf(sc->dev, "seems we can continue normaly\n");
/* Start output */
- if( ifp->if_snd.ifq_head ) epic_ifstart( ifp );
+ if (ifp->if_snd.ifq_head) epic_ifstart(ifp);
splx(x);
}
@@ -1175,7 +911,7 @@ epic_ifmedia_upd(ifp)
media = ifm->ifm_cur->ifm_media;
/* Do not do anything if interface is not up */
- if(!(ifp->if_flags & IFF_UP))
+ if ((ifp->if_flags & IFF_UP) == 0)
return (0);
/*
@@ -1189,8 +925,6 @@ epic_ifmedia_upd(ifp)
sc->miicfg &= ~MIICFG_SERIAL_ENABLE;
CSR_WRITE_4(sc, MIICFG, sc->miicfg);
- dprintf((EPIC_FORMAT ": MII selected\n", EPIC_ARGS(sc)));
-
/* Default to unknown PHY */
sc->phyid = EPIC_UNKN_PHY;
@@ -1275,11 +1009,9 @@ epic_ifmedia_upd(ifp)
*/
epic_miibus_statchg(sc->dev);
- dprintf((EPIC_FORMAT ": SERIAL selected\n", EPIC_ARGS(sc)));
-
break;
default:
- printf(EPIC_FORMAT ": ERROR! Unknown PHY selected\n", EPIC_ARGS(sc));
+ device_printf(sc->dev, "ERROR! Unknown PHY selected\n");
return (EINVAL);
}
@@ -1303,7 +1035,7 @@ epic_ifmedia_sts(ifp, ifmr)
ifm = &mii->mii_media;
/* Nothing should be selected if interface is down */
- if(!(ifp->if_flags & IFF_UP)) {
+ if ((ifp->if_flags & IFF_UP) == 0) {
ifmr->ifm_active = IFM_NONE;
ifmr->ifm_status = 0;
@@ -1347,7 +1079,7 @@ epic_miibus_statchg(dev)
/* On some cards we need manualy set fullduplex led */
if (sc->cardid == SMC9432FTX ||
sc->cardid == SMC9432FTX_SC) {
- if (IFM_OPTIONS(media) & IFM_FDX)
+ if (IFM_OPTIONS(media) & IFM_FDX)
sc->miicfg |= MIICFG_694_ENABLE;
else
sc->miicfg &= ~MIICFG_694_ENABLE;
@@ -1373,8 +1105,8 @@ static void
epic_miibus_mediainit(dev)
device_t dev;
{
- epic_softc_t *sc;
- struct mii_data *mii;
+ epic_softc_t *sc;
+ struct mii_data *mii;
struct ifmedia *ifm;
int media;
@@ -1385,7 +1117,7 @@ epic_miibus_mediainit(dev)
/* Add Serial Media Interface if present, this applies to
* SMC9432BTX serie
*/
- if(CSR_READ_4(sc, MIICFG) & MIICFG_PHY_PRESENT) {
+ if (CSR_READ_4(sc, MIICFG) & MIICFG_PHY_PRESENT) {
/* Store its instance */
sc->serinst = mii->mii_instance++;
@@ -1394,34 +1126,33 @@ epic_miibus_mediainit(dev)
ifmedia_add(ifm, media, 0, NULL);
/* Report to user */
- printf(EPIC_FORMAT ": serial PHY detected (10Base2/BNC)\n",EPIC_ARGS(sc));
+ device_printf(sc->dev, "serial PHY detected (10Base2/BNC)\n");
}
return;
}
-
/*
* Reset chip, allocate rings, and update media.
*/
static int
epic_init(sc)
epic_softc_t *sc;
-{
+{
struct ifnet *ifp = &sc->sc_if;
int s,i;
-
+
s = splimp();
- /* If interface is already running, then we need not do anything */
+ /* If interface is already running, then we need not do anything */
if (ifp->if_flags & IFF_RUNNING) {
splx(s);
return 0;
}
/* Soft reset the chip (we have to power up card before) */
- CSR_WRITE_4( sc, GENCTL, 0 );
- CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET );
+ CSR_WRITE_4(sc, GENCTL, 0);
+ CSR_WRITE_4(sc, GENCTL, GENCTL_SOFT_RESET);
/*
* Reset takes 15 pci ticks which depends on PCI bus speed.
@@ -1430,38 +1161,38 @@ epic_init(sc)
DELAY(500);
/* Wake up */
- CSR_WRITE_4( sc, GENCTL, 0 );
+ CSR_WRITE_4(sc, GENCTL, 0);
/* Workaround for Application Note 7-15 */
for (i=0; i<16; i++) CSR_WRITE_4(sc, TEST1, TEST1_CLOCK_TEST);
/* Initialize rings */
- if( epic_init_rings( sc ) ) {
- printf(EPIC_FORMAT ": failed to init rings\n",EPIC_ARGS(sc));
+ if (epic_init_rings(sc)) {
+ device_printf(sc->dev, "failed to init rings\n");
splx(s);
return -1;
}
/* Give rings to EPIC */
- CSR_WRITE_4( sc, PRCDAR, vtophys( sc->rx_desc ) );
- CSR_WRITE_4( sc, PTCDAR, vtophys( sc->tx_desc ) );
+ CSR_WRITE_4(sc, PRCDAR, vtophys(sc->rx_desc));
+ CSR_WRITE_4(sc, PTCDAR, vtophys(sc->tx_desc));
/* Put node address to EPIC */
- CSR_WRITE_4( sc, LAN0, ((u_int16_t *)sc->sc_macaddr)[0] );
- CSR_WRITE_4( sc, LAN1, ((u_int16_t *)sc->sc_macaddr)[1] );
- CSR_WRITE_4( sc, LAN2, ((u_int16_t *)sc->sc_macaddr)[2] );
+ CSR_WRITE_4(sc, LAN0, ((u_int16_t *)sc->sc_macaddr)[0]);
+ CSR_WRITE_4(sc, LAN1, ((u_int16_t *)sc->sc_macaddr)[1]);
+ CSR_WRITE_4(sc, LAN2, ((u_int16_t *)sc->sc_macaddr)[2]);
/* Set tx mode, includeing transmit threshold */
epic_set_tx_mode(sc);
/* Compute and set RXCON. */
- epic_set_rx_mode( sc );
+ epic_set_rx_mode(sc);
/* Set multicast table */
- epic_set_mc_table( sc );
+ epic_set_mc_table(sc);
/* Enable interrupts by setting the interrupt mask. */
- CSR_WRITE_4( sc, INTMASK,
+ CSR_WRITE_4(sc, INTMASK,
INTSTAT_RCC | /* INTSTAT_RQE | INTSTAT_OVW | INTSTAT_RXE | */
/* INTSTAT_TXC | */ INTSTAT_TCC | INTSTAT_TQE | INTSTAT_TXU |
INTSTAT_FATAL);
@@ -1470,12 +1201,12 @@ epic_init(sc)
CSR_WRITE_4(sc, INTSTAT, CSR_READ_4(sc, INTSTAT));
/* Enable interrupts, set for PCI read multiple and etc */
- CSR_WRITE_4( sc, GENCTL,
+ CSR_WRITE_4(sc, GENCTL,
GENCTL_ENABLE_INTERRUPT | GENCTL_MEMORY_READ_MULTIPLE |
- GENCTL_ONECOPY | GENCTL_RECEIVE_FIFO_THRESHOLD64 );
+ GENCTL_ONECOPY | GENCTL_RECEIVE_FIFO_THRESHOLD64);
/* Mark interface running ... */
- if( ifp->if_flags & IFF_UP ) ifp->if_flags |= IFF_RUNNING;
+ if (ifp->if_flags & IFF_UP) ifp->if_flags |= IFF_RUNNING;
else ifp->if_flags &= ~IFF_RUNNING;
/* ... and free */
@@ -1503,7 +1234,7 @@ epic_set_rx_mode(sc)
epic_softc_t *sc;
{
u_int32_t flags = sc->sc_if.if_flags;
- u_int32_t rxcon = RXCON_DEFAULT;
+ u_int32_t rxcon = RXCON_DEFAULT;
#if defined(EPIC_EARLY_RX)
rxcon |= RXCON_EARLY_RX;
@@ -1511,7 +1242,7 @@ epic_set_rx_mode(sc)
rxcon |= (flags & IFF_PROMISC) ? RXCON_PROMISCUOUS_MODE : 0;
- CSR_WRITE_4( sc, RXCON, rxcon );
+ CSR_WRITE_4(sc, RXCON, rxcon);
return;
}
@@ -1525,9 +1256,9 @@ epic_set_tx_mode(sc)
epic_softc_t *sc;
{
if (sc->txcon & TXCON_EARLY_TRANSMIT_ENABLE)
- CSR_WRITE_4 (sc, ETXTHR, sc->tx_threshold);
+ CSR_WRITE_4(sc, ETXTHR, sc->tx_threshold);
- CSR_WRITE_4 (sc, TXCON, sc->txcon);
+ CSR_WRITE_4(sc, TXCON, sc->txcon);
}
/*
@@ -1560,7 +1291,11 @@ epic_set_mc_table(sc)
filter[2] = 0;
filter[3] = 0;
+#if __FreeBSD_version < 500000
+ LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+#else
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+#endif
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
h = epic_calchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
@@ -1604,7 +1339,7 @@ epic_calchash(addr)
}
-/*
+/*
* Synopsis: Start receive process and transmit one, if they need.
*/
static void
@@ -1615,7 +1350,6 @@ epic_start_activity(sc)
CSR_WRITE_4(sc, COMMAND,
COMMAND_RXQUEUED | COMMAND_START_RX |
(sc->pending_txs?COMMAND_TXQUEUED:0));
- dprintf((EPIC_FORMAT ": activity started\n",EPIC_ARGS(sc)));
}
/*
@@ -1624,66 +1358,83 @@ epic_start_activity(sc)
*/
static void
epic_stop_activity(sc)
- epic_softc_t *sc;
+ epic_softc_t *sc;
{
- int i;
-
- /* Stop Tx and Rx DMA */
- CSR_WRITE_4(sc,COMMAND,COMMAND_STOP_RX|COMMAND_STOP_RDMA|COMMAND_STOP_TDMA);
-
- /* Wait Rx and Tx DMA to stop (why 1 ms ??? XXX) */
- dprintf((EPIC_FORMAT ": waiting Rx and Tx DMA to stop\n",EPIC_ARGS(sc)));
- for(i=0;i<0x1000;i++) {
- if((CSR_READ_4(sc,INTSTAT) & (INTSTAT_TXIDLE | INTSTAT_RXIDLE)) ==
- (INTSTAT_TXIDLE | INTSTAT_RXIDLE) )
- break;
- DELAY(1);
- }
+ int status, i;
+
+ /* Stop Tx and Rx DMA */
+ CSR_WRITE_4(sc, COMMAND,
+ COMMAND_STOP_RX | COMMAND_STOP_RDMA | COMMAND_STOP_TDMA);
+
+ /* Wait Rx and Tx DMA to stop (why 1 ms ??? XXX) */
+ for (i=0; i<0x1000; i++) {
+ status = CSR_READ_4(sc, INTSTAT) & (INTSTAT_TXIDLE | INTSTAT_RXIDLE);
+ if (status == (INTSTAT_TXIDLE | INTSTAT_RXIDLE))
+ break;
+ DELAY(1);
+ }
- if( !(CSR_READ_4(sc,INTSTAT)&INTSTAT_RXIDLE) )
- printf(EPIC_FORMAT ": can't stop Rx DMA\n",EPIC_ARGS(sc));
+ /* Catch all finished packets */
+ epic_rx_done(sc);
+ epic_tx_done(sc);
- if( !(CSR_READ_4(sc,INTSTAT)&INTSTAT_TXIDLE) )
- printf(EPIC_FORMAT ": can't stop Tx DMA\n",EPIC_ARGS(sc));
+ status = CSR_READ_4(sc, INTSTAT);
- /* Catch all finished packets */
- epic_rx_done(sc);
- epic_tx_done(sc);
+ if ((status & INTSTAT_RXIDLE) == 0)
+ device_printf(sc->dev, "ERROR! Can't stop Rx DMA\n");
- /*
- * May need to queue one more packet if TQE, this is rare but existing
- * case.
- */
- if( (CSR_READ_4( sc, INTSTAT ) & INTSTAT_TQE) &&
- !(CSR_READ_4( sc, INTSTAT ) & INTSTAT_TXIDLE) ) {
+ if ((status & INTSTAT_TXIDLE) == 0)
+ device_printf(sc->dev, "ERROR! Can't stop Tx DMA\n");
+
+ /*
+ * May need to queue one more packet if TQE, this is rare
+ * but existing case.
+ */
+ if ((status & INTSTAT_TQE) && !(status & INTSTAT_TXIDLE))
+ (void) epic_queue_last_packet(sc);
+
+}
+
+/*
+ * The EPIC transmitter may stuck in TQE state. It will not go IDLE until
+ * a packet from current descriptor will be copied to internal RAM. We
+ * compose a dummy packet here and queue it for transmission.
+ *
+ * XXX the packet will then be actually sent over network...
+ */
+static int
+epic_queue_last_packet(sc)
+ epic_softc_t *sc;
+{
struct epic_tx_desc *desc;
struct epic_frag_list *flist;
struct epic_tx_buffer *buf;
struct mbuf *m0;
+ int i;
- dprintf((EPIC_FORMAT ": queue last packet\n",EPIC_ARGS(sc)));
+ device_printf(sc->dev, "queue last packet\n");
desc = sc->tx_desc + sc->cur_tx;
flist = sc->tx_flist + sc->cur_tx;
buf = sc->tx_buffer + sc->cur_tx;
if ((desc->status & 0x8000) || (buf->mbuf != NULL))
- return;
+ return (EBUSY);
- MGETHDR(m0,M_DONTWAIT,MT_DATA);
+ MGETHDR(m0, M_DONTWAIT, MT_DATA);
if (NULL == m0)
- return;
+ return (ENOBUFS);
/* Prepare mbuf */
- m0->m_len = min(MHLEN,ETHER_MIN_LEN-ETHER_CRC_LEN);
+ m0->m_len = min(MHLEN, ETHER_MIN_LEN-ETHER_CRC_LEN);
flist->frag[0].fraglen = m0->m_len;
m0->m_pkthdr.len = m0->m_len;
m0->m_pkthdr.rcvif = &sc->sc_if;
- bzero(mtod(m0,caddr_t),m0->m_len);
+ bzero(mtod(m0,caddr_t), m0->m_len);
/* Fill fragments list */
- flist->frag[0].fraglen = m0->m_len;
- flist->frag[0].fragaddr = vtophys( mtod(m0, caddr_t) );
+ flist->frag[0].fraglen = m0->m_len;
+ flist->frag[0].fragaddr = vtophys(mtod(m0, caddr_t));
flist->numfrags = 1;
/* Fill in descriptor */
@@ -1698,20 +1449,18 @@ epic_stop_activity(sc)
CSR_WRITE_4(sc, COMMAND, COMMAND_STOP_TDMA | COMMAND_TXQUEUED);
/* Wait Tx DMA to stop (for how long??? XXX) */
- dprintf((EPIC_FORMAT ": waiting Tx DMA to stop\n",EPIC_ARGS(sc)));
- for(i=0;i<1000;i++) {
- if( (CSR_READ_4(sc,INTSTAT)&INTSTAT_TXIDLE) == INTSTAT_TXIDLE )
- break;
- DELAY(1);
+ for (i=0; i<1000; i++) {
+ if (CSR_READ_4(sc, INTSTAT) & INTSTAT_TXIDLE)
+ break;
+ DELAY(1);
}
- if( !(CSR_READ_4(sc,INTSTAT)&INTSTAT_TXIDLE) )
- printf(EPIC_FORMAT ": can't stop TX DMA\n",EPIC_ARGS(sc));
+ if ((CSR_READ_4(sc, INTSTAT) & INTSTAT_TXIDLE) == 0)
+ device_printf(sc->dev, "ERROR! can't stop Tx DMA (2)\n");
else
- epic_tx_done(sc);
- }
+ epic_tx_done(sc);
- dprintf((EPIC_FORMAT ": activity stoped\n",EPIC_ARGS(sc)));
+ return 0;
}
/*
@@ -1730,14 +1479,14 @@ epic_stop(sc)
untimeout((timeout_t *)epic_stats_update, sc, sc->stat_ch);
/* Disable interrupts */
- CSR_WRITE_4( sc, INTMASK, 0 );
- CSR_WRITE_4( sc, GENCTL, 0 );
+ CSR_WRITE_4(sc, INTMASK, 0);
+ CSR_WRITE_4(sc, GENCTL, 0);
/* Try to stop Rx and TX processes */
epic_stop_activity(sc);
/* Reset chip */
- CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET );
+ CSR_WRITE_4(sc, GENCTL, GENCTL_SOFT_RESET);
DELAY(1000);
/* Make chip go to bed */
@@ -1755,14 +1504,14 @@ epic_stop(sc)
/*
* Synopsis: This function should free all memory allocated for rings.
- */
+ */
static void
epic_free_rings(sc)
epic_softc_t *sc;
{
int i;
- for(i=0;i<RX_RING_SIZE;i++){
+ for (i=0; i<RX_RING_SIZE; i++) {
struct epic_rx_buffer *buf = sc->rx_buffer + i;
struct epic_rx_desc *desc = sc->rx_desc + i;
@@ -1770,11 +1519,11 @@ epic_free_rings(sc)
desc->buflength = 0;
desc->bufaddr = 0;
- if( buf->mbuf ) m_freem( buf->mbuf );
+ if (buf->mbuf) m_freem(buf->mbuf);
buf->mbuf = NULL;
}
- for(i=0;i<TX_RING_SIZE;i++){
+ for (i=0; i<TX_RING_SIZE; i++) {
struct epic_tx_buffer *buf = sc->tx_buffer + i;
struct epic_tx_desc *desc = sc->tx_desc + i;
@@ -1782,7 +1531,7 @@ epic_free_rings(sc)
desc->buflength = 0;
desc->bufaddr = 0;
- if( buf->mbuf ) m_freem( buf->mbuf );
+ if (buf->mbuf) m_freem(buf->mbuf);
buf->mbuf = NULL;
}
}
@@ -1805,17 +1554,20 @@ epic_init_rings(sc)
struct epic_rx_desc *desc = sc->rx_desc + i;
desc->status = 0; /* Owned by driver */
- desc->next = vtophys( sc->rx_desc + ((i+1) & RX_RING_MASK) );
+ desc->next = vtophys(sc->rx_desc + ((i+1) & RX_RING_MASK));
- if( (desc->next & 3) || ((desc->next & 0xFFF) + sizeof(struct epic_rx_desc) > 0x1000 ) )
- printf(EPIC_FORMAT ": WARNING! rx_desc is misbound or misaligned\n",EPIC_ARGS(sc));
+ if ((desc->next & 3) ||
+ ((desc->next & PAGE_MASK) + sizeof *desc) > PAGE_SIZE) {
+ epic_free_rings(sc);
+ return EFAULT;
+ }
- EPIC_MGETCLUSTER( buf->mbuf );
- if( NULL == buf->mbuf ) {
+ EPIC_MGETCLUSTER(buf->mbuf);
+ if (NULL == buf->mbuf) {
epic_free_rings(sc);
- return -1;
+ return ENOBUFS;
}
- desc->bufaddr = vtophys( mtod(buf->mbuf,caddr_t) );
+ desc->bufaddr = vtophys(mtod(buf->mbuf, caddr_t));
desc->buflength = MCLBYTES; /* Max RX buffer length */
desc->status = 0x8000; /* Set owner bit to NIC */
@@ -1826,15 +1578,22 @@ epic_init_rings(sc)
struct epic_tx_desc *desc = sc->tx_desc + i;
desc->status = 0;
- desc->next = vtophys( sc->tx_desc + ( (i+1) & TX_RING_MASK ) );
+ desc->next = vtophys(sc->tx_desc + ((i+1) & TX_RING_MASK));
- if( (desc->next & 3) || ((desc->next & 0xFFF) + sizeof(struct epic_tx_desc) > 0x1000 ) )
- printf(EPIC_FORMAT ": WARNING! tx_desc is misbound or misaligned\n",EPIC_ARGS(sc));
+ if ((desc->next & 3) ||
+ ((desc->next & PAGE_MASK) + sizeof *desc) > PAGE_SIZE) {
+ epic_free_rings(sc);
+ return EFAULT;
+ }
buf->mbuf = NULL;
- desc->bufaddr = vtophys( sc->tx_flist + i );
- if( (desc->bufaddr & 3) || ((desc->bufaddr & 0xFFF) + sizeof(struct epic_frag_list) > 0x1000 ) )
- printf(EPIC_FORMAT ": WARNING! frag_list is misbound or misaligned\n",EPIC_ARGS(sc));
+ desc->bufaddr = vtophys(sc->tx_flist + i);
+
+ if ((desc->bufaddr & 3) ||
+ ((desc->bufaddr & PAGE_MASK) + sizeof(struct epic_frag_list)) > PAGE_SIZE) {
+ epic_free_rings(sc);
+ return EFAULT;
+ }
}
return 0;
@@ -1850,10 +1609,10 @@ epic_write_eepromreg(sc, val)
{
u_int16_t i;
- CSR_WRITE_1( sc, EECTL, val );
+ CSR_WRITE_1(sc, EECTL, val);
for (i=0; i<0xFF; i++)
- if( !(CSR_READ_1( sc, EECTL ) & 0x20) ) break;
+ if ((CSR_READ_1(sc, EECTL) & 0x20) == 0) break;
return;
}
@@ -1863,18 +1622,18 @@ epic_read_eepromreg(sc)
epic_softc_t *sc;
{
return CSR_READ_1(sc, EECTL);
-}
+}
static u_int8_t
epic_eeprom_clock(sc, val)
epic_softc_t *sc;
u_int8_t val;
{
- epic_write_eepromreg( sc, val );
- epic_write_eepromreg( sc, (val | 0x4) );
- epic_write_eepromreg( sc, val );
+ epic_write_eepromreg(sc, val);
+ epic_write_eepromreg(sc, (val | 0x4));
+ epic_write_eepromreg(sc, val);
- return epic_read_eepromreg( sc );
+ return epic_read_eepromreg(sc);
}
static void
@@ -1882,10 +1641,13 @@ epic_output_eepromw(sc, val)
epic_softc_t *sc;
u_int16_t val;
{
- int i;
- for( i = 0xF; i >= 0; i--){
- if( (val & (1 << i)) ) epic_eeprom_clock( sc, 0x0B );
- else epic_eeprom_clock( sc, 3);
+ int i;
+
+ for (i = 0xF; i >= 0; i--) {
+ if (val & (1 << i))
+ epic_eeprom_clock(sc, 0x0B);
+ else
+ epic_eeprom_clock(sc, 0x03);
}
}
@@ -1893,16 +1655,14 @@ static u_int16_t
epic_input_eepromw(sc)
epic_softc_t *sc;
{
- int i;
- int tmp;
u_int16_t retval = 0;
+ int i;
- for( i = 0xF; i >= 0; i--) {
- tmp = epic_eeprom_clock( sc, 0x3 );
- if( tmp & 0x10 ){
+ for (i = 0xF; i >= 0; i--) {
+ if (epic_eeprom_clock(sc, 0x3) & 0x10)
retval |= (1 << i);
- }
}
+
return retval;
}
@@ -1914,18 +1674,18 @@ epic_read_eeprom(sc, loc)
u_int16_t dataval;
u_int16_t read_cmd;
- epic_write_eepromreg( sc , 3);
+ epic_write_eepromreg(sc, 3);
- if( epic_read_eepromreg( sc ) & 0x40 )
- read_cmd = ( loc & 0x3F ) | 0x180;
+ if (epic_read_eepromreg(sc) & 0x40)
+ read_cmd = (loc & 0x3F) | 0x180;
else
- read_cmd = ( loc & 0xFF ) | 0x600;
+ read_cmd = (loc & 0xFF) | 0x600;
- epic_output_eepromw( sc, read_cmd );
+ epic_output_eepromw(sc, read_cmd);
- dataval = epic_input_eepromw( sc );
+ dataval = epic_input_eepromw(sc);
- epic_write_eepromreg( sc, 1 );
+ epic_write_eepromreg(sc, 1);
return dataval;
}
@@ -1940,14 +1700,14 @@ epic_read_phy_reg(sc, phy, reg)
{
int i;
- CSR_WRITE_4 (sc, MIICTL, ((reg << 4) | (phy << 9) | 0x01));
+ CSR_WRITE_4(sc, MIICTL, ((reg << 4) | (phy << 9) | 0x01));
- for (i=0;i<0x100;i++) {
- if( !(CSR_READ_4(sc, MIICTL) & 0x01) ) break;
+ for (i = 0; i < 0x100; i++) {
+ if ((CSR_READ_4(sc, MIICTL) & 0x01) == 0) break;
DELAY(1);
}
- return (CSR_READ_4 (sc, MIIDATA));
+ return (CSR_READ_4(sc, MIIDATA));
}
static void
@@ -1957,11 +1717,11 @@ epic_write_phy_reg(sc, phy, reg, val)
{
int i;
- CSR_WRITE_4 (sc, MIIDATA, val);
- CSR_WRITE_4 (sc, MIICTL, ((reg << 4) | (phy << 9) | 0x02));
+ CSR_WRITE_4(sc, MIIDATA, val);
+ CSR_WRITE_4(sc, MIICTL, ((reg << 4) | (phy << 9) | 0x02));
for(i=0;i<0x100;i++) {
- if( !(CSR_READ_4(sc, MIICTL) & 0x02) ) break;
+ if ((CSR_READ_4(sc, MIICTL) & 0x02) == 0) break;
DELAY(1);
}
diff --git a/sys/dev/tx/if_txreg.h b/sys/dev/tx/if_txreg.h
index 0c883c9..2028850 100644
--- a/sys/dev/tx/if_txreg.h
+++ b/sys/dev/tx/if_txreg.h
@@ -1,6 +1,3 @@
-/* $OpenBSD: if_txvar.h,v 1.7 1999/11/17 05:21:19 jason Exp $ */
-/* $FreeBSD$ */
-
/*-
* Copyright (c) 1997 Semen Ustimenko
* All rights reserved.
@@ -25,18 +22,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $FreeBSD$
*/
#define EPIC_MAX_MTU 1600 /* This is experiment-derived value */
/* PCI aux configuration registers */
-#if defined(__FreeBSD__)
#define PCIR_BASEIO (PCIR_MAPS + 0x0) /* Base IO Address */
#define PCIR_BASEMEM (PCIR_MAPS + 0x4) /* Base Memory Address */
-#else /* __OpenBSD__ */
-#define PCI_BASEIO (PCI_MAPS + 0x0) /* Base IO Address */
-#define PCI_BASEMEM (PCI_MAPS + 0x4) /* Base Memory Address */
-#endif /* __FreeBSD__ */
/* PCI identification */
#define SMC_VENDORID 0x10B8
@@ -174,6 +168,7 @@
*/
#define TXCON_DEFAULT (TXCON_SLOT_TIME | TXCON_EARLY_TRANSMIT_ENABLE)
#define TRANSMIT_THRESHOLD 0x300
+#define TRANSMIT_THRESHOLD_MAX 0x600
#define RXCON_DEFAULT (RXCON_RECEIVE_MULTICAST_FRAMES | \
RXCON_RECEIVE_BROADCAST_FRAMES)
diff --git a/sys/dev/tx/if_txvar.h b/sys/dev/tx/if_txvar.h
index 432f14b..922eaf2 100644
--- a/sys/dev/tx/if_txvar.h
+++ b/sys/dev/tx/if_txvar.h
@@ -1,6 +1,3 @@
-/* $OpenBSD: if_txvar.h,v 1.7 1999/11/17 05:21:19 jason Exp $ */
-/* $FreeBSD$ */
-
/*-
* Copyright (c) 1997 Semen Ustimenko
* All rights reserved.
@@ -25,14 +22,16 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $FreeBSD$
*/
/*
* Configuration
*/
-/*#define EPIC_DEBUG 1*/
+/*#define EPIC_DIAG 1*/
/*#define EPIC_USEIOSPACE 1*/
-#define EPIC_EARLY_RX 1
+/*#define EPIC_EARLY_RX 1*/
#ifndef ETHER_MAX_LEN
#define ETHER_MAX_LEN 1518
@@ -69,10 +68,6 @@ struct epic_tx_buffer {
/* Driver status structure */
typedef struct {
struct arpcom arpcom;
-#if defined(__OpenBSD__)
- mii_data_t sc_mii;
- struct device dev;
-#else /* __FreeBSD__ */
struct resource *res;
struct resource *irq;
@@ -81,7 +76,6 @@ typedef struct {
struct callout_handle stat_ch;
u_int32_t unit;
-#endif
void *sc_ih;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
@@ -107,6 +101,7 @@ typedef struct {
struct mii_softc *physc;
u_int32_t phyid;
int serinst;
+ void *pool;
} epic_softc_t;
struct epic_type {
@@ -115,42 +110,26 @@ struct epic_type {
char *name;
};
-#if defined(EPIC_DEBUG)
-#define dprintf(a) printf a
-#else
-#define dprintf(a)
-#endif
-
-#if defined(__FreeBSD__)
-#define EPIC_FORMAT "tx%d"
-#define EPIC_ARGS(sc) (sc->unit)
-#define EPIC_BPFTAP_ARG(ifp) ifp
-#else /* __OpenBSD__ */
-#define EPIC_FORMAT "%s"
-#define EPIC_ARGS(sc) (sc->sc_dev.dv_xname)
-#define EPIC_BPFTAP_ARG(ifp) (ifp)->if_bpf
-#endif
-
#define sc_if arpcom.ac_if
#define sc_macaddr arpcom.ac_enaddr
-#define CSR_WRITE_4(sc,reg,val) \
- bus_space_write_4( (sc)->sc_st, (sc)->sc_sh, (reg), (val) )
-#define CSR_WRITE_2(sc,reg,val) \
- bus_space_write_2( (sc)->sc_st, (sc)->sc_sh, (reg), (val) )
-#define CSR_WRITE_1(sc,reg,val) \
- bus_space_write_1( (sc)->sc_st, (sc)->sc_sh, (reg), (val) )
-#define CSR_READ_4(sc,reg) \
- bus_space_read_4( (sc)->sc_st, (sc)->sc_sh, (reg) )
-#define CSR_READ_2(sc,reg) \
- bus_space_read_2( (sc)->sc_st, (sc)->sc_sh, (reg) )
-#define CSR_READ_1(sc,reg) \
- bus_space_read_1( (sc)->sc_st, (sc)->sc_sh, (reg) )
-
-#define PHY_READ_2(sc,phy,reg) \
- epic_read_phy_reg((sc),(phy),(reg))
-#define PHY_WRITE_2(sc,phy,reg,val) \
- epic_write_phy_reg((sc),(phy),(reg),(val))
+#define CSR_WRITE_4(sc, reg, val) \
+ bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
+#define CSR_WRITE_2(sc, reg, val) \
+ bus_space_write_2((sc)->sc_st, (sc)->sc_sh, (reg), (val))
+#define CSR_WRITE_1(sc, reg, val) \
+ bus_space_write_1((sc)->sc_st, (sc)->sc_sh, (reg), (val))
+#define CSR_READ_4(sc, reg) \
+ bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
+#define CSR_READ_2(sc, reg) \
+ bus_space_read_2((sc)->sc_st, (sc)->sc_sh, (reg))
+#define CSR_READ_1(sc, reg) \
+ bus_space_read_1((sc)->sc_st, (sc)->sc_sh, (reg))
+
+#define PHY_READ_2(sc, phy, reg) \
+ epic_read_phy_reg((sc), (phy), (reg))
+#define PHY_WRITE_2(sc, phy, reg, val) \
+ epic_write_phy_reg((sc), (phy), (reg), (val))
/* Macro to get either mbuf cluster or nothing */
#define EPIC_MGETCLUSTER(m) \
OpenPOWER on IntegriCloud