updated bge to current

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28602 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2008-11-11 12:20:21 +00:00
parent 59795d428e
commit 11d2eeb7eb
3 changed files with 461 additions and 143 deletions

View File

@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/bge/if_bge.c,v 1.198 2007/09/30 11:05:14 marius Exp $");
__FBSDID("$FreeBSD: src/sys/dev/bge/if_bge.c,v 1.215 2008/10/27 22:10:01 marius Exp $");
/*
* Broadcom BCM570x family gigabit ethernet driver for FreeBSD.
@ -134,7 +134,7 @@ MODULE_DEPEND(bge, miibus, 1, 1, 1);
* ID burned into it, though it will always be overriden by the vendor
* ID in the EEPROM. Just to be safe, we cover all possibilities.
*/
static struct bge_type {
static const struct bge_type {
uint16_t bge_vid;
uint16_t bge_did;
} bge_devs[] = {
@ -169,6 +169,7 @@ static struct bge_type {
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5715S },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5720 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5721 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5722 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5750 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5750M },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5751 },
@ -195,6 +196,8 @@ static struct bge_type {
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5901 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5901A2 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5903M },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5906 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5906M },
{ SK_VENDORID, SK_DEVICEID_ALTIMA },
@ -267,10 +270,13 @@ static const struct bge_revision {
{ BGE_CHIPID_BCM5755_A0, "BCM5755 A0" },
{ BGE_CHIPID_BCM5755_A1, "BCM5755 A1" },
{ BGE_CHIPID_BCM5755_A2, "BCM5755 A2" },
{ BGE_CHIPID_BCM5722_A0, "BCM5722 A0" },
/* 5754 and 5787 share the same ASIC ID */
{ BGE_CHIPID_BCM5787_A0, "BCM5754/5787 A0" },
{ BGE_CHIPID_BCM5787_A1, "BCM5754/5787 A1" },
{ BGE_CHIPID_BCM5787_A2, "BCM5754/5787 A2" },
{ BGE_CHIPID_BCM5906_A1, "BCM5906 A1" },
{ BGE_CHIPID_BCM5906_A2, "BCM5906 A2" },
{ 0, NULL }
};
@ -293,6 +299,7 @@ static const struct bge_revision bge_majorrevs[] = {
{ BGE_ASICREV_BCM5755, "unknown BCM5755" },
/* 5754 and 5787 share the same ASIC ID */
{ BGE_ASICREV_BCM5787, "unknown BCM5754/5787" },
{ BGE_ASICREV_BCM5906, "unknown BCM5906" },
{ 0, NULL }
};
@ -305,6 +312,9 @@ static const struct bge_revision bge_majorrevs[] = {
const struct bge_revision * bge_lookup_rev(uint32_t);
const struct bge_vendor * bge_lookup_vendor(uint16_t);
typedef int (*bge_eaddr_fcn_t)(struct bge_softc *, uint8_t[]);
static int bge_probe(device_t);
static int bge_attach(device_t);
static int bge_detach(device_t);
@ -315,6 +325,12 @@ static void bge_dma_map_addr(void *, bus_dma_segment_t *, int, int);
static int bge_dma_alloc(device_t);
static void bge_dma_free(struct bge_softc *);
static int bge_get_eaddr_fw(struct bge_softc *sc, uint8_t ether_addr[]);
static int bge_get_eaddr_mem(struct bge_softc *, uint8_t[]);
static int bge_get_eaddr_nvram(struct bge_softc *, uint8_t[]);
static int bge_get_eaddr_eeprom(struct bge_softc *, uint8_t[]);
static int bge_get_eaddr(struct bge_softc *, uint8_t[]);
static void bge_txeof(struct bge_softc *);
static void bge_rxeof(struct bge_softc *);
@ -337,6 +353,9 @@ static int bge_ifmedia_upd_locked(struct ifnet *);
static int bge_ifmedia_upd(struct ifnet *);
static void bge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
static uint8_t bge_nvram_getbyte(struct bge_softc *, int, uint8_t *);
static int bge_read_nvram(struct bge_softc *, caddr_t, int, int);
static uint8_t bge_eeprom_getbyte(struct bge_softc *, int, uint8_t *);
static int bge_read_eeprom(struct bge_softc *, caddr_t, int, int);
@ -356,9 +375,10 @@ static int bge_init_tx_ring(struct bge_softc *);
static int bge_chipinit(struct bge_softc *);
static int bge_blockinit(struct bge_softc *);
static int bge_has_eeprom(struct bge_softc *);
static int bge_has_eaddr(struct bge_softc *);
static uint32_t bge_readmem_ind(struct bge_softc *, int);
static void bge_writemem_ind(struct bge_softc *, int, int);
static void bge_writembx(struct bge_softc *, int, int);
#ifdef notdef
static uint32_t bge_readreg_ind(struct bge_softc *, int);
#endif
@ -440,7 +460,7 @@ SYSCTL_INT(_hw_bge, OID_AUTO, allow_asf, CTLFLAG_RD, &bge_allow_asf, 0,
#define SPARC64_OFW_SUBVENDOR "subsystem-vendor-id"
static int
bge_has_eeprom(struct bge_softc *sc)
bge_has_eaddr(struct bge_softc *sc)
{
#ifdef __sparc64__
char buf[sizeof(SPARC64_BLADE_1500_PATH_BGE)];
@ -452,7 +472,7 @@ bge_has_eeprom(struct bge_softc *sc)
/*
* The on-board BGEs found in sun4u machines aren't fitted with
* an EEPROM which means that we have to obtain the MAC address
* via OFW and that some tests will always fail. We distinguish
* via OFW and that some tests will always fail. We distinguish
* such BGEs by the subvendor ID, which also has to be obtained
* from OFW instead of the PCI configuration space as the latter
* indicates Broadcom as the subvendor of the netboot interface.
@ -533,6 +553,15 @@ bge_writemem_direct(struct bge_softc *sc, int off, int val)
CSR_WRITE_4(sc, off, val);
}
static void
bge_writembx(struct bge_softc *sc, int off, int val)
{
if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
off += BGE_LPMBX_IRQ0_HI - BGE_MBX_IRQ0_HI;
CSR_WRITE_4(sc, off, val);
}
/*
* Map a single buffer address.
*/
@ -555,6 +584,78 @@ bge_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
ctx->bge_busaddr = segs->ds_addr;
}
static uint8_t
bge_nvram_getbyte(struct bge_softc *sc, int addr, uint8_t *dest)
{
uint32_t access, byte = 0;
int i;
/* Lock. */
CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_SET1);
for (i = 0; i < 8000; i++) {
if (CSR_READ_4(sc, BGE_NVRAM_SWARB) & BGE_NVRAMSWARB_GNT1)
break;
DELAY(20);
}
if (i == 8000)
return (1);
/* Enable access. */
access = CSR_READ_4(sc, BGE_NVRAM_ACCESS);
CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access | BGE_NVRAMACC_ENABLE);
CSR_WRITE_4(sc, BGE_NVRAM_ADDR, addr & 0xfffffffc);
CSR_WRITE_4(sc, BGE_NVRAM_CMD, BGE_NVRAM_READCMD);
for (i = 0; i < BGE_TIMEOUT * 10; i++) {
DELAY(10);
if (CSR_READ_4(sc, BGE_NVRAM_CMD) & BGE_NVRAMCMD_DONE) {
DELAY(10);
break;
}
}
if (i == BGE_TIMEOUT * 10) {
if_printf(sc->bge_ifp, "nvram read timed out\n");
return (1);
}
/* Get result. */
byte = CSR_READ_4(sc, BGE_NVRAM_RDDATA);
*dest = (bswap32(byte) >> ((addr % 4) * 8)) & 0xFF;
/* Disable access. */
CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access);
/* Unlock. */
CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_CLR1);
CSR_READ_4(sc, BGE_NVRAM_SWARB);
return (0);
}
/*
* Read a sequence of bytes from NVRAM.
*/
static int
bge_read_nvram(struct bge_softc *sc, caddr_t dest, int off, int cnt)
{
int err = 0, i;
uint8_t byte = 0;
if (sc->bge_asicrev != BGE_ASICREV_BCM5906)
return (1);
for (i = 0; i < cnt; i++) {
err = bge_nvram_getbyte(sc, off + i, &byte);
if (err)
break;
*(dest + i) = byte;
}
return (err ? 1 : 0);
}
/*
* Read a byte of data stored in the EEPROM at address 'addr.' The
* BCM570x supports both the traditional bitbang interface and an
@ -659,11 +760,14 @@ bge_miibus_readreg(device_t dev, int phy, int reg)
}
if (i == BGE_TIMEOUT) {
device_printf(sc->bge_dev, "PHY read timed out\n");
device_printf(sc->bge_dev,
"PHY read timed out (phy %d, reg %d, val 0x%08x)\n",
phy, reg, val);
val = 0;
goto done;
}
DELAY(5);
val = CSR_READ_4(sc, BGE_MI_COMM);
done:
@ -687,6 +791,10 @@ bge_miibus_writereg(device_t dev, int phy, int reg, int val)
sc = device_get_softc(dev);
if (sc->bge_asicrev == BGE_ASICREV_BCM5906 &&
(reg == BRGPHY_MII_1000CTL || reg == BRGPHY_MII_AUXCTL))
return(0);
/* Reading with autopolling on may trigger PCI errors */
autopoll = CSR_READ_4(sc, BGE_MI_MODE);
if (autopoll & BGE_MIMODE_AUTOPOLL) {
@ -699,12 +807,17 @@ bge_miibus_writereg(device_t dev, int phy, int reg, int val)
for (i = 0; i < BGE_TIMEOUT; i++) {
DELAY(10);
if (!(CSR_READ_4(sc, BGE_MI_COMM) & BGE_MICOMM_BUSY))
if (!(CSR_READ_4(sc, BGE_MI_COMM) & BGE_MICOMM_BUSY)) {
DELAY(5);
CSR_READ_4(sc, BGE_MI_COMM); /* dummy read */
break;
}
}
if (i == BGE_TIMEOUT) {
device_printf(sc->bge_dev, "PHY write timed out\n");
device_printf(sc->bge_dev,
"PHY write timed out (phy %d, reg %d, val %d)\n",
phy, reg, val);
return (0);
}
@ -887,7 +1000,7 @@ bge_init_rx_ring_std(struct bge_softc *sc)
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
sc->bge_std = i - 1;
CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
return (0);
}
@ -934,7 +1047,7 @@ bge_init_rx_ring_jumbo(struct bge_softc *sc)
BGE_RCB_FLAG_USE_EXT_RX_BD);
CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags);
CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
return (0);
}
@ -990,17 +1103,17 @@ bge_init_tx_ring(struct bge_softc *sc)
/* Initialize transmit producer index for host-memory send ring. */
sc->bge_tx_prodidx = 0;
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
/* 5700 b2 errata */
if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
/* NIC-memory send ring not used; initialize to zero. */
CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
/* 5700 b2 errata */
if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
return (0);
}
@ -1168,10 +1281,10 @@ bge_chipinit(struct bge_softc *sc)
/*
* Check the 'ROM failed' bit on the RX CPU to see if
* self-tests passed. Skip this check when there's no
* EEPROM fitted, since in that case it will always
* fail.
* chip containing the Ethernet address fitted, since
* in that case it will always fail.
*/
if ((sc->bge_flags & BGE_FLAG_EEPROM) &&
if ((sc->bge_flags & BGE_FLAG_EADDR) &&
CSR_READ_4(sc, BGE_RXCPU_MODE) & BGE_RXCPUMODE_ROMFAIL) {
device_printf(sc->bge_dev, "RX CPU self-diagnostics failed!\n");
return (ENODEV);
@ -1271,6 +1384,16 @@ bge_chipinit(struct bge_softc *sc)
/* Set the timer prescaler (always 66Mhz) */
CSR_WRITE_4(sc, BGE_MISC_CFG, BGE_32BITTIME_66MHZ);
/* XXX: The Linux tg3 driver does this at the start of brgphy_reset. */
if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
DELAY(40); /* XXX */
/* Put PHY into ready state */
BGE_CLRBIT(sc, BGE_MISC_CFG, BGE_MISCCFG_EPHY_IDDQ);
CSR_READ_4(sc, BGE_MISC_CFG); /* Flush */
DELAY(40);
}
return (0);
}
@ -1308,14 +1431,19 @@ bge_blockinit(struct bge_softc *sc)
}
/* Configure mbuf pool watermarks */
if (!(BGE_IS_5705_PLUS(sc))) {
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10);
} else {
if (!BGE_IS_5705_PLUS(sc)) {
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x50);
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x20);
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
} else if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x04);
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x10);
} else {
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10);
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
}
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
/* Configure DMA resource watermarks */
CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5);
@ -1421,6 +1549,9 @@ bge_blockinit(struct bge_softc *sc)
* requirement of all 575x family chips. The Linux driver sets
* the lower threshold for all 5705 family chips as well, but there
* are reports that it might not need to be so strict.
*
* XXX Linux does some extra fiddling here for the 5906 parts as
* well.
*/
if (BGE_IS_5705_PLUS(sc))
val = 8;
@ -1462,15 +1593,15 @@ bge_blockinit(struct bge_softc *sc)
BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt,
BGE_RCB_FLAG_RING_DISABLED));
RCB_WRITE_4(sc, vrcb, bge_nicaddr, 0);
CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO +
bge_writembx(sc, BGE_MBX_RX_CONS0_LO +
(i * (sizeof(uint64_t))), 0);
vrcb += sizeof(struct bge_rcb);
}
/* Initialize RX ring indexes */
CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, 0);
CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0);
CSR_WRITE_4(sc, BGE_MBX_RX_MINI_PROD_LO, 0);
bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, 0);
bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0);
bge_writembx(sc, BGE_MBX_RX_MINI_PROD_LO, 0);
/*
* Set up RX return ring 0
@ -1720,7 +1851,7 @@ bge_lookup_vendor(uint16_t vid)
static int
bge_probe(device_t dev)
{
struct bge_type *t = bge_devs;
const struct bge_type *t = bge_devs;
struct bge_softc *sc = device_get_softc(dev);
uint16_t vid, did;
@ -1742,7 +1873,8 @@ bge_probe(device_t dev)
#if __FreeBSD_version > 700024
const char *pname;
if (pci_get_vpd_ident(dev, &pname) == 0)
if (bge_has_eaddr(sc) &&
pci_get_vpd_ident(dev, &pname) == 0)
snprintf(model, 64, "%s", pname);
else
#endif
@ -1892,16 +2024,10 @@ bge_dma_alloc(device_t dev)
/*
* Allocate the parent bus DMA tag appropriate for PCI.
*/
error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev), /* parent */
1, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
MAXBSIZE, BGE_NSEG_NEW, /* maxsize, nsegments */
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
0, /* flags */
NULL, NULL, /* lockfunc, lockarg */
&sc->bge_cdata.bge_parent_tag);
error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev),
1, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
NULL, BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT,
0, NULL, NULL, &sc->bge_cdata.bge_parent_tag);
if (error != 0) {
device_printf(sc->bge_dev,
@ -1910,7 +2036,7 @@ bge_dma_alloc(device_t dev)
}
/*
* Create tag for RX mbufs.
* Create tag for mbufs.
*/
error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag, 1,
0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
@ -2202,10 +2328,11 @@ bge_can_use_msi(struct bge_softc *sc)
int can_use_msi = 0;
switch (sc->bge_asicrev) {
case BGE_ASICREV_BCM5714_A0:
case BGE_ASICREV_BCM5714:
/*
* Apparently, MSI doesn't work when this chip is configured
* in single-port mode.
* Apparently, MSI doesn't work when these chips are
* configured in single-port mode.
*/
if (bge_has_multiple_ports(sc))
can_use_msi = 1;
@ -2215,10 +2342,9 @@ bge_can_use_msi(struct bge_softc *sc)
sc->bge_chiprev != BGE_CHIPREV_5750_BX)
can_use_msi = 1;
break;
case BGE_ASICREV_BCM5752:
case BGE_ASICREV_BCM5780:
can_use_msi = 1;
break;
default:
if (BGE_IS_575X_PLUS(sc))
can_use_msi = 1;
}
return (can_use_msi);
}
@ -2229,8 +2355,7 @@ bge_attach(device_t dev)
{
struct ifnet *ifp;
struct bge_softc *sc;
uint32_t hwcfg = 0;
uint32_t mac_tmp = 0;
uint32_t hwcfg = 0, misccfg;
u_char eaddr[ETHER_ADDR_LEN];
int error, reg, rid, trys;
@ -2244,7 +2369,7 @@ bge_attach(device_t dev)
rid = BGE_PCI_BAR0;
sc->bge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE | PCI_RF_DENSE);
RF_ACTIVE);
if (sc->bge_res == NULL) {
device_printf (sc->bge_dev, "couldn't map memory\n");
@ -2252,19 +2377,25 @@ bge_attach(device_t dev)
goto fail;
}
sc->bge_btag = rman_get_bustag(sc->bge_res);
sc->bge_bhandle = rman_get_bushandle(sc->bge_res);
/* Save ASIC rev. */
sc->bge_chipid =
pci_read_config(dev, BGE_PCI_MISC_CTL, 4) &
BGE_PCIMISCCTL_ASICREV;
sc->bge_asicrev = BGE_ASICREV(sc->bge_chipid);
sc->bge_chiprev = BGE_CHIPREV(sc->bge_chipid);
if (bge_has_eeprom(sc))
sc->bge_flags |= BGE_FLAG_EEPROM;
/*
* Don't enable Ethernet@WireSpeed for the 5700, 5906, or the
* 5705 A0 and A1 chips.
*/
if (sc->bge_asicrev != BGE_ASICREV_BCM5700 &&
sc->bge_asicrev != BGE_ASICREV_BCM5906 &&
sc->bge_chipid != BGE_CHIPID_BCM5705_A0 &&
sc->bge_chipid != BGE_CHIPID_BCM5705_A1)
sc->bge_flags |= BGE_FLAG_WIRESPEED;
if (bge_has_eaddr(sc))
sc->bge_flags |= BGE_FLAG_EADDR;
/* Save chipset family. */
switch (sc->bge_asicrev) {
@ -2283,6 +2414,7 @@ bge_attach(device_t dev)
case BGE_ASICREV_BCM5752:
case BGE_ASICREV_BCM5755:
case BGE_ASICREV_BCM5787:
case BGE_ASICREV_BCM5906:
sc->bge_flags |= BGE_FLAG_575X_PLUS;
/* FALLTHRU */
case BGE_ASICREV_BCM5705:
@ -2302,12 +2434,23 @@ bge_attach(device_t dev)
if (BGE_IS_5705_PLUS(sc) &&
!(sc->bge_flags & BGE_FLAG_ADJUST_TRIM)) {
if (sc->bge_asicrev == BGE_ASICREV_BCM5755 ||
sc->bge_asicrev == BGE_ASICREV_BCM5787)
sc->bge_flags |= BGE_FLAG_JITTER_BUG;
else
sc->bge_asicrev == BGE_ASICREV_BCM5787) {
if (sc->bge_chipid != BGE_CHIPID_BCM5722_A0)
sc->bge_flags |= BGE_FLAG_JITTER_BUG;
} else if (sc->bge_asicrev != BGE_ASICREV_BCM5906)
sc->bge_flags |= BGE_FLAG_BER_BUG;
}
/*
* We could possibly check for BCOM_DEVICEID_BCM5788 in bge_probe()
* but I do not know the DEVICEID for the 5788M.
*/
misccfg = CSR_READ_4(sc, BGE_MISC_CFG) & BGE_MISCCFG_BOARD_ID;
if (misccfg == BGE_MISCCFG_BOARD_ID_5788 ||
misccfg == BGE_MISCCFG_BOARD_ID_5788M)
sc->bge_flags |= BGE_FLAG_5788;
/*
* Check if this is a PCI-X or PCI Express device.
*/
@ -2414,28 +2557,12 @@ bge_attach(device_t dev)
goto fail;
}
#ifdef __sparc64__
if ((sc->bge_flags & BGE_FLAG_EEPROM) == 0)
OF_getetheraddr(dev, eaddr);
else
#endif
{
mac_tmp = bge_readmem_ind(sc, 0x0C14);
if ((mac_tmp >> 16) == 0x484B) {
eaddr[0] = (u_char)(mac_tmp >> 8);
eaddr[1] = (u_char)mac_tmp;
mac_tmp = bge_readmem_ind(sc, 0x0C18);
eaddr[2] = (u_char)(mac_tmp >> 24);
eaddr[3] = (u_char)(mac_tmp >> 16);
eaddr[4] = (u_char)(mac_tmp >> 8);
eaddr[5] = (u_char)mac_tmp;
} else if (bge_read_eeprom(sc, eaddr,
BGE_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) {
device_printf(sc->bge_dev,
"failed to read station address\n");
error = ENXIO;
goto fail;
}
error = bge_get_eaddr(sc, eaddr);
if (error) {
device_printf(sc->bge_dev,
"failed to read station address\n");
error = ENXIO;
goto fail;
}
/* 5705 limits RX return ring to 512 entries. */
@ -2507,7 +2634,8 @@ bge_attach(device_t dev)
*/
if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) == BGE_MAGIC_NUMBER)
hwcfg = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG);
else if (sc->bge_flags & BGE_FLAG_EEPROM) {
else if ((sc->bge_flags & BGE_FLAG_EADDR) &&
(sc->bge_asicrev != BGE_ASICREV_BCM5906)) {
if (bge_read_eeprom(sc, (caddr_t)&hwcfg, BGE_EE_HWCFG_OFFSET,
sizeof(hwcfg))) {
device_printf(sc->bge_dev, "failed to read EEPROM\n");
@ -2682,13 +2810,14 @@ static int
bge_reset(struct bge_softc *sc)
{
device_t dev;
uint32_t cachesize, command, pcistate, reset;
uint32_t cachesize, command, pcistate, reset, val;
void (*write_op)(struct bge_softc *, int, int);
int i, val = 0;
int i;
dev = sc->bge_dev;
if (BGE_IS_575X_PLUS(sc) && !BGE_IS_5714_FAMILY(sc)) {
if (BGE_IS_575X_PLUS(sc) && !BGE_IS_5714_FAMILY(sc) &&
(sc->bge_asicrev != BGE_ASICREV_BCM5906)) {
if (sc->bge_flags & BGE_FLAG_PCIE)
write_op = bge_writemem_direct;
else
@ -2744,16 +2873,23 @@ bge_reset(struct bge_softc *sc)
/* Issue global reset */
write_op(sc, BGE_MISC_CFG, reset);
if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
val = CSR_READ_4(sc, BGE_VCPU_STATUS);
CSR_WRITE_4(sc, BGE_VCPU_STATUS,
val | BGE_VCPU_STATUS_DRV_RESET);
val = CSR_READ_4(sc, BGE_VCPU_EXT_CTRL);
CSR_WRITE_4(sc, BGE_VCPU_EXT_CTRL,
val & ~BGE_VCPU_EXT_CTRL_HALT_CPU);
}
DELAY(1000);
/* XXX: Broadcom Linux driver. */
if (sc->bge_flags & BGE_FLAG_PCIE) {
if (sc->bge_chipid == BGE_CHIPID_BCM5750_A0) {
uint32_t v;
DELAY(500000); /* wait for link training to complete */
v = pci_read_config(dev, 0xC4, 4);
pci_write_config(dev, 0xC4, v | (1 << 15), 4);
val = pci_read_config(dev, 0xC4, 4);
pci_write_config(dev, 0xC4, val | (1 << 15), 4);
}
/*
* Set PCIE max payload size to 128 bytes and clear error
@ -2772,8 +2908,6 @@ bge_reset(struct bge_softc *sc)
/* Re-enable MSI, if neccesary, and enable the memory arbiter. */
if (BGE_IS_5714_FAMILY(sc)) {
uint32_t val;
/* This chip disables MSI on reset. */
if (sc->bge_flags & BGE_FLAG_MSI) {
val = pci_read_config(dev, BGE_PCI_MSI_CTL, 2);
@ -2788,21 +2922,35 @@ bge_reset(struct bge_softc *sc)
} else
CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
/*
* Poll until we see the 1's complement of the magic number.
* This indicates that the firmware initialization is complete.
* We expect this to fail if no EEPROM is fitted though.
*/
for (i = 0; i < BGE_TIMEOUT; i++) {
DELAY(10);
val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);
if (val == ~BGE_MAGIC_NUMBER)
break;
}
if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
for (i = 0; i < BGE_TIMEOUT; i++) {
val = CSR_READ_4(sc, BGE_VCPU_STATUS);
if (val & BGE_VCPU_STATUS_INIT_DONE)
break;
DELAY(100);
}
if (i == BGE_TIMEOUT) {
device_printf(sc->bge_dev, "reset timed out\n");
return (1);
}
} else {
/*
* Poll until we see the 1's complement of the magic number.
* This indicates that the firmware initialization is complete.
* We expect this to fail if no chip containing the Ethernet
* address is fitted though.
*/
for (i = 0; i < BGE_TIMEOUT; i++) {
DELAY(10);
val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);
if (val == ~BGE_MAGIC_NUMBER)
break;
}
if ((sc->bge_flags & BGE_FLAG_EEPROM) && i == BGE_TIMEOUT)
device_printf(sc->bge_dev, "firmware handshake timed out, "
"found 0x%08x\n", val);
if ((sc->bge_flags & BGE_FLAG_EADDR) && i == BGE_TIMEOUT)
device_printf(sc->bge_dev, "firmware handshake timed out, "
"found 0x%08x\n", val);
}
/*
* XXX Wait for the value of the PCISTATE register to
@ -2840,20 +2988,16 @@ bge_reset(struct bge_softc *sc)
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5704 &&
sc->bge_flags & BGE_FLAG_TBI) {
uint32_t serdescfg;
serdescfg = CSR_READ_4(sc, BGE_SERDES_CFG);
serdescfg = (serdescfg & ~0xFFF) | 0x880;
CSR_WRITE_4(sc, BGE_SERDES_CFG, serdescfg);
val = CSR_READ_4(sc, BGE_SERDES_CFG);
val = (val & ~0xFFF) | 0x880;
CSR_WRITE_4(sc, BGE_SERDES_CFG, val);
}
/* XXX: Broadcom Linux driver. */
if (sc->bge_flags & BGE_FLAG_PCIE &&
sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {
uint32_t v;
v = CSR_READ_4(sc, 0x7C00);
CSR_WRITE_4(sc, 0x7C00, v | (1 << 25));
val = CSR_READ_4(sc, 0x7C00);
CSR_WRITE_4(sc, 0x7C00, val | (1 << 25));
}
DELAY(10000);
@ -3022,11 +3166,11 @@ bge_rxeof(struct bge_softc *sc)
bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_PREWRITE);
CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
bge_writembx(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
if (stdcnt)
CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
if (jumbocnt)
CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
#ifdef notyet
/*
* This register wraps very quickly under heavy packet drops.
@ -3168,7 +3312,7 @@ bge_intr(void *xsc)
* the status check). So toggling would probably be a pessimization
* even with MSI. It would only be needed for using a task queue.
*/
CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
/*
* Do the mandatory PCI flush as well as get the link status.
@ -3240,8 +3384,12 @@ bge_tick(void *xsc)
if ((sc->bge_flags & BGE_FLAG_TBI) == 0) {
mii = device_get_softc(sc->bge_miibus);
/* Don't mess with the PHY in IPMI/ASF mode */
if (!((sc->bge_asf_mode & ASF_STACKUP) && (sc->bge_link)))
/*
* Do not touch PHY if we have link up. This could break
* IPMI/ASF mode or produce extra input errors
* (extra errors was reported for bcm5701 & bcm5704).
*/
if (!sc->bge_link)
mii_tick(mii);
} else {
/*
@ -3255,7 +3403,11 @@ bge_tick(void *xsc)
#endif
{
sc->bge_link_evt++;
BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET);
if (sc->bge_asicrev == BGE_ASICREV_BCM5700 ||
sc->bge_flags & BGE_FLAG_5788)
BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET);
else
BGE_SETBIT(sc, BGE_HCC_MODE, BGE_HCCMODE_COAL_NOW);
}
}
@ -3390,7 +3542,7 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_mtag, map, m, segs,
&nsegs, BUS_DMA_NOWAIT);
if (error == EFBIG) {
m = m_defrag(m, M_DONTWAIT);
m = m_collapse(m, M_DONTWAIT, BGE_NSEG_NEW);
if (m == NULL) {
m_freem(*m_head);
*m_head = NULL;
@ -3545,10 +3697,10 @@ bge_start_locked(struct ifnet *ifp)
return;
/* Transmit. */
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
/* 5700 b2 errata */
if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
sc->bge_tx_prodidx = prodidx;
@ -3675,7 +3827,7 @@ bge_init_locked(struct bge_softc *sc)
if (ifp->if_capenable & IFCAP_POLLING) {
BGE_SETBIT(sc, BGE_PCI_MISC_CTL,
BGE_PCIMISCCTL_MASK_PCI_INTR);
CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
} else
#endif
@ -3683,7 +3835,7 @@ bge_init_locked(struct bge_softc *sc)
{
BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA);
BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
}
bge_ifmedia_upd_locked(ifp);
@ -3783,6 +3935,24 @@ bge_ifmedia_upd_locked(struct ifnet *ifp)
}
mii_mediachg(mii);
/*
* Force an interrupt so that we will call bge_link_upd
* if needed and clear any pending link state attention.
* Without this we are not getting any further interrupts
* for link state changes and thus will not UP the link and
* not be able to send in bge_start_locked. The only
* way to get things working was to receive a packet and
* get an RX intr.
* bge_tick should help for fiber cards and we might not
* need to do this here if BGE_FLAG_TBI is set but as
* we poll for fiber anyway it should not harm.
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5700 ||
sc->bge_flags & BGE_FLAG_5788)
BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET);
else
BGE_SETBIT(sc, BGE_HCC_MODE, BGE_HCCMODE_COAL_NOW);
return (0);
}
@ -3906,7 +4076,7 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
BGE_LOCK(sc);
BGE_SETBIT(sc, BGE_PCI_MISC_CTL,
BGE_PCIMISCCTL_MASK_PCI_INTR);
CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
ifp->if_capenable |= IFCAP_POLLING;
BGE_UNLOCK(sc);
} else {
@ -3915,7 +4085,7 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
BGE_LOCK(sc);
BGE_CLRBIT(sc, BGE_PCI_MISC_CTL,
BGE_PCIMISCCTL_MASK_PCI_INTR);
CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
ifp->if_capenable &= ~IFCAP_POLLING;
BGE_UNLOCK(sc);
}
@ -4040,7 +4210,7 @@ bge_stop(struct bge_softc *sc)
/* Disable host interrupts. */
BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
/*
* Tell firmware we're shutting down.
@ -4295,6 +4465,9 @@ bge_add_sysctls(struct bge_softc *sc)
#endif
if (BGE_IS_5705_PLUS(sc))
return;
tree = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "stats", CTLFLAG_RD,
NULL, "BGE Statistics");
schildren = children = SYSCTL_CHILDREN(tree);
@ -4417,16 +4590,12 @@ bge_sysctl_stats(SYSCTL_HANDLER_ARGS)
{
struct bge_softc *sc;
uint32_t result;
int base, offset;
int offset;
sc = (struct bge_softc *)arg1;
offset = arg2;
if (BGE_IS_5705_PLUS(sc))
base = BGE_MAC_STATS;
else
base = BGE_MEMWIN_START + BGE_STATS_BLOCK;
result = CSR_READ_4(sc, base + offset + offsetof(bge_hostaddr,
bge_addr_lo));
result = CSR_READ_4(sc, BGE_MEMWIN_START + BGE_STATS_BLOCK + offset +
offsetof(bge_hostaddr, bge_addr_lo));
return (sysctl_handle_int(oidp, &result, 0, req));
}
@ -4537,3 +4706,79 @@ bge_sysctl_mem_read(SYSCTL_HANDLER_ARGS)
return (error);
}
#endif
static int
bge_get_eaddr_fw(struct bge_softc *sc, uint8_t ether_addr[])
{
if (sc->bge_flags & BGE_FLAG_EADDR)
return (1);
#ifdef __sparc64__
OF_getetheraddr(sc->bge_dev, ether_addr);
return (0);
#endif
return (1);
}
static int
bge_get_eaddr_mem(struct bge_softc *sc, uint8_t ether_addr[])
{
uint32_t mac_addr;
mac_addr = bge_readmem_ind(sc, 0x0c14);
if ((mac_addr >> 16) == 0x484b) {
ether_addr[0] = (uint8_t)(mac_addr >> 8);
ether_addr[1] = (uint8_t)mac_addr;
mac_addr = bge_readmem_ind(sc, 0x0c18);
ether_addr[2] = (uint8_t)(mac_addr >> 24);
ether_addr[3] = (uint8_t)(mac_addr >> 16);
ether_addr[4] = (uint8_t)(mac_addr >> 8);
ether_addr[5] = (uint8_t)mac_addr;
return (0);
}
return (1);
}
static int
bge_get_eaddr_nvram(struct bge_softc *sc, uint8_t ether_addr[])
{
int mac_offset = BGE_EE_MAC_OFFSET;
if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
mac_offset = BGE_EE_MAC_OFFSET_5906;
return (bge_read_nvram(sc, ether_addr, mac_offset + 2,
ETHER_ADDR_LEN));
}
static int
bge_get_eaddr_eeprom(struct bge_softc *sc, uint8_t ether_addr[])
{
if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
return (1);
return (bge_read_eeprom(sc, ether_addr, BGE_EE_MAC_OFFSET + 2,
ETHER_ADDR_LEN));
}
static int
bge_get_eaddr(struct bge_softc *sc, uint8_t eaddr[])
{
static const bge_eaddr_fcn_t bge_eaddr_funcs[] = {
/* NOTE: Order is critical */
bge_get_eaddr_fw,
bge_get_eaddr_mem,
bge_get_eaddr_nvram,
bge_get_eaddr_eeprom,
NULL
};
const bge_eaddr_fcn_t *func;
for (func = bge_eaddr_funcs; *func != NULL; ++func) {
if ((*func)(sc, eaddr) == 0)
break;
}
return (*func == NULL ? ENXIO : 0);
}

View File

@ -30,7 +30,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/bge/if_bgereg.h,v 1.73 2007/05/22 19:22:58 jkim Exp $
* $FreeBSD: src/sys/dev/bge/if_bgereg.h,v 1.81 2008/10/14 20:28:42 marius Exp $
*/
/*
@ -277,12 +277,15 @@
#define BGE_CHIPID_BCM5755_A0 0xa0000000
#define BGE_CHIPID_BCM5755_A1 0xa0010000
#define BGE_CHIPID_BCM5755_A2 0xa0020000
#define BGE_CHIPID_BCM5722_A0 0xa2000000
#define BGE_CHIPID_BCM5754_A0 0xb0000000
#define BGE_CHIPID_BCM5754_A1 0xb0010000
#define BGE_CHIPID_BCM5754_A2 0xb0020000
#define BGE_CHIPID_BCM5787_A0 0xb0000000
#define BGE_CHIPID_BCM5787_A1 0xb0010000
#define BGE_CHIPID_BCM5787_A2 0xb0020000
#define BGE_CHIPID_BCM5906_A1 0xc0010000
#define BGE_CHIPID_BCM5906_A2 0xc0020000
/* shorthand one */
#define BGE_ASICREV(x) ((x) >> 28)
@ -299,6 +302,7 @@
#define BGE_ASICREV_BCM5755 0x0a
#define BGE_ASICREV_BCM5754 0x0b
#define BGE_ASICREV_BCM5787 0x0b
#define BGE_ASICREV_BCM5906 0x0c
/* chip revisions */
#define BGE_CHIPREV(x) ((x) >> 24)
@ -1438,6 +1442,17 @@
#define BGE_RXCPUSTAT_MA_REQ_FIFOOFLOW 0x40000000
#define BGE_RXCPUSTAT_BLOCKING_READ 0x80000000
/*
* V? CPU registers
*/
#define BGE_VCPU_STATUS 0x5100
#define BGE_VCPU_EXT_CTRL 0x6890
#define BGE_VCPU_STATUS_INIT_DONE 0x04000000
#define BGE_VCPU_STATUS_DRV_RESET 0x08000000
#define BGE_VCPU_EXT_CTRL_HALT_CPU 0x00400000
#define BGE_VCPU_EXT_CTRL_DISABLE_WOL 0x20000000
/*
* TX CPU registers
@ -1684,6 +1699,56 @@
#define BGE_EE_DELAY 0x6848
#define BGE_FASTBOOT_PC 0x6894
/*
* NVRAM Control registers
*/
#define BGE_NVRAM_CMD 0x7000
#define BGE_NVRAM_STAT 0x7004
#define BGE_NVRAM_WRDATA 0x7008
#define BGE_NVRAM_ADDR 0x700c
#define BGE_NVRAM_RDDATA 0x7010
#define BGE_NVRAM_CFG1 0x7014
#define BGE_NVRAM_CFG2 0x7018
#define BGE_NVRAM_CFG3 0x701c
#define BGE_NVRAM_SWARB 0x7020
#define BGE_NVRAM_ACCESS 0x7024
#define BGE_NVRAM_WRITE1 0x7028
#define BGE_NVRAMCMD_RESET 0x00000001
#define BGE_NVRAMCMD_DONE 0x00000008
#define BGE_NVRAMCMD_START 0x00000010
#define BGE_NVRAMCMD_WR 0x00000020 /* 1 = wr, 0 = rd */
#define BGE_NVRAMCMD_ERASE 0x00000040
#define BGE_NVRAMCMD_FIRST 0x00000080
#define BGE_NVRAMCMD_LAST 0x00000100
#define BGE_NVRAM_READCMD \
(BGE_NVRAMCMD_FIRST|BGE_NVRAMCMD_LAST| \
BGE_NVRAMCMD_START|BGE_NVRAMCMD_DONE)
#define BGE_NVRAM_WRITECMD \
(BGE_NVRAMCMD_FIRST|BGE_NVRAMCMD_LAST| \
BGE_NVRAMCMD_START|BGE_NVRAMCMD_DONE|BGE_NVRAMCMD_WR)
#define BGE_NVRAMSWARB_SET0 0x00000001
#define BGE_NVRAMSWARB_SET1 0x00000002
#define BGE_NVRAMSWARB_SET2 0x00000003
#define BGE_NVRAMSWARB_SET3 0x00000004
#define BGE_NVRAMSWARB_CLR0 0x00000010
#define BGE_NVRAMSWARB_CLR1 0x00000020
#define BGE_NVRAMSWARB_CLR2 0x00000040
#define BGE_NVRAMSWARB_CLR3 0x00000080
#define BGE_NVRAMSWARB_GNT0 0x00000100
#define BGE_NVRAMSWARB_GNT1 0x00000200
#define BGE_NVRAMSWARB_GNT2 0x00000400
#define BGE_NVRAMSWARB_GNT3 0x00000800
#define BGE_NVRAMSWARB_REQ0 0x00001000
#define BGE_NVRAMSWARB_REQ1 0x00002000
#define BGE_NVRAMSWARB_REQ2 0x00004000
#define BGE_NVRAMSWARB_REQ3 0x00008000
#define BGE_NVRAMACC_ENABLE 0x00000001
#define BGE_NVRAMACC_WRENABLE 0x00000002
/* Mode control register */
#define BGE_MODECTL_INT_SNDCOAL_ONLY 0x00000001
#define BGE_MODECTL_BYTESWAP_NONFRAME 0x00000002
@ -1711,6 +1776,10 @@
/* Misc. config register */
#define BGE_MISCCFG_RESET_CORE_CLOCKS 0x00000001
#define BGE_MISCCFG_TIMER_PRESCALER 0x000000FE
#define BGE_MISCCFG_BOARD_ID 0x0001E000
#define BGE_MISCCFG_BOARD_ID_5788 0x00010000
#define BGE_MISCCFG_BOARD_ID_5788M 0x00018000
#define BGE_MISCCFG_EPHY_IDDQ 0x00200000
#define BGE_32BITTIME_66MHZ (0x41 << 1)
@ -1827,8 +1896,7 @@ struct bge_rcb {
};
#define RCB_WRITE_4(sc, rcb, offset, val) \
bus_space_write_4(sc->bge_btag, sc->bge_bhandle, \
rcb + offsetof(struct bge_rcb, offset), val)
bus_write_4(sc->bge_res, rcb + offsetof(struct bge_rcb, offset), val)
#define BGE_RCB_MAXLEN_FLAGS(maxlen, flags) ((maxlen) << 16 | (flags))
#define BGE_RCB_FLAG_USE_EXT_RX_BD 0x0001
@ -2011,6 +2079,7 @@ struct bge_status_block {
#define BCOM_DEVICEID_BCM5715S 0x1679
#define BCOM_DEVICEID_BCM5720 0x1658
#define BCOM_DEVICEID_BCM5721 0x1659
#define BCOM_DEVICEID_BCM5722 0x165A
#define BCOM_DEVICEID_BCM5750 0x1676
#define BCOM_DEVICEID_BCM5750M 0x167C
#define BCOM_DEVICEID_BCM5751 0x1677
@ -2037,6 +2106,8 @@ struct bge_status_block {
#define BCOM_DEVICEID_BCM5901 0x170D
#define BCOM_DEVICEID_BCM5901A2 0x170E
#define BCOM_DEVICEID_BCM5903M 0x16FF
#define BCOM_DEVICEID_BCM5906 0x1712
#define BCOM_DEVICEID_BCM5906M 0x1713
/*
* Alteon AceNIC PCI vendor/device ID.
@ -2090,6 +2161,7 @@ struct bge_status_block {
* Offset of MAC address inside EEPROM.
*/
#define BGE_EE_MAC_OFFSET 0x7C
#define BGE_EE_MAC_OFFSET_5906 0x10
#define BGE_EE_HWCFG_OFFSET 0xC8
#define BGE_HWCFG_VOLTAGE 0x00000003
@ -2321,10 +2393,10 @@ struct bge_gib {
*/
#define CSR_WRITE_4(sc, reg, val) \
bus_space_write_4(sc->bge_btag, sc->bge_bhandle, reg, val)
bus_write_4(sc->bge_res, reg, val)
#define CSR_READ_4(sc, reg) \
bus_space_read_4(sc->bge_btag, sc->bge_bhandle, reg)
bus_read_4(sc->bge_res, reg)
#define BGE_SETBIT(sc, reg, x) \
CSR_WRITE_4(sc, reg, (CSR_READ_4(sc, reg) | (x)))
@ -2449,8 +2521,6 @@ struct bge_softc {
device_t bge_dev;
struct mtx bge_mtx;
device_t bge_miibus;
bus_space_handle_t bge_bhandle;
bus_space_tag_t bge_btag;
void *bge_intrhand;
struct resource *bge_irq;
struct resource *bge_res;
@ -2458,7 +2528,8 @@ struct bge_softc {
uint32_t bge_flags;
#define BGE_FLAG_TBI 0x00000001
#define BGE_FLAG_JUMBO 0x00000002
#define BGE_FLAG_EEPROM 0x00000004
#define BGE_FLAG_WIRESPEED 0x00000004
#define BGE_FLAG_EADDR 0x00000008
#define BGE_FLAG_MSI 0x00000100
#define BGE_FLAG_PCIX 0x00000200
#define BGE_FLAG_PCIE 0x00000400
@ -2474,6 +2545,7 @@ struct bge_softc {
#define BGE_FLAG_BER_BUG 0x02000000
#define BGE_FLAG_ADJUST_TRIM 0x04000000
#define BGE_FLAG_CRC_BUG 0x08000000
#define BGE_FLAG_5788 0x20000000
uint32_t bge_chipid;
uint8_t bge_asicrev;
uint8_t bge_chiprev;

View File

@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/mii/brgphyreg.h,v 1.10 2007/06/07 02:21:38 davidch Exp $
* $FreeBSD: src/sys/dev/mii/brgphyreg.h,v 1.11 2008/04/29 19:47:13 jhb Exp $
*/
#ifndef _DEV_MII_BRGPHYREG_H_
@ -161,6 +161,7 @@
#define BRGPHY_MII_DSP_RW_PORT 0x15 /* DSP coefficient r/w port */
#define BRGPHY_MII_DSP_ADDR_REG 0x17 /* DSP coefficient addr register */
#define BRGPHY_MII_EPHY_PTEST 0x17 /* 5906 PHY register */
#define BRGPHY_DSP_TAP_NUMBER_MASK 0x00
#define BRGPHY_DSP_AGC_A 0x00