o Revert the part of if_gem.c rev. 1.35 which added a call to gem_stop()

to gem_attach() as the former access softc members not yet initialized
  at that time and gem_reset() actually is enough to stop the chip. [1]
o Revise the use of gem_bitwait(); add bus_barrier() calls before calling
  gem_bitwait() to ensure the respective bit has been written before we
  starting polling on it and poll for the right bits to change, f.e. even
  though we only reset RX we have to actually wait for both GEM_RESET_RX
  and GEM_RESET_TX to clear. Add some additional gem_bitwait() calls in
  places we've been missing them according to the GEM documentation.
  Along with this some excessive DELAYs, which probably only were added
  because of bugs in gem_bitwait() and its use in the first place, as
  well as as have of an gem_bitwait() reimplementation in gem_reset_tx()
  were removed.
o Add gem_reset_rxdma() and use it to deal with GEM_MAC_RX_OVERFLOW errors
  more gracefully as unlike gem_init_locked() it resets the RX DMA engine
  only, causing no link loss and the FIFOs not to be cleared. Also use it
  deal with GEM_INTR_RX_TAG_ERR errors, with previously were unhandled.
  This was based on information obtained from the Linux GEM and OpenSolaris
  ERI drivers.
o Turn on workarounds for silicon bugs in the Apple GMAC variants.
  This was based on information obtained from the Darwin GMAC and Linux GEM
  drivers.
o Turn on "infinite" (i.e. maximum 31 * 64 bytes in length) DMA bursts.
  This greatly improves especially RX performance.
o Optimize the RX path, this consists of:
  - kicking the receiver as soon as we've a spare descriptor in gem_rint()
    again instead of just once after all the ready ones have been handled;
  - kicking the receiver the right way, i.e. as outlined in the GEM
    documentation in batches of 4 and by pointing it to the descriptor
    after the last valid one;
  - calling gem_rint() before gem_tint() in gem_intr() as gem_tint() may
    take quite a while;
  - doubling the size of the RX ring to 256 descriptors.
  Overall the RX performance of a GEM in a 1GHz Sun Fire V210 was improved
  from ~100Mbit/s to ~850Mbit/s.
o In gem_add_rxbuf() don't assign the newly allocated mbuf to rxs_mbuf
  before calling bus_dmamap_load_mbuf_sg(), if bus_dmamap_load_mbuf_sg()
  fails we'll free the newly allocated mbuf, unable to recycle the
  previous one but a NULL pointer dereference instead.
o In gem_init_locked() honor the return value of gem_meminit().
o Simplify gem_ringsize() and dont' return garbage in the default case.
  Based on OpenBSD.
o Don't turn on MAC control, MIF and PCS interrupts unless GEM_DEBUG is
  defined as we don't need/use these interrupts for operation.
o In gem_start_locked() sync the DMA maps of the descriptor rings before
  every kick of the transmitter and not just once after enqueuing all
  packets as the NIC might instantly start transmitting after we kicked
  it the first time.
o Keep state of the link state and use it to enable or disable the MAC
  in gem_mii_statchg() accordingly as well as to return early from
  gem_start_locked() in case the link is down. [3]
o Initialize the maximum frame size to a sane value.
o In gem_mii_statchg() enable carrier extension if appropriate.
o Increment if_ierrors in case of an GEM_MAC_RX_OVERFLOW error and in
  gem_eint(). [3]
o Handle IFF_ALLMULTI correctly; don't set it if we've turned promiscuous
  group mode on and don't clear the flag if we've disabled promiscuous
  group mode (these were mostly NOPs though). [2]
o Let gem_eint() also report GEM_INTR_PERR errors.
o Move setting sc_variant from gem_pci_probe() to gem_pci_attach() as
  device probe methods are not supposed to touch the softc.
o Collapse sc_inited and sc_pci into bits for sc_flags.
o Add CTASSERTs ensuring that GEM_NRXDESC and GEM_NTXDESC are set to
  legal values.
o Correctly set up for 802.3x flow control, though #ifdef out the code
  that actually enables it as this needs more testing and mainly a proper
  framework to support it.
o Correct and add some conversions from hard-coded functions names to
  __func__ which were borked or forgotten in if_gem.c rev. 1.42.
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o In gem_pci_attach() in case attaching fails release the resources in
  the opposite order they were allocated.
o Make gem_reset() static to if_gem.c as it's not needed outside that
  module.
o Remove the GEM_GIGABIT flag and the associated code; GEM_GIGABIT was
  never set and the associated code was in the wrong place.
o Remove sc_mif_config; it was only used to cache the contents of the
  respective register within gem_attach().
o Remove the #ifdef'ed out NetBSD/OpenBSD code for establishing a suspend
  hook as it will never be used on FreeBSD.
o Also probe Apple Intrepid 2 GMAC and Apple Shasta GMAC, add support for
  Apple K2 GMAC. Based on OpenBSD.
o Add support for Sun GBE/P cards, or in other words actually add support
  for cards based on GEM to gem(4). This mainly consists of adding support
  for the TBI of these chips. Along with this the PHY selection code was
  rewritten to hardcode the PHY number for certain configurations as for
  example the PHY of the on-board ERI of Blade 1000 shows up twice causing
  no link as the second incarnation is isolated.
  These changes were ported from OpenBSD with some additional improvements
  and modulo some bugs.
o Add code to if_gem_pci.c allowing to read the MAC-address from the VPD on
  systems without Open Firmware.
  This is an improved version of my variant of the respective code in
  if_hme_pci.c
o Now that gem(4) is MI enable it for all archs.

Pointed out by:	yongari [1]
Suggested by:	rwatson [2], yongari [3]
Tested on:	i386 (GEM), powerpc (GMACs by marcel and yongari),
		sparc64 (ERI and GEM)
Reviewed by:	yongari
Approved by:	re (kensmith)
This commit is contained in:
Marius Strobl 2007-09-26 21:14:18 +00:00
parent ae3b789193
commit 1ed3fed743
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=172334
8 changed files with 790 additions and 427 deletions

View File

@ -33,7 +33,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd June 4, 2007
.Dd September 26, 2007
.Dt GEM 4
.Os
.Sh NAME
@ -74,6 +74,17 @@ Sun ERI 10/100 Mbps Ethernet
.It
Sun GEM Gigabit Ethernet
.El
.Pp
The
following add-on cards are known to work with the
.Nm
driver at this time:
.Pp
.Bl -bullet -compact
.It
Sun Gigabit Ethernet PCI 2.0/3.0 (GBE/P)
(part no.\& 501-4373)
.El
.Sh NOTES
On sparc64 the
.Nm
@ -100,11 +111,7 @@ and the Sun Gigabit Ethernet 2.0/3.0 GBE add-on cards.
.Sh CAVEATS
Currently the
.Nm
driver fails to attach to Sun Gigabit Ethernet 2.0/3.0 (GBE/P) cards,
as the SERDES used on these cards is not supported so far.
The
.Nm
driver will also fail to probe and attach to Sun Gigabit Ethernet 2.0/3.0 (GBE/S) cards,
driver fails to attach to Sun Gigabit Ethernet SBus 2.0/3.0 (GBE/S) cards,
as no SBus front-end has been written so far.
.Sh SEE ALSO
.Xr altq 4 ,

View File

@ -1766,6 +1766,7 @@ device miibus
# fpa: Support for the Digital DEFPA PCI FDDI. `device fddi' is also needed.
# fxp: Intel EtherExpress Pro/100B
# (hint of prefer_iomap can be done to prefer I/O instead of Mem mapping)
# gem: Apple GMAC/Sun ERI/Sun GEM
# hme: Sun HME (Happy Meal Ethernet)
# le: AMD Am7900 LANCE and Am79C9xx PCnet
# lge: Support for PCI gigabit ethernet adapters based on the Level 1
@ -1880,6 +1881,7 @@ device cxgb # Chelsio T3 10 Gigabit Ethernet
device dc # DEC/Intel 21143 and various workalikes
device fxp # Intel EtherExpress PRO/100B (82557, 82558)
hint.fxp.0.prefer_iomap="0"
device gem # Apple GMAC/Sun ERI/Sun GEM
device hme # Sun HME (Happy Meal Ethernet)
device lge # Level 1 LXT1001 gigabit Ethernet
device my # Myson Fast Ethernet (MTD80X, MTD89X)

File diff suppressed because it is too large Load Diff

View File

@ -25,50 +25,41 @@
* 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$");
/*
* PCI bindings for Sun GEM ethernet controllers.
* PCI bindings for Apple GMAC, Sun ERI and Sun GEM Ethernet controllers
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/malloc.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 <machine/endian.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <machine/bus.h>
#include <machine/resource.h>
#if defined(__powerpc__) || defined(__sparc64__)
#include <dev/ofw/openfirm.h>
#include <machine/ofw_machdep.h>
#include <sys/rman.h>
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>
#endif
#include <machine/resource.h>
#include <dev/gem/if_gemreg.h>
#include <dev/gem/if_gemvar.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include "miibus_if.h"
@ -106,41 +97,35 @@ static driver_t gem_pci_driver = {
sizeof(struct gem_softc)
};
DRIVER_MODULE(gem, pci, gem_pci_driver, gem_devclass, 0, 0);
MODULE_DEPEND(gem, pci, 1, 1, 1);
MODULE_DEPEND(gem, ether, 1, 1, 1);
struct gem_pci_dev {
u_int32_t gpd_devid;
int gpd_variant;
char *gpd_desc;
static const struct gem_pci_dev {
uint32_t gpd_devid;
int gpd_variant;
const char *gpd_desc;
} gem_pci_devlist[] = {
{ 0x1101108e, GEM_SUN_GEM, "Sun ERI 10/100 Ethernet Adaptor" },
{ 0x2bad108e, GEM_SUN_GEM, "Sun GEM Gigabit Ethernet Adaptor" },
{ 0x0021106b, GEM_APPLE_GMAC, "Apple GMAC Ethernet Adaptor" },
{ 0x0024106b, GEM_APPLE_GMAC, "Apple GMAC2 Ethernet Adaptor" },
{ 0x0032106b, GEM_APPLE_GMAC, "Apple GMAC3 Ethernet Adaptor" },
{ 0x1101108e, GEM_SUN_ERI, "Sun ERI 10/100 Ethernet" },
{ 0x2bad108e, GEM_SUN_GEM, "Sun GEM Gigabit Ethernet" },
{ 0x0021106b, GEM_APPLE_GMAC, "Apple UniNorth GMAC Ethernet" },
{ 0x0024106b, GEM_APPLE_GMAC, "Apple Pangea GMAC Ethernet" },
{ 0x0032106b, GEM_APPLE_GMAC, "Apple UniNorth2 GMAC Ethernet" },
{ 0x004c106b, GEM_APPLE_K2_GMAC,"Apple K2 GMAC Ethernet" },
{ 0x0051106b, GEM_APPLE_GMAC, "Apple Shasta GMAC Ethernet" },
{ 0x006b106b, GEM_APPLE_GMAC, "Apple Intrepid 2 GMAC Ethernet" },
{ 0, 0, NULL }
};
/*
* Attach routines need to be split out to different bus-specific files.
*/
static int
gem_pci_probe(dev)
device_t dev;
{
int i;
u_int32_t devid;
struct gem_softc *sc;
devid = pci_get_devid(dev);
for (i = 0; gem_pci_devlist[i].gpd_desc != NULL; i++) {
if (devid == gem_pci_devlist[i].gpd_devid) {
if (pci_get_devid(dev) == gem_pci_devlist[i].gpd_devid) {
device_set_desc(dev, gem_pci_devlist[i].gpd_desc);
sc = device_get_softc(dev);
sc->sc_variant = gem_pci_devlist[i].gpd_variant;
return (BUS_PROBE_DEFAULT);
}
}
@ -149,7 +134,7 @@ gem_pci_probe(dev)
}
static struct resource_spec gem_pci_res_spec[] = {
{ SYS_RES_MEMORY, PCI_GEM_BASEADDR, RF_ACTIVE },
{ SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_SHAREABLE | RF_ACTIVE },
{ -1, 0 }
};
@ -158,7 +143,24 @@ static int
gem_pci_attach(dev)
device_t dev;
{
struct gem_softc *sc = device_get_softc(dev);
struct gem_softc *sc;
int i;
#if !(defined(__powerpc__) || defined(__sparc64__))
int j;
#endif
sc = device_get_softc(dev);
sc->sc_variant = GEM_UNKNOWN;
for (i = 0; gem_pci_devlist[i].gpd_desc != NULL; i++) {
if (pci_get_devid(dev) == gem_pci_devlist[i].gpd_devid) {
sc->sc_variant = gem_pci_devlist[i].gpd_variant;
break;
}
}
if (sc->sc_variant == GEM_UNKNOWN) {
device_printf(dev, "unknown adaptor\n");
return (ENXIO);
}
pci_enable_busmaster(dev);
@ -170,7 +172,7 @@ gem_pci_attach(dev)
pci_set_intpin(dev, 1);
sc->sc_dev = dev;
sc->sc_pci = 1; /* XXX */
sc->sc_flags |= GEM_PCI; /* XXX */
if (bus_alloc_resources(dev, gem_pci_res_spec, sc->sc_res)) {
device_printf(dev, "failed to allocate resources\n");
@ -180,8 +182,93 @@ gem_pci_attach(dev)
GEM_LOCK_INIT(sc, device_get_nameunit(dev));
/* All platform that this driver is used on must provide this. */
#if defined(__powerpc__) || defined(__sparc64__)
OF_getetheraddr(dev, sc->sc_enaddr);
#else
/*
* Dig out VPD (vital product data) and read NA (network address).
* The VPD of GEM resides in the PCI Expansion ROM (PCI FCode) and
* can't be accessed via the PCI capability pointer.
* ``Writing FCode 3.x Programs'' (newer ones, dated 1997 and later)
* chapter 2 describes the data structure.
*/
#define PCI_ROMHDR_SIZE 0x1c
#define PCI_ROMHDR_SIG 0x00
#define PCI_ROMHDR_SIG_MAGIC 0xaa55 /* little endian */
#define PCI_ROMHDR_PTR_DATA 0x18
#define PCI_ROM_SIZE 0x18
#define PCI_ROM_SIG 0x00
#define PCI_ROM_SIG_MAGIC 0x52494350 /* "PCIR", endian */
/* reversed */
#define PCI_ROM_VENDOR 0x04
#define PCI_ROM_DEVICE 0x06
#define PCI_ROM_PTR_VPD 0x08
#define PCI_VPDRES_BYTE0 0x00
#define PCI_VPDRES_ISLARGE(x) ((x) & 0x80)
#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_MSB 0x02
#define PCI_VPDRES_LARGE_DATA 0x03
#define PCI_VPD_SIZE 0x03
#define PCI_VPD_KEY0 0x00
#define PCI_VPD_KEY1 0x01
#define PCI_VPD_LEN 0x02
#define PCI_VPD_DATA 0x03
#define GEM_ROM_READ_N(n, sc, offs) \
bus_read_ ## n ((sc)->sc_res[0], GEM_PCI_ROM_OFFSET + (offs))
#define GEM_ROM_READ_1(sc, offs) GEM_ROM_READ_N(1, (sc), (offs))
#define GEM_ROM_READ_2(sc, offs) GEM_ROM_READ_N(2, (sc), (offs))
#define GEM_ROM_READ_4(sc, offs) GEM_ROM_READ_N(4, (sc), (offs))
/* Read PCI Expansion ROM header. */
if (GEM_ROM_READ_2(sc, PCI_ROMHDR_SIG) != PCI_ROMHDR_SIG_MAGIC ||
(i = GEM_ROM_READ_2(sc, PCI_ROMHDR_PTR_DATA)) < PCI_ROMHDR_SIZE) {
device_printf(dev, "unexpected PCI Expansion ROM header\n");
goto fail;
}
/* Read PCI Expansion ROM data. */
if (GEM_ROM_READ_4(sc, i + PCI_ROM_SIG) != PCI_ROM_SIG_MAGIC ||
GEM_ROM_READ_2(sc, i + PCI_ROM_VENDOR) != pci_get_vendor(dev) ||
GEM_ROM_READ_2(sc, i + PCI_ROM_DEVICE) != pci_get_device(dev) ||
(j = GEM_ROM_READ_2(sc, i + PCI_ROM_PTR_VPD)) < i + PCI_ROM_SIZE) {
device_printf(dev, "unexpected PCI Expansion ROM data\n");
goto fail;
}
/*
* Read PCI VPD.
* SUNW,pci-gem cards have a single large resource VPD-R tag
* containing one NA. The VPD used is not in PCI 2.2 standard
* format however. The length in the resource header is in big
* endian and the end tag is non-standard (0x79) and followed
* by an all-zero "checksum" byte. Sun calls this a "Fresh
* Choice Ethernet" VPD...
*/
if (PCI_VPDRES_ISLARGE(GEM_ROM_READ_1(sc, j + PCI_VPDRES_BYTE0)) == 0 ||
PCI_VPDRES_LARGE_NAME(GEM_ROM_READ_1(sc, 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_MSB)) !=
PCI_VPD_SIZE + ETHER_ADDR_LEN ||
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_KEY0) !=
0x4e /* N */ ||
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_KEY1) !=
0x41 /* A */ ||
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_LEN) !=
ETHER_ADDR_LEN ||
GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_DATA +
ETHER_ADDR_LEN) != 0x79) {
device_printf(dev, "unexpected PCI VPD\n");
goto fail;
}
bus_read_region_1(sc->sc_res[0], GEM_PCI_ROM_OFFSET + j +
PCI_VPDRES_LARGE_DATA + PCI_VPD_DATA, sc->sc_enaddr,
ETHER_ADDR_LEN);
#endif
/*
* call the main configure
@ -200,8 +287,8 @@ gem_pci_attach(dev)
return (0);
fail:
bus_release_resources(dev, gem_pci_res_spec, sc->sc_res);
GEM_LOCK_DESTROY(sc);
bus_release_resources(dev, gem_pci_res_spec, sc->sc_res);
return (ENXIO);
}

View File

@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: NetBSD: gemreg.h,v 1.15 2002/05/11 00:36:02 matt Exp
* from: NetBSD: gemreg.h,v 1.8 2005/12/11 12:21:26 christos Exp
*
* $FreeBSD$
*/
@ -55,10 +55,15 @@
/* Bits in GEM_CONFIG register */
#define GEM_CONFIG_BURST_64 0x000000000 /* 0->infininte, 1->64KB */
#define GEM_CONFIG_BURST_INF 0x000000001 /* 0->infininte, 1->64KB */
#define GEM_CONFIG_BURST_64 0x000000000 /* maximum burst size 64KB */
#define GEM_CONFIG_BURST_INF 0x000000001 /* infinite for entire packet */
#define GEM_CONFIG_TXDMA_LIMIT 0x00000003e
#define GEM_CONFIG_RXDMA_LIMIT 0x0000007c0
/* GEM_CONFIG_RONPAULBIT and GEM_CONFIG_BUG2FIX are Apple only. */
#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
@ -68,31 +73,35 @@
#define GEM_STATUS_TX_COMPL 0xfff800000 /* TX completion reg. */
/* Interrupt bits, for both the GEM_STATUS and GEM_INTMASK regs. */
/*
* 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_PCS 0x000002000
#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" \
#define GEM_INTR_BITS "\177\020" \
"b\0INTME\0b\1TXEMPTY\0b\2TXDONE\0" \
"b\4RXDONE\0b\5RXNOBUF\0b\6RX_TAG_ERR\0" \
"b\15PCS\0b\16TXMAC\0b\17RXMAC\0" \
"b\20MAC_CONTROL\0b\21MIF\0b\22BERR\0\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 */
@ -100,6 +109,8 @@
#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"
/* GEM_RESET register bits -- TX and RX self clear when complete. */
@ -188,7 +199,7 @@
#define GEM_RX_CONFIG_RXRING_SZ 0x0000001e /* RX ring size */
#define GEM_RX_CONFIG_BATCH_DIS 0x00000020 /* desc batching disable */
#define GEM_RX_CONFIG_FBOFF 0x00001c00 /* first byte offset */
#define GEM_RX_CONFIG_CXM_START 0x000fe000 /* checksum start offset */
#define GEM_RX_CONFIG_CXM_START 0x000fe000 /* cksum start offset bytes */
#define GEM_RX_CONFIG_FIFO_THRS 0x07000000 /* fifo threshold size */
#define GEM_THRSH_64 0
@ -232,7 +243,7 @@
#define GEM_MAC_IPG0 0x6040 /* inter packet gap 0 */
#define GEM_MAC_IPG1 0x6044 /* inter packet gap 1 */
#define GEM_MAC_IPG2 0x6048 /* inter packet gap 2 */
#define GEM_MAC_SLOT_TIME 0x604c
#define GEM_MAC_SLOT_TIME 0x604c /* slot time, bits 0-7 */
#define GEM_MAC_MAC_MIN_FRAME 0x6050
#define GEM_MAC_MAC_MAX_FRAME 0x6054
#define GEM_MAC_PREAMBLE_LEN 0x6058
@ -285,7 +296,7 @@
#define GEM_MAC_RX_CRC_ERR_CNT 0x6124
#define GEM_MAC_RX_CODE_VIOL 0x6128
#define GEM_MAC_RANDOM_SEED 0x6130
#define GEM_MAC_MAC_STATE 0x6134 /* MAC sstate machine reg */
#define GEM_MAC_MAC_STATE 0x6134 /* MAC state machine reg */
/* GEM_MAC_SEND_PAUSE_CMD register bits */
@ -319,7 +330,12 @@
#define GEM_MAC_PAUSED 0x00000001 /* Pause received */
#define GEM_MAC_PAUSE 0x00000002 /* enter pause state */
#define GEM_MAC_RESUME 0x00000004 /* exit pause state */
#define GEM_MAC_PAUSE_TIME 0xffff0000
#define GEM_MAC_PAUSE_TIME_SLTS 0xffff0000 /* pause time in slots */
#define GEM_MAC_STATUS_BITS "\177\020b\0PAUSED\0b\1PAUSE\0b\2RESUME\0\0"
#define GEM_MAC_PAUSE_TIME_SHFT 16
#define GEM_MAC_PAUSE_TIME(x) \
(((x) & GEM_MAC_PAUSE_TIME_SLTS) >> GEM_MAC_PAUSE_TIME_SHFT)
/* GEM_MAC_XIF_CONFIG register bits */
#define GEM_MAC_XIF_TX_MII_ENA 0x00000001 /* Enable XIF output drivers */
@ -329,11 +345,22 @@
#define GEM_MAC_XIF_MII_BUF_ENA 0x00000010 /* Enable MII recv buffers */
#define GEM_MAC_XIF_LINK_LED 0x00000020 /* force link LED active */
#define GEM_MAC_XIF_FDPLX_LED 0x00000040 /* force FDPLX LED active */
#define GEM_MAC_XIF_BITS "\177\020b\0TXMIIENA\0b\1MIILOOP\0b\2NOECHO" \
"\0b\3GMII\0b\4MIIBUFENA\0b\5LINKLED\0" \
"b\6FDLED\0\0"
/*
* GEM_MAC_SLOT_TIME register
* The slot time is used as PAUSE time unit, value depends on whether carrier
* extension is enabled.
*/
#define GEM_MAC_SLOT_TIME_CARR_EXTEND 0x200
#define GEM_MAC_SLOT_TIME_NORMAL 0x40
/* GEM_MAC_TX_CONFIG register bits */
#define GEM_MAC_TX_ENABLE 0x00000001 /* TX enable */
#define GEM_MAC_TX_IGN_CARRIER 0x00000002 /* Ignore carrier sense */
#define GEM_MAC_TX_IGN_COLLIS 0x00000004 /* ignore collitions */
#define GEM_MAC_TX_IGN_COLLIS 0x00000004 /* ignore collisions */
#define GEM_MAC_TX_ENA_IPG0 0x00000008 /* extend Rx-to-TX IPG */
#define GEM_MAC_TX_NGU 0x00000010 /* Never give up */
#define GEM_MAC_TX_NGU_LIMIT 0x00000020 /* Never give up limit */
@ -342,6 +369,11 @@
#define GEM_MAC_TX_NO_FCS 0x00000100 /* no FCS will be generated */
#define GEM_MAC_TX_CARR_EXTEND 0x00000200 /* Ena TX Carrier Extension */
/* Carrier Extension is required for half duplex Gbps operation */
#define GEM_MAC_TX_CONFIG_BITS "\177\020" \
"b\0TXENA\0b\1IGNCAR\0b\2IGNCOLLIS\0" \
"b\3IPG0ENA\0b\4TXNGU\0b\5TXNGULIM\0" \
"b\6NOBKOFF\0b\7SLOWDN\0b\x8NOFCS\0" \
"b\x9TXCARREXT\0\0"
/* GEM_MAC_RX_CONFIG register bits */
@ -358,12 +390,17 @@
* Carrier Extension enables reception of packet bursts generated by
* senders with carrier extension enabled.
*/
#define GEM_MAC_RX_CONFIG_BITS "\177\020" \
"b\0RXENA\0b\1STRPAD\0b\2STRCRC\0" \
"b\3PROMIS\0b\4PROMISCGRP\0b\5HASHFLTR\0" \
"b\6ADDRFLTR\0b\7ERRCHKDIS\0b\x9TXCARREXT\0\0"
/* GEM_MAC_CONTROL_CONFIG bits */
#define GEM_MAC_CC_TX_PAUSE 0x00000001 /* send 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_BITS "\177\020b\0TXPAUSE\0b\1RXPAUSE\0b\2NOPAUSE\0\0"
/* GEM MIF registers */
@ -395,14 +432,16 @@
/* GEM_MIF_CONFIG register bits */
#define GEM_MIF_CONFIG_PHY_SEL 0x00000001 /* PHY select */
#define GEM_MIF_CONFIG_PHY_SEL 0x00000001 /* PHY select, 0=MDIO0 */
#define GEM_MIF_CONFIG_POLL_ENA 0x00000002 /* poll 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_MDI0 0x00000100 /* MDIO_0 Data/MDIO_0 atached */
#define GEM_MIF_CONFIG_MDI1 0x00000200 /* MDIO_1 Data/MDIO_1 atached */
#define GEM_MIF_CONFIG_PHY_ADR 0x00007c00 /* poll PHY address */
/* MDI0 is onboard tranciever MID1 is external, PHYAD for both is 0 */
/* MDI0 is onboard transceiver MDI1 is external, PHYAD for both is 0 */
#define GEM_MIF_CONFIG_BITS "\177\020b\0PHYSEL\0b\1POLL\0b\2BBENA\0" \
"b\x8MDIO0\0b\x9MDIO1\0\0"
/* GEM_MIF_BASIC_STATUS and GEM_MIF_INTERRUPT_MASK bits */
@ -416,47 +455,52 @@
*/
/* The GEM PCS/Serial link register. */
/* The GEM PCS/Serial link registers. */
/* DO NOT TOUCH THESE REGISTERS ON ERI -- IT HARD HANGS. */
#define GEM_MII_CONTROL 0x9000
#define GEM_MII_STATUS 0x9004
#define GEM_MII_ANAR 0x9008 /* MII advertisement reg */
#define GEM_MII_ANLPAR 0x900c /* LP ability reg */
#define GEM_MII_ANLPAR 0x900c /* Link Partner Ability Reg */
#define GEM_MII_CONFIG 0x9010
#define GEM_MII_STATE_MACHINE 0x9014
#define GEM_MII_INTERRUP_STATUS 0x9018
#define GEM_MII_INTERRUP_STATUS 0x9018 /* PCS interrupt state */
#define GEM_MII_DATAPATH_MODE 0x9050
#define GEM_MII_SLINK_CONTROL 0x9054 /* Serial link control */
#define GEM_MII_OUTPUT_SELECT 0x9058
#define GEM_MII_SLINK_STATUS 0x905c /* serial link status */
/* GEM_MII_CONTROL bits */
/*
* DO NOT TOUCH THIS REGISTER ON ERI -- IT HARD HANGS.
*/
/* GEM_MII_CONTROL bits - PCS "BMCR" (Basic Mode Control Reg) */
#define GEM_MII_CONTROL_RESET 0x00008000
#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 negotioation */
#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_BITS "\177\020b\7COLTST\0b\x8_FD\0b\x9RAN\0" \
"b\xaISOLATE\0b\xbPWRDWN\0b\xc_ANEG\0" \
"b\xdGIGE\0b\xeLOOP\0b\xfRESET\0\0"
/* GEM_MII_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_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_EXTCAP 0x00000001 /* extended register capability */
#define GEM_MII_STATUS_BITS "\177\020b\0EXTCAP\0b\1JABBER\0b\2LINKSTS\0" \
"b\3ACFG\0b\4REMFLT\0b\5ANEGCPT\0b\x9GBHDX\0" \
"b\xaGBFDX\0\0"
/* GEM_MII_ANAR and GEM_MII_ANLAR reg bits */
/* GEM_MII_ANAR and GEM_MII_ANLPAR reg bits */
#define GEM_MII_ANEG_NP 0x00008000 /* next page bit */
#define GEM_MII_ANEG_ACK 0x00004000 /* ack reception of */
/* Link Partner Capability */
@ -465,27 +509,59 @@
#define GEM_MII_ANEG_SYM_PAUSE 0x00000080 /* symmetric pause */
#define GEM_MII_ANEG_HLF_DUPLX 0x00000040
#define GEM_MII_ANEG_FUL_DUPLX 0x00000020
#define GEM_MII_ANEG_BITS "\177\020b\5FDX\0b\6HDX\0b\7SYMPAUSE\0" \
"\b\x8_ASYMPAUSE\0\b\xdREMFLT\0\b\xeLPACK\0" \
"\b\xfNPBIT\0\0"
/* GEM_MII_CONFIG reg */
#define GEM_MII_CONFIG_TIMER 0x0000001c /* link monitor timer values */
#define GEM_MII_CONFIG_TIMER 0x0000000e /* link monitor timer values */
#define GEM_MII_CONFIG_ANTO 0x00000020 /* 10ms ANEG timer override */
#define GEM_MII_CONFIG_JS 0x00000018 /* Jitter Study, 0 normal
* 1 high freq, 2 low freq */
#define GEM_MII_CONFIG_SDL 0x00000004 /* Signal Detect active low */
#define GEM_MII_CONFIG_SDO 0x00000002 /* Signal Detect Override */
#define GEM_MII_CONFIG_ENABLE 0x00000001 /* Enable PCS */
#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
* No mask register; mask with the global interrupt mask register.
*/
#define GEM_MII_INTERRUP_LINK 0x00000004 /* PCS link status change */
/* GEM_MII_DATAPATH_MODE reg */
#define GEM_MII_DATAPATH_SERIAL 0x00000001 /* Serial link */
#define GEM_MII_DATAPATH_SERDES 0x00000002 /* Use PCS via 10bit interfac */
#define GEM_MII_DATAPATH_MII 0x00000004 /* Use MII, not PCS */
#define GEM_MII_DATAPATH_MII 0x00000004 /* Use {G}MII, not PCS */
#define GEM_MII_DATAPATH_MIIOUT 0x00000008 /* enable serial output on GMII */
#define GEM_MII_DATAPATH_BITS "\177\020" \
"b\0SERIAL\0b\1SERDES\0b\2MII\0b\3MIIOUT\0\0"
/* GEM_MII_SLINK_CONTROL reg */
#define GEM_MII_SLINK_LOOPBACK 0x00000001 /* enable loopback at sl */
#define GEM_MII_SLINK_LOOPBACK 0x00000001 /* enable loopback at sl, logic
* reversed for SERDES */
#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_EMPHASIS 0x00000008 /* enable emphasis */
#define GEM_MII_SLINK_SELFTEST 0x000001c0
#define GEM_MII_SLINK_POWER_OFF 0x00000200 /* Power down serial link */
#define GEM_MII_SLINK_CONTROL_BITS \
"\177\020b\0LOOP\0b\1ENASYNC\0b\2LOCKREF" \
"\0b\3EMPHASIS\0b\x9PWRDWN\0\0"
/* GEM_MII_SLINK_STATUS reg */
@ -494,6 +570,13 @@
#define GEM_MII_SLINK_COMMA 0x00000002 /* waiting for comma detect */
#define GEM_MII_SLINK_SYNC 0x00000003 /* recv data synchronized */
/*
* PCI Expansion ROM runtime access
* Sun GEMs map a 1MB space for the PCI Expansion ROM as the second half
* of the first register bank, although they only support up to 64KB ROMs.
*/
#define GEM_PCI_ROM_OFFSET 0x100000
#define GEM_PCI_ROM_SIZE 0x10000
/* Wired GEM PHY addresses */
#define GEM_PHYAD_INTERNAL 1
@ -524,7 +607,7 @@ struct gem_desc {
*/
/* Receive flags */
#define GEM_RD_CHECKSUM 0x000000000000ffffLL
#define GEM_RD_CHECKSUM 0x000000000000ffffLL /* is the complement */
#define GEM_RD_BUFSIZE 0x000000007fff0000LL
#define GEM_RD_OWN 0x0000000080000000LL /* 1 - owned by h/w */
#define GEM_RD_HASHVAL 0x0ffff00000000000LL
@ -533,9 +616,6 @@ struct gem_desc {
#define GEM_RD_BAD_CRC 0x4000000000000000LL
#define GEM_RD_BUFSHIFT 16
#define GEM_RD_BUFLEN(x) (((x)&GEM_RD_BUFSIZE)>>GEM_RD_BUFSHIFT)
/* PCI support */
#define PCI_GEM_BASEADDR 0x10
#define GEM_RD_BUFLEN(x) (((x) & GEM_RD_BUFSIZE) >> GEM_RD_BUFSHIFT)
#endif

View File

@ -58,9 +58,8 @@
* Receive descriptor list size. We have one Rx buffer per incoming
* packet, so this logic is a little simpler.
*/
#define GEM_NRXDESC 128
#define GEM_NRXDESC 256
#define GEM_NRXDESC_MASK (GEM_NRXDESC - 1)
#define GEM_PREVRX(x) ((x - 1) & GEM_NRXDESC_MASK)
#define GEM_NEXTRX(x) ((x + 1) & GEM_NRXDESC_MASK)
/*
@ -118,15 +117,15 @@ struct gem_rxsoft {
*/
struct gem_softc {
struct ifnet *sc_ifp;
struct mtx sc_mtx;
device_t sc_miibus;
struct mii_data *sc_mii; /* MII media control */
device_t sc_dev; /* generic device information */
u_char sc_enaddr[6];
u_char sc_enaddr[ETHER_ADDR_LEN];
struct callout sc_tick_ch; /* tick callout */
struct callout sc_rx_ch; /* delayed rx callout */
int sc_wdog_timer; /* watchdog timer */
/* The following bus handles are to be provided by the bus front-end */
void *sc_ih;
struct resource *sc_res[2];
bus_dma_tag_t sc_pdmatag; /* parent bus dma tag */
@ -135,18 +134,24 @@ struct gem_softc {
bus_dma_tag_t sc_cdmatag; /* control data bus dma tag */
bus_dmamap_t sc_dmamap; /* bus dma handle */
int sc_phys[2]; /* MII instance -> PHY map */
int sc_phyad; /* addr. of PHY to use or -1 for any */
int sc_mif_config; /* Selected MII reg setting */
int sc_pci; /* XXXXX -- PCI buses are LE. */
u_int sc_variant; /* which GEM are we dealing with? */
#define GEM_UNKNOWN 0 /* don't know */
#define GEM_SUN_GEM 1 /* Sun GEM variant */
#define GEM_APPLE_GMAC 2 /* Apple GMAC variant */
#define GEM_SUN_GEM 1 /* Sun GEM */
#define GEM_SUN_ERI 2 /* Sun ERI */
#define GEM_APPLE_GMAC 3 /* Apple GMAC */
#define GEM_APPLE_K2_GMAC 4 /* Apple K2 GMAC */
#define GEM_IS_APPLE(sc) \
((sc)->sc_variant == GEM_APPLE_GMAC || \
(sc)->sc_variant == GEM_APPLE_K2_GMAC)
u_int sc_flags; /* */
#define GEM_GIGABIT 0x0001 /* has a gigabit PHY */
#define GEM_INITED (1 << 0) /* reset persistent regs initialized */
#define GEM_LINK (1 << 1) /* link is up */
#define GEM_PCI (1 << 2) /* XXX PCI busses are little-endian */
#define GEM_SERDES (1 << 3) /* use the SERDES */
/*
* Ring buffer DMA stuff.
@ -169,33 +174,31 @@ struct gem_softc {
#define sc_txdescs sc_control_data->gcd_txdescs
#define sc_rxdescs sc_control_data->gcd_rxdescs
int sc_txfree; /* number of free Tx descriptors */
int sc_txnext; /* next ready Tx descriptor */
int sc_txwin; /* Tx descriptors since last Tx int */
int sc_txfree; /* number of free Tx descriptors */
int sc_txnext; /* next ready Tx descriptor */
int sc_txwin; /* Tx descriptors since last Tx int */
struct gem_txsq sc_txfreeq; /* free Tx descsofts */
struct gem_txsq sc_txdirtyq; /* dirty Tx descsofts */
int sc_rxptr; /* next ready RX descriptor/descsoft */
int sc_rxfifosize; /* Rx FIFO size (bytes) */
int sc_rxptr; /* next ready RX descriptor/descsoft */
int sc_rxfifosize; /* Rx FIFO size (bytes) */
/* ========== */
int sc_inited;
int sc_debug;
int sc_ifflags;
int sc_csum_features;
struct mtx sc_mtx;
};
#define GEM_DMA_READ(sc, v) (((sc)->sc_pci) ? le64toh(v) : be64toh(v))
#define GEM_DMA_WRITE(sc, v) (((sc)->sc_pci) ? htole64(v) : htobe64(v))
#define GEM_DMA_READ(sc, v) \
((((sc)->sc_flags & GEM_PCI) != 0) ? le64toh(v) : be64toh(v))
#define GEM_DMA_WRITE(sc, v) \
((((sc)->sc_flags & GEM_PCI) != 0) ? htole64(v) : htobe64(v))
#define GEM_CDTXADDR(sc, x) ((sc)->sc_cddma + GEM_CDTXOFF((x)))
#define GEM_CDRXADDR(sc, x) ((sc)->sc_cddma + GEM_CDRXOFF((x)))
#define GEM_CDSYNC(sc, ops) \
bus_dmamap_sync((sc)->sc_cdmatag, (sc)->sc_cddmamap, (ops)); \
bus_dmamap_sync((sc)->sc_cdmatag, (sc)->sc_cddmamap, (ops));
#define GEM_INIT_RXDESC(sc, x) \
do { \
@ -208,7 +211,19 @@ do { \
GEM_DMA_WRITE((sc), __rxs->rxs_paddr); \
__rxd->gd_flags = \
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); \
} while (0)
#define GEM_UPDATE_RXDESC(sc, x) \
do { \
struct gem_rxsoft *__rxs = &sc->sc_rxsoft[(x)]; \
struct gem_desc *__rxd = &sc->sc_rxdescs[(x)]; \
struct mbuf *__m = __rxs->rxs_mbuf; \
\
__rxd->gd_flags = \
GEM_DMA_WRITE((sc), \
(((__m->m_ext.ext_size) << GEM_RD_BUFSHIFT) \
& GEM_RD_BUFSIZE) | GEM_RD_OWN); \
} while (0)
@ -231,8 +246,6 @@ void gem_intr(void *);
int gem_mediachange(struct ifnet *);
void gem_mediastatus(struct ifnet *, struct ifmediareq *);
void gem_reset(struct gem_softc *);
/* MII methods & callbacks */
int gem_mii_readreg(device_t, int, int);
int gem_mii_writereg(device_t, int, int, int);
@ -240,5 +253,4 @@ void gem_mii_statchg(device_t);
#endif /* _KERNEL */
#endif

View File

@ -87,7 +87,7 @@ SUBDIR= ${_3dfx} \
firewire \
firmware \
fxp \
${_gem} \
gem \
geom \
${_harp} \
hatm \
@ -579,7 +579,6 @@ _ath_hal= ath_hal
_ath_rate_amrr= ath_rate_amrr
_ath_rate_onoe= ath_rate_onoe
_ath_rate_sample=ath_rate_sample
_gem= gem
_powermac_nvram= powermac_nvram
_smbfs= smbfs
.endif
@ -592,7 +591,6 @@ _ath_rate_onoe= ath_rate_onoe
_ath_rate_sample=ath_rate_sample
_auxio= auxio
_em= em
_gem= gem
_i2c= i2c
_sound= sound
.endif

View File

@ -20,7 +20,6 @@ options SC_OFWFB # OFW frame buffer
# Standard busses
device pci
device gem # Sun GEM/Sun ERI/Apple GMAC
device ofwd # Open Firmware disks