- Initialize the ifnet structure, especially if_dname, before probing
the PHYs as some PHY drivers use it (but probably shouldn't). How gem(4) has worked with brgphy(4) on powerpc without this so far is unclear to me. - Introduce a dying flag which is set during detach and checked in gem_ioctl() in order to prevent active BPF listeners to clear promiscuous mode which may lead to the tick callout being restarted which will trigger a panic once it's actually gone. - In gem_stop() reset rather than just disable the transmitter and receiver in order to ensure we're not unloading DMA maps still in use by the hardware. [1] - The blanking time is specified in PCI clocks so we should use twice the value when operating at 66MHz. - Spell some 2 as ETHER_ALIGN and a 19 as GEM_STATUS_TX_COMPLETION_SHFT to make the actual intentions clear. - As we don't unload the peak attempts counter ignore its overflow interrupts. - Remove a stale setting of a variable to GEM_TD_INTERRUPT_ME which isn't used afterwards. - For optimum performance increment the TX kick register in multiples of 4 if possible as suggested by the documentation. - Partially revert r164931; drivers should only clear the watchdog timer if all outstanding TX descriptors are done. - Fix some debugging strings. - Add a missing BUS_DMASYNC_POSTWRITE in gem_rint(). - As the error paths in the interrupt handler are generally unlikely predict them as false. - Add support for the SBus version of the GEM controller. [2] - Add some lock assertions. - Improve some comments. - Fix some more or less cosmetic issues in the code of the PCI front-end. - Change some softc members to be unsigned where more appropriate and remove unused ones. Approved by: re (kib) Obtained from: NetBSD (partially) [2], OpenBSD [1] MFC after: 2 weeks
This commit is contained in:
parent
b97457e2e6
commit
9ba2b298df
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=194763
@ -923,6 +923,7 @@ dev/flash/at45d.c optional at45d
|
|||||||
dev/fxp/if_fxp.c optional fxp inet
|
dev/fxp/if_fxp.c optional fxp inet
|
||||||
dev/gem/if_gem.c optional gem
|
dev/gem/if_gem.c optional gem
|
||||||
dev/gem/if_gem_pci.c optional gem pci
|
dev/gem/if_gem_pci.c optional gem pci
|
||||||
|
dev/gem/if_gem_sbus.c optional gem sbus
|
||||||
dev/hatm/if_hatm.c optional hatm pci
|
dev/hatm/if_hatm.c optional hatm pci
|
||||||
dev/hatm/if_hatm_intr.c optional hatm pci
|
dev/hatm/if_hatm_intr.c optional hatm pci
|
||||||
dev/hatm/if_hatm_ioctl.c optional hatm pci
|
dev/hatm/if_hatm_ioctl.c optional hatm pci
|
||||||
|
@ -84,7 +84,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
CTASSERT(powerof2(GEM_NRXDESC) && GEM_NRXDESC >= 32 && GEM_NRXDESC <= 8192);
|
CTASSERT(powerof2(GEM_NRXDESC) && GEM_NRXDESC >= 32 && GEM_NRXDESC <= 8192);
|
||||||
CTASSERT(powerof2(GEM_NTXDESC) && GEM_NTXDESC >= 32 && GEM_NTXDESC <= 8192);
|
CTASSERT(powerof2(GEM_NTXDESC) && GEM_NTXDESC >= 32 && GEM_NTXDESC <= 8192);
|
||||||
|
|
||||||
#define TRIES 10000
|
#define GEM_TRIES 10000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The hardware supports basic TCP/UDP checksum offloading. However,
|
* The hardware supports basic TCP/UDP checksum offloading. However,
|
||||||
@ -119,7 +119,7 @@ static void gem_rint(struct gem_softc *sc);
|
|||||||
#ifdef GEM_RINT_TIMEOUT
|
#ifdef GEM_RINT_TIMEOUT
|
||||||
static void gem_rint_timeout(void *arg);
|
static void gem_rint_timeout(void *arg);
|
||||||
#endif
|
#endif
|
||||||
static __inline void gem_rxcksum(struct mbuf *m, uint64_t flags);
|
static inline void gem_rxcksum(struct mbuf *m, uint64_t flags);
|
||||||
static void gem_rxdrain(struct gem_softc *sc);
|
static void gem_rxdrain(struct gem_softc *sc);
|
||||||
static void gem_setladrf(struct gem_softc *sc);
|
static void gem_setladrf(struct gem_softc *sc);
|
||||||
static void gem_start(struct ifnet *ifp);
|
static void gem_start(struct ifnet *ifp);
|
||||||
@ -127,6 +127,7 @@ static void gem_start_locked(struct ifnet *ifp);
|
|||||||
static void gem_stop(struct ifnet *ifp, int disable);
|
static void gem_stop(struct ifnet *ifp, int disable);
|
||||||
static void gem_tick(void *arg);
|
static void gem_tick(void *arg);
|
||||||
static void gem_tint(struct gem_softc *sc);
|
static void gem_tint(struct gem_softc *sc);
|
||||||
|
static inline void gem_txkick(struct gem_softc *sc);
|
||||||
static int gem_watchdog(struct gem_softc *sc);
|
static int gem_watchdog(struct gem_softc *sc);
|
||||||
|
|
||||||
devclass_t gem_devclass;
|
devclass_t gem_devclass;
|
||||||
@ -151,9 +152,24 @@ gem_attach(struct gem_softc *sc)
|
|||||||
int error, i;
|
int error, i;
|
||||||
uint32_t v;
|
uint32_t v;
|
||||||
|
|
||||||
|
if (bootverbose)
|
||||||
|
device_printf(sc->sc_dev, "flags=0x%x\n", sc->sc_flags);
|
||||||
|
|
||||||
|
/* Set up ifnet structure. */
|
||||||
ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
|
ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
|
||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
return (ENOSPC);
|
return (ENOSPC);
|
||||||
|
sc->sc_csum_features = GEM_CSUM_FEATURES;
|
||||||
|
ifp->if_softc = sc;
|
||||||
|
if_initname(ifp, device_get_name(sc->sc_dev),
|
||||||
|
device_get_unit(sc->sc_dev));
|
||||||
|
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||||
|
ifp->if_start = gem_start;
|
||||||
|
ifp->if_ioctl = gem_ioctl;
|
||||||
|
ifp->if_init = gem_init;
|
||||||
|
IFQ_SET_MAXLEN(&ifp->if_snd, GEM_TXQUEUELEN);
|
||||||
|
ifp->if_snd.ifq_drv_maxlen = GEM_TXQUEUELEN;
|
||||||
|
IFQ_SET_READY(&ifp->if_snd);
|
||||||
|
|
||||||
callout_init_mtx(&sc->sc_tick_ch, &sc->sc_mtx, 0);
|
callout_init_mtx(&sc->sc_tick_ch, &sc->sc_mtx, 0);
|
||||||
#ifdef GEM_RINT_TIMEOUT
|
#ifdef GEM_RINT_TIMEOUT
|
||||||
@ -161,27 +177,26 @@ gem_attach(struct gem_softc *sc)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Make sure the chip is stopped. */
|
/* Make sure the chip is stopped. */
|
||||||
ifp->if_softc = sc;
|
|
||||||
gem_reset(sc);
|
gem_reset(sc);
|
||||||
|
|
||||||
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
|
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
|
||||||
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
|
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
|
||||||
BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, 0, NULL,
|
BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, 0, NULL,
|
||||||
NULL, &sc->sc_pdmatag);
|
NULL, &sc->sc_pdmatag);
|
||||||
if (error)
|
if (error != 0)
|
||||||
goto fail_ifnet;
|
goto fail_ifnet;
|
||||||
|
|
||||||
error = bus_dma_tag_create(sc->sc_pdmatag, 1, 0,
|
error = bus_dma_tag_create(sc->sc_pdmatag, 1, 0,
|
||||||
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
|
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
|
||||||
1, MCLBYTES, BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_rdmatag);
|
1, MCLBYTES, BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_rdmatag);
|
||||||
if (error)
|
if (error != 0)
|
||||||
goto fail_ptag;
|
goto fail_ptag;
|
||||||
|
|
||||||
error = bus_dma_tag_create(sc->sc_pdmatag, 1, 0,
|
error = bus_dma_tag_create(sc->sc_pdmatag, 1, 0,
|
||||||
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
|
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
|
||||||
MCLBYTES * GEM_NTXSEGS, GEM_NTXSEGS, MCLBYTES,
|
MCLBYTES * GEM_NTXSEGS, GEM_NTXSEGS, MCLBYTES,
|
||||||
BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_tdmatag);
|
BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_tdmatag);
|
||||||
if (error)
|
if (error != 0)
|
||||||
goto fail_rtag;
|
goto fail_rtag;
|
||||||
|
|
||||||
error = bus_dma_tag_create(sc->sc_pdmatag, PAGE_SIZE, 0,
|
error = bus_dma_tag_create(sc->sc_pdmatag, PAGE_SIZE, 0,
|
||||||
@ -189,7 +204,7 @@ gem_attach(struct gem_softc *sc)
|
|||||||
sizeof(struct gem_control_data), 1,
|
sizeof(struct gem_control_data), 1,
|
||||||
sizeof(struct gem_control_data), 0,
|
sizeof(struct gem_control_data), 0,
|
||||||
NULL, NULL, &sc->sc_cdmatag);
|
NULL, NULL, &sc->sc_cdmatag);
|
||||||
if (error)
|
if (error != 0)
|
||||||
goto fail_ttag;
|
goto fail_ttag;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -199,7 +214,7 @@ gem_attach(struct gem_softc *sc)
|
|||||||
if ((error = bus_dmamem_alloc(sc->sc_cdmatag,
|
if ((error = bus_dmamem_alloc(sc->sc_cdmatag,
|
||||||
(void **)&sc->sc_control_data,
|
(void **)&sc->sc_control_data,
|
||||||
BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
|
BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
|
||||||
&sc->sc_cddmamap))) {
|
&sc->sc_cddmamap)) != 0) {
|
||||||
device_printf(sc->sc_dev,
|
device_printf(sc->sc_dev,
|
||||||
"unable to allocate control data, error = %d\n", error);
|
"unable to allocate control data, error = %d\n", error);
|
||||||
goto fail_ctag;
|
goto fail_ctag;
|
||||||
@ -338,19 +353,6 @@ gem_attach(struct gem_softc *sc)
|
|||||||
device_printf(sc->sc_dev, "%ukB RX FIFO, %ukB TX FIFO\n",
|
device_printf(sc->sc_dev, "%ukB RX FIFO, %ukB TX FIFO\n",
|
||||||
sc->sc_rxfifosize / 1024, v / 16);
|
sc->sc_rxfifosize / 1024, v / 16);
|
||||||
|
|
||||||
sc->sc_csum_features = GEM_CSUM_FEATURES;
|
|
||||||
/* Initialize ifnet structure. */
|
|
||||||
ifp->if_softc = sc;
|
|
||||||
if_initname(ifp, device_get_name(sc->sc_dev),
|
|
||||||
device_get_unit(sc->sc_dev));
|
|
||||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
|
||||||
ifp->if_start = gem_start;
|
|
||||||
ifp->if_ioctl = gem_ioctl;
|
|
||||||
ifp->if_init = gem_init;
|
|
||||||
IFQ_SET_MAXLEN(&ifp->if_snd, GEM_TXQUEUELEN);
|
|
||||||
ifp->if_snd.ifq_drv_maxlen = GEM_TXQUEUELEN;
|
|
||||||
IFQ_SET_READY(&ifp->if_snd);
|
|
||||||
|
|
||||||
/* Attach the interface. */
|
/* Attach the interface. */
|
||||||
ether_ifattach(ifp, sc->sc_enaddr);
|
ether_ifattach(ifp, sc->sc_enaddr);
|
||||||
|
|
||||||
@ -402,6 +404,7 @@ gem_detach(struct gem_softc *sc)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
GEM_LOCK(sc);
|
GEM_LOCK(sc);
|
||||||
|
sc->sc_flags |= GEM_DYING;
|
||||||
gem_stop(ifp, 1);
|
gem_stop(ifp, 1);
|
||||||
GEM_UNLOCK(sc);
|
GEM_UNLOCK(sc);
|
||||||
callout_drain(&sc->sc_tick_ch);
|
callout_drain(&sc->sc_tick_ch);
|
||||||
@ -456,7 +459,7 @@ gem_resume(struct gem_softc *sc)
|
|||||||
GEM_UNLOCK(sc);
|
GEM_UNLOCK(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void
|
static inline void
|
||||||
gem_rxcksum(struct mbuf *m, uint64_t flags)
|
gem_rxcksum(struct mbuf *m, uint64_t flags)
|
||||||
{
|
{
|
||||||
struct ether_header *eh;
|
struct ether_header *eh;
|
||||||
@ -535,12 +538,11 @@ static void
|
|||||||
gem_tick(void *arg)
|
gem_tick(void *arg)
|
||||||
{
|
{
|
||||||
struct gem_softc *sc = arg;
|
struct gem_softc *sc = arg;
|
||||||
struct ifnet *ifp;
|
struct ifnet *ifp = sc->sc_ifp;
|
||||||
uint32_t v;
|
uint32_t v;
|
||||||
|
|
||||||
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
||||||
|
|
||||||
ifp = sc->sc_ifp;
|
|
||||||
/*
|
/*
|
||||||
* Unload collision and error counters.
|
* Unload collision and error counters.
|
||||||
*/
|
*/
|
||||||
@ -584,7 +586,7 @@ gem_bitwait(struct gem_softc *sc, u_int bank, bus_addr_t r, uint32_t clr,
|
|||||||
int i;
|
int i;
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
|
|
||||||
for (i = TRIES; i--; DELAY(100)) {
|
for (i = GEM_TRIES; i--; DELAY(100)) {
|
||||||
reg = GEM_BANKN_READ_M(bank, 4, sc, r);
|
reg = GEM_BANKN_READ_M(bank, 4, sc, r);
|
||||||
if ((reg & clr) == 0 && (reg & set) == set)
|
if ((reg & clr) == 0 && (reg & set) == set)
|
||||||
return (1);
|
return (1);
|
||||||
@ -593,8 +595,7 @@ gem_bitwait(struct gem_softc *sc, u_int bank, bus_addr_t r, uint32_t clr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gem_reset(sc)
|
gem_reset(struct gem_softc *sc)
|
||||||
struct gem_softc *sc;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef GEM_DEBUG
|
#ifdef GEM_DEBUG
|
||||||
@ -644,9 +645,8 @@ gem_stop(struct ifnet *ifp, int disable)
|
|||||||
callout_stop(&sc->sc_rx_ch);
|
callout_stop(&sc->sc_rx_ch);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* XXX should we reset these instead? */
|
gem_reset_tx(sc);
|
||||||
gem_disable_tx(sc);
|
gem_reset_rx(sc);
|
||||||
gem_disable_rx(sc);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Release any queued transmit buffers.
|
* Release any queued transmit buffers.
|
||||||
@ -721,7 +721,7 @@ gem_reset_rxdma(struct gem_softc *sc)
|
|||||||
if (sc->sc_rxsoft[i].rxs_mbuf != NULL)
|
if (sc->sc_rxsoft[i].rxs_mbuf != NULL)
|
||||||
GEM_UPDATE_RXDESC(sc, i);
|
GEM_UPDATE_RXDESC(sc, i);
|
||||||
sc->sc_rxptr = 0;
|
sc->sc_rxptr = 0;
|
||||||
GEM_CDSYNC(sc, BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
GEM_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||||
|
|
||||||
/* NOTE: we use only 32-bit DMA addresses here. */
|
/* NOTE: we use only 32-bit DMA addresses here. */
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_RX_RING_PTR_HI, 0);
|
GEM_BANK1_WRITE_4(sc, GEM_RX_RING_PTR_HI, 0);
|
||||||
@ -732,9 +732,11 @@ gem_reset_rxdma(struct gem_softc *sc)
|
|||||||
((ETHER_HDR_LEN + sizeof(struct ip)) <<
|
((ETHER_HDR_LEN + sizeof(struct ip)) <<
|
||||||
GEM_RX_CONFIG_CXM_START_SHFT) |
|
GEM_RX_CONFIG_CXM_START_SHFT) |
|
||||||
(GEM_THRSH_1024 << GEM_RX_CONFIG_FIFO_THRS_SHIFT) |
|
(GEM_THRSH_1024 << GEM_RX_CONFIG_FIFO_THRS_SHIFT) |
|
||||||
(2 << GEM_RX_CONFIG_FBOFF_SHFT));
|
(ETHER_ALIGN << GEM_RX_CONFIG_FBOFF_SHFT));
|
||||||
|
/* Adjust for the SBus clock probably isn't worth the fuzz. */
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_RX_BLANKING,
|
GEM_BANK1_WRITE_4(sc, GEM_RX_BLANKING,
|
||||||
(6 << GEM_RX_BLANKING_TIME_SHIFT) | 6);
|
((6 * (sc->sc_flags & GEM_PCI66) != 0 ? 2 : 1) <<
|
||||||
|
GEM_RX_BLANKING_TIME_SHIFT) | 6);
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_RX_PAUSE_THRESH,
|
GEM_BANK1_WRITE_4(sc, GEM_RX_PAUSE_THRESH,
|
||||||
(3 * sc->sc_rxfifosize / 256) |
|
(3 * sc->sc_rxfifosize / 256) |
|
||||||
((sc->sc_rxfifosize / 256) << 12));
|
((sc->sc_rxfifosize / 256) << 12));
|
||||||
@ -798,12 +800,13 @@ gem_disable_tx(struct gem_softc *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gem_meminit(sc)
|
gem_meminit(struct gem_softc *sc)
|
||||||
struct gem_softc *sc;
|
|
||||||
{
|
{
|
||||||
struct gem_rxsoft *rxs;
|
struct gem_rxsoft *rxs;
|
||||||
int error, i;
|
int error, i;
|
||||||
|
|
||||||
|
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the transmit descriptor ring.
|
* Initialize the transmit descriptor ring.
|
||||||
*/
|
*/
|
||||||
@ -837,7 +840,8 @@ gem_meminit(sc)
|
|||||||
GEM_INIT_RXDESC(sc, i);
|
GEM_INIT_RXDESC(sc, i);
|
||||||
}
|
}
|
||||||
sc->sc_rxptr = 0;
|
sc->sc_rxptr = 0;
|
||||||
GEM_CDSYNC(sc, BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
|
||||||
|
GEM_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -938,6 +942,20 @@ gem_init_locked(struct gem_softc *sc)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* step 8. Global Configuration & Interrupt Mask */
|
/* step 8. Global Configuration & Interrupt Mask */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the internal arbitration to "infinite" bursts of the
|
||||||
|
* maximum length of 31 * 64 bytes so DMA transfers aren't
|
||||||
|
* split up in cache line size chunks. This greatly improves
|
||||||
|
* RX performance.
|
||||||
|
* Enable silicon bug workarounds for the Apple variants.
|
||||||
|
*/
|
||||||
|
GEM_BANK1_WRITE_4(sc, GEM_CONFIG,
|
||||||
|
GEM_CONFIG_TXDMA_LIMIT | GEM_CONFIG_RXDMA_LIMIT |
|
||||||
|
((sc->sc_flags & GEM_PCI) != 0 ? GEM_CONFIG_BURST_INF :
|
||||||
|
GEM_CONFIG_BURST_64) | (GEM_IS_APPLE(sc) ?
|
||||||
|
GEM_CONFIG_RONPAULBIT | GEM_CONFIG_BUG2FIX : 0));
|
||||||
|
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_INTMASK,
|
GEM_BANK1_WRITE_4(sc, GEM_INTMASK,
|
||||||
~(GEM_INTR_TX_INTME | GEM_INTR_TX_EMPTY | GEM_INTR_RX_DONE |
|
~(GEM_INTR_TX_INTME | GEM_INTR_TX_EMPTY | GEM_INTR_RX_DONE |
|
||||||
GEM_INTR_RX_NOBUF | GEM_INTR_RX_TAG_ERR | GEM_INTR_PERR |
|
GEM_INTR_RX_NOBUF | GEM_INTR_RX_TAG_ERR | GEM_INTR_PERR |
|
||||||
@ -949,7 +967,8 @@ gem_init_locked(struct gem_softc *sc)
|
|||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_MASK,
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_MASK,
|
||||||
GEM_MAC_RX_DONE | GEM_MAC_RX_FRAME_CNT);
|
GEM_MAC_RX_DONE | GEM_MAC_RX_FRAME_CNT);
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_TX_MASK,
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_TX_MASK,
|
||||||
GEM_MAC_TX_XMIT_DONE | GEM_MAC_TX_DEFER_EXP);
|
GEM_MAC_TX_XMIT_DONE | GEM_MAC_TX_DEFER_EXP |
|
||||||
|
GEM_MAC_TX_PEAK_EXP);
|
||||||
#ifdef GEM_DEBUG
|
#ifdef GEM_DEBUG
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_CONTROL_MASK,
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_CONTROL_MASK,
|
||||||
~(GEM_MAC_PAUSED | GEM_MAC_PAUSE | GEM_MAC_RESUME));
|
~(GEM_MAC_PAUSED | GEM_MAC_PAUSE | GEM_MAC_RESUME));
|
||||||
@ -961,7 +980,8 @@ gem_init_locked(struct gem_softc *sc)
|
|||||||
/* step 9. ETX Configuration: use mostly default values. */
|
/* step 9. ETX Configuration: use mostly default values. */
|
||||||
|
|
||||||
/* Enable DMA. */
|
/* Enable DMA. */
|
||||||
v = gem_ringsize(GEM_NTXDESC /* XXX */);
|
v = gem_ringsize(GEM_NTXDESC);
|
||||||
|
/* Set TX FIFO threshold and enable DMA. */
|
||||||
v |= ((sc->sc_variant == GEM_SUN_ERI ? 0x100 : 0x4ff) << 10) &
|
v |= ((sc->sc_variant == GEM_SUN_ERI ? 0x100 : 0x4ff) << 10) &
|
||||||
GEM_TX_CONFIG_TXFIFO_TH;
|
GEM_TX_CONFIG_TXFIFO_TH;
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_TX_CONFIG, v | GEM_TX_CONFIG_TXDMA_EN);
|
GEM_BANK1_WRITE_4(sc, GEM_TX_CONFIG, v | GEM_TX_CONFIG_TXDMA_EN);
|
||||||
@ -973,14 +993,16 @@ gem_init_locked(struct gem_softc *sc)
|
|||||||
/* RX TCP/UDP checksum offset */
|
/* RX TCP/UDP checksum offset */
|
||||||
v |= ((ETHER_HDR_LEN + sizeof(struct ip)) <<
|
v |= ((ETHER_HDR_LEN + sizeof(struct ip)) <<
|
||||||
GEM_RX_CONFIG_CXM_START_SHFT);
|
GEM_RX_CONFIG_CXM_START_SHFT);
|
||||||
|
/* Set RX FIFO threshold, set first byte offset and enable DMA. */
|
||||||
/* Enable DMA. */
|
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_RX_CONFIG,
|
GEM_BANK1_WRITE_4(sc, GEM_RX_CONFIG,
|
||||||
v | (GEM_THRSH_1024 << GEM_RX_CONFIG_FIFO_THRS_SHIFT) |
|
v | (GEM_THRSH_1024 << GEM_RX_CONFIG_FIFO_THRS_SHIFT) |
|
||||||
(2 << GEM_RX_CONFIG_FBOFF_SHFT) | GEM_RX_CONFIG_RXDMA_EN);
|
(ETHER_ALIGN << GEM_RX_CONFIG_FBOFF_SHFT) |
|
||||||
|
GEM_RX_CONFIG_RXDMA_EN);
|
||||||
|
|
||||||
|
/* Adjust for the SBus clock probably isn't worth the fuzz. */
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_RX_BLANKING,
|
GEM_BANK1_WRITE_4(sc, GEM_RX_BLANKING,
|
||||||
(6 << GEM_RX_BLANKING_TIME_SHIFT) | 6);
|
((6 * (sc->sc_flags & GEM_PCI66) != 0 ? 2 : 1) <<
|
||||||
|
GEM_RX_BLANKING_TIME_SHIFT) | 6);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following value is for an OFF Threshold of about 3/4 full
|
* The following value is for an OFF Threshold of about 3/4 full
|
||||||
@ -1002,7 +1024,7 @@ gem_init_locked(struct gem_softc *sc)
|
|||||||
device_printf(sc->sc_dev, "cannot configure RX MAC\n");
|
device_printf(sc->sc_dev, "cannot configure RX MAC\n");
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_CONFIG, v);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_CONFIG, v);
|
||||||
|
|
||||||
/* step 13. TX_MAC Configuration Register */
|
/* step 13. TX_MAC Configuration Register */
|
||||||
v = GEM_BANK1_READ_4(sc, GEM_MAC_TX_CONFIG);
|
v = GEM_BANK1_READ_4(sc, GEM_MAC_TX_CONFIG);
|
||||||
v |= GEM_MAC_TX_ENABLE;
|
v |= GEM_MAC_TX_ENABLE;
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_TX_CONFIG, 0);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_TX_CONFIG, 0);
|
||||||
@ -1037,6 +1059,8 @@ gem_load_txmbuf(struct gem_softc *sc, struct mbuf **m_head)
|
|||||||
uint64_t cflags, flags;
|
uint64_t cflags, flags;
|
||||||
int error, nexttx, nsegs, offset, seg;
|
int error, nexttx, nsegs, offset, seg;
|
||||||
|
|
||||||
|
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
||||||
|
|
||||||
/* Get a work queue entry. */
|
/* Get a work queue entry. */
|
||||||
if ((txs = STAILQ_FIRST(&sc->sc_txfreeq)) == NULL) {
|
if ((txs = STAILQ_FIRST(&sc->sc_txfreeq)) == NULL) {
|
||||||
/* Ran out of descriptors. */
|
/* Ran out of descriptors. */
|
||||||
@ -1143,7 +1167,6 @@ gem_load_txmbuf(struct gem_softc *sc, struct mbuf **m_head)
|
|||||||
#endif
|
#endif
|
||||||
if (++sc->sc_txwin > GEM_NTXSEGS * 2 / 3) {
|
if (++sc->sc_txwin > GEM_NTXSEGS * 2 / 3) {
|
||||||
sc->sc_txwin = 0;
|
sc->sc_txwin = 0;
|
||||||
flags |= GEM_TD_INTERRUPT_ME;
|
|
||||||
sc->sc_txdescs[txs->txs_firstdesc].gd_flags |=
|
sc->sc_txdescs[txs->txs_firstdesc].gd_flags |=
|
||||||
GEM_DMA_WRITE(sc, GEM_TD_INTERRUPT_ME |
|
GEM_DMA_WRITE(sc, GEM_TD_INTERRUPT_ME |
|
||||||
GEM_TD_START_OF_PACKET);
|
GEM_TD_START_OF_PACKET);
|
||||||
@ -1175,6 +1198,8 @@ gem_init_regs(struct gem_softc *sc)
|
|||||||
{
|
{
|
||||||
const u_char *laddr = IF_LLADDR(sc->sc_ifp);
|
const u_char *laddr = IF_LLADDR(sc->sc_ifp);
|
||||||
|
|
||||||
|
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
||||||
|
|
||||||
/* These registers are not cleared on reset. */
|
/* These registers are not cleared on reset. */
|
||||||
if ((sc->sc_flags & GEM_INITED) == 0) {
|
if ((sc->sc_flags & GEM_INITED) == 0) {
|
||||||
/* magic values */
|
/* magic values */
|
||||||
@ -1182,16 +1207,19 @@ gem_init_regs(struct gem_softc *sc)
|
|||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_IPG1, 8);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_IPG1, 8);
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_IPG2, 4);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_IPG2, 4);
|
||||||
|
|
||||||
|
/* min frame length */
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_MAC_MIN_FRAME, ETHER_MIN_LEN);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_MAC_MIN_FRAME, ETHER_MIN_LEN);
|
||||||
/* max frame and max burst size */
|
/* max frame length and max burst size */
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_MAC_MAX_FRAME,
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_MAC_MAX_FRAME,
|
||||||
(ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) | (0x2000 << 16));
|
(ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) | (0x2000 << 16));
|
||||||
|
|
||||||
|
/* more magic values */
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_PREAMBLE_LEN, 0x7);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_PREAMBLE_LEN, 0x7);
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_JAM_SIZE, 0x4);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_JAM_SIZE, 0x4);
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_ATTEMPT_LIMIT, 0x10);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_ATTEMPT_LIMIT, 0x10);
|
||||||
/* dunno... */
|
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_CONTROL_TYPE, 0x8088);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_CONTROL_TYPE, 0x8088);
|
||||||
|
|
||||||
|
/* random number seed */
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_RANDOM_SEED,
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_RANDOM_SEED,
|
||||||
((laddr[5] << 8) | laddr[4]) & 0x3ff);
|
((laddr[5] << 8) | laddr[4]) & 0x3ff);
|
||||||
|
|
||||||
@ -1209,7 +1237,6 @@ gem_init_regs(struct gem_softc *sc)
|
|||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR_FILTER0, 0);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR_FILTER0, 0);
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR_FILTER1, 0);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR_FILTER1, 0);
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR_FILTER2, 0);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR_FILTER2, 0);
|
||||||
|
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADR_FLT_MASK1_2, 0);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADR_FLT_MASK1_2, 0);
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADR_FLT_MASK0, 0);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADR_FLT_MASK0, 0);
|
||||||
|
|
||||||
@ -1232,18 +1259,6 @@ gem_init_regs(struct gem_softc *sc)
|
|||||||
/* Set XOFF PAUSE time. */
|
/* Set XOFF PAUSE time. */
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_SEND_PAUSE_CMD, 0x1BF0);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_SEND_PAUSE_CMD, 0x1BF0);
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the internal arbitration to "infinite" bursts of the
|
|
||||||
* maximum length of 31 * 64 bytes so DMA transfers aren't
|
|
||||||
* split up in cache line size chunks. This greatly improves
|
|
||||||
* especially RX performance.
|
|
||||||
* Enable silicon bug workarounds for the Apple variants.
|
|
||||||
*/
|
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_CONFIG,
|
|
||||||
GEM_CONFIG_TXDMA_LIMIT | GEM_CONFIG_RXDMA_LIMIT |
|
|
||||||
GEM_CONFIG_BURST_INF | (GEM_IS_APPLE(sc) ?
|
|
||||||
GEM_CONFIG_RONPAULBIT | GEM_CONFIG_BUG2FIX : 0));
|
|
||||||
|
|
||||||
/* Set the station address. */
|
/* Set the station address. */
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR0, (laddr[4] << 8) | laddr[5]);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR0, (laddr[4] << 8) | laddr[5]);
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR1, (laddr[2] << 8) | laddr[3]);
|
GEM_BANK1_WRITE_4(sc, GEM_MAC_ADDR1, (laddr[2] << 8) | laddr[3]);
|
||||||
@ -1263,12 +1278,32 @@ gem_start(struct ifnet *ifp)
|
|||||||
GEM_UNLOCK(sc);
|
GEM_UNLOCK(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gem_txkick(struct gem_softc *sc)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update the TX kick register. This register has to point to the
|
||||||
|
* descriptor after the last valid one and for optimum performance
|
||||||
|
* should be incremented in multiples of 4 (the DMA engine fetches/
|
||||||
|
* updates descriptors in batches of 4).
|
||||||
|
*/
|
||||||
|
#ifdef GEM_DEBUG
|
||||||
|
CTR3(KTR_GEM, "%s: %s: kicking TX %d",
|
||||||
|
device_get_name(sc->sc_dev), __func__, sc->sc_txnext);
|
||||||
|
#endif
|
||||||
|
GEM_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||||
|
GEM_BANK1_WRITE_4(sc, GEM_TX_KICK, sc->sc_txnext);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gem_start_locked(struct ifnet *ifp)
|
gem_start_locked(struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
struct gem_softc *sc = ifp->if_softc;
|
struct gem_softc *sc = ifp->if_softc;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
int ntx;
|
int kicked, ntx;
|
||||||
|
|
||||||
|
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
||||||
|
|
||||||
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
|
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
|
||||||
IFF_DRV_RUNNING || (sc->sc_flags & GEM_LINK) == 0)
|
IFF_DRV_RUNNING || (sc->sc_flags & GEM_LINK) == 0)
|
||||||
@ -1280,6 +1315,7 @@ gem_start_locked(struct ifnet *ifp)
|
|||||||
sc->sc_txnext);
|
sc->sc_txnext);
|
||||||
#endif
|
#endif
|
||||||
ntx = 0;
|
ntx = 0;
|
||||||
|
kicked = 0;
|
||||||
for (; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && sc->sc_txfree > 1;) {
|
for (; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && sc->sc_txfree > 1;) {
|
||||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
|
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
@ -1291,19 +1327,18 @@ gem_start_locked(struct ifnet *ifp)
|
|||||||
IFQ_DRV_PREPEND(&ifp->if_snd, m);
|
IFQ_DRV_PREPEND(&ifp->if_snd, m);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if ((sc->sc_txnext % 4) == 0) {
|
||||||
|
gem_txkick(sc);
|
||||||
|
kicked = 1;
|
||||||
|
} else
|
||||||
|
kicked = 0;
|
||||||
ntx++;
|
ntx++;
|
||||||
/* Kick the transmitter. */
|
|
||||||
#ifdef GEM_DEBUG
|
|
||||||
CTR3(KTR_GEM, "%s: %s: kicking TX %d",
|
|
||||||
device_get_name(sc->sc_dev), __func__, sc->sc_txnext);
|
|
||||||
#endif
|
|
||||||
GEM_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
|
||||||
GEM_BANK1_WRITE_4(sc, GEM_TX_KICK, sc->sc_txnext);
|
|
||||||
|
|
||||||
BPF_MTAP(ifp, m);
|
BPF_MTAP(ifp, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ntx > 0) {
|
if (ntx > 0) {
|
||||||
|
if (kicked == 0)
|
||||||
|
gem_txkick(sc);
|
||||||
#ifdef GEM_DEBUG
|
#ifdef GEM_DEBUG
|
||||||
CTR2(KTR_GEM, "%s: packets enqueued, OWN on %d",
|
CTR2(KTR_GEM, "%s: packets enqueued, OWN on %d",
|
||||||
device_get_name(sc->sc_dev), sc->sc_txnext);
|
device_get_name(sc->sc_dev), sc->sc_txnext);
|
||||||
@ -1324,10 +1359,13 @@ gem_tint(struct gem_softc *sc)
|
|||||||
{
|
{
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
struct ifnet *ifp = sc->sc_ifp;
|
||||||
struct gem_txsoft *txs;
|
struct gem_txsoft *txs;
|
||||||
int txlast, progress;
|
int progress;
|
||||||
|
uint32_t txlast;
|
||||||
#ifdef GEM_DEBUG
|
#ifdef GEM_DEBUG
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
||||||
|
|
||||||
CTR2(KTR_GEM, "%s: %s", device_get_name(sc->sc_dev), __func__);
|
CTR2(KTR_GEM, "%s: %s", device_get_name(sc->sc_dev), __func__);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1338,7 +1376,6 @@ gem_tint(struct gem_softc *sc)
|
|||||||
progress = 0;
|
progress = 0;
|
||||||
GEM_CDSYNC(sc, BUS_DMASYNC_POSTREAD);
|
GEM_CDSYNC(sc, BUS_DMASYNC_POSTREAD);
|
||||||
while ((txs = STAILQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
|
while ((txs = STAILQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
|
||||||
|
|
||||||
#ifdef GEM_DEBUG
|
#ifdef GEM_DEBUG
|
||||||
if ((ifp->if_flags & IFF_DEBUG) != 0) {
|
if ((ifp->if_flags & IFF_DEBUG) != 0) {
|
||||||
printf(" txsoft %p transmit chain:\n", txs);
|
printf(" txsoft %p transmit chain:\n", txs);
|
||||||
@ -1419,8 +1456,8 @@ gem_tint(struct gem_softc *sc)
|
|||||||
* and restart.
|
* and restart.
|
||||||
*/
|
*/
|
||||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||||
sc->sc_wdog_timer = STAILQ_EMPTY(&sc->sc_txdirtyq) ? 0 : 5;
|
if (STAILQ_EMPTY(&sc->sc_txdirtyq))
|
||||||
|
sc->sc_wdog_timer = 0;
|
||||||
gem_start_locked(ifp);
|
gem_start_locked(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1437,6 +1474,7 @@ gem_rint_timeout(void *arg)
|
|||||||
struct gem_softc *sc = arg;
|
struct gem_softc *sc = arg;
|
||||||
|
|
||||||
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
||||||
|
|
||||||
gem_rint(sc);
|
gem_rint(sc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1449,6 +1487,8 @@ gem_rint(struct gem_softc *sc)
|
|||||||
uint64_t rxstat;
|
uint64_t rxstat;
|
||||||
uint32_t rxcomp;
|
uint32_t rxcomp;
|
||||||
|
|
||||||
|
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
||||||
|
|
||||||
#ifdef GEM_RINT_TIMEOUT
|
#ifdef GEM_RINT_TIMEOUT
|
||||||
callout_stop(&sc->sc_rx_ch);
|
callout_stop(&sc->sc_rx_ch);
|
||||||
#endif
|
#endif
|
||||||
@ -1461,12 +1501,11 @@ gem_rint(struct gem_softc *sc)
|
|||||||
* how long the following loop can execute.
|
* how long the following loop can execute.
|
||||||
*/
|
*/
|
||||||
rxcomp = GEM_BANK1_READ_4(sc, GEM_RX_COMPLETION);
|
rxcomp = GEM_BANK1_READ_4(sc, GEM_RX_COMPLETION);
|
||||||
|
|
||||||
#ifdef GEM_DEBUG
|
#ifdef GEM_DEBUG
|
||||||
CTR3(KTR_GEM, "%s: sc->rxptr %d, complete %d",
|
CTR3(KTR_GEM, "%s: sc->sc_rxptr %d, complete %d",
|
||||||
__func__, sc->sc_rxptr, rxcomp);
|
__func__, sc->sc_rxptr, rxcomp);
|
||||||
#endif
|
#endif
|
||||||
GEM_CDSYNC(sc, BUS_DMASYNC_POSTREAD);
|
GEM_CDSYNC(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
||||||
for (; sc->sc_rxptr != rxcomp;) {
|
for (; sc->sc_rxptr != rxcomp;) {
|
||||||
m = sc->sc_rxsoft[sc->sc_rxptr].rxs_mbuf;
|
m = sc->sc_rxsoft[sc->sc_rxptr].rxs_mbuf;
|
||||||
rxstat = GEM_DMA_READ(sc,
|
rxstat = GEM_DMA_READ(sc,
|
||||||
@ -1525,9 +1564,9 @@ gem_rint(struct gem_softc *sc)
|
|||||||
/*
|
/*
|
||||||
* Update the RX kick register. This register has to point
|
* Update the RX kick register. This register has to point
|
||||||
* to the descriptor after the last valid one (before the
|
* to the descriptor after the last valid one (before the
|
||||||
* current batch) and must be incremented in multiples of
|
* current batch) and for optimum performance should be
|
||||||
* 4 (because the DMA engine fetches/updates descriptors
|
* incremented in multiples of 4 (the DMA engine fetches/
|
||||||
* in batches of 4).
|
* updates descriptors in batches of 4).
|
||||||
*/
|
*/
|
||||||
sc->sc_rxptr = GEM_NEXTRX(sc->sc_rxptr);
|
sc->sc_rxptr = GEM_NEXTRX(sc->sc_rxptr);
|
||||||
if ((sc->sc_rxptr % 4) == 0) {
|
if ((sc->sc_rxptr % 4) == 0) {
|
||||||
@ -1545,7 +1584,7 @@ gem_rint(struct gem_softc *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ifp->if_ipackets++;
|
ifp->if_ipackets++;
|
||||||
m->m_data += 2; /* We're already off by two */
|
m->m_data += ETHER_ALIGN; /* first byte offset */
|
||||||
m->m_pkthdr.rcvif = ifp;
|
m->m_pkthdr.rcvif = ifp;
|
||||||
m->m_pkthdr.len = m->m_len = GEM_RD_BUFLEN(rxstat);
|
m->m_pkthdr.len = m->m_len = GEM_RD_BUFLEN(rxstat);
|
||||||
|
|
||||||
@ -1559,7 +1598,7 @@ gem_rint(struct gem_softc *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GEM_DEBUG
|
#ifdef GEM_DEBUG
|
||||||
CTR3(KTR_GEM, "%s: done sc->rxptr %d, complete %d", __func__,
|
CTR3(KTR_GEM, "%s: done sc->sc_rxptr %d, complete %d", __func__,
|
||||||
sc->sc_rxptr, GEM_BANK1_READ_4(sc, GEM_RX_COMPLETION));
|
sc->sc_rxptr, GEM_BANK1_READ_4(sc, GEM_RX_COMPLETION));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -1572,6 +1611,8 @@ gem_add_rxbuf(struct gem_softc *sc, int idx)
|
|||||||
bus_dma_segment_t segs[1];
|
bus_dma_segment_t segs[1];
|
||||||
int error, nsegs;
|
int error, nsegs;
|
||||||
|
|
||||||
|
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
||||||
|
|
||||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return (ENOBUFS);
|
return (ENOBUFS);
|
||||||
@ -1620,7 +1661,15 @@ gem_eint(struct gem_softc *sc, u_int status)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_printf(sc->sc_dev, "%s: status=%x\n", __func__, status);
|
device_printf(sc->sc_dev, "%s: status 0x%x", __func__, status);
|
||||||
|
if ((status & GEM_INTR_BERR) != 0) {
|
||||||
|
if ((sc->sc_flags & GEM_PCI) != 0)
|
||||||
|
printf(", PCI bus error 0x%x\n",
|
||||||
|
GEM_BANK1_READ_4(sc, GEM_PCI_ERROR_STATUS));
|
||||||
|
else
|
||||||
|
printf(", SBus error 0x%x\n",
|
||||||
|
GEM_BANK1_READ_4(sc, GEM_SBUS_STATUS));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1634,8 +1683,8 @@ gem_intr(void *v)
|
|||||||
|
|
||||||
#ifdef GEM_DEBUG
|
#ifdef GEM_DEBUG
|
||||||
CTR4(KTR_GEM, "%s: %s: cplt %x, status %x",
|
CTR4(KTR_GEM, "%s: %s: cplt %x, status %x",
|
||||||
device_get_name(sc->sc_dev), __func__, (status >> 19),
|
device_get_name(sc->sc_dev), __func__,
|
||||||
(u_int)status);
|
(status >> GEM_STATUS_TX_COMPLETION_SHFT), (u_int)status);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PCS interrupts must be cleared, otherwise no traffic is passed!
|
* PCS interrupts must be cleared, otherwise no traffic is passed!
|
||||||
@ -1665,7 +1714,7 @@ gem_intr(void *v)
|
|||||||
device_printf(sc->sc_dev, "%s: MIF interrupt\n", __func__);
|
device_printf(sc->sc_dev, "%s: MIF interrupt\n", __func__);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((status &
|
if (__predict_false(status &
|
||||||
(GEM_INTR_RX_TAG_ERR | GEM_INTR_PERR | GEM_INTR_BERR)) != 0)
|
(GEM_INTR_RX_TAG_ERR | GEM_INTR_PERR | GEM_INTR_BERR)) != 0)
|
||||||
gem_eint(sc, status);
|
gem_eint(sc, status);
|
||||||
|
|
||||||
@ -1675,17 +1724,20 @@ gem_intr(void *v)
|
|||||||
if ((status & (GEM_INTR_TX_EMPTY | GEM_INTR_TX_INTME)) != 0)
|
if ((status & (GEM_INTR_TX_EMPTY | GEM_INTR_TX_INTME)) != 0)
|
||||||
gem_tint(sc);
|
gem_tint(sc);
|
||||||
|
|
||||||
if (status & GEM_INTR_TX_MAC) {
|
if (__predict_false((status & GEM_INTR_TX_MAC) != 0)) {
|
||||||
status2 = GEM_BANK1_READ_4(sc, GEM_MAC_TX_STATUS);
|
status2 = GEM_BANK1_READ_4(sc, GEM_MAC_TX_STATUS);
|
||||||
if ((status2 &
|
if ((status2 &
|
||||||
~(GEM_MAC_TX_XMIT_DONE | GEM_MAC_TX_DEFER_EXP)) != 0)
|
~(GEM_MAC_TX_XMIT_DONE | GEM_MAC_TX_DEFER_EXP |
|
||||||
|
GEM_MAC_TX_PEAK_EXP)) != 0)
|
||||||
device_printf(sc->sc_dev,
|
device_printf(sc->sc_dev,
|
||||||
"MAC TX fault, status %x\n", status2);
|
"MAC TX fault, status %x\n", status2);
|
||||||
if ((status2 &
|
if ((status2 &
|
||||||
(GEM_MAC_TX_UNDERRUN | GEM_MAC_TX_PKT_TOO_LONG)) != 0)
|
(GEM_MAC_TX_UNDERRUN | GEM_MAC_TX_PKT_TOO_LONG)) != 0) {
|
||||||
|
sc->sc_ifp->if_oerrors++;
|
||||||
gem_init_locked(sc);
|
gem_init_locked(sc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (status & GEM_INTR_RX_MAC) {
|
if (__predict_false((status & GEM_INTR_RX_MAC) != 0)) {
|
||||||
status2 = GEM_BANK1_READ_4(sc, GEM_MAC_RX_STATUS);
|
status2 = GEM_BANK1_READ_4(sc, GEM_MAC_RX_STATUS);
|
||||||
/*
|
/*
|
||||||
* At least with GEM_SUN_GEM and some GEM_SUN_ERI
|
* At least with GEM_SUN_GEM and some GEM_SUN_ERI
|
||||||
@ -1906,6 +1958,8 @@ gem_mii_statchg(device_t dev)
|
|||||||
|
|
||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
|
|
||||||
|
GEM_LOCK_ASSERT(sc, MA_OWNED);
|
||||||
|
|
||||||
#ifdef GEM_DEBUG
|
#ifdef GEM_DEBUG
|
||||||
if ((sc->sc_ifp->if_flags & IFF_DEBUG) != 0)
|
if ((sc->sc_ifp->if_flags & IFF_DEBUG) != 0)
|
||||||
device_printf(sc->sc_dev, "%s: status change: PHY = %d\n",
|
device_printf(sc->sc_dev, "%s: status change: PHY = %d\n",
|
||||||
@ -1985,7 +2039,7 @@ gem_mii_statchg(device_t dev)
|
|||||||
if ((GEM_BANK1_READ_4(sc, GEM_MIF_CONFIG) &
|
if ((GEM_BANK1_READ_4(sc, GEM_MIF_CONFIG) &
|
||||||
GEM_MIF_CONFIG_PHY_SEL) != 0) {
|
GEM_MIF_CONFIG_PHY_SEL) != 0) {
|
||||||
/* External MII needs echo disable if half duplex. */
|
/* External MII needs echo disable if half duplex. */
|
||||||
if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) &
|
if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) &
|
||||||
IFM_FDX) == 0)
|
IFM_FDX) == 0)
|
||||||
v |= GEM_MAC_XIF_ECHO_DISABL;
|
v |= GEM_MAC_XIF_ECHO_DISABL;
|
||||||
} else
|
} else
|
||||||
@ -2053,6 +2107,11 @@ gem_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCSIFFLAGS:
|
case SIOCSIFFLAGS:
|
||||||
GEM_LOCK(sc);
|
GEM_LOCK(sc);
|
||||||
|
if ((sc->sc_flags & GEM_DYING) != 0) {
|
||||||
|
error = EINVAL;
|
||||||
|
GEM_UNLOCK(sc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if ((ifp->if_flags & IFF_UP) != 0) {
|
if ((ifp->if_flags & IFF_UP) != 0) {
|
||||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
|
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
|
||||||
((ifp->if_flags ^ sc->sc_ifflags) &
|
((ifp->if_flags ^ sc->sc_ifflags) &
|
||||||
|
@ -90,7 +90,7 @@ static device_method_t gem_pci_methods[] = {
|
|||||||
DEVMETHOD(miibus_writereg, gem_mii_writereg),
|
DEVMETHOD(miibus_writereg, gem_mii_writereg),
|
||||||
DEVMETHOD(miibus_statchg, gem_mii_statchg),
|
DEVMETHOD(miibus_statchg, gem_mii_statchg),
|
||||||
|
|
||||||
{ 0, 0 }
|
KOBJMETHOD_END
|
||||||
};
|
};
|
||||||
|
|
||||||
static driver_t gem_pci_driver = {
|
static driver_t gem_pci_driver = {
|
||||||
@ -107,7 +107,7 @@ static const struct gem_pci_dev {
|
|||||||
uint32_t gpd_devid;
|
uint32_t gpd_devid;
|
||||||
int gpd_variant;
|
int gpd_variant;
|
||||||
const char *gpd_desc;
|
const char *gpd_desc;
|
||||||
} gem_pci_devlist[] = {
|
} const gem_pci_devlist[] = {
|
||||||
{ 0x1101108e, GEM_SUN_ERI, "Sun ERI 10/100 Ethernet" },
|
{ 0x1101108e, GEM_SUN_ERI, "Sun ERI 10/100 Ethernet" },
|
||||||
{ 0x2bad108e, GEM_SUN_GEM, "Sun GEM Gigabit Ethernet" },
|
{ 0x2bad108e, GEM_SUN_GEM, "Sun GEM Gigabit Ethernet" },
|
||||||
{ 0x0021106b, GEM_APPLE_GMAC, "Apple UniNorth GMAC Ethernet" },
|
{ 0x0021106b, GEM_APPLE_GMAC, "Apple UniNorth GMAC Ethernet" },
|
||||||
@ -200,13 +200,18 @@ gem_pci_attach(device_t dev)
|
|||||||
GEM_PCI_BANK2_OFFSET, GEM_PCI_BANK2_SIZE,
|
GEM_PCI_BANK2_OFFSET, GEM_PCI_BANK2_SIZE,
|
||||||
&sc->sc_res[GEM_RES_BANK2]->r_bushandle);
|
&sc->sc_res[GEM_RES_BANK2]->r_bushandle);
|
||||||
|
|
||||||
|
/* Determine whether we're running at 66MHz. */
|
||||||
|
if ((GEM_BANK2_READ_4(sc, GEM_PCI_BIF_CONFIG) &
|
||||||
|
GEM_PCI_BIF_CNF_M66EN) != 0)
|
||||||
|
sc->sc_flags |= GEM_PCI66;
|
||||||
|
|
||||||
#if defined(__powerpc__) || defined(__sparc64__)
|
#if defined(__powerpc__) || defined(__sparc64__)
|
||||||
OF_getetheraddr(dev, sc->sc_enaddr);
|
OF_getetheraddr(dev, sc->sc_enaddr);
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* Dig out VPD (vital product data) and read NA (network address).
|
* Dig out VPD (vital product data) and read NA (network address).
|
||||||
* The VPD of GEM resides in the PCI Expansion ROM (PCI FCode) and
|
* The VPD resides in the PCI Expansion ROM (PCI FCode) and can't
|
||||||
* can't be accessed via the PCI capability pointer.
|
* be accessed via the PCI capability pointer.
|
||||||
* ``Writing FCode 3.x Programs'' (newer ones, dated 1997 and later)
|
* ``Writing FCode 3.x Programs'' (newer ones, dated 1997 and later)
|
||||||
* chapter 2 describes the data structure.
|
* chapter 2 describes the data structure.
|
||||||
*/
|
*/
|
||||||
@ -225,22 +230,21 @@ gem_pci_attach(device_t dev)
|
|||||||
#define PCI_VPDRES_BYTE0 0x00
|
#define PCI_VPDRES_BYTE0 0x00
|
||||||
#define PCI_VPDRES_ISLARGE(x) ((x) & 0x80)
|
#define PCI_VPDRES_ISLARGE(x) ((x) & 0x80)
|
||||||
#define PCI_VPDRES_LARGE_NAME(x) ((x) & 0x7f)
|
#define PCI_VPDRES_LARGE_NAME(x) ((x) & 0x7f)
|
||||||
#define PCI_VPDRES_TYPE_VPD 0x10 /* large */
|
|
||||||
#define PCI_VPDRES_LARGE_LEN_LSB 0x01
|
#define PCI_VPDRES_LARGE_LEN_LSB 0x01
|
||||||
#define PCI_VPDRES_LARGE_LEN_MSB 0x02
|
#define PCI_VPDRES_LARGE_LEN_MSB 0x02
|
||||||
#define PCI_VPDRES_LARGE_DATA 0x03
|
#define PCI_VPDRES_LARGE_SIZE 0x03
|
||||||
#define PCI_VPD_SIZE 0x03
|
#define PCI_VPDRES_TYPE_VPD 0x10 /* large */
|
||||||
#define PCI_VPD_KEY0 0x00
|
#define PCI_VPD_KEY0 0x00
|
||||||
#define PCI_VPD_KEY1 0x01
|
#define PCI_VPD_KEY1 0x01
|
||||||
#define PCI_VPD_LEN 0x02
|
#define PCI_VPD_LEN 0x02
|
||||||
#define PCI_VPD_DATA 0x03
|
#define PCI_VPD_SIZE 0x03
|
||||||
|
|
||||||
#define GEM_ROM_READ_1(sc, offs) \
|
#define GEM_ROM_READ_1(sc, offs) \
|
||||||
GEM_BANK1_READ_1((sc), GEM_PCI_ROM_OFFSET + (offs))
|
GEM_BANK1_READ_1((sc), GEM_PCI_ROM_OFFSET + (offs))
|
||||||
#define GEM_ROM_READ_2(sc, offs) \
|
#define GEM_ROM_READ_2(sc, offs) \
|
||||||
GEM_BANK1_READ_2((sc), GEM_PCI_ROM_OFFSET + (offs))
|
GEM_BANK1_READ_2((sc), GEM_PCI_ROM_OFFSET + (offs))
|
||||||
#define GEM_ROM_READ_4(sc, offs) \
|
#define GEM_ROM_READ_4(sc, offs) \
|
||||||
GEM_BANK1_READ_4((sc), GEM_PCI_ROM_OFFSET + (offs))
|
GEM_BANK1_READ_4((sc), GEM_PCI_ROM_OFFSET + (offs))
|
||||||
|
|
||||||
/* Read PCI Expansion ROM header. */
|
/* Read PCI Expansion ROM header. */
|
||||||
if (GEM_ROM_READ_2(sc, PCI_ROMHDR_SIG) != PCI_ROMHDR_SIG_MAGIC ||
|
if (GEM_ROM_READ_2(sc, PCI_ROMHDR_SIG) != PCI_ROMHDR_SIG_MAGIC ||
|
||||||
@ -273,22 +277,22 @@ gem_pci_attach(device_t dev)
|
|||||||
j + PCI_VPDRES_BYTE0)) == 0 ||
|
j + PCI_VPDRES_BYTE0)) == 0 ||
|
||||||
PCI_VPDRES_LARGE_NAME(GEM_ROM_READ_1(sc,
|
PCI_VPDRES_LARGE_NAME(GEM_ROM_READ_1(sc,
|
||||||
j + PCI_VPDRES_BYTE0)) != PCI_VPDRES_TYPE_VPD ||
|
j + PCI_VPDRES_BYTE0)) != PCI_VPDRES_TYPE_VPD ||
|
||||||
(GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_LSB) << 8 |
|
((GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_LSB) << 8) |
|
||||||
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_MSB)) !=
|
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_MSB)) !=
|
||||||
PCI_VPD_SIZE + ETHER_ADDR_LEN ||
|
PCI_VPD_SIZE + ETHER_ADDR_LEN ||
|
||||||
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_KEY0) !=
|
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_KEY0) !=
|
||||||
0x4e /* N */ ||
|
0x4e /* N */ ||
|
||||||
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_KEY1) !=
|
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_KEY1) !=
|
||||||
0x41 /* A */ ||
|
0x41 /* A */ ||
|
||||||
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_LEN) !=
|
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_LEN) !=
|
||||||
ETHER_ADDR_LEN ||
|
ETHER_ADDR_LEN ||
|
||||||
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_DATA +
|
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_SIZE +
|
||||||
ETHER_ADDR_LEN) != 0x79) {
|
ETHER_ADDR_LEN) != 0x79) {
|
||||||
device_printf(dev, "unexpected PCI VPD\n");
|
device_printf(dev, "unexpected PCI VPD\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
bus_read_region_1(sc->sc_res[GEM_RES_BANK1],
|
bus_read_region_1(sc->sc_res[GEM_RES_BANK1],
|
||||||
GEM_PCI_ROM_OFFSET + j + PCI_VPDRES_LARGE_DATA + PCI_VPD_DATA,
|
GEM_PCI_ROM_OFFSET + j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_SIZE,
|
||||||
sc->sc_enaddr, ETHER_ADDR_LEN);
|
sc->sc_enaddr, ETHER_ADDR_LEN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -330,19 +334,15 @@ gem_pci_detach(device_t dev)
|
|||||||
static int
|
static int
|
||||||
gem_pci_suspend(device_t dev)
|
gem_pci_suspend(device_t dev)
|
||||||
{
|
{
|
||||||
struct gem_softc *sc;
|
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
gem_suspend(device_get_softc(dev));
|
||||||
gem_suspend(sc);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gem_pci_resume(device_t dev)
|
gem_pci_resume(device_t dev)
|
||||||
{
|
{
|
||||||
struct gem_softc *sc;
|
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
gem_resume(device_get_softc(dev));
|
||||||
gem_resume(sc);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
210
sys/dev/gem/if_gem_sbus.c
Normal file
210
sys/dev/gem/if_gem_sbus.c
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (C) 2001 Eduardo Horvath.
|
||||||
|
* Copyright (c) 2007 Marius Strobl <marius@FreeBSD.org>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* from: NetBSD: if_gem_pci.c,v 1.7 2001/10/18 15:09:15 thorpej Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SBus bindings for Sun GEM Ethernet controllers
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/bus.h>
|
||||||
|
#include <sys/kernel.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
|
#include <sys/module.h>
|
||||||
|
#include <sys/mutex.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <sys/rman.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <net/ethernet.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#include <dev/ofw/ofw_bus.h>
|
||||||
|
|
||||||
|
#include <machine/bus.h>
|
||||||
|
#include <machine/ofw_machdep.h>
|
||||||
|
#include <machine/resource.h>
|
||||||
|
|
||||||
|
#include <sparc64/sbus/sbusvar.h>
|
||||||
|
|
||||||
|
#include <dev/gem/if_gemreg.h>
|
||||||
|
#include <dev/gem/if_gemvar.h>
|
||||||
|
|
||||||
|
#include "miibus_if.h"
|
||||||
|
|
||||||
|
static device_probe_t gem_sbus_probe;
|
||||||
|
static device_attach_t gem_sbus_attach;
|
||||||
|
static device_detach_t gem_sbus_detach;
|
||||||
|
static device_suspend_t gem_sbus_suspend;
|
||||||
|
static device_resume_t gem_sbus_resume;
|
||||||
|
|
||||||
|
static device_method_t gem_sbus_methods[] = {
|
||||||
|
/* Device interface */
|
||||||
|
DEVMETHOD(device_probe, gem_sbus_probe),
|
||||||
|
DEVMETHOD(device_attach, gem_sbus_attach),
|
||||||
|
DEVMETHOD(device_detach, gem_sbus_detach),
|
||||||
|
DEVMETHOD(device_suspend, gem_sbus_suspend),
|
||||||
|
DEVMETHOD(device_resume, gem_sbus_resume),
|
||||||
|
/* Use the suspend handler here, it is all that is required. */
|
||||||
|
DEVMETHOD(device_shutdown, gem_sbus_suspend),
|
||||||
|
|
||||||
|
/* bus interface */
|
||||||
|
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||||
|
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
||||||
|
|
||||||
|
/* MII interface */
|
||||||
|
DEVMETHOD(miibus_readreg, gem_mii_readreg),
|
||||||
|
DEVMETHOD(miibus_writereg, gem_mii_writereg),
|
||||||
|
DEVMETHOD(miibus_statchg, gem_mii_statchg),
|
||||||
|
|
||||||
|
KOBJMETHOD_END
|
||||||
|
};
|
||||||
|
|
||||||
|
static driver_t gem_sbus_driver = {
|
||||||
|
"gem",
|
||||||
|
gem_sbus_methods,
|
||||||
|
sizeof(struct gem_softc)
|
||||||
|
};
|
||||||
|
|
||||||
|
DRIVER_MODULE(gem, sbus, gem_sbus_driver, gem_devclass, 0, 0);
|
||||||
|
MODULE_DEPEND(gem, sbus, 1, 1, 1);
|
||||||
|
MODULE_DEPEND(gem, ether, 1, 1, 1);
|
||||||
|
|
||||||
|
static int
|
||||||
|
gem_sbus_probe(device_t dev)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (strcmp(ofw_bus_get_name(dev), "network") == 0 &&
|
||||||
|
ofw_bus_get_compat(dev) != NULL &&
|
||||||
|
strcmp(ofw_bus_get_compat(dev), "SUNW,sbus-gem") == 0) {
|
||||||
|
device_set_desc(dev, "Sun GEM Gigabit Ethernet");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ENXIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct resource_spec gem_sbus_res_spec[] = {
|
||||||
|
{ SYS_RES_IRQ, 0, RF_SHAREABLE | RF_ACTIVE }, /* GEM_RES_INTR */
|
||||||
|
{ SYS_RES_MEMORY, 1, RF_ACTIVE }, /* GEM_RES_BANK1 */
|
||||||
|
{ SYS_RES_MEMORY, 0, RF_ACTIVE }, /* GEM_RES_BANK2 */
|
||||||
|
{ -1, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
gem_sbus_attach(device_t dev)
|
||||||
|
{
|
||||||
|
struct gem_softc *sc;
|
||||||
|
int burst;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
sc = device_get_softc(dev);
|
||||||
|
sc->sc_variant = GEM_SUN_GEM;
|
||||||
|
sc->sc_dev = dev;
|
||||||
|
|
||||||
|
if (bus_alloc_resources(dev, gem_sbus_res_spec, sc->sc_res)) {
|
||||||
|
device_printf(dev, "failed to allocate resources\n");
|
||||||
|
bus_release_resources(dev, gem_sbus_res_spec, sc->sc_res);
|
||||||
|
return (ENXIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
GEM_LOCK_INIT(sc, device_get_nameunit(dev));
|
||||||
|
|
||||||
|
OF_getetheraddr(dev, sc->sc_enaddr);
|
||||||
|
|
||||||
|
burst = sbus_get_burstsz(dev);
|
||||||
|
val = GEM_SBUS_CFG_PARITY;
|
||||||
|
if ((burst & SBUS_BURST64_MASK) != 0) {
|
||||||
|
val |= GEM_SBUS_CFG_64BIT;
|
||||||
|
burst >>= SBUS_BURST64_SHIFT;
|
||||||
|
}
|
||||||
|
if ((burst & SBUS_BURST_64) != 0)
|
||||||
|
val |= GEM_SBUS_CFG_BURST_64;
|
||||||
|
else if ((burst & SBUS_BURST_32) != 0)
|
||||||
|
val |= GEM_SBUS_CFG_BURST_32;
|
||||||
|
else {
|
||||||
|
device_printf(dev, "unsupported burst size\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
/* Reset the SBus interface only. */
|
||||||
|
(void)GEM_BANK2_READ_4(sc, GEM_SBUS_BIF_RESET);
|
||||||
|
DELAY(100);
|
||||||
|
GEM_BANK2_WRITE_4(sc, GEM_SBUS_CONFIG, val);
|
||||||
|
|
||||||
|
if (gem_attach(sc) != 0) {
|
||||||
|
device_printf(dev, "could not be attached\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bus_setup_intr(dev, sc->sc_res[GEM_RES_INTR], INTR_TYPE_NET |
|
||||||
|
INTR_MPSAFE, NULL, gem_intr, sc, &sc->sc_ih) != 0) {
|
||||||
|
device_printf(dev, "failed to set up interrupt\n");
|
||||||
|
gem_detach(sc);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
GEM_LOCK_DESTROY(sc);
|
||||||
|
bus_release_resources(dev, gem_sbus_res_spec, sc->sc_res);
|
||||||
|
return (ENXIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gem_sbus_detach(device_t dev)
|
||||||
|
{
|
||||||
|
struct gem_softc *sc;
|
||||||
|
|
||||||
|
sc = device_get_softc(dev);
|
||||||
|
bus_teardown_intr(dev, sc->sc_res[GEM_RES_INTR], sc->sc_ih);
|
||||||
|
gem_detach(sc);
|
||||||
|
GEM_LOCK_DESTROY(sc);
|
||||||
|
bus_release_resources(dev, gem_sbus_res_spec, sc->sc_res);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gem_sbus_suspend(device_t dev)
|
||||||
|
{
|
||||||
|
|
||||||
|
gem_suspend(device_get_softc(dev));
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gem_sbus_resume(device_t dev)
|
||||||
|
{
|
||||||
|
|
||||||
|
gem_resume(device_get_softc(dev));
|
||||||
|
return (0);
|
||||||
|
}
|
@ -32,7 +32,7 @@
|
|||||||
#ifndef _IF_GEMREG_H
|
#ifndef _IF_GEMREG_H
|
||||||
#define _IF_GEMREG_H
|
#define _IF_GEMREG_H
|
||||||
|
|
||||||
/* Register definitions for Sun GEM gigabit ethernet */
|
/* register definitions for Apple GMAC, Sun ERI and Sun GEM */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First bank: this registers live at the start of the PCI
|
* First bank: this registers live at the start of the PCI
|
||||||
@ -47,6 +47,51 @@
|
|||||||
#define GEM_INTACK 0x0014 /* Interrupt acknowledge, W/O */
|
#define GEM_INTACK 0x0014 /* Interrupt acknowledge, W/O */
|
||||||
#define GEM_STATUS_ALIAS 0x001c
|
#define GEM_STATUS_ALIAS 0x001c
|
||||||
|
|
||||||
|
/* Bits in GEM_SEB register */
|
||||||
|
#define GEM_SEB_ARB 0x00000002 /* Arbitration status */
|
||||||
|
#define GEM_SEB_RXWON 0x00000004
|
||||||
|
|
||||||
|
/* Bits in GEM_CONFIG register */
|
||||||
|
#define GEM_CONFIG_BURST_64 0x00000000 /* maximum burst size 64KB */
|
||||||
|
#define GEM_CONFIG_BURST_INF 0x00000001 /* infinite for entire packet */
|
||||||
|
#define GEM_CONFIG_TXDMA_LIMIT 0x0000003e
|
||||||
|
#define GEM_CONFIG_RXDMA_LIMIT 0x000007c0
|
||||||
|
/* GEM_CONFIG_RONPAULBIT and GEM_CONFIG_BUG2FIX are Apple only. */
|
||||||
|
#define GEM_CONFIG_RONPAULBIT 0x00000800 /* after infinite burst use */
|
||||||
|
/* memory read multiple for */
|
||||||
|
/* PCI commands */
|
||||||
|
#define GEM_CONFIG_BUG2FIX 0x00001000 /* fix RX hang after overflow */
|
||||||
|
|
||||||
|
#define GEM_CONFIG_TXDMA_LIMIT_SHIFT 1
|
||||||
|
#define GEM_CONFIG_RXDMA_LIMIT_SHIFT 6
|
||||||
|
|
||||||
|
/* Top part of GEM_STATUS has TX completion information */
|
||||||
|
#define GEM_STATUS_TX_COMPLETION_MASK 0xfff80000 /* TX completion reg. */
|
||||||
|
#define GEM_STATUS_TX_COMPLETION_SHFT 19
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt bits, for both the GEM_STATUS and GEM_INTMASK regs
|
||||||
|
* Bits 0-6 auto-clear when read.
|
||||||
|
*/
|
||||||
|
#define GEM_INTR_TX_INTME 0x00000001 /* Frame w/INTME bit set sent */
|
||||||
|
#define GEM_INTR_TX_EMPTY 0x00000002 /* TX ring empty */
|
||||||
|
#define GEM_INTR_TX_DONE 0x00000004 /* TX complete */
|
||||||
|
#define GEM_INTR_RX_DONE 0x00000010 /* Got a packet */
|
||||||
|
#define GEM_INTR_RX_NOBUF 0x00000020
|
||||||
|
#define GEM_INTR_RX_TAG_ERR 0x00000040
|
||||||
|
#define GEM_INTR_PERR 0x00000080 /* Parity error */
|
||||||
|
#define GEM_INTR_PCS 0x00002000 /* Physical Code Sub-layer */
|
||||||
|
#define GEM_INTR_TX_MAC 0x00004000
|
||||||
|
#define GEM_INTR_RX_MAC 0x00008000
|
||||||
|
#define GEM_INTR_MAC_CONTROL 0x00010000 /* MAC control interrupt */
|
||||||
|
#define GEM_INTR_MIF 0x00020000
|
||||||
|
#define GEM_INTR_BERR 0x00040000 /* Bus error interrupt */
|
||||||
|
#define GEM_INTR_BITS "\177\020" \
|
||||||
|
"b\0INTME\0b\1TXEMPTY\0b\2TXDONE\0" \
|
||||||
|
"b\4RXDONE\0b\5RXNOBUF\0b\6RX_TAG_ERR\0" \
|
||||||
|
"b\xdPCS\0b\xeTXMAC\0b\xfRXMAC\0" \
|
||||||
|
"b\x10MAC_CONTROL\0b\x11MIF\0b\x12IBERR\0\0"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Second bank: this registers live at offset 0x1000 of the PCI
|
* Second bank: this registers live at offset 0x1000 of the PCI
|
||||||
* mapping, and at the start of the first bank of the SBus
|
* mapping, and at the start of the first bank of the SBus
|
||||||
@ -55,89 +100,57 @@
|
|||||||
#define GEM_PCI_BANK2_OFFSET 0x1000
|
#define GEM_PCI_BANK2_OFFSET 0x1000
|
||||||
#define GEM_PCI_BANK2_SIZE 0x14
|
#define GEM_PCI_BANK2_SIZE 0x14
|
||||||
/* This is the same as the GEM_STATUS reg but reading it does not clear bits. */
|
/* This is the same as the GEM_STATUS reg but reading it does not clear bits. */
|
||||||
#define GEM_ERROR_STATUS 0x0000 /* PCI error status R/C */
|
#define GEM_PCI_ERROR_STATUS 0x0000 /* PCI error status */
|
||||||
#define GEM_ERROR_MASK 0x0004
|
#define GEM_PCI_ERROR_MASK 0x0004 /* PCI error mask */
|
||||||
#define GEM_SBUS_CONFIG 0x0004
|
#define GEM_PCI_BIF_CONFIG 0x0008 /* PCI BIF configuration */
|
||||||
#define GEM_BIF_CONFIG 0x0008 /* BIF config reg */
|
#define GEM_PCI_BIF_DIAG 0x000c /* PCI BIF diagnostic */
|
||||||
#define GEM_BIF_DIAG 0x000c
|
|
||||||
#define GEM_RESET 0x0010 /* Software reset register */
|
|
||||||
|
|
||||||
|
#define GEM_SBUS_BIF_RESET 0x0000 /* SBus BIF only software reset */
|
||||||
|
#define GEM_SBUS_CONFIG 0x0004 /* SBus IO configuration */
|
||||||
|
#define GEM_SBUS_STATUS 0x0008 /* SBus IO status */
|
||||||
|
#define GEM_SBUS_REVISION 0x000c /* SBus revision ID */
|
||||||
|
|
||||||
/* Bits in GEM_SEB register */
|
#define GEM_RESET 0x0010 /* software reset */
|
||||||
#define GEM_SEB_ARB 0x000000002 /* Arbitration status */
|
|
||||||
#define GEM_SEB_RXWON 0x000000004
|
|
||||||
|
|
||||||
/* Bits in GEM_SBUS_CONFIG register */
|
/* GEM_PCI_ERROR_STATUS and GEM_PCI_ERROR_MASK error bits */
|
||||||
#define GEM_SBUS_CFG_BMODE64 0x00000008
|
#define GEM_PCI_ERR_STAT_BADACK 0x00000001 /* No ACK64# */
|
||||||
#define GEM_SBUS_CFG_PARITY 0x00000200
|
#define GEM_PCI_ERR_STAT_DTRTO 0x00000002 /* Delayed xaction timeout */
|
||||||
|
#define GEM_PCI_ERR_STAT_OTHERS 0x00000004
|
||||||
|
#define GEM_PCI_ERR_BITS "\177\020b\0ACKBAD\0b\1DTRTO\0b\2OTHER\0\0"
|
||||||
|
|
||||||
/* Bits in GEM_CONFIG register */
|
/* GEM_PCI_BIF_CONFIG register bits */
|
||||||
#define GEM_CONFIG_BURST_64 0x000000000 /* maximum burst size 64KB */
|
#define GEM_PCI_BIF_CNF_SLOWCLK 0x00000001 /* Parity error timing */
|
||||||
#define GEM_CONFIG_BURST_INF 0x000000001 /* infinite for entire packet */
|
#define GEM_PCI_BIF_CNF_HOST_64 0x00000002 /* 64-bit host */
|
||||||
#define GEM_CONFIG_TXDMA_LIMIT 0x00000003e
|
#define GEM_PCI_BIF_CNF_B64D_DS 0x00000004 /* no 64-bit data cycle */
|
||||||
#define GEM_CONFIG_RXDMA_LIMIT 0x0000007c0
|
#define GEM_PCI_BIF_CNF_M66EN 0x00000008
|
||||||
/* GEM_CONFIG_RONPAULBIT and GEM_CONFIG_BUG2FIX are Apple only. */
|
#define GEM_PCI_BIF_CNF_BITS "\177\020b\0SLOWCLK\0b\1HOST64\0" \
|
||||||
#define GEM_CONFIG_RONPAULBIT 0x000000800 /* after infinite burst use */
|
|
||||||
/* memory read multiple for */
|
|
||||||
/* PCI commands */
|
|
||||||
#define GEM_CONFIG_BUG2FIX 0x000001000 /* fix RX hang after overflow */
|
|
||||||
|
|
||||||
#define GEM_CONFIG_TXDMA_LIMIT_SHIFT 1
|
|
||||||
#define GEM_CONFIG_RXDMA_LIMIT_SHIFT 6
|
|
||||||
|
|
||||||
|
|
||||||
/* Top part of GEM_STATUS has TX completion information */
|
|
||||||
#define GEM_STATUS_TX_COMPL 0xfff800000 /* TX completion reg. */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Interrupt bits, for both the GEM_STATUS and GEM_INTMASK regs
|
|
||||||
* Bits 0-6 auto-clear when read.
|
|
||||||
*/
|
|
||||||
#define GEM_INTR_TX_INTME 0x000000001 /* Frame w/INTME bit set sent */
|
|
||||||
#define GEM_INTR_TX_EMPTY 0x000000002 /* TX ring empty */
|
|
||||||
#define GEM_INTR_TX_DONE 0x000000004 /* TX complete */
|
|
||||||
#define GEM_INTR_RX_DONE 0x000000010 /* Got a packet */
|
|
||||||
#define GEM_INTR_RX_NOBUF 0x000000020
|
|
||||||
#define GEM_INTR_RX_TAG_ERR 0x000000040
|
|
||||||
#define GEM_INTR_PERR 0x000000080 /* Parity error */
|
|
||||||
#define GEM_INTR_PCS 0x000002000 /* Physical Code Sub-layer */
|
|
||||||
#define GEM_INTR_TX_MAC 0x000004000
|
|
||||||
#define GEM_INTR_RX_MAC 0x000008000
|
|
||||||
#define GEM_INTR_MAC_CONTROL 0x000010000 /* MAC control interrupt */
|
|
||||||
#define GEM_INTR_MIF 0x000020000
|
|
||||||
#define GEM_INTR_BERR 0x000040000 /* Bus error interrupt */
|
|
||||||
#define GEM_INTR_BITS "\177\020" \
|
|
||||||
"b\0INTME\0b\1TXEMPTY\0b\2TXDONE\0" \
|
|
||||||
"b\4RXDONE\0b\5RXNOBUF\0b\6RX_TAG_ERR\0" \
|
|
||||||
"b\xdPCS\0b\xeTXMAC\0b\xfRXMAC\0" \
|
|
||||||
"b\x10MAC_CONTROL\0b\x11MIF\0b\x12IBERR\0\0"
|
|
||||||
|
|
||||||
|
|
||||||
/* GEM_ERROR_STATUS and GEM_ERROR_MASK PCI error bits */
|
|
||||||
#define GEM_ERROR_STAT_BADACK 0x000000001 /* No ACK64# */
|
|
||||||
#define GEM_ERROR_STAT_DTRTO 0x000000002 /* Delayed xaction timeout */
|
|
||||||
#define GEM_ERROR_STAT_OTHERS 0x000000004
|
|
||||||
#define GEM_ERROR_BITS "\177\020b\0ACKBAD\0b\1DTRTO\0b\2OTHER\0\0"
|
|
||||||
|
|
||||||
|
|
||||||
/* GEM_BIF_CONFIG register bits */
|
|
||||||
#define GEM_BIF_CONFIG_SLOWCLK 0x000000001 /* Parity error timing */
|
|
||||||
#define GEM_BIF_CONFIG_HOST_64 0x000000002 /* 64-bit host */
|
|
||||||
#define GEM_BIF_CONFIG_B64D_DIS 0x000000004 /* no 64-bit data cycle */
|
|
||||||
#define GEM_BIF_CONFIG_M66EN 0x000000008
|
|
||||||
#define GEM_BIF_CONFIG_BITS "\177\020b\0SLOWCLK\0b\1HOST64\0" \
|
|
||||||
"b\2B64DIS\0b\3M66EN\0\0"
|
"b\2B64DIS\0b\3M66EN\0\0"
|
||||||
|
|
||||||
|
/* GEM_PCI_BIF_DIAG register bits */
|
||||||
|
#define GEN_PCI_BIF_DIAG_BC_SM 0x007f0000 /* burst ctrl. state machine */
|
||||||
|
#define GEN_PCI_BIF_DIAG_SM 0xff000000 /* BIF state machine */
|
||||||
|
|
||||||
|
/* Bits in GEM_SBUS_CONFIG register */
|
||||||
|
#define GEM_SBUS_CFG_BURST_32 0x00000001 /* 32 byte bursts */
|
||||||
|
#define GEM_SBUS_CFG_BURST_64 0x00000002 /* 64 byte bursts */
|
||||||
|
#define GEM_SBUS_CFG_BURST_128 0x00000004 /* 128 byte bursts */
|
||||||
|
#define GEM_SBUS_CFG_64BIT 0x00000008 /* extended transfer mode */
|
||||||
|
#define GEM_SBUS_CFG_PARITY 0x00000200 /* enable parity checking */
|
||||||
|
|
||||||
|
/* GEM_SBUS_STATUS register bits */
|
||||||
|
#define GEM_SBUS_STATUS_LERR 0x00000001 /* LERR from SBus slave */
|
||||||
|
#define GEM_SBUS_STATUS_SACK 0x00000002 /* size ack. error */
|
||||||
|
#define GEM_SBUS_STATUS_EACK 0x00000004 /* SBus ctrl. or slave error */
|
||||||
|
#define GEM_SBUS_STATUS_MPARITY 0x00000008 /* SBus master parity error */
|
||||||
|
|
||||||
/* GEM_RESET register bits -- TX and RX self clear when complete. */
|
/* GEM_RESET register bits -- TX and RX self clear when complete. */
|
||||||
#define GEM_RESET_TX 0x000000001 /* Reset TX half */
|
#define GEM_RESET_TX 0x00000001 /* Reset TX half. */
|
||||||
#define GEM_RESET_RX 0x000000002 /* Reset RX half */
|
#define GEM_RESET_RX 0x00000002 /* Reset RX half. */
|
||||||
#define GEM_RESET_RSTOUT 0x000000004 /* Force PCI RSTOUT# */
|
#define GEM_RESET_PCI_RSTOUT 0x00000004 /* Force PCI RSTOUT#. */
|
||||||
|
|
||||||
|
|
||||||
/* The rest of the registers live in the first bank again. */
|
/* The rest of the registers live in the first bank again. */
|
||||||
/* GEM TX DMA registers */
|
|
||||||
|
/* TX DMA registers */
|
||||||
#define GEM_TX_KICK 0x2000 /* Write last valid desc + 1 */
|
#define GEM_TX_KICK 0x2000 /* Write last valid desc + 1 */
|
||||||
#define GEM_TX_CONFIG 0x2004
|
#define GEM_TX_CONFIG 0x2004
|
||||||
#define GEM_TX_RING_PTR_LO 0x2008
|
#define GEM_TX_RING_PTR_LO 0x2008
|
||||||
@ -162,7 +175,6 @@
|
|||||||
#define GEM_TX_FIFO_SIZE 0x2118
|
#define GEM_TX_FIFO_SIZE 0x2118
|
||||||
#define GEM_TX_DEBUG 0x3028
|
#define GEM_TX_DEBUG 0x3028
|
||||||
|
|
||||||
|
|
||||||
/* GEM_TX_CONFIG register bits */
|
/* GEM_TX_CONFIG register bits */
|
||||||
#define GEM_TX_CONFIG_TXDMA_EN 0x00000001 /* TX DMA enable */
|
#define GEM_TX_CONFIG_TXDMA_EN 0x00000001 /* TX DMA enable */
|
||||||
#define GEM_TX_CONFIG_TXRING_SZ 0x0000001e /* TX ring size */
|
#define GEM_TX_CONFIG_TXRING_SZ 0x0000001e /* TX ring size */
|
||||||
@ -179,12 +191,10 @@
|
|||||||
#define GEM_RING_SZ_4096 (7<<1)
|
#define GEM_RING_SZ_4096 (7<<1)
|
||||||
#define GEM_RING_SZ_8192 (8<<1)
|
#define GEM_RING_SZ_8192 (8<<1)
|
||||||
|
|
||||||
|
|
||||||
/* GEM_TX_COMPLETION register bits */
|
/* GEM_TX_COMPLETION register bits */
|
||||||
#define GEM_TX_COMPLETION_MASK 0x00001fff /* # of last descriptor */
|
#define GEM_TX_COMPLETION_MASK 0x00001fff /* # of last descriptor */
|
||||||
|
|
||||||
|
/* RX DMA registers */
|
||||||
/* GEM RX DMA registers */
|
|
||||||
#define GEM_RX_CONFIG 0x4000
|
#define GEM_RX_CONFIG 0x4000
|
||||||
#define GEM_RX_RING_PTR_LO 0x4004 /* 64-bits unaligned GAK! */
|
#define GEM_RX_RING_PTR_LO 0x4004 /* 64-bits unaligned GAK! */
|
||||||
#define GEM_RX_RING_PTR_HI 0x4008 /* 64-bits unaligned GAK! */
|
#define GEM_RX_RING_PTR_HI 0x4008 /* 64-bits unaligned GAK! */
|
||||||
@ -211,7 +221,6 @@
|
|||||||
#define GEM_RX_FIFO_DATA_HI_T0 0x411c
|
#define GEM_RX_FIFO_DATA_HI_T0 0x411c
|
||||||
#define GEM_RX_FIFO_SIZE 0x4120
|
#define GEM_RX_FIFO_SIZE 0x4120
|
||||||
|
|
||||||
|
|
||||||
/* GEM_RX_CONFIG register bits */
|
/* GEM_RX_CONFIG register bits */
|
||||||
#define GEM_RX_CONFIG_RXDMA_EN 0x00000001 /* RX DMA enable */
|
#define GEM_RX_CONFIG_RXDMA_EN 0x00000001 /* RX DMA enable */
|
||||||
#define GEM_RX_CONFIG_RXRING_SZ 0x0000001e /* RX ring size */
|
#define GEM_RX_CONFIG_RXRING_SZ 0x0000001e /* RX ring size */
|
||||||
@ -231,19 +240,16 @@
|
|||||||
#define GEM_RX_CONFIG_FBOFF_SHFT 10
|
#define GEM_RX_CONFIG_FBOFF_SHFT 10
|
||||||
#define GEM_RX_CONFIG_CXM_START_SHFT 13
|
#define GEM_RX_CONFIG_CXM_START_SHFT 13
|
||||||
|
|
||||||
|
|
||||||
/* GEM_RX_PAUSE_THRESH register bits -- sizes in multiples of 64 bytes */
|
/* GEM_RX_PAUSE_THRESH register bits -- sizes in multiples of 64 bytes */
|
||||||
#define GEM_RX_PTH_XOFF_THRESH 0x000001ff
|
#define GEM_RX_PTH_XOFF_THRESH 0x000001ff
|
||||||
#define GEM_RX_PTH_XON_THRESH 0x001ff000
|
#define GEM_RX_PTH_XON_THRESH 0x001ff000
|
||||||
|
|
||||||
|
|
||||||
/* GEM_RX_BLANKING register bits */
|
/* GEM_RX_BLANKING register bits */
|
||||||
#define GEM_RX_BLANKING_PACKETS 0x000001ff /* Delay intr for x packets */
|
#define GEM_RX_BLANKING_PACKETS 0x000001ff /* Delay intr for x packets */
|
||||||
#define GEM_RX_BLANKING_TIME 0x000ff000 /* Delay intr for x ticks */
|
#define GEM_RX_BLANKING_TIME 0x000ff000 /* Delay intr for x ticks */
|
||||||
#define GEM_RX_BLANKING_TIME_SHIFT 12
|
#define GEM_RX_BLANKING_TIME_SHIFT 12
|
||||||
/* One tick is 2048 PCI clocks, or 16us at 66MHz */
|
/* One tick is 2048 PCI clocks, or 16us at 66MHz */
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MAC registers */
|
/* GEM_MAC registers */
|
||||||
#define GEM_MAC_TXRESET 0x6000 /* Store 1, cleared when done */
|
#define GEM_MAC_TXRESET 0x6000 /* Store 1, cleared when done */
|
||||||
#define GEM_MAC_RXRESET 0x6004 /* ditto */
|
#define GEM_MAC_RXRESET 0x6004 /* ditto */
|
||||||
@ -316,12 +322,10 @@
|
|||||||
#define GEM_MAC_RANDOM_SEED 0x6130
|
#define GEM_MAC_RANDOM_SEED 0x6130
|
||||||
#define GEM_MAC_MAC_STATE 0x6134 /* MAC state machine reg */
|
#define GEM_MAC_MAC_STATE 0x6134 /* MAC state machine reg */
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MAC_SEND_PAUSE_CMD register bits */
|
/* GEM_MAC_SEND_PAUSE_CMD register bits */
|
||||||
#define GEM_MAC_PAUSE_CMD_TIME 0x0000ffff
|
#define GEM_MAC_PAUSE_CMD_TIME 0x0000ffff
|
||||||
#define GEM_MAC_PAUSE_CMD_SEND 0x00010000
|
#define GEM_MAC_PAUSE_CMD_SEND 0x00010000
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MAC_TX_STATUS and _MASK register bits */
|
/* GEM_MAC_TX_STATUS and _MASK register bits */
|
||||||
#define GEM_MAC_TX_XMIT_DONE 0x00000001
|
#define GEM_MAC_TX_XMIT_DONE 0x00000001
|
||||||
#define GEM_MAC_TX_UNDERRUN 0x00000002
|
#define GEM_MAC_TX_UNDERRUN 0x00000002
|
||||||
@ -333,7 +337,6 @@
|
|||||||
#define GEM_MAC_TX_DEFER_EXP 0x00000080
|
#define GEM_MAC_TX_DEFER_EXP 0x00000080
|
||||||
#define GEM_MAC_TX_PEAK_EXP 0x00000100
|
#define GEM_MAC_TX_PEAK_EXP 0x00000100
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MAC_RX_STATUS and _MASK register bits */
|
/* GEM_MAC_RX_STATUS and _MASK register bits */
|
||||||
#define GEM_MAC_RX_DONE 0x00000001
|
#define GEM_MAC_RX_DONE 0x00000001
|
||||||
#define GEM_MAC_RX_OVERFLOW 0x00000002
|
#define GEM_MAC_RX_OVERFLOW 0x00000002
|
||||||
@ -343,7 +346,6 @@
|
|||||||
#define GEM_MAC_RX_LEN_EXP 0x00000020
|
#define GEM_MAC_RX_LEN_EXP 0x00000020
|
||||||
#define GEM_MAC_RX_CVI_EXP 0x00000040 /* Code violation */
|
#define GEM_MAC_RX_CVI_EXP 0x00000040 /* Code violation */
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MAC_CONTROL_STATUS and GEM_MAC_CONTROL_MASK register bits */
|
/* GEM_MAC_CONTROL_STATUS and GEM_MAC_CONTROL_MASK register bits */
|
||||||
#define GEM_MAC_PAUSED 0x00000001 /* Pause received */
|
#define GEM_MAC_PAUSED 0x00000001 /* Pause received */
|
||||||
#define GEM_MAC_PAUSE 0x00000002 /* enter pause state */
|
#define GEM_MAC_PAUSE 0x00000002 /* enter pause state */
|
||||||
@ -386,14 +388,13 @@
|
|||||||
#define GEM_MAC_TX_SLOWDOWN 0x00000080
|
#define GEM_MAC_TX_SLOWDOWN 0x00000080
|
||||||
#define GEM_MAC_TX_NO_FCS 0x00000100 /* no FCS will be generated */
|
#define GEM_MAC_TX_NO_FCS 0x00000100 /* no FCS will be generated */
|
||||||
#define GEM_MAC_TX_CARR_EXTEND 0x00000200 /* Ena TX Carrier Extension */
|
#define GEM_MAC_TX_CARR_EXTEND 0x00000200 /* Ena TX Carrier Extension */
|
||||||
/* Carrier Extension is required for half duplex Gbps operation */
|
/* Carrier Extension is required for half duplex Gbps operation. */
|
||||||
#define GEM_MAC_TX_CONFIG_BITS "\177\020" \
|
#define GEM_MAC_TX_CONFIG_BITS "\177\020" \
|
||||||
"b\0TXENA\0b\1IGNCAR\0b\2IGNCOLLIS\0" \
|
"b\0TXENA\0b\1IGNCAR\0b\2IGNCOLLIS\0" \
|
||||||
"b\3IPG0ENA\0b\4TXNGU\0b\5TXNGULIM\0" \
|
"b\3IPG0ENA\0b\4TXNGU\0b\5TXNGULIM\0" \
|
||||||
"b\6NOBKOFF\0b\7SLOWDN\0b\x8NOFCS\0" \
|
"b\6NOBKOFF\0b\7SLOWDN\0b\x8NOFCS\0" \
|
||||||
"b\x9TXCARREXT\0\0"
|
"b\x9TXCARREXT\0\0"
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MAC_RX_CONFIG register bits */
|
/* GEM_MAC_RX_CONFIG register bits */
|
||||||
#define GEM_MAC_RX_ENABLE 0x00000001 /* RX enable */
|
#define GEM_MAC_RX_ENABLE 0x00000001 /* RX enable */
|
||||||
#define GEM_MAC_RX_STRIP_PAD 0x00000002 /* strip pad bytes */
|
#define GEM_MAC_RX_STRIP_PAD 0x00000002 /* strip pad bytes */
|
||||||
@ -413,32 +414,31 @@
|
|||||||
"b\3PROMIS\0b\4PROMISCGRP\0b\5HASHFLTR\0" \
|
"b\3PROMIS\0b\4PROMISCGRP\0b\5HASHFLTR\0" \
|
||||||
"b\6ADDRFLTR\0b\7ERRCHKDIS\0b\x9TXCARREXT\0\0"
|
"b\6ADDRFLTR\0b\7ERRCHKDIS\0b\x9TXCARREXT\0\0"
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MAC_CONTROL_CONFIG bits */
|
/* GEM_MAC_CONTROL_CONFIG bits */
|
||||||
#define GEM_MAC_CC_TX_PAUSE 0x00000001 /* send pause enabled */
|
#define GEM_MAC_CC_TX_PAUSE 0x00000001 /* send pause enabled */
|
||||||
#define GEM_MAC_CC_RX_PAUSE 0x00000002 /* receive pause enabled */
|
#define GEM_MAC_CC_RX_PAUSE 0x00000002 /* receive pause enabled */
|
||||||
#define GEM_MAC_CC_PASS_PAUSE 0x00000004 /* pass pause up */
|
#define GEM_MAC_CC_PASS_PAUSE 0x00000004 /* pass pause up */
|
||||||
#define GEM_MAC_CC_BITS "\177\020b\0TXPAUSE\0b\1RXPAUSE\0b\2NOPAUSE\0\0"
|
#define GEM_MAC_CC_BITS "\177\020b\0TXPAUSE\0b\1RXPAUSE\0b\2NOPAUSE\0\0"
|
||||||
|
|
||||||
|
/*
|
||||||
/* GEM MIF registers */
|
* MIF registers
|
||||||
/* Bit bang registers use low bit only. */
|
* Bit bang registers use low bit only.
|
||||||
|
*/
|
||||||
#define GEM_MIF_BB_CLOCK 0x6200 /* bit bang clock */
|
#define GEM_MIF_BB_CLOCK 0x6200 /* bit bang clock */
|
||||||
#define GEM_MIF_BB_DATA 0x6204 /* bit bang data */
|
#define GEM_MIF_BB_DATA 0x6204 /* bit bang data */
|
||||||
#define GEM_MIF_BB_OUTPUT_ENAB 0x6208
|
#define GEM_MIF_BB_OUTPUT_ENAB 0x6208
|
||||||
#define GEM_MIF_FRAME 0x620c /* MIF frame - ctl and data */
|
#define GEM_MIF_FRAME 0x620c /* MIF frame - ctl and data */
|
||||||
#define GEM_MIF_CONFIG 0x6210
|
#define GEM_MIF_CONFIG 0x6210
|
||||||
#define GEM_MIF_INTERRUPT_MASK 0x6214
|
#define GEM_MIF_MASK 0x6214
|
||||||
#define GEM_MIF_BASIC_STATUS 0x6218
|
#define GEM_MIF_STATUS 0x6218
|
||||||
#define GEM_MIF_STATE_MACHINE 0x621c
|
#define GEM_MIF_STATE_MACHINE 0x621c
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MIF_FRAME bits */
|
/* GEM_MIF_FRAME bits */
|
||||||
#define GEM_MIF_FRAME_DATA 0x0000ffff
|
#define GEM_MIF_FRAME_DATA 0x0000ffff
|
||||||
#define GEM_MIF_FRAME_TA0 0x00010000 /* TA bit, 1 for completion */
|
#define GEM_MIF_FRAME_TA0 0x00010000 /* TA LSB, 1 for completion */
|
||||||
#define GEM_MIF_FRAME_TA1 0x00020000 /* TA bits */
|
#define GEM_MIF_FRAME_TA1 0x00020000 /* TA MSB, 1 for instruction */
|
||||||
#define GEM_MIF_FRAME_REG_ADDR 0x007c0000
|
#define GEM_MIF_FRAME_REG_ADDR 0x007c0000
|
||||||
#define GEM_MIF_FRAME_PHY_ADDR 0x0f800000 /* phy address, should be 0 */
|
#define GEM_MIF_FRAME_PHY_ADDR 0x0f800000 /* PHY address */
|
||||||
#define GEM_MIF_FRAME_OP 0x30000000 /* operation - write/read */
|
#define GEM_MIF_FRAME_OP 0x30000000 /* operation - write/read */
|
||||||
#define GEM_MIF_FRAME_START 0xc0000000 /* START bits */
|
#define GEM_MIF_FRAME_START 0xc0000000 /* START bits */
|
||||||
|
|
||||||
@ -448,31 +448,29 @@
|
|||||||
#define GEM_MIF_REG_SHIFT 18
|
#define GEM_MIF_REG_SHIFT 18
|
||||||
#define GEM_MIF_PHY_SHIFT 23
|
#define GEM_MIF_PHY_SHIFT 23
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MIF_CONFIG register bits */
|
/* GEM_MIF_CONFIG register bits */
|
||||||
#define GEM_MIF_CONFIG_PHY_SEL 0x00000001 /* PHY select, 0=MDIO0 */
|
#define GEM_MIF_CONFIG_PHY_SEL 0x00000001 /* PHY select, 0: MDIO_0 */
|
||||||
#define GEM_MIF_CONFIG_POLL_ENA 0x00000002 /* poll enable */
|
#define GEM_MIF_CONFIG_POLL_ENA 0x00000002 /* poll enable */
|
||||||
#define GEM_MIF_CONFIG_BB_ENA 0x00000004 /* bit bang enable */
|
#define GEM_MIF_CONFIG_BB_ENA 0x00000004 /* bit bang enable */
|
||||||
#define GEM_MIF_CONFIG_REG_ADR 0x000000f8 /* poll register address */
|
#define GEM_MIF_CONFIG_REG_ADR 0x000000f8 /* poll register address */
|
||||||
#define GEM_MIF_CONFIG_MDI0 0x00000100 /* MDIO_0 Data/MDIO_0 atached */
|
#define GEM_MIF_CONFIG_MDI0 0x00000100 /* MDIO_0 attached/data */
|
||||||
#define GEM_MIF_CONFIG_MDI1 0x00000200 /* MDIO_1 Data/MDIO_1 atached */
|
#define GEM_MIF_CONFIG_MDI1 0x00000200 /* MDIO_1 attached/data */
|
||||||
#define GEM_MIF_CONFIG_PHY_ADR 0x00007c00 /* poll PHY address */
|
#define GEM_MIF_CONFIG_PHY_ADR 0x00007c00 /* poll PHY address */
|
||||||
/* MDI0 is the onboard transceiver, MDI1 is external, PHYAD for both is 0. */
|
/* MDI0 is the onboard transceiver, MDI1 is external, PHYAD for both is 0. */
|
||||||
#define GEM_MIF_CONFIG_BITS "\177\020b\0PHYSEL\0b\1POLL\0b\2BBENA\0" \
|
#define GEM_MIF_CONFIG_BITS "\177\020b\0PHYSEL\0b\1POLL\0b\2BBENA\0" \
|
||||||
"b\x8MDIO0\0b\x9MDIO1\0\0"
|
"b\x8MDIO0\0b\x9MDIO1\0\0"
|
||||||
|
|
||||||
|
/* GEM_MIF_STATUS and GEM_MIF_MASK bits */
|
||||||
/* GEM_MIF_BASIC_STATUS and GEM_MIF_INTERRUPT_MASK bits */
|
#define GEM_MIF_POLL_STATUS_MASK 0x0000ffff /* polling status */
|
||||||
#define GEM_MIF_STATUS 0x0000ffff
|
#define GEM_MIF_POLL_STATUS_SHFT 0
|
||||||
#define GEM_MIF_BASIC 0xffff0000
|
#define GEM_MIF_POLL_DATA_MASK 0xffff0000 /* polling data */
|
||||||
|
#define GEM_MIF_POLL_DATA_SHFT 8
|
||||||
/*
|
/*
|
||||||
* The Basic part is the last value read in the POLL field of the config
|
* The Basic part is the last value read in the POLL field of the config
|
||||||
* register.
|
* register.
|
||||||
*
|
|
||||||
* The status part indicates the bits that have changed.
|
* The status part indicates the bits that have changed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* GEM PCS/Serial link registers */
|
/* GEM PCS/Serial link registers */
|
||||||
/* DO NOT TOUCH THESE REGISTERS ON ERI -- IT HARD HANGS. */
|
/* DO NOT TOUCH THESE REGISTERS ON ERI -- IT HARD HANGS. */
|
||||||
#define GEM_MII_CONTROL 0x9000
|
#define GEM_MII_CONTROL 0x9000
|
||||||
@ -485,106 +483,94 @@
|
|||||||
#define GEM_MII_DATAPATH_MODE 0x9050
|
#define GEM_MII_DATAPATH_MODE 0x9050
|
||||||
#define GEM_MII_SLINK_CONTROL 0x9054 /* Serial link control */
|
#define GEM_MII_SLINK_CONTROL 0x9054 /* Serial link control */
|
||||||
#define GEM_MII_OUTPUT_SELECT 0x9058
|
#define GEM_MII_OUTPUT_SELECT 0x9058
|
||||||
#define GEM_MII_SLINK_STATUS 0x905c /* serial link status */
|
#define GEM_MII_SLINK_STATUS 0x905c /* Serialink status */
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MII_CONTROL bits - PCS "BMCR" (Basic Mode Control Reg) */
|
/* GEM_MII_CONTROL bits - PCS "BMCR" (Basic Mode Control Reg) */
|
||||||
#define GEM_MII_CONTROL_RESET 0x00008000
|
#define GEM_MII_CONTROL_1000M 0x00000040 /* 1000Mbps speed select */
|
||||||
#define GEM_MII_CONTROL_LOOPBK 0x00004000 /* 10-bit i/f loopback */
|
|
||||||
#define GEM_MII_CONTROL_1000M 0x00002000 /* speed select, always 0 */
|
|
||||||
#define GEM_MII_CONTROL_AUTONEG 0x00001000 /* auto negotiation enabled */
|
|
||||||
#define GEM_MII_CONTROL_POWERDN 0x00000800
|
|
||||||
#define GEM_MII_CONTROL_ISOLATE 0x00000400 /* isolate phy from mii */
|
|
||||||
#define GEM_MII_CONTROL_RAN 0x00000200 /* restart auto negotiation */
|
|
||||||
#define GEM_MII_CONTROL_FDUPLEX 0x00000100 /* full duplex, always 0 */
|
|
||||||
#define GEM_MII_CONTROL_COL_TST 0x00000080 /* collision test */
|
#define GEM_MII_CONTROL_COL_TST 0x00000080 /* collision test */
|
||||||
|
#define GEM_MII_CONTROL_FDUPLEX 0x00000100 /* full-duplex, always 0 */
|
||||||
|
#define GEM_MII_CONTROL_RAN 0x00000200 /* restart auto-negotiation */
|
||||||
|
#define GEM_MII_CONTROL_ISOLATE 0x00000400 /* isolate PHY from MII */
|
||||||
|
#define GEM_MII_CONTROL_POWERDN 0x00000800 /* power down */
|
||||||
|
#define GEM_MII_CONTROL_AUTONEG 0x00001000 /* auto-negotiation enable */
|
||||||
|
#define GEM_MII_CONTROL_10_100M 0x00002000 /* 10/100Mbps speed select */
|
||||||
|
#define GEM_MII_CONTROL_LOOPBK 0x00004000 /* 10-bit i/f loopback */
|
||||||
|
#define GEM_MII_CONTROL_RESET 0x00008000 /* Reset PCS. */
|
||||||
#define GEM_MII_CONTROL_BITS "\177\020b\7COLTST\0b\x8_FD\0b\x9RAN\0" \
|
#define GEM_MII_CONTROL_BITS "\177\020b\7COLTST\0b\x8_FD\0b\x9RAN\0" \
|
||||||
"b\xaISOLATE\0b\xbPWRDWN\0b\xc_ANEG\0" \
|
"b\xaISOLATE\0b\xbPWRDWN\0b\xc_ANEG\0" \
|
||||||
"b\xdGIGE\0b\xeLOOP\0b\xfRESET\0\0"
|
"b\xdGIGE\0b\xeLOOP\0b\xfRESET\0\0"
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MII_STATUS reg - PCS "BMSR" (Basic Mode Status Reg) */
|
/* GEM_MII_STATUS reg - PCS "BMSR" (Basic Mode Status Reg) */
|
||||||
#define GEM_MII_STATUS_GB_FDX 0x00000400 /* can perform GBit FDX */
|
#define GEM_MII_STATUS_EXTCAP 0x00000001 /* extended capability */
|
||||||
#define GEM_MII_STATUS_GB_HDX 0x00000200 /* can perform GBit HDX */
|
|
||||||
#define GEM_MII_STATUS_UNK 0x00000100
|
|
||||||
#define GEM_MII_STATUS_ANEG_CPT 0x00000020 /* auto negotiate compete */
|
|
||||||
#define GEM_MII_STATUS_REM_FLT 0x00000010 /* remote fault detected */
|
|
||||||
#define GEM_MII_STATUS_ACFG 0x00000008 /* can auto negotiate */
|
|
||||||
#define GEM_MII_STATUS_LINK_STS 0x00000004 /* link status */
|
|
||||||
#define GEM_MII_STATUS_JABBER 0x00000002 /* jabber condition detected */
|
#define GEM_MII_STATUS_JABBER 0x00000002 /* jabber condition detected */
|
||||||
#define GEM_MII_STATUS_EXTCAP 0x00000001 /* extended register capability */
|
#define GEM_MII_STATUS_LINK_STS 0x00000004 /* link status */
|
||||||
|
#define GEM_MII_STATUS_ACFG 0x00000008 /* can auto-negotiate */
|
||||||
|
#define GEM_MII_STATUS_REM_FLT 0x00000010 /* remote fault detected */
|
||||||
|
#define GEM_MII_STATUS_ANEG_CPT 0x00000020 /* auto-negotiate complete */
|
||||||
|
#define GEM_MII_STATUS_EXTENDED 0x00000100 /* extended status */
|
||||||
#define GEM_MII_STATUS_BITS "\177\020b\0EXTCAP\0b\1JABBER\0b\2LINKSTS\0" \
|
#define GEM_MII_STATUS_BITS "\177\020b\0EXTCAP\0b\1JABBER\0b\2LINKSTS\0" \
|
||||||
"b\3ACFG\0b\4REMFLT\0b\5ANEGCPT\0b\x9GBHDX\0" \
|
"b\3ACFG\0b\4REMFLT\0b\5ANEGCPT\0\0"
|
||||||
"b\xaGBFDX\0\0"
|
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MII_ANAR and GEM_MII_ANLPAR reg bits */
|
/* GEM_MII_ANAR and GEM_MII_ANLPAR reg bits */
|
||||||
#define GEM_MII_ANEG_NP 0x00008000 /* next page bit */
|
#define GEM_MII_ANEG_FDUPLX 0x00000020 /* full-duplex */
|
||||||
#define GEM_MII_ANEG_ACK 0x00004000 /* ack reception of */
|
#define GEM_MII_ANEG_HDUPLX 0x00000040 /* half-duplex */
|
||||||
/* Link Partner Capability */
|
#define GEM_MII_ANEG_PAUSE 0x00000080 /* symmetric PAUSE */
|
||||||
#define GEM_MII_ANEG_RF 0x00003000 /* advertise remote fault cap */
|
#define GEM_MII_ANEG_ASM_DIR 0x00000100 /* asymmetric PAUSE */
|
||||||
#define GEM_MII_ANEG_ASYM_PAUSE 0x00000100 /* asymmetric pause */
|
#define GEM_MII_ANEG_RFLT_FAIL 0x00001000 /* remote fault - fail */
|
||||||
#define GEM_MII_ANEG_SYM_PAUSE 0x00000080 /* symmetric pause */
|
#define GEM_MII_ANEG_RFLT_OFF 0x00002000 /* remote fault - off-line */
|
||||||
#define GEM_MII_ANEG_HLF_DUPLX 0x00000040
|
#define GEM_MII_ANEG_RFLT_MASK \
|
||||||
#define GEM_MII_ANEG_FUL_DUPLX 0x00000020
|
(CAS_PCS_ANEG_RFLT_FAIL | CAS_PCS_ANEG_RFLT_OFF)
|
||||||
|
#define GEM_MII_ANEG_ACK 0x00004000 /* acknowledge */
|
||||||
|
#define GEM_MII_ANEG_NP 0x00008000 /* next page */
|
||||||
#define GEM_MII_ANEG_BITS "\177\020b\5FDX\0b\6HDX\0b\7SYMPAUSE\0" \
|
#define GEM_MII_ANEG_BITS "\177\020b\5FDX\0b\6HDX\0b\7SYMPAUSE\0" \
|
||||||
"\b\x8_ASYMPAUSE\0\b\xdREMFLT\0\b\xeLPACK\0" \
|
"\b\x8_ASYMPAUSE\0\b\xdREMFLT\0\b\xeLPACK\0" \
|
||||||
"\b\xfNPBIT\0\0"
|
"\b\xfNPBIT\0\0"
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MII_CONFIG reg */
|
/* GEM_MII_CONFIG reg */
|
||||||
#define GEM_MII_CONFIG_TIMER 0x0000000e /* link monitor timer values */
|
#define GEM_MII_CONFIG_ENABLE 0x00000001 /* Enable PCS. */
|
||||||
#define GEM_MII_CONFIG_ANTO 0x00000020 /* 10ms ANEG timer override */
|
#define GEM_MII_CONFIG_SDO 0x00000002 /* signal detect override */
|
||||||
#define GEM_MII_CONFIG_JS 0x00000018 /* Jitter Study, 0 normal
|
#define GEM_MII_CONFIG_SDL 0x00000004 /* signal detect active-low */
|
||||||
* 1 high freq, 2 low freq */
|
#define GEM_MII_CONFIG_JS_NORM 0x00000000 /* jitter study - normal op. */
|
||||||
#define GEM_MII_CONFIG_SDL 0x00000004 /* Signal Detect active low */
|
#define GEM_MII_CONFIG_JS_HF 0x00000008 /* jitter study - HF test */
|
||||||
#define GEM_MII_CONFIG_SDO 0x00000002 /* Signal Detect Override */
|
#define GEM_MII_CONFIG_JS_LF 0x00000010 /* jitter study - LF test */
|
||||||
#define GEM_MII_CONFIG_ENABLE 0x00000001 /* Enable PCS */
|
#define GEM_MII_CONFIG_JS_MASK \
|
||||||
|
(GEM_MII_CONFIG_JS_HF | GEM_MII_CONFIG_JS_LF)
|
||||||
|
#define GEM_MII_CONFIG_ANTO 0x00000020 /* auto-neg. timer override */
|
||||||
#define GEM_MII_CONFIG_BITS "\177\020b\0PCSENA\0\0"
|
#define GEM_MII_CONFIG_BITS "\177\020b\0PCSENA\0\0"
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GEM_MII_STATE_MACHINE
|
|
||||||
* XXX These are best guesses from observed behavior.
|
|
||||||
*/
|
|
||||||
#define GEM_MII_FSM_STOP 0x00000000 /* stopped */
|
|
||||||
#define GEM_MII_FSM_RUN 0x00000001 /* running */
|
|
||||||
#define GEM_MII_FSM_UNKWN 0x00000100 /* unknown */
|
|
||||||
#define GEM_MII_FSM_DONE 0x00000101 /* complete */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GEM_MII_INTERRUP_STATUS reg
|
* GEM_MII_INTERRUP_STATUS reg
|
||||||
* No mask register; mask with the global interrupt mask register.
|
* No mask register; mask with the global interrupt mask register.
|
||||||
*/
|
*/
|
||||||
#define GEM_MII_INTERRUP_LINK 0x00000004 /* PCS link status change */
|
#define GEM_MII_INTERRUP_LINK 0x00000004 /* PCS link status change */
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MII_DATAPATH_MODE reg */
|
/* GEM_MII_DATAPATH_MODE reg */
|
||||||
#define GEM_MII_DATAPATH_SERIAL 0x00000001 /* Serial link */
|
#define GEM_MII_DATAPATH_SERIAL 0x00000001 /* Serialink */
|
||||||
#define GEM_MII_DATAPATH_SERDES 0x00000002 /* Use PCS via 10bit interfac */
|
#define GEM_MII_DATAPATH_SERDES 0x00000002 /* SERDES via 10-bit */
|
||||||
#define GEM_MII_DATAPATH_MII 0x00000004 /* Use {G}MII, not PCS */
|
#define GEM_MII_DATAPATH_MII 0x00000004 /* GMII/MII */
|
||||||
#define GEM_MII_DATAPATH_MIIOUT 0x00000008 /* enable serial output on GMII */
|
#define GEM_MII_DATAPATH_GMIIOE 0x00000008 /* serial output on GMII en. */
|
||||||
#define GEM_MII_DATAPATH_BITS "\177\020" \
|
#define GEM_MII_DATAPATH_BITS "\177\020" \
|
||||||
"b\0SERIAL\0b\1SERDES\0b\2MII\0b\3MIIOUT\0\0"
|
"b\0SERIAL\0b\1SERDES\0b\2MII\0b\3GMIIOE\0\0"
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MII_SLINK_CONTROL reg */
|
/* GEM_MII_SLINK_CONTROL reg */
|
||||||
#define GEM_MII_SLINK_LOOPBACK 0x00000001 /* enable loopback at sl, logic
|
#define GEM_MII_SLINK_LOOPBACK 0x00000001 /* enable loopback at SL, logic
|
||||||
* reversed for SERDES */
|
* reversed for SERDES */
|
||||||
#define GEM_MII_SLINK_EN_SYNC_D 0x00000002 /* enable sync detection */
|
#define GEM_MII_SLINK_EN_SYNC_D 0x00000002 /* enable sync detection */
|
||||||
#define GEM_MII_SLINK_LOCK_REF 0x00000004 /* lock reference clock */
|
#define GEM_MII_SLINK_LOCK_REF 0x00000004 /* lock to reference clock */
|
||||||
#define GEM_MII_SLINK_EMPHASIS 0x00000008 /* enable emphasis */
|
#define GEM_MII_SLINK_EMPHASIS 0x00000018 /* enable emphasis */
|
||||||
#define GEM_MII_SLINK_SELFTEST 0x000001c0
|
#define GEM_MII_SLINK_SELFTEST 0x000001c0 /* self-test */
|
||||||
#define GEM_MII_SLINK_POWER_OFF 0x00000200 /* Power down serial link */
|
#define GEM_MII_SLINK_POWER_OFF 0x00000200 /* Power down Serialink. */
|
||||||
|
#define GEM_MII_SLINK_RX_ZERO 0x00000c00 /* PLL input to Serialink. */
|
||||||
|
#define GEM_MII_SLINK_RX_POLE 0x00003000 /* PLL input to Serialink. */
|
||||||
|
#define GEM_MII_SLINK_TX_ZERO 0x0000c000 /* PLL input to Serialink. */
|
||||||
|
#define GEM_MII_SLINK_TX_POLE 0x00030000 /* PLL input to Serialink. */
|
||||||
#define GEM_MII_SLINK_CONTROL_BITS \
|
#define GEM_MII_SLINK_CONTROL_BITS \
|
||||||
"\177\020b\0LOOP\0b\1ENASYNC\0b\2LOCKREF" \
|
"\177\020b\0LOOP\0b\1ENASYNC\0b\2LOCKREF" \
|
||||||
"\0b\3EMPHASIS\0b\x9PWRDWN\0\0"
|
"\0b\3EMPHASIS\0b\x9PWRDWN\0\0"
|
||||||
|
|
||||||
|
|
||||||
/* GEM_MII_SLINK_STATUS reg */
|
/* GEM_MII_SLINK_STATUS reg */
|
||||||
#define GEM_MII_SLINK_TEST 0x00000000 /* undergoing test */
|
#define GEM_MII_SLINK_TEST 0x00000000 /* undergoing test */
|
||||||
#define GEM_MII_SLINK_LOCKED 0x00000001 /* waiting 500us lockrefn */
|
#define GEM_MII_SLINK_LOCKED 0x00000001 /* waiting 500us w/ lockrefn */
|
||||||
#define GEM_MII_SLINK_COMMA 0x00000002 /* waiting for comma detect */
|
#define GEM_MII_SLINK_COMMA 0x00000002 /* waiting for comma detect */
|
||||||
#define GEM_MII_SLINK_SYNC 0x00000003 /* recv data synchronized */
|
#define GEM_MII_SLINK_SYNC 0x00000003 /* recv data synchronized */
|
||||||
|
|
||||||
@ -596,12 +582,12 @@
|
|||||||
#define GEM_PCI_ROM_OFFSET 0x100000
|
#define GEM_PCI_ROM_OFFSET 0x100000
|
||||||
#define GEM_PCI_ROM_SIZE 0x10000
|
#define GEM_PCI_ROM_SIZE 0x10000
|
||||||
|
|
||||||
/* Wired GEM PHY addresses */
|
/* Wired PHY addresses */
|
||||||
#define GEM_PHYAD_INTERNAL 1
|
#define GEM_PHYAD_INTERNAL 1
|
||||||
#define GEM_PHYAD_EXTERNAL 0
|
#define GEM_PHYAD_EXTERNAL 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GEM descriptor table structures
|
* descriptor table structures
|
||||||
*/
|
*/
|
||||||
struct gem_desc {
|
struct gem_desc {
|
||||||
uint64_t gd_flags;
|
uint64_t gd_flags;
|
||||||
@ -609,29 +595,29 @@ struct gem_desc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Transmit flags */
|
/* Transmit flags */
|
||||||
#define GEM_TD_BUFSIZE 0x0000000000007fffLL
|
#define GEM_TD_BUFSIZE 0x0000000000007fffULL
|
||||||
#define GEM_TD_CXSUM_START 0x00000000001f8000LL /* Cxsum start offset */
|
#define GEM_TD_CXSUM_START 0x00000000001f8000ULL /* Cxsum start offset */
|
||||||
#define GEM_TD_CXSUM_STARTSHFT 15
|
#define GEM_TD_CXSUM_STARTSHFT 15
|
||||||
#define GEM_TD_CXSUM_STUFF 0x000000001fe00000LL /* Cxsum stuff offset */
|
#define GEM_TD_CXSUM_STUFF 0x000000001fe00000ULL /* Cxsum stuff offset */
|
||||||
#define GEM_TD_CXSUM_STUFFSHFT 21
|
#define GEM_TD_CXSUM_STUFFSHFT 21
|
||||||
#define GEM_TD_CXSUM_ENABLE 0x0000000020000000LL /* Cxsum generation enable */
|
#define GEM_TD_CXSUM_ENABLE 0x0000000020000000ULL /* Cxsum generation enable */
|
||||||
#define GEM_TD_END_OF_PACKET 0x0000000040000000LL
|
#define GEM_TD_END_OF_PACKET 0x0000000040000000ULL
|
||||||
#define GEM_TD_START_OF_PACKET 0x0000000080000000LL
|
#define GEM_TD_START_OF_PACKET 0x0000000080000000ULL
|
||||||
#define GEM_TD_INTERRUPT_ME 0x0000000100000000LL /* Interrupt me now */
|
#define GEM_TD_INTERRUPT_ME 0x0000000100000000ULL /* Interrupt me now */
|
||||||
#define GEM_TD_NO_CRC 0x0000000200000000LL /* do not insert crc */
|
#define GEM_TD_NO_CRC 0x0000000200000000ULL /* do not insert crc */
|
||||||
/*
|
/*
|
||||||
* Only need to set GEM_TD_CXSUM_ENABLE, GEM_TD_CXSUM_STUFF,
|
* Only need to set GEM_TD_CXSUM_ENABLE, GEM_TD_CXSUM_STUFF,
|
||||||
* GEM_TD_CXSUM_START, and GEM_TD_INTERRUPT_ME in 1st descriptor of a group.
|
* GEM_TD_CXSUM_START, and GEM_TD_INTERRUPT_ME in 1st descriptor of a group.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Receive flags */
|
/* Receive flags */
|
||||||
#define GEM_RD_CHECKSUM 0x000000000000ffffLL /* is the complement */
|
#define GEM_RD_CHECKSUM 0x000000000000ffffULL /* is the complement */
|
||||||
#define GEM_RD_BUFSIZE 0x000000007fff0000LL
|
#define GEM_RD_BUFSIZE 0x000000007fff0000ULL
|
||||||
#define GEM_RD_OWN 0x0000000080000000LL /* 1 - owned by h/w */
|
#define GEM_RD_OWN 0x0000000080000000ULL /* 1 - owned by h/w */
|
||||||
#define GEM_RD_HASHVAL 0x0ffff00000000000LL
|
#define GEM_RD_HASHVAL 0x0ffff00000000000ULL
|
||||||
#define GEM_RD_HASH_PASS 0x1000000000000000LL /* passed hash filter */
|
#define GEM_RD_HASH_PASS 0x1000000000000000ULL /* passed hash filter */
|
||||||
#define GEM_RD_ALTERNATE_MAC 0x2000000000000000LL /* Alternate MAC adrs */
|
#define GEM_RD_ALTERNATE_MAC 0x2000000000000000ULL /* Alternate MAC adrs */
|
||||||
#define GEM_RD_BAD_CRC 0x4000000000000000LL
|
#define GEM_RD_BAD_CRC 0x4000000000000000ULL
|
||||||
|
|
||||||
#define GEM_RD_BUFSHIFT 16
|
#define GEM_RD_BUFSHIFT 16
|
||||||
#define GEM_RD_BUFLEN(x) (((x) & GEM_RD_BUFSIZE) >> GEM_RD_BUFSHIFT)
|
#define GEM_RD_BUFLEN(x) (((x) & GEM_RD_BUFSIZE) >> GEM_RD_BUFSHIFT)
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#include <sys/callout.h>
|
#include <sys/callout.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit descriptor list size. This is arbitrary, but allocate
|
* Transmit descriptor ring size - this is arbitrary, but allocate
|
||||||
* enough descriptors for 64 pending transmissions and 16 segments
|
* enough descriptors for 64 pending transmissions and 16 segments
|
||||||
* per packet. This limit is not actually enforced (packets with
|
* per packet. This limit is not actually enforced (packets with
|
||||||
* more segments can be sent, depending on the busdma backend); it
|
* more segments can be sent, depending on the busdma backend); it
|
||||||
@ -50,7 +50,7 @@
|
|||||||
#define GEM_NEXTTX(x) ((x + 1) & GEM_NTXDESC_MASK)
|
#define GEM_NEXTTX(x) ((x + 1) & GEM_NTXDESC_MASK)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Receive descriptor list size. We have one RX buffer per incoming
|
* Receive descriptor ring size - we have one RX buffer per incoming
|
||||||
* packet, so this logic is a little simpler.
|
* packet, so this logic is a little simpler.
|
||||||
*/
|
*/
|
||||||
#define GEM_NRXDESC 256
|
#define GEM_NRXDESC 256
|
||||||
@ -64,7 +64,7 @@
|
|||||||
#define GEM_RXOWN_TICKS (hz / 50)
|
#define GEM_RXOWN_TICKS (hz / 50)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Control structures are DMA'd to the GEM chip. We allocate them
|
* Control structures are DMA'd to the chip. We allocate them
|
||||||
* in a single clump that maps to a single DMA segment to make
|
* in a single clump that maps to a single DMA segment to make
|
||||||
* several things easier.
|
* several things easier.
|
||||||
*/
|
*/
|
||||||
@ -83,9 +83,9 @@ struct gem_control_data {
|
|||||||
struct gem_txsoft {
|
struct gem_txsoft {
|
||||||
struct mbuf *txs_mbuf; /* head of our mbuf chain */
|
struct mbuf *txs_mbuf; /* head of our mbuf chain */
|
||||||
bus_dmamap_t txs_dmamap; /* our DMA map */
|
bus_dmamap_t txs_dmamap; /* our DMA map */
|
||||||
int txs_firstdesc; /* first descriptor in packet */
|
u_int txs_firstdesc; /* first descriptor in packet */
|
||||||
int txs_lastdesc; /* last descriptor in packet */
|
u_int txs_lastdesc; /* last descriptor in packet */
|
||||||
int txs_ndescs; /* number of descriptors */
|
u_int txs_ndescs; /* number of descriptors */
|
||||||
STAILQ_ENTRY(gem_txsoft) txs_q;
|
STAILQ_ENTRY(gem_txsoft) txs_q;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ struct gem_softc {
|
|||||||
u_char sc_enaddr[ETHER_ADDR_LEN];
|
u_char sc_enaddr[ETHER_ADDR_LEN];
|
||||||
struct callout sc_tick_ch; /* tick callout */
|
struct callout sc_tick_ch; /* tick callout */
|
||||||
struct callout sc_rx_ch; /* delayed RX callout */
|
struct callout sc_rx_ch; /* delayed RX callout */
|
||||||
int sc_wdog_timer; /* watchdog timer */
|
u_int sc_wdog_timer; /* watchdog timer */
|
||||||
|
|
||||||
void *sc_ih;
|
void *sc_ih;
|
||||||
struct resource *sc_res[3];
|
struct resource *sc_res[3];
|
||||||
@ -141,15 +141,15 @@ struct gem_softc {
|
|||||||
|
|
||||||
u_int sc_flags;
|
u_int sc_flags;
|
||||||
#define GEM_INITED (1 << 0) /* reset persistent regs init'ed */
|
#define GEM_INITED (1 << 0) /* reset persistent regs init'ed */
|
||||||
#define GEM_LINK (1 << 1) /* link is up */
|
#define GEM_DYING (1 << 1) /* detach initiated */
|
||||||
#define GEM_PCI (1 << 2) /* PCI busses are little-endian */
|
#define GEM_LINK (1 << 2) /* link is up */
|
||||||
#define GEM_SERDES (1 << 3) /* use the SERDES */
|
#define GEM_PCI (1 << 3) /* PCI busses are little-endian */
|
||||||
|
#define GEM_PCI66 (1 << 4) /* PCI bus runs at 66MHz */
|
||||||
|
#define GEM_SERDES (1 << 5) /* use the SERDES */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ring buffer DMA stuff
|
* ring buffer DMA stuff
|
||||||
*/
|
*/
|
||||||
bus_dma_segment_t sc_cdseg; /* control data memory */
|
|
||||||
int sc_cdnseg; /* number of segments */
|
|
||||||
bus_dmamap_t sc_cddmamap; /* control data DMA map */
|
bus_dmamap_t sc_cddmamap; /* control data DMA map */
|
||||||
bus_addr_t sc_cddma;
|
bus_addr_t sc_cddma;
|
||||||
|
|
||||||
@ -166,18 +166,18 @@ struct gem_softc {
|
|||||||
#define sc_txdescs sc_control_data->gcd_txdescs
|
#define sc_txdescs sc_control_data->gcd_txdescs
|
||||||
#define sc_rxdescs sc_control_data->gcd_rxdescs
|
#define sc_rxdescs sc_control_data->gcd_rxdescs
|
||||||
|
|
||||||
int sc_txfree; /* number of free TX descriptors */
|
u_int sc_txfree; /* number of free TX descriptors */
|
||||||
int sc_txnext; /* next ready TX descriptor */
|
u_int sc_txnext; /* next ready TX descriptor */
|
||||||
int sc_txwin; /* TX desc. since last TX intr. */
|
u_int sc_txwin; /* TX desc. since last TX intr. */
|
||||||
|
|
||||||
struct gem_txsq sc_txfreeq; /* free TX descsofts */
|
struct gem_txsq sc_txfreeq; /* free TX descsofts */
|
||||||
struct gem_txsq sc_txdirtyq; /* dirty TX descsofts */
|
struct gem_txsq sc_txdirtyq; /* dirty TX descsofts */
|
||||||
|
|
||||||
int sc_rxptr; /* next ready RX desc./descsoft */
|
u_int sc_rxptr; /* next ready RX descriptor/state */
|
||||||
int sc_rxfifosize; /* RX FIFO size (bytes) */
|
u_int sc_rxfifosize; /* RX FIFO size (bytes) */
|
||||||
|
|
||||||
int sc_ifflags;
|
int sc_ifflags;
|
||||||
int sc_csum_features;
|
u_long sc_csum_features;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GEM_BANKN_BARRIER(n, sc, offs, len, flags) \
|
#define GEM_BANKN_BARRIER(n, sc, offs, len, flags) \
|
||||||
@ -238,10 +238,9 @@ do { \
|
|||||||
__m->m_data = __m->m_ext.ext_buf; \
|
__m->m_data = __m->m_ext.ext_buf; \
|
||||||
__rxd->gd_addr = \
|
__rxd->gd_addr = \
|
||||||
GEM_DMA_WRITE((sc), __rxs->rxs_paddr); \
|
GEM_DMA_WRITE((sc), __rxs->rxs_paddr); \
|
||||||
__rxd->gd_flags = \
|
__rxd->gd_flags = GEM_DMA_WRITE((sc), \
|
||||||
GEM_DMA_WRITE((sc), \
|
(((__m->m_ext.ext_size) << GEM_RD_BUFSHIFT) & \
|
||||||
(((__m->m_ext.ext_size) << GEM_RD_BUFSHIFT) \
|
GEM_RD_BUFSIZE) | GEM_RD_OWN); \
|
||||||
& GEM_RD_BUFSIZE) | GEM_RD_OWN); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define GEM_UPDATE_RXDESC(sc, x) \
|
#define GEM_UPDATE_RXDESC(sc, x) \
|
||||||
@ -250,10 +249,9 @@ do { \
|
|||||||
struct gem_desc *__rxd = &sc->sc_rxdescs[(x)]; \
|
struct gem_desc *__rxd = &sc->sc_rxdescs[(x)]; \
|
||||||
struct mbuf *__m = __rxs->rxs_mbuf; \
|
struct mbuf *__m = __rxs->rxs_mbuf; \
|
||||||
\
|
\
|
||||||
__rxd->gd_flags = \
|
__rxd->gd_flags = GEM_DMA_WRITE((sc), \
|
||||||
GEM_DMA_WRITE((sc), \
|
(((__m->m_ext.ext_size) << GEM_RD_BUFSHIFT) & \
|
||||||
(((__m->m_ext.ext_size) << GEM_RD_BUFSHIFT) \
|
GEM_RD_BUFSIZE) | GEM_RD_OWN); \
|
||||||
& GEM_RD_BUFSIZE) | GEM_RD_OWN); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define GEM_LOCK_INIT(_sc, _name) \
|
#define GEM_LOCK_INIT(_sc, _name) \
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
.PATH: ${.CURDIR}/../../dev/gem
|
.PATH: ${.CURDIR}/../../dev/gem
|
||||||
|
|
||||||
KMOD= if_gem
|
KMOD= if_gem
|
||||||
SRCS= if_gem.c if_gem_pci.c device_if.h bus_if.h pci_if.h miibus_if.h
|
SRCS= bus_if.h device_if.h if_gem.c if_gem_pci.c miibus_if.h pci_if.h
|
||||||
|
|
||||||
|
.if ${MACHINE} == "sparc64"
|
||||||
|
SRCS+= if_gem_sbus.c ofw_bus_if.h
|
||||||
|
.endif
|
||||||
|
|
||||||
.include <bsd.kmod.mk>
|
.include <bsd.kmod.mk>
|
||||||
|
Loading…
Reference in New Issue
Block a user