Define all members in TX/RX DMA descriptors as u_int32_t and use proper shift
and mask ops since smc83c170 chips access them in 32bit width with proper byteswap mechanism, so that all #if BYTE_ORDER in descriptors can be removed. While here, do some slight optimizations in epic_start() and epic_intr().
This commit is contained in:
parent
addcf5d254
commit
1fafd3e354
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: smc83c170.c,v 1.54 2003/11/02 11:07:46 wiz Exp $ */
|
||||
/* $NetBSD: smc83c170.c,v 1.55 2003/11/08 16:08:13 tsutsui Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
|
@ -43,7 +43,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: smc83c170.c,v 1.54 2003/11/02 11:07:46 wiz Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: smc83c170.c,v 1.55 2003/11/08 16:08:13 tsutsui Exp $");
|
||||
|
||||
#include "bpfilter.h"
|
||||
|
||||
|
@ -371,6 +371,7 @@ epic_start(ifp)
|
|||
struct epic_fraglist *fr;
|
||||
bus_dmamap_t dmamap;
|
||||
int error, firsttx, nexttx, opending, seg;
|
||||
u_int len;
|
||||
|
||||
/*
|
||||
* Remember the previous txpending and the first transmit
|
||||
|
@ -453,10 +454,11 @@ epic_start(ifp)
|
|||
fr->ef_frags[seg].ef_length =
|
||||
dmamap->dm_segs[seg].ds_len;
|
||||
}
|
||||
if (m0->m_pkthdr.len < ETHER_PAD_LEN) {
|
||||
len = m0->m_pkthdr.len;
|
||||
if (len < ETHER_PAD_LEN) {
|
||||
fr->ef_frags[seg].ef_addr = sc->sc_nulldma;
|
||||
fr->ef_frags[seg].ef_length =
|
||||
ETHER_PAD_LEN - m0->m_pkthdr.len;
|
||||
fr->ef_frags[seg].ef_length = ETHER_PAD_LEN - len;
|
||||
len = ETHER_PAD_LEN;
|
||||
seg++;
|
||||
}
|
||||
fr->ef_nfrags = seg;
|
||||
|
@ -476,7 +478,6 @@ epic_start(ifp)
|
|||
* Fill in the transmit descriptor.
|
||||
*/
|
||||
txd->et_control = ET_TXCTL_LASTDESC | ET_TXCTL_FRAGLIST;
|
||||
txd->et_txlength = max(m0->m_pkthdr.len, ETHER_PAD_LEN);
|
||||
|
||||
/*
|
||||
* If this is the first descriptor we're enqueueing,
|
||||
|
@ -484,9 +485,10 @@ epic_start(ifp)
|
|||
* a race condition. We'll do it below.
|
||||
*/
|
||||
if (nexttx == firsttx)
|
||||
txd->et_txstatus = 0;
|
||||
txd->et_txstatus = TXSTAT_TXLENGTH(len);
|
||||
else
|
||||
txd->et_txstatus = ET_TXSTAT_OWNER;
|
||||
txd->et_txstatus =
|
||||
TXSTAT_TXLENGTH(len) | ET_TXSTAT_OWNER;
|
||||
|
||||
EPIC_CDTXSYNC(sc, nexttx,
|
||||
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
||||
|
@ -529,7 +531,7 @@ epic_start(ifp)
|
|||
* The entire packet chain is set up. Give the
|
||||
* first descriptor to the EPIC now.
|
||||
*/
|
||||
EPIC_CDTX(sc, firsttx)->et_txstatus = ET_TXSTAT_OWNER;
|
||||
EPIC_CDTX(sc, firsttx)->et_txstatus |= ET_TXSTAT_OWNER;
|
||||
EPIC_CDTXSYNC(sc, firsttx,
|
||||
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
||||
|
||||
|
@ -612,7 +614,7 @@ epic_intr(arg)
|
|||
struct epic_txdesc *txd;
|
||||
struct epic_descsoft *ds;
|
||||
struct mbuf *m;
|
||||
u_int32_t intstat;
|
||||
u_int32_t intstat, rxstatus, txstatus;
|
||||
int i, claimed = 0;
|
||||
u_int len;
|
||||
|
||||
|
@ -643,7 +645,8 @@ epic_intr(arg)
|
|||
EPIC_CDRXSYNC(sc, i,
|
||||
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
if (rxd->er_rxstatus & ER_RXSTAT_OWNER) {
|
||||
rxstatus = rxd->er_rxstatus;
|
||||
if (rxstatus & ER_RXSTAT_OWNER) {
|
||||
/*
|
||||
* We have processed all of the
|
||||
* receive buffers.
|
||||
|
@ -657,11 +660,11 @@ epic_intr(arg)
|
|||
* The buffer will be reused the next time the
|
||||
* descriptor comes up in the ring.
|
||||
*/
|
||||
if ((rxd->er_rxstatus & ER_RXSTAT_PKTINTACT) == 0) {
|
||||
if (rxd->er_rxstatus & ER_RXSTAT_CRCERROR)
|
||||
if ((rxstatus & ER_RXSTAT_PKTINTACT) == 0) {
|
||||
if (rxstatus & ER_RXSTAT_CRCERROR)
|
||||
printf("%s: CRC error\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
if (rxd->er_rxstatus & ER_RXSTAT_ALIGNERROR)
|
||||
if (rxstatus & ER_RXSTAT_ALIGNERROR)
|
||||
printf("%s: alignment error\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
ifp->if_ierrors++;
|
||||
|
@ -675,7 +678,7 @@ epic_intr(arg)
|
|||
/*
|
||||
* The EPIC includes the CRC with every packet.
|
||||
*/
|
||||
len = rxd->er_rxlength;
|
||||
len = RXSTAT_RXLENGTH(rxstatus);
|
||||
|
||||
if (len < sizeof(struct ether_header)) {
|
||||
/*
|
||||
|
@ -775,7 +778,8 @@ epic_intr(arg)
|
|||
EPIC_CDTXSYNC(sc, i,
|
||||
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
if (txd->et_txstatus & ET_TXSTAT_OWNER)
|
||||
txstatus = txd->et_txstatus;
|
||||
if (txstatus & ET_TXSTAT_OWNER)
|
||||
break;
|
||||
|
||||
EPIC_CDFLSYNC(sc, i, BUS_DMASYNC_POSTWRITE);
|
||||
|
@ -790,13 +794,13 @@ epic_intr(arg)
|
|||
/*
|
||||
* Check for errors and collisions.
|
||||
*/
|
||||
if ((txd->et_txstatus & ET_TXSTAT_PACKETTX) == 0)
|
||||
if ((txstatus & ET_TXSTAT_PACKETTX) == 0)
|
||||
ifp->if_oerrors++;
|
||||
else
|
||||
ifp->if_opackets++;
|
||||
ifp->if_collisions +=
|
||||
TXSTAT_COLLISIONS(txd->et_txstatus);
|
||||
if (txd->et_txstatus & ET_TXSTAT_CARSENSELOST)
|
||||
TXSTAT_COLLISIONS(txstatus);
|
||||
if (txstatus & ET_TXSTAT_CARSENSELOST)
|
||||
printf("%s: lost carrier\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: smc83c170reg.h,v 1.8 2003/11/02 11:07:46 wiz Exp $ */
|
||||
/* $NetBSD: smc83c170reg.h,v 1.9 2003/11/08 16:08:13 tsutsui Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -49,25 +49,16 @@
|
|||
* EPIC transmit descriptor. Must be 4-byte aligned.
|
||||
*/
|
||||
struct epic_txdesc {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_int16_t et_txlength; /* transmit length */
|
||||
u_int16_t et_txstatus; /* transmit status; see below */
|
||||
#else
|
||||
u_int16_t et_txstatus; /* transmit status; see below */
|
||||
u_int16_t et_txlength; /* transmit length */
|
||||
#endif
|
||||
u_int32_t et_txstatus; /* transmit status; see below */
|
||||
u_int32_t et_bufaddr; /* buffer address */
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_int16_t et_control; /* control word; see below */
|
||||
u_int16_t et_buflength; /* buffer length */
|
||||
#else
|
||||
u_int16_t et_buflength; /* buffer length */
|
||||
u_int16_t et_control; /* control word; see below */
|
||||
#endif
|
||||
u_int32_t et_control; /* control word; see below */
|
||||
u_int32_t et_nextdesc; /* next descriptor pointer */
|
||||
};
|
||||
|
||||
/* et_txstatus */
|
||||
#define TXSTAT_TXLENGTH_SHIFT 16 /* TX length in higher 16bits */
|
||||
#define TXSTAT_TXLENGTH(x) ((x) << TXSTAT_TXLENGTH_SHIFT)
|
||||
|
||||
#define ET_TXSTAT_OWNER 0x8000 /* NIC owns descriptor */
|
||||
#define ET_TXSTAT_COLLMASK 0x1f00 /* collisions */
|
||||
#define ET_TXSTAT_DEFERRING 0x0080 /* deferring due to jabber */
|
||||
|
@ -82,35 +73,29 @@ struct epic_txdesc {
|
|||
#define TXSTAT_COLLISIONS(x) (((x) & ET_TXSTAT_COLLMASK) >> 8)
|
||||
|
||||
/* et_control */
|
||||
#define ET_TXCTL_LASTDESC 0x0010 /* last descriptor in frame */
|
||||
#define ET_TXCTL_NOCRC 0x0008 /* disable CRC generation */
|
||||
#define ET_TXCTL_IAF 0x0004 /* interrupt after frame */
|
||||
#define ET_TXCTL_LFFORM 0x0002 /* alternate fraglist format */
|
||||
#define ET_TXCTL_FRAGLIST 0x0001 /* descriptor points to fraglist */
|
||||
#define TXCTL_BUFLENGTH_MASK 0x0000ffff /* buf length in lower 16bits */
|
||||
#define TXCTL_BUFLENGTH(x) ((x) & TXCTL_BUFLENGTH_MASK)
|
||||
|
||||
#define ET_TXCTL_LASTDESC 0x00100000 /* last descriptor in frame */
|
||||
#define ET_TXCTL_NOCRC 0x00080000 /* disable CRC generation */
|
||||
#define ET_TXCTL_IAF 0x00040000 /* interrupt after frame */
|
||||
#define ET_TXCTL_LFFORM 0x00020000 /* alternate fraglist format */
|
||||
#define ET_TXCTL_FRAGLIST 0x00010000 /* descriptor points to fraglist */
|
||||
|
||||
/*
|
||||
* EPIC receive descriptor. Must be 4-byte aligned.
|
||||
*/
|
||||
struct epic_rxdesc {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_int16_t er_rxlength; /* receive frame length */
|
||||
u_int16_t er_rxstatus; /* receive status; see below */
|
||||
#else
|
||||
u_int16_t er_rxstatus; /* receive status; see below */
|
||||
u_int16_t er_rxlength; /* receive frame length */
|
||||
#endif
|
||||
u_int32_t er_rxstatus; /* receive status; see below */
|
||||
u_int32_t er_bufaddr; /* buffer address */
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_int16_t er_control; /* control word; see below */
|
||||
u_int16_t er_buflength; /* buffer length */
|
||||
#else
|
||||
u_int16_t er_buflength; /* buffer length */
|
||||
u_int16_t er_control; /* control word; see below */
|
||||
#endif
|
||||
u_int32_t er_control; /* control word; see below */
|
||||
u_int32_t er_nextdesc; /* next descriptor pointer */
|
||||
};
|
||||
|
||||
/* er_rxstatus */
|
||||
#define RXSTAT_RXLENGTH_SHIFT 16 /* TX length in higher 16bits */
|
||||
#define RXSTAT_RXLENGTH(x) ((x) >> RXSTAT_RXLENGTH_SHIFT)
|
||||
|
||||
#define ER_RXSTAT_OWNER 0x8000 /* NIC owns descriptor */
|
||||
#define ER_RXSTAT_HDRCOPIED 0x4000 /* rx status posted after hdr copy */
|
||||
#define ER_RXSTAT_FRAGLISTERR 0x2000 /* ran out of frags to copy frame */
|
||||
|
@ -124,9 +109,12 @@ struct epic_rxdesc {
|
|||
#define ER_RXSTAT_PKTINTACT 0x0001 /* packet received without error */
|
||||
|
||||
/* er_control */
|
||||
#define ER_RXCTL_HEADER 0x0004 /* descriptor is for hdr copy */
|
||||
#define ER_RXCTL_LFFORM 0x0002 /* alternate fraglist format */
|
||||
#define ER_RXCTL_FRAGLIST 0x0001 /* descriptor points to fraglist */
|
||||
#define RXCTL_BUFLENGTH_MASK 0x0000ffff /* buf length in lower 16bits */
|
||||
#define RXCTL_BUFLENGTH(x) ((x) & RXCTL_BUFLENGTH_MASK)
|
||||
|
||||
#define ER_RXCTL_HEADER 0x00040000 /* descriptor is for hdr copy */
|
||||
#define ER_RXCTL_LFFORM 0x00020000 /* alternate fraglist format */
|
||||
#define ER_RXCTL_FRAGLIST 0x00010000 /* descriptor points to fraglist */
|
||||
|
||||
/*
|
||||
* This is not really part of the register description, but we need
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: smc83c170var.h,v 1.7 2003/01/13 17:00:18 bouyer Exp $ */
|
||||
/* $NetBSD: smc83c170var.h,v 1.8 2003/11/08 16:08:13 tsutsui Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
|
@ -176,12 +176,11 @@ do { \
|
|||
*/ \
|
||||
__m->m_data = __m->m_ext.ext_buf + 2; \
|
||||
__rxd->er_bufaddr = __ds->ds_dmamap->dm_segs[0].ds_addr + 2; \
|
||||
__rxd->er_buflength = __m->m_ext.ext_size - 2; \
|
||||
__rxd->er_control = 0; \
|
||||
__rxd->er_control = RXCTL_BUFLENGTH(__m->m_ext.ext_size - 2); \
|
||||
__rxd->er_rxstatus = ER_RXSTAT_OWNER; \
|
||||
__rxd->er_nextdesc = EPIC_CDRXADDR((sc), EPIC_NEXTRX((x))); \
|
||||
EPIC_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
|
||||
} while (0)
|
||||
} while (/* CONSTCOND */ 0)
|
||||
|
||||
#ifdef _KERNEL
|
||||
void epic_attach __P((struct epic_softc *));
|
||||
|
|
Loading…
Reference in New Issue