Module Name: src
Committed By: thorpej
Date: Sun Mar 8 02:44:12 UTC 2020
Modified Files:
src/sys/dev/pci: if_sip.c if_sipreg.h
Log Message:
Support 64-bit DMA addressing on the DP83820, used only when a 64-bit
DMA tag is available.
To generate a diff of this commit:
cvs rdiff -u -r1.178 -r1.179 src/sys/dev/pci/if_sip.c
cvs rdiff -u -r1.20 -r1.21 src/sys/dev/pci/if_sipreg.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/if_sip.c
diff -u src/sys/dev/pci/if_sip.c:1.178 src/sys/dev/pci/if_sip.c:1.179
--- src/sys/dev/pci/if_sip.c:1.178 Fri Feb 7 00:04:28 2020
+++ src/sys/dev/pci/if_sip.c Sun Mar 8 02:44:12 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: if_sip.c,v 1.178 2020/02/07 00:04:28 thorpej Exp $ */
+/* $NetBSD: if_sip.c,v 1.179 2020/03/08 02:44:12 thorpej Exp $ */
/*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.178 2020/02/07 00:04:28 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.179 2020/03/08 02:44:12 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -208,9 +208,14 @@ struct sip_softc {
struct ethercom sc_ethercom; /* ethernet common data */
const struct sip_product *sc_model; /* which model are we? */
- int sc_gigabit; /* 1: 83820, 0: other */
+ bool sc_gigabit; /* 1: 83820, 0: other */
+ bool sc_dma64; /* using 64-bit DMA addresses */
int sc_rev; /* chip revision */
+ unsigned int sc_bufptr_idx;
+ unsigned int sc_cmdsts_idx;
+ unsigned int sc_extsts_idx; /* DP83820 only */
+
void *sc_ih; /* interrupt cookie */
struct mii_data sc_mii; /* MII/media information */
@@ -471,6 +476,24 @@ sip_rxchain_link(struct sip_softc *sc, s
#define SIP_CDRXADDR(sc, x) ((sc)->sc_cddma + SIP_CDRXOFF((x)))
static inline void
+sip_set_rxdp(struct sip_softc *sc, bus_addr_t addr)
+{
+ if (sc->sc_gigabit)
+ bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RXDP_HI,
+ BUS_ADDR_HI32(addr));
+ bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RXDP, BUS_ADDR_LO32(addr));
+}
+
+static inline void
+sip_set_txdp(struct sip_softc *sc, bus_addr_t addr)
+{
+ if (sc->sc_gigabit)
+ bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_TXDP_HI,
+ BUS_ADDR_HI32(addr));
+ bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_TXDP, BUS_ADDR_LO32(addr));
+}
+
+static inline void
sip_cdtxsync(struct sip_softc *sc, const int x0, const int n0, const int ops)
{
int x, n;
@@ -499,26 +522,51 @@ sip_cdrxsync(struct sip_softc *sc, int x
SIP_CDRXOFF(x), sizeof(struct sip_desc), ops);
}
-#if 0
-#ifdef DP83820
- uint32_t sipd_bufptr; /* pointer to DMA segment */
- uint32_t sipd_cmdsts; /* command/status word */
-#else
- uint32_t sipd_cmdsts; /* command/status word */
- uint32_t sipd_bufptr; /* pointer to DMA segment */
-#endif /* DP83820 */
-#endif /* 0 */
-
-static inline volatile uint32_t *
-sipd_cmdsts(struct sip_softc *sc, struct sip_desc *sipd)
+static void
+sip_init_txring(struct sip_softc *sc)
{
- return &sipd->sipd_cbs[(sc->sc_gigabit) ? 1 : 0];
+ struct sip_desc *sipd;
+ bus_addr_t next_desc;
+ int i;
+
+ memset(sc->sc_txdescs, 0, sizeof(sc->sc_txdescs));
+ for (i = 0; i < sc->sc_ntxdesc; i++) {
+ sipd = &sc->sc_txdescs[i];
+ next_desc = SIP_CDTXADDR(sc, sip_nexttx(sc, i));
+ if (sc->sc_dma64) {
+ sipd->sipd_words[GSIP64_DESC_LINK_LO] =
+ htole32(BUS_ADDR_LO32(next_desc));
+ sipd->sipd_words[GSIP64_DESC_LINK_HI] =
+ htole32(BUS_ADDR_HI32(next_desc));
+ } else {
+ /* SIP_DESC_LINK == GSIP_DESC_LINK */
+ sipd->sipd_words[SIP_DESC_LINK] = htole32(next_desc);
+ }
+ }
+ sip_cdtxsync(sc, 0, sc->sc_ntxdesc,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ sc->sc_txfree = sc->sc_ntxdesc;
+ sc->sc_txnext = 0;
+ sc->sc_txwin = 0;
}
-static inline volatile uint32_t *
-sipd_bufptr(struct sip_softc *sc, struct sip_desc *sipd)
+static inline void
+sip_init_txdesc(struct sip_softc *sc, int x, bus_addr_t bufptr, uint32_t cmdsts)
{
- return &sipd->sipd_cbs[(sc->sc_gigabit) ? 0 : 1];
+ struct sip_desc *sipd = &sc->sc_txdescs[x];
+
+ if (sc->sc_dma64) {
+ sipd->sipd_words[GSIP64_DESC_BUFPTR_LO] =
+ htole32(BUS_ADDR_LO32(bufptr));
+ sipd->sipd_words[GSIP64_DESC_BUFPTR_HI] =
+ htole32(BUS_ADDR_HI32(bufptr));
+ } else {
+ sipd->sipd_words[sc->sc_bufptr_idx] = htole32(bufptr);
+ }
+ sipd->sipd_words[sc->sc_extsts_idx] = 0;
+ membar_producer();
+ sipd->sipd_words[sc->sc_cmdsts_idx] = htole32(cmdsts);
+ /* sip_cdtxsync() will be done later. */
}
static inline void
@@ -526,12 +574,27 @@ sip_init_rxdesc(struct sip_softc *sc, in
{
struct sip_rxsoft *rxs = &sc->sc_rxsoft[x];
struct sip_desc *sipd = &sc->sc_rxdescs[x];
+ const bus_addr_t next_desc = SIP_CDRXADDR(sc, sip_nextrx(sc, x));
- sipd->sipd_link = htole32(SIP_CDRXADDR(sc, sip_nextrx(sc, x)));
- *sipd_bufptr(sc, sipd) = htole32(rxs->rxs_dmamap->dm_segs[0].ds_addr);
- *sipd_cmdsts(sc, sipd) = htole32(CMDSTS_INTR |
- (sc->sc_parm->p_rxbuf_len & sc->sc_bits.b_cmdsts_size_mask));
- sipd->sipd_extsts = 0;
+ if (sc->sc_dma64) {
+ sipd->sipd_words[GSIP64_DESC_LINK_LO] =
+ htole32(BUS_ADDR_LO32(next_desc));
+ sipd->sipd_words[GSIP64_DESC_LINK_HI] =
+ htole32(BUS_ADDR_HI32(next_desc));
+ sipd->sipd_words[GSIP64_DESC_BUFPTR_LO] =
+ htole32(BUS_ADDR_LO32(rxs->rxs_dmamap->dm_segs[0].ds_addr));
+ sipd->sipd_words[GSIP64_DESC_BUFPTR_HI] =
+ htole32(BUS_ADDR_HI32(rxs->rxs_dmamap->dm_segs[0].ds_addr));
+ } else {
+ sipd->sipd_words[SIP_DESC_LINK] = htole32(next_desc);
+ sipd->sipd_words[sc->sc_bufptr_idx] =
+ htole32(rxs->rxs_dmamap->dm_segs[0].ds_addr);
+ }
+ sipd->sipd_words[sc->sc_extsts_idx] = 0;
+ membar_producer();
+ sipd->sipd_words[sc->sc_cmdsts_idx] =
+ htole32(CMDSTS_INTR | (sc->sc_parm->p_rxbuf_len &
+ sc->sc_bits.b_cmdsts_size_mask));
sip_cdrxsync(sc, x, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
}
@@ -670,25 +733,26 @@ static const struct sip_product {
pci_product_id_t sip_product;
const char *sip_name;
const struct sip_variant *sip_variant;
- int sip_gigabit;
+ bool sip_gigabit;
} sipcom_products[] = {
{ PCI_VENDOR_NS, PCI_PRODUCT_NS_DP83820,
"NatSemi DP83820 Gigabit Ethernet",
- &sipcom_variant_dp83820, 1 },
+ &sipcom_variant_dp83820, true },
+
{ PCI_VENDOR_SIS, PCI_PRODUCT_SIS_900,
"SiS 900 10/100 Ethernet",
- &sipcom_variant_sis900, 0 },
+ &sipcom_variant_sis900, false },
{ PCI_VENDOR_SIS, PCI_PRODUCT_SIS_7016,
"SiS 7016 10/100 Ethernet",
- &sipcom_variant_sis900, 0 },
+ &sipcom_variant_sis900, false },
{ PCI_VENDOR_NS, PCI_PRODUCT_NS_DP83815,
"NatSemi DP83815 10/100 Ethernet",
- &sipcom_variant_dp83815, 0 },
+ &sipcom_variant_dp83815, false },
{ 0, 0,
NULL,
- NULL, 0 },
+ NULL, false },
};
static const struct sip_product *
@@ -812,24 +876,30 @@ sipcom_dp83820_attach(struct sip_softc *
}
printf("\n");
}
-
+
/*
- * XXX Need some PCI flags indicating support for
- * XXX 64-bit addressing.
+ * The T64ADDR bit is loaded by the chip from the EEPROM and
+ * is read-only.
*/
-#if 0
- if (reg & CFG_M64ADDR)
- sc->sc_cfg |= CFG_M64ADDR;
if (reg & CFG_T64ADDR)
sc->sc_cfg |= CFG_T64ADDR;
-#endif
+
+ /*
+ * We can use 64-bit DMA addressing regardless of what
+ * sort of slot we're in.
+ */
+ if (pci_dma64_available(pa)) {
+ sc->sc_dmat = pa->pa_dmat64;
+ sc->sc_cfg |= CFG_M64ADDR;
+ sc->sc_dma64 = true;
+ }
if (reg & (CFG_TBI_EN | CFG_EXT_125)) {
const char *sep = "";
printf("%s: using ", device_xname(sc->sc_dev));
if (reg & CFG_EXT_125) {
sc->sc_cfg |= CFG_EXT_125;
- printf("%s125MHz clock", sep);
+ printf("%sexternal 125MHz clock", sep);
sep = ", ";
}
if (reg & CFG_TBI_EN) {
@@ -1004,15 +1074,32 @@ sipcom_attach(device_t parent, device_t
}
sc->sc_dev = self;
sc->sc_gigabit = sip->sip_gigabit;
+ sc->sc_dma64 = false;
pmf_self_suspensor_init(self, &sc->sc_suspensor, &sc->sc_qual);
sc->sc_pc = pc;
if (sc->sc_gigabit) {
+ if (sc->sc_dma64) {
+ sc->sc_bufptr_idx = GSIP64_DESC_BUFPTR_LO;
+ sc->sc_cmdsts_idx = GSIP64_DESC_CMDSTS;
+ sc->sc_extsts_idx = GSIP64_DESC_EXTSTS;
+ } else {
+ sc->sc_bufptr_idx = GSIP_DESC_BUFPTR;
+ sc->sc_cmdsts_idx = GSIP_DESC_CMDSTS;
+ sc->sc_extsts_idx = GSIP_DESC_EXTSTS;
+ }
sc->sc_rxintr = gsip_rxintr;
sc->sc_parm = &gsip_parm;
} else {
sc->sc_rxintr = sip_rxintr;
sc->sc_parm = &sip_parm;
+ sc->sc_bufptr_idx = SIP_DESC_BUFPTR;
+ sc->sc_cmdsts_idx = SIP_DESC_CMDSTS;
+ /*
+ * EXTSTS doesn't really exist on non-GigE parts,
+ * but we initialize the index for simplicity later.
+ */
+ sc->sc_extsts_idx = GSIP_DESC_EXTSTS;
}
tx_dmamap_size = sc->sc_parm->p_tx_dmamap_size;
ntxsegs_alloc = sc->sc_parm->p_ntxsegs_alloc;
@@ -1376,7 +1463,7 @@ static inline void
sipcom_set_extsts(struct sip_softc *sc, int lasttx, struct mbuf *m0,
uint64_t capenable)
{
- uint32_t extsts;
+ uint32_t extsts = 0;
#ifdef DEBUG
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
#endif
@@ -1397,7 +1484,7 @@ sipcom_set_extsts(struct sip_softc *sc,
* unconditional swap instead of htons() inside.
*/
if (vlan_has_tag(m0)) {
- sc->sc_txdescs[lasttx].sipd_extsts |=
+ sc->sc_txdescs[lasttx].sipd_words[sc->sc_extsts_idx] |=
htole32(EXTSTS_VPKT |
(bswap16(vlan_get_tag(m0)) &
EXTSTS_VTCI));
@@ -1413,7 +1500,6 @@ sipcom_set_extsts(struct sip_softc *sc,
*
* Byte-swap constants so the compiler can optimize.
*/
- extsts = 0;
if (m0->m_pkthdr.csum_flags & M_CSUM_IPv4) {
KDASSERT(ifp->if_capenable & IFCAP_CSUM_IPv4_Tx);
SIP_EVCNT_INCR(&sc->sc_ev_txipsum);
@@ -1428,7 +1514,7 @@ sipcom_set_extsts(struct sip_softc *sc,
SIP_EVCNT_INCR(&sc->sc_ev_txudpsum);
extsts |= htole32(EXTSTS_UDPPKT);
}
- sc->sc_txdescs[sc->sc_txnext].sipd_extsts |= extsts;
+ sc->sc_txdescs[sc->sc_txnext].sipd_words[sc->sc_extsts_idx] |= extsts;
}
/*
@@ -1446,6 +1532,7 @@ sipcom_start(struct ifnet *ifp)
bus_dmamap_t dmamap;
int error, nexttx, lasttx, seg;
int ofree = sc->sc_txfree;
+ uint32_t cmdsts;
#if 0
int firsttx = sc->sc_txnext;
#endif
@@ -1586,26 +1673,24 @@ sipcom_start(struct ifnet *ifp)
* yet. That could cause a race condition.
* We'll do it below.
*/
- *sipd_bufptr(sc, &sc->sc_txdescs[nexttx]) =
- htole32(dmamap->dm_segs[seg].ds_addr);
- *sipd_cmdsts(sc, &sc->sc_txdescs[nexttx]) =
- htole32((nexttx == sc->sc_txnext ? 0 : CMDSTS_OWN)
- | CMDSTS_MORE | dmamap->dm_segs[seg].ds_len);
- sc->sc_txdescs[nexttx].sipd_extsts = 0;
+
+ cmdsts = dmamap->dm_segs[seg].ds_len;
+ if (nexttx != sc->sc_txnext)
+ cmdsts |= CMDSTS_OWN;
+ if (seg < dmamap->dm_nsegs - 1)
+ cmdsts |= CMDSTS_MORE;
+ sip_init_txdesc(sc, nexttx,
+ dmamap->dm_segs[seg].ds_addr, cmdsts);
lasttx = nexttx;
}
- /* Clear the MORE bit on the last segment. */
- *sipd_cmdsts(sc, &sc->sc_txdescs[lasttx]) &=
- htole32(~CMDSTS_MORE);
-
/*
* If we're in the interrupt delay window, delay the
* interrupt.
*/
if (++sc->sc_txwin >= (SIP_TXQUEUELEN * 2 / 3)) {
SIP_EVCNT_INCR(&sc->sc_ev_txforceintr);
- *sipd_cmdsts(sc, &sc->sc_txdescs[lasttx]) |=
+ sc->sc_txdescs[lasttx].sipd_words[sc->sc_cmdsts_idx] |=
htole32(CMDSTS_INTR);
sc->sc_txwin = 0;
}
@@ -1621,7 +1706,7 @@ sipcom_start(struct ifnet *ifp)
* The entire packet is set up. Give the first descrptor
* to the chip now.
*/
- *sipd_cmdsts(sc, &sc->sc_txdescs[sc->sc_txnext]) |=
+ sc->sc_txdescs[sc->sc_txnext].sipd_words[sc->sc_cmdsts_idx] |=
htole32(CMDSTS_OWN);
sip_cdtxsync(sc, sc->sc_txnext, 1,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@@ -1670,8 +1755,7 @@ sipcom_start(struct ifnet *ifp)
#if 0
if ((bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_CR) &
CR_TXE) == 0) {
- bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_TXDP,
- SIP_CDTXADDR(sc, firsttx));
+ sip_set_txdp(sc, SIP_CDTXADDR(sc, firsttx));
bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_CR, CR_TXE);
}
#else
@@ -1862,8 +1946,8 @@ sipcom_intr(void *arg)
device_xname(sc->sc_dev));
/* Get the receive process going again. */
- bus_space_write_4(sc->sc_st, sc->sc_sh,
- SIP_RXDP, SIP_CDRXADDR(sc, sc->sc_rxptr));
+ sip_set_rxdp(sc,
+ SIP_CDRXADDR(sc, sc->sc_rxptr));
bus_space_write_4(sc->sc_st, sc->sc_sh,
SIP_CR, CR_RXE);
}
@@ -1979,8 +2063,8 @@ sipcom_txintr(struct sip_softc *sc)
sip_cdtxsync(sc, txs->txs_firstdesc, txs->txs_dmamap->dm_nsegs,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- cmdsts = le32toh(*sipd_cmdsts(sc,
- &sc->sc_txdescs[txs->txs_lastdesc]));
+ cmdsts = le32toh(sc->sc_txdescs[
+ txs->txs_lastdesc].sipd_words[sc->sc_cmdsts_idx]);
if (cmdsts & CMDSTS_OWN)
break;
@@ -2051,8 +2135,10 @@ gsip_rxintr(struct sip_softc *sc)
sip_cdrxsync(sc, i,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- cmdsts = le32toh(*sipd_cmdsts(sc, &sc->sc_rxdescs[i]));
- extsts = le32toh(sc->sc_rxdescs[i].sipd_extsts);
+ cmdsts =
+ le32toh(sc->sc_rxdescs[i].sipd_words[sc->sc_cmdsts_idx]);
+ extsts =
+ le32toh(sc->sc_rxdescs[i].sipd_words[sc->sc_extsts_idx]);
len = CMDSTS_SIZE(sc, cmdsts);
/*
@@ -2262,7 +2348,8 @@ sip_rxintr(struct sip_softc *sc)
sip_cdrxsync(sc, i,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- cmdsts = le32toh(*sipd_cmdsts(sc, &sc->sc_rxdescs[i]));
+ cmdsts =
+ le32toh(sc->sc_rxdescs[i].sipd_words[sc->sc_cmdsts_idx]);
/*
* NOTE: OWN is set if owned by _consumer_. We're the
@@ -2527,7 +2614,6 @@ sipcom_init(struct ifnet *ifp)
bus_space_handle_t sh = sc->sc_sh;
struct sip_txsoft *txs;
struct sip_rxsoft *rxs;
- struct sip_desc *sipd;
int i, error = 0;
if (device_is_active(sc->sc_dev)) {
@@ -2574,19 +2660,8 @@ sipcom_init(struct ifnet *ifp)
bus_space_write_4(st, sh, 0x00cc, 0x0000);
}
- /*
- * Initialize the transmit descriptor ring.
- */
- for (i = 0; i < sc->sc_ntxdesc; i++) {
- sipd = &sc->sc_txdescs[i];
- memset(sipd, 0, sizeof(struct sip_desc));
- sipd->sipd_link = htole32(SIP_CDTXADDR(sc, sip_nexttx(sc, i)));
- }
- sip_cdtxsync(sc, 0, sc->sc_ntxdesc,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- sc->sc_txfree = sc->sc_ntxdesc;
- sc->sc_txnext = 0;
- sc->sc_txwin = 0;
+ /* Initialize the transmit descriptor ring. */
+ sip_init_txring(sc);
/*
* Initialize the transmit job descriptors.
@@ -2708,8 +2783,8 @@ sipcom_init(struct ifnet *ifp)
/*
* Give the transmit and receive rings to the chip.
*/
- bus_space_write_4(st, sh, SIP_TXDP, SIP_CDTXADDR(sc, sc->sc_txnext));
- bus_space_write_4(st, sh, SIP_RXDP, SIP_CDRXADDR(sc, sc->sc_rxptr));
+ sip_set_txdp(sc, SIP_CDTXADDR(sc, sc->sc_txnext));
+ sip_set_rxdp(sc, SIP_CDRXADDR(sc, sc->sc_rxptr));
/*
* Initialize the interrupt mask.
@@ -2840,8 +2915,9 @@ sipcom_stop(struct ifnet *ifp, int disab
while ((txs = SIMPLEQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
if ((ifp->if_flags & IFF_DEBUG) != 0 &&
SIMPLEQ_NEXT(txs, txs_q) == NULL &&
- (le32toh(*sipd_cmdsts(sc, &sc->sc_txdescs[txs->txs_lastdesc])) &
- CMDSTS_INTR) == 0)
+ (sc->sc_txdescs[
+ txs->txs_lastdesc].sipd_words[
+ sc->sc_cmdsts_idx] & htole32(CMDSTS_INTR)) == 0)
printf("%s: sip_stop: last descriptor does not "
"have INTR bit set\n", device_xname(sc->sc_dev));
SIMPLEQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
@@ -2853,7 +2929,8 @@ sipcom_stop(struct ifnet *ifp, int disab
}
#endif
cmdsts |= /* DEBUG */
- le32toh(*sipd_cmdsts(sc, &sc->sc_txdescs[txs->txs_lastdesc]));
+ le32toh(sc->sc_txdescs[
+ txs->txs_lastdesc].sipd_words[sc->sc_cmdsts_idx]);
bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
m_freem(txs->txs_mbuf);
txs->txs_mbuf = NULL;
Index: src/sys/dev/pci/if_sipreg.h
diff -u src/sys/dev/pci/if_sipreg.h:1.20 src/sys/dev/pci/if_sipreg.h:1.21
--- src/sys/dev/pci/if_sipreg.h:1.20 Thu Feb 8 09:05:19 2018
+++ src/sys/dev/pci/if_sipreg.h Sun Mar 8 02:44:12 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: if_sipreg.h,v 1.20 2018/02/08 09:05:19 dholland Exp $ */
+/* $NetBSD: if_sipreg.h,v 1.21 2020/03/08 02:44:12 thorpej Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -85,17 +85,32 @@
* and receive descriptor chains.
*
* Note the DP83820 can use 64-bit DMA addresses for link and bufptr.
- * However, we do not yet support that.
+ * Note also that the buffer pointer and command/status words are in
+ * the opposite order on the DP83820 to facilitate 64-bit DMA addresses.
*
* For transmit, buffers need not be aligned. For receive, buffers
* must be aligned to 4-byte (8-byte on DP83820) boundaries.
*/
+#define SIP_DESC_LINK 0 /* link to next descriptor */
+#define SIP_DESC_CMDSTS 1 /* ccommand/status */
+#define SIP_DESC_BUFPTR 2 /* pointer to DMA segment */
+
+#define GSIP_DESC_LINK 0
+#define GSIP_DESC_BUFPTR 1
+#define GSIP_DESC_CMDSTS 2
+#define GSIP_DESC_EXTSTS 3 /* extended status */
+
+#define GSIP64_DESC_LINK_LO 0
+#define GSIP64_DESC_LINK_HI 1
+#define GSIP64_DESC_BUFPTR_LO 2
+#define GSIP64_DESC_BUFPTR_HI 3
+#define GSIP64_DESC_CMDSTS 4
+#define GSIP64_DESC_EXTSTS 5
+
+#define SIP_NDESC_WORDS 6
+
struct sip_desc {
- u_int32_t sipd_link; /* link to next descriptor */
- uint32_t sipd_cbs[2]; /* command/status and pointer to
- * DMA segment
- */
- u_int32_t sipd_extsts; /* extended status */
+ uint32_t sipd_words[SIP_NDESC_WORDS];
};
/*