Add support for the BCM5906[M] adapters. These adapters only support
10/100 operation and place the mailbox registers at a different offset. They also do not have an EEPROM, so the MAC address must be read from NVRAM instead. MFC after: 1 month PR: kern/118975 Submitted by: benjsc, Thomas Nyström thn at saeab dot se Submitted by: sephe (original patch for DragonflyBSD)
This commit is contained in:
parent
624e4d168d
commit
38cc658ff6
@ -196,6 +196,8 @@ static struct bge_type {
|
|||||||
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5901 },
|
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5901 },
|
||||||
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5901A2 },
|
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5901A2 },
|
||||||
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5903M },
|
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5903M },
|
||||||
|
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5906 },
|
||||||
|
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5906M },
|
||||||
|
|
||||||
{ SK_VENDORID, SK_DEVICEID_ALTIMA },
|
{ SK_VENDORID, SK_DEVICEID_ALTIMA },
|
||||||
|
|
||||||
@ -273,6 +275,8 @@ static const struct bge_revision {
|
|||||||
{ BGE_CHIPID_BCM5787_A0, "BCM5754/5787 A0" },
|
{ BGE_CHIPID_BCM5787_A0, "BCM5754/5787 A0" },
|
||||||
{ BGE_CHIPID_BCM5787_A1, "BCM5754/5787 A1" },
|
{ BGE_CHIPID_BCM5787_A1, "BCM5754/5787 A1" },
|
||||||
{ BGE_CHIPID_BCM5787_A2, "BCM5754/5787 A2" },
|
{ BGE_CHIPID_BCM5787_A2, "BCM5754/5787 A2" },
|
||||||
|
{ BGE_CHIPID_BCM5906_A1, "BCM5906 A1" },
|
||||||
|
{ BGE_CHIPID_BCM5906_A2, "BCM5906 A2" },
|
||||||
|
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
@ -295,6 +299,7 @@ static const struct bge_revision bge_majorrevs[] = {
|
|||||||
{ BGE_ASICREV_BCM5755, "unknown BCM5755" },
|
{ BGE_ASICREV_BCM5755, "unknown BCM5755" },
|
||||||
/* 5754 and 5787 share the same ASIC ID */
|
/* 5754 and 5787 share the same ASIC ID */
|
||||||
{ BGE_ASICREV_BCM5787, "unknown BCM5754/5787" },
|
{ BGE_ASICREV_BCM5787, "unknown BCM5754/5787" },
|
||||||
|
{ BGE_ASICREV_BCM5906, "unknown BCM5906" },
|
||||||
|
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
@ -307,6 +312,9 @@ static const struct bge_revision bge_majorrevs[] = {
|
|||||||
|
|
||||||
const struct bge_revision * bge_lookup_rev(uint32_t);
|
const struct bge_revision * bge_lookup_rev(uint32_t);
|
||||||
const struct bge_vendor * bge_lookup_vendor(uint16_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_probe(device_t);
|
||||||
static int bge_attach(device_t);
|
static int bge_attach(device_t);
|
||||||
static int bge_detach(device_t);
|
static int bge_detach(device_t);
|
||||||
@ -317,6 +325,11 @@ static void bge_dma_map_addr(void *, bus_dma_segment_t *, int, int);
|
|||||||
static int bge_dma_alloc(device_t);
|
static int bge_dma_alloc(device_t);
|
||||||
static void bge_dma_free(struct bge_softc *);
|
static void bge_dma_free(struct bge_softc *);
|
||||||
|
|
||||||
|
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_txeof(struct bge_softc *);
|
||||||
static void bge_rxeof(struct bge_softc *);
|
static void bge_rxeof(struct bge_softc *);
|
||||||
|
|
||||||
@ -339,6 +352,9 @@ static int bge_ifmedia_upd_locked(struct ifnet *);
|
|||||||
static int bge_ifmedia_upd(struct ifnet *);
|
static int bge_ifmedia_upd(struct ifnet *);
|
||||||
static void bge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
|
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 uint8_t bge_eeprom_getbyte(struct bge_softc *, int, uint8_t *);
|
||||||
static int bge_read_eeprom(struct bge_softc *, caddr_t, int, int);
|
static int bge_read_eeprom(struct bge_softc *, caddr_t, int, int);
|
||||||
|
|
||||||
@ -361,6 +377,7 @@ static int bge_blockinit(struct bge_softc *);
|
|||||||
static int bge_has_eeprom(struct bge_softc *);
|
static int bge_has_eeprom(struct bge_softc *);
|
||||||
static uint32_t bge_readmem_ind(struct bge_softc *, int);
|
static uint32_t bge_readmem_ind(struct bge_softc *, int);
|
||||||
static void bge_writemem_ind(struct bge_softc *, int, int);
|
static void bge_writemem_ind(struct bge_softc *, int, int);
|
||||||
|
static void bge_writembx(struct bge_softc *, int, int);
|
||||||
#ifdef notdef
|
#ifdef notdef
|
||||||
static uint32_t bge_readreg_ind(struct bge_softc *, int);
|
static uint32_t bge_readreg_ind(struct bge_softc *, int);
|
||||||
#endif
|
#endif
|
||||||
@ -476,6 +493,10 @@ bge_has_eeprom(struct bge_softc *sc)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
|
||||||
|
return (0);
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,6 +556,15 @@ bge_writemem_direct(struct bge_softc *sc, int off, int val)
|
|||||||
CSR_WRITE_4(sc, off, 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.
|
* Map a single buffer address.
|
||||||
*/
|
*/
|
||||||
@ -557,6 +587,78 @@ bge_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
|||||||
ctx->bge_busaddr = segs->ds_addr;
|
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
|
* Read a byte of data stored in the EEPROM at address 'addr.' The
|
||||||
* BCM570x supports both the traditional bitbang interface and an
|
* BCM570x supports both the traditional bitbang interface and an
|
||||||
@ -661,11 +763,13 @@ bge_miibus_readreg(device_t dev, int phy, int reg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i == BGE_TIMEOUT) {
|
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;
|
val = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DELAY(5);
|
||||||
val = CSR_READ_4(sc, BGE_MI_COMM);
|
val = CSR_READ_4(sc, BGE_MI_COMM);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@ -689,6 +793,10 @@ bge_miibus_writereg(device_t dev, int phy, int reg, int val)
|
|||||||
|
|
||||||
sc = device_get_softc(dev);
|
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 */
|
/* Reading with autopolling on may trigger PCI errors */
|
||||||
autopoll = CSR_READ_4(sc, BGE_MI_MODE);
|
autopoll = CSR_READ_4(sc, BGE_MI_MODE);
|
||||||
if (autopoll & BGE_MIMODE_AUTOPOLL) {
|
if (autopoll & BGE_MIMODE_AUTOPOLL) {
|
||||||
@ -701,12 +809,17 @@ bge_miibus_writereg(device_t dev, int phy, int reg, int val)
|
|||||||
|
|
||||||
for (i = 0; i < BGE_TIMEOUT; i++) {
|
for (i = 0; i < BGE_TIMEOUT; i++) {
|
||||||
DELAY(10);
|
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;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == BGE_TIMEOUT) {
|
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);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -889,7 +1002,7 @@ bge_init_rx_ring_std(struct bge_softc *sc)
|
|||||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||||
|
|
||||||
sc->bge_std = i - 1;
|
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);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -936,7 +1049,7 @@ bge_init_rx_ring_jumbo(struct bge_softc *sc)
|
|||||||
BGE_RCB_FLAG_USE_EXT_RX_BD);
|
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_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);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -992,17 +1105,17 @@ bge_init_tx_ring(struct bge_softc *sc)
|
|||||||
|
|
||||||
/* Initialize transmit producer index for host-memory send ring. */
|
/* Initialize transmit producer index for host-memory send ring. */
|
||||||
sc->bge_tx_prodidx = 0;
|
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 */
|
/* 5700 b2 errata */
|
||||||
if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
|
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. */
|
/* 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 */
|
/* 5700 b2 errata */
|
||||||
if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
|
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);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -1273,6 +1386,16 @@ bge_chipinit(struct bge_softc *sc)
|
|||||||
/* Set the timer prescaler (always 66Mhz) */
|
/* Set the timer prescaler (always 66Mhz) */
|
||||||
CSR_WRITE_4(sc, BGE_MISC_CFG, BGE_32BITTIME_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);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1310,14 +1433,19 @@ bge_blockinit(struct bge_softc *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Configure mbuf pool watermarks */
|
/* Configure mbuf pool watermarks */
|
||||||
if (BGE_IS_5705_PLUS(sc)) {
|
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 {
|
|
||||||
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x50);
|
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_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 */
|
/* Configure DMA resource watermarks */
|
||||||
CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5);
|
CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5);
|
||||||
@ -1423,6 +1551,9 @@ bge_blockinit(struct bge_softc *sc)
|
|||||||
* requirement of all 575x family chips. The Linux driver sets
|
* requirement of all 575x family chips. The Linux driver sets
|
||||||
* the lower threshold for all 5705 family chips as well, but there
|
* the lower threshold for all 5705 family chips as well, but there
|
||||||
* are reports that it might not need to be so strict.
|
* 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))
|
if (BGE_IS_5705_PLUS(sc))
|
||||||
val = 8;
|
val = 8;
|
||||||
@ -1464,15 +1595,15 @@ bge_blockinit(struct bge_softc *sc)
|
|||||||
BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt,
|
BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt,
|
||||||
BGE_RCB_FLAG_RING_DISABLED));
|
BGE_RCB_FLAG_RING_DISABLED));
|
||||||
RCB_WRITE_4(sc, vrcb, bge_nicaddr, 0);
|
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);
|
(i * (sizeof(uint64_t))), 0);
|
||||||
vrcb += sizeof(struct bge_rcb);
|
vrcb += sizeof(struct bge_rcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize RX ring indexes */
|
/* Initialize RX ring indexes */
|
||||||
CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, 0);
|
bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, 0);
|
||||||
CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0);
|
bge_writembx(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_MINI_PROD_LO, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up RX return ring 0
|
* Set up RX return ring 0
|
||||||
@ -2226,7 +2357,6 @@ bge_attach(device_t dev)
|
|||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
struct bge_softc *sc;
|
struct bge_softc *sc;
|
||||||
uint32_t hwcfg = 0;
|
uint32_t hwcfg = 0;
|
||||||
uint32_t mac_tmp = 0;
|
|
||||||
u_char eaddr[ETHER_ADDR_LEN];
|
u_char eaddr[ETHER_ADDR_LEN];
|
||||||
int error, reg, rid, trys;
|
int error, reg, rid, trys;
|
||||||
|
|
||||||
@ -2260,10 +2390,11 @@ bge_attach(device_t dev)
|
|||||||
sc->bge_chiprev = BGE_CHIPREV(sc->bge_chipid);
|
sc->bge_chiprev = BGE_CHIPREV(sc->bge_chipid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't enable Ethernet@WireSpeed for the 5700 or the
|
* Don't enable Ethernet@WireSpeed for the 5700, 5906, or the
|
||||||
* 5705 A0 and A1 chips.
|
* 5705 A0 and A1 chips.
|
||||||
*/
|
*/
|
||||||
if (sc->bge_asicrev != BGE_ASICREV_BCM5700 &&
|
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_A0 &&
|
||||||
sc->bge_chipid != BGE_CHIPID_BCM5705_A1)
|
sc->bge_chipid != BGE_CHIPID_BCM5705_A1)
|
||||||
sc->bge_flags |= BGE_FLAG_WIRESPEED;
|
sc->bge_flags |= BGE_FLAG_WIRESPEED;
|
||||||
@ -2288,6 +2419,7 @@ bge_attach(device_t dev)
|
|||||||
case BGE_ASICREV_BCM5752:
|
case BGE_ASICREV_BCM5752:
|
||||||
case BGE_ASICREV_BCM5755:
|
case BGE_ASICREV_BCM5755:
|
||||||
case BGE_ASICREV_BCM5787:
|
case BGE_ASICREV_BCM5787:
|
||||||
|
case BGE_ASICREV_BCM5906:
|
||||||
sc->bge_flags |= BGE_FLAG_575X_PLUS;
|
sc->bge_flags |= BGE_FLAG_575X_PLUS;
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
case BGE_ASICREV_BCM5705:
|
case BGE_ASICREV_BCM5705:
|
||||||
@ -2310,7 +2442,7 @@ bge_attach(device_t dev)
|
|||||||
sc->bge_asicrev == BGE_ASICREV_BCM5787) {
|
sc->bge_asicrev == BGE_ASICREV_BCM5787) {
|
||||||
if (sc->bge_chipid != BGE_CHIPID_BCM5722_A0)
|
if (sc->bge_chipid != BGE_CHIPID_BCM5722_A0)
|
||||||
sc->bge_flags |= BGE_FLAG_JITTER_BUG;
|
sc->bge_flags |= BGE_FLAG_JITTER_BUG;
|
||||||
} else
|
} else if (sc->bge_asicrev != BGE_ASICREV_BCM5906)
|
||||||
sc->bge_flags |= BGE_FLAG_BER_BUG;
|
sc->bge_flags |= BGE_FLAG_BER_BUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2421,22 +2553,14 @@ bge_attach(device_t dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __sparc64__
|
#ifdef __sparc64__
|
||||||
if ((sc->bge_flags & BGE_FLAG_EEPROM) == 0)
|
if (((sc->bge_flags & BGE_FLAG_EEPROM) == 0) &&
|
||||||
|
(sc->bge_asicrev != BGE_ASICREV_BCM5906))
|
||||||
OF_getetheraddr(dev, eaddr);
|
OF_getetheraddr(dev, eaddr);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
mac_tmp = bge_readmem_ind(sc, 0x0C14);
|
error = bge_get_eaddr(sc, eaddr);
|
||||||
if ((mac_tmp >> 16) == 0x484B) {
|
if (error) {
|
||||||
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,
|
device_printf(sc->bge_dev,
|
||||||
"failed to read station address\n");
|
"failed to read station address\n");
|
||||||
error = ENXIO;
|
error = ENXIO;
|
||||||
@ -2694,7 +2818,8 @@ bge_reset(struct bge_softc *sc)
|
|||||||
|
|
||||||
dev = sc->bge_dev;
|
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)
|
if (sc->bge_flags & BGE_FLAG_PCIE)
|
||||||
write_op = bge_writemem_direct;
|
write_op = bge_writemem_direct;
|
||||||
else
|
else
|
||||||
@ -2750,6 +2875,17 @@ bge_reset(struct bge_softc *sc)
|
|||||||
/* Issue global reset */
|
/* Issue global reset */
|
||||||
write_op(sc, BGE_MISC_CFG, reset);
|
write_op(sc, BGE_MISC_CFG, reset);
|
||||||
|
|
||||||
|
if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
|
||||||
|
uint32_t status, ctrl;
|
||||||
|
|
||||||
|
status = CSR_READ_4(sc, BGE_VCPU_STATUS);
|
||||||
|
CSR_WRITE_4(sc, BGE_VCPU_STATUS,
|
||||||
|
status | BGE_VCPU_STATUS_DRV_RESET);
|
||||||
|
ctrl = CSR_READ_4(sc, BGE_VCPU_EXT_CTRL);
|
||||||
|
CSR_WRITE_4(sc, BGE_VCPU_EXT_CTRL,
|
||||||
|
ctrl & ~BGE_VCPU_EXT_CTRL_HALT_CPU);
|
||||||
|
}
|
||||||
|
|
||||||
DELAY(1000);
|
DELAY(1000);
|
||||||
|
|
||||||
/* XXX: Broadcom Linux driver. */
|
/* XXX: Broadcom Linux driver. */
|
||||||
@ -2794,21 +2930,34 @@ bge_reset(struct bge_softc *sc)
|
|||||||
} else
|
} else
|
||||||
CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
|
CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
|
||||||
|
|
||||||
/*
|
if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
|
||||||
* Poll until we see the 1's complement of the magic number.
|
for (i = 0; i < BGE_TIMEOUT; i++) {
|
||||||
* This indicates that the firmware initialization is complete.
|
val = CSR_READ_4(sc, BGE_VCPU_STATUS);
|
||||||
* We expect this to fail if no EEPROM is fitted though.
|
if (val & BGE_VCPU_STATUS_INIT_DONE)
|
||||||
*/
|
break;
|
||||||
for (i = 0; i < BGE_TIMEOUT; i++) {
|
DELAY(100);
|
||||||
DELAY(10);
|
}
|
||||||
val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);
|
if (i == BGE_TIMEOUT) {
|
||||||
if (val == ~BGE_MAGIC_NUMBER)
|
device_printf(sc->bge_dev, "reset timed out\n");
|
||||||
break;
|
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 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_flags & BGE_FLAG_EEPROM) && i == BGE_TIMEOUT)
|
if ((sc->bge_flags & BGE_FLAG_EEPROM) && i == BGE_TIMEOUT)
|
||||||
device_printf(sc->bge_dev, "firmware handshake timed out, "
|
device_printf(sc->bge_dev, "firmware handshake timed out, "
|
||||||
"found 0x%08x\n", val);
|
"found 0x%08x\n", val);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX Wait for the value of the PCISTATE register to
|
* XXX Wait for the value of the PCISTATE register to
|
||||||
@ -3028,11 +3177,11 @@ bge_rxeof(struct bge_softc *sc)
|
|||||||
bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
|
bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
|
||||||
sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_PREWRITE);
|
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)
|
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)
|
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
|
#ifdef notyet
|
||||||
/*
|
/*
|
||||||
* This register wraps very quickly under heavy packet drops.
|
* This register wraps very quickly under heavy packet drops.
|
||||||
@ -3174,7 +3323,7 @@ bge_intr(void *xsc)
|
|||||||
* the status check). So toggling would probably be a pessimization
|
* the status check). So toggling would probably be a pessimization
|
||||||
* even with MSI. It would only be needed for using a task queue.
|
* 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.
|
* Do the mandatory PCI flush as well as get the link status.
|
||||||
@ -3551,10 +3700,10 @@ bge_start_locked(struct ifnet *ifp)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Transmit. */
|
/* 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 */
|
/* 5700 b2 errata */
|
||||||
if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
|
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;
|
sc->bge_tx_prodidx = prodidx;
|
||||||
|
|
||||||
@ -3681,7 +3830,7 @@ bge_init_locked(struct bge_softc *sc)
|
|||||||
if (ifp->if_capenable & IFCAP_POLLING) {
|
if (ifp->if_capenable & IFCAP_POLLING) {
|
||||||
BGE_SETBIT(sc, BGE_PCI_MISC_CTL,
|
BGE_SETBIT(sc, BGE_PCI_MISC_CTL,
|
||||||
BGE_PCIMISCCTL_MASK_PCI_INTR);
|
BGE_PCIMISCCTL_MASK_PCI_INTR);
|
||||||
CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
|
bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -3689,7 +3838,7 @@ bge_init_locked(struct bge_softc *sc)
|
|||||||
{
|
{
|
||||||
BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA);
|
BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA);
|
||||||
BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
|
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);
|
bge_ifmedia_upd_locked(ifp);
|
||||||
@ -3929,7 +4078,7 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
|||||||
BGE_LOCK(sc);
|
BGE_LOCK(sc);
|
||||||
BGE_SETBIT(sc, BGE_PCI_MISC_CTL,
|
BGE_SETBIT(sc, BGE_PCI_MISC_CTL,
|
||||||
BGE_PCIMISCCTL_MASK_PCI_INTR);
|
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;
|
ifp->if_capenable |= IFCAP_POLLING;
|
||||||
BGE_UNLOCK(sc);
|
BGE_UNLOCK(sc);
|
||||||
} else {
|
} else {
|
||||||
@ -3938,7 +4087,7 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
|||||||
BGE_LOCK(sc);
|
BGE_LOCK(sc);
|
||||||
BGE_CLRBIT(sc, BGE_PCI_MISC_CTL,
|
BGE_CLRBIT(sc, BGE_PCI_MISC_CTL,
|
||||||
BGE_PCIMISCCTL_MASK_PCI_INTR);
|
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;
|
ifp->if_capenable &= ~IFCAP_POLLING;
|
||||||
BGE_UNLOCK(sc);
|
BGE_UNLOCK(sc);
|
||||||
}
|
}
|
||||||
@ -4063,7 +4212,7 @@ bge_stop(struct bge_softc *sc)
|
|||||||
|
|
||||||
/* Disable host interrupts. */
|
/* Disable host interrupts. */
|
||||||
BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
|
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.
|
* Tell firmware we're shutting down.
|
||||||
@ -4559,3 +4708,63 @@ bge_sysctl_mem_read(SYSCTL_HANDLER_ARGS)
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
bge_get_eaddr_mem(struct bge_softc *sc, uint8_t ether_addr[])
|
||||||
|
{
|
||||||
|
uint32_t mac_addr;
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
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;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_flags & BGE_FLAG_EEPROM))
|
||||||
|
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_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);
|
||||||
|
}
|
||||||
|
@ -284,6 +284,8 @@
|
|||||||
#define BGE_CHIPID_BCM5787_A0 0xb0000000
|
#define BGE_CHIPID_BCM5787_A0 0xb0000000
|
||||||
#define BGE_CHIPID_BCM5787_A1 0xb0010000
|
#define BGE_CHIPID_BCM5787_A1 0xb0010000
|
||||||
#define BGE_CHIPID_BCM5787_A2 0xb0020000
|
#define BGE_CHIPID_BCM5787_A2 0xb0020000
|
||||||
|
#define BGE_CHIPID_BCM5906_A1 0xc0010000
|
||||||
|
#define BGE_CHIPID_BCM5906_A2 0xc0020000
|
||||||
|
|
||||||
/* shorthand one */
|
/* shorthand one */
|
||||||
#define BGE_ASICREV(x) ((x) >> 28)
|
#define BGE_ASICREV(x) ((x) >> 28)
|
||||||
@ -300,6 +302,7 @@
|
|||||||
#define BGE_ASICREV_BCM5755 0x0a
|
#define BGE_ASICREV_BCM5755 0x0a
|
||||||
#define BGE_ASICREV_BCM5754 0x0b
|
#define BGE_ASICREV_BCM5754 0x0b
|
||||||
#define BGE_ASICREV_BCM5787 0x0b
|
#define BGE_ASICREV_BCM5787 0x0b
|
||||||
|
#define BGE_ASICREV_BCM5906 0x0c
|
||||||
|
|
||||||
/* chip revisions */
|
/* chip revisions */
|
||||||
#define BGE_CHIPREV(x) ((x) >> 24)
|
#define BGE_CHIPREV(x) ((x) >> 24)
|
||||||
@ -1439,6 +1442,17 @@
|
|||||||
#define BGE_RXCPUSTAT_MA_REQ_FIFOOFLOW 0x40000000
|
#define BGE_RXCPUSTAT_MA_REQ_FIFOOFLOW 0x40000000
|
||||||
#define BGE_RXCPUSTAT_BLOCKING_READ 0x80000000
|
#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
|
* TX CPU registers
|
||||||
@ -1685,6 +1699,56 @@
|
|||||||
#define BGE_EE_DELAY 0x6848
|
#define BGE_EE_DELAY 0x6848
|
||||||
#define BGE_FASTBOOT_PC 0x6894
|
#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 */
|
/* Mode control register */
|
||||||
#define BGE_MODECTL_INT_SNDCOAL_ONLY 0x00000001
|
#define BGE_MODECTL_INT_SNDCOAL_ONLY 0x00000001
|
||||||
#define BGE_MODECTL_BYTESWAP_NONFRAME 0x00000002
|
#define BGE_MODECTL_BYTESWAP_NONFRAME 0x00000002
|
||||||
@ -1712,6 +1776,7 @@
|
|||||||
/* Misc. config register */
|
/* Misc. config register */
|
||||||
#define BGE_MISCCFG_RESET_CORE_CLOCKS 0x00000001
|
#define BGE_MISCCFG_RESET_CORE_CLOCKS 0x00000001
|
||||||
#define BGE_MISCCFG_TIMER_PRESCALER 0x000000FE
|
#define BGE_MISCCFG_TIMER_PRESCALER 0x000000FE
|
||||||
|
#define BGE_MISCCFG_EPHY_IDDQ 0x00200000
|
||||||
|
|
||||||
#define BGE_32BITTIME_66MHZ (0x41 << 1)
|
#define BGE_32BITTIME_66MHZ (0x41 << 1)
|
||||||
|
|
||||||
@ -2039,6 +2104,8 @@ struct bge_status_block {
|
|||||||
#define BCOM_DEVICEID_BCM5901 0x170D
|
#define BCOM_DEVICEID_BCM5901 0x170D
|
||||||
#define BCOM_DEVICEID_BCM5901A2 0x170E
|
#define BCOM_DEVICEID_BCM5901A2 0x170E
|
||||||
#define BCOM_DEVICEID_BCM5903M 0x16FF
|
#define BCOM_DEVICEID_BCM5903M 0x16FF
|
||||||
|
#define BCOM_DEVICEID_BCM5906 0x1712
|
||||||
|
#define BCOM_DEVICEID_BCM5906M 0x1713
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Alteon AceNIC PCI vendor/device ID.
|
* Alteon AceNIC PCI vendor/device ID.
|
||||||
@ -2092,6 +2159,7 @@ struct bge_status_block {
|
|||||||
* Offset of MAC address inside EEPROM.
|
* Offset of MAC address inside EEPROM.
|
||||||
*/
|
*/
|
||||||
#define BGE_EE_MAC_OFFSET 0x7C
|
#define BGE_EE_MAC_OFFSET 0x7C
|
||||||
|
#define BGE_EE_MAC_OFFSET_5906 0x10
|
||||||
#define BGE_EE_HWCFG_OFFSET 0xC8
|
#define BGE_EE_HWCFG_OFFSET 0xC8
|
||||||
|
|
||||||
#define BGE_HWCFG_VOLTAGE 0x00000003
|
#define BGE_HWCFG_VOLTAGE 0x00000003
|
||||||
@ -2477,6 +2545,7 @@ struct bge_softc {
|
|||||||
#define BGE_FLAG_BER_BUG 0x02000000
|
#define BGE_FLAG_BER_BUG 0x02000000
|
||||||
#define BGE_FLAG_ADJUST_TRIM 0x04000000
|
#define BGE_FLAG_ADJUST_TRIM 0x04000000
|
||||||
#define BGE_FLAG_CRC_BUG 0x08000000
|
#define BGE_FLAG_CRC_BUG 0x08000000
|
||||||
|
#define BGE_FLAG_NO_EEPROM 0x10000000
|
||||||
uint32_t bge_chipid;
|
uint32_t bge_chipid;
|
||||||
uint8_t bge_asicrev;
|
uint8_t bge_asicrev;
|
||||||
uint8_t bge_chiprev;
|
uint8_t bge_chiprev;
|
||||||
|
@ -134,6 +134,7 @@ static const struct mii_phydesc brgphys[] = {
|
|||||||
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709CAX),
|
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709CAX),
|
||||||
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5722),
|
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5722),
|
||||||
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C),
|
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C),
|
||||||
|
MII_PHY_DESC(BROADCOM2, BCM5906),
|
||||||
MII_PHY_END
|
MII_PHY_END
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -189,6 +190,7 @@ brgphy_attach(device_t dev)
|
|||||||
/* Handle any special cases based on the PHY ID */
|
/* Handle any special cases based on the PHY ID */
|
||||||
switch (bsc->mii_oui) {
|
switch (bsc->mii_oui) {
|
||||||
case MII_OUI_BROADCOM:
|
case MII_OUI_BROADCOM:
|
||||||
|
case MII_OUI_BROADCOM2:
|
||||||
break;
|
break;
|
||||||
case MII_OUI_xxBROADCOM:
|
case MII_OUI_xxBROADCOM:
|
||||||
switch (bsc->mii_model) {
|
switch (bsc->mii_model) {
|
||||||
@ -229,12 +231,14 @@ brgphy_attach(device_t dev)
|
|||||||
bce_sc = ifp->if_softc;
|
bce_sc = ifp->if_softc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Todo: Need to add additional controllers such as 5906 & 5787F */
|
/* Todo: Need to add additional controllers such as 5787F */
|
||||||
/* The 590x chips are 10/100 only. */
|
/* The 590x chips are 10/100 only. */
|
||||||
if (bge_sc &&
|
if (bge_sc &&
|
||||||
pci_get_vendor(bge_sc->bge_dev) == BCOM_VENDORID &&
|
pci_get_vendor(bge_sc->bge_dev) == BCOM_VENDORID &&
|
||||||
(pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901 ||
|
(pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901 ||
|
||||||
pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901A2)) {
|
pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901A2 ||
|
||||||
|
pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906 ||
|
||||||
|
pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906M)) {
|
||||||
fast_ether = 1;
|
fast_ether = 1;
|
||||||
sc->mii_anegticks = MII_ANEGTICKS;
|
sc->mii_anegticks = MII_ANEGTICKS;
|
||||||
}
|
}
|
||||||
@ -927,6 +931,11 @@ brgphy_reset(struct mii_softc *sc)
|
|||||||
PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL) &
|
PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL) &
|
||||||
~BRGPHY_PHY_EXTCTL_3_LED);
|
~BRGPHY_PHY_EXTCTL_3_LED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Adjust output voltage (From Linux driver) */
|
||||||
|
if (bge_sc->bge_asicrev == BGE_ASICREV_BCM5906)
|
||||||
|
PHY_WRITE(sc, BRGPHY_MII_EPHY_PTEST, 0x12);
|
||||||
|
|
||||||
/* Handle any bce (NetXtreme II) workarounds. */
|
/* Handle any bce (NetXtreme II) workarounds. */
|
||||||
} else if (bce_sc) {
|
} else if (bce_sc) {
|
||||||
|
|
||||||
|
@ -161,6 +161,7 @@
|
|||||||
#define BRGPHY_MII_DSP_RW_PORT 0x15 /* DSP coefficient r/w port */
|
#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_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_TAP_NUMBER_MASK 0x00
|
||||||
#define BRGPHY_DSP_AGC_A 0x00
|
#define BRGPHY_DSP_AGC_A 0x00
|
||||||
|
@ -52,6 +52,7 @@ $FreeBSD$
|
|||||||
oui ALTIMA 0x0010a9 Altima Communications
|
oui ALTIMA 0x0010a9 Altima Communications
|
||||||
oui AMD 0x00001a Advanced Micro Devices
|
oui AMD 0x00001a Advanced Micro Devices
|
||||||
oui BROADCOM 0x001018 Broadcom Corporation
|
oui BROADCOM 0x001018 Broadcom Corporation
|
||||||
|
oui BROADCOM2 0x000af7 Broadcom Corporation
|
||||||
oui CICADA 0x0003F1 Cicada Semiconductor
|
oui CICADA 0x0003F1 Cicada Semiconductor
|
||||||
oui DAVICOM 0x00606e Davicom Semiconductor
|
oui DAVICOM 0x00606e Davicom Semiconductor
|
||||||
oui ICPLUS 0x0090c3 IC Plus Corp.
|
oui ICPLUS 0x0090c3 IC Plus Corp.
|
||||||
@ -138,6 +139,7 @@ model xxBROADCOM_ALT1 BCM5708S 0x0015 BCM5708S 1000/2500BaseSX PHY
|
|||||||
model xxBROADCOM_ALT1 BCM5709CAX 0x002c BCM5709C(AX) 10/100/1000baseTX PHY
|
model xxBROADCOM_ALT1 BCM5709CAX 0x002c BCM5709C(AX) 10/100/1000baseTX PHY
|
||||||
model xxBROADCOM_ALT1 BCM5722 0x002d BCM5722 10/100/1000baseTX PHY
|
model xxBROADCOM_ALT1 BCM5722 0x002d BCM5722 10/100/1000baseTX PHY
|
||||||
model xxBROADCOM_ALT1 BCM5709C 0x003c BCM5709C 10/100/1000baseTX PHY
|
model xxBROADCOM_ALT1 BCM5709C 0x003c BCM5709C 10/100/1000baseTX PHY
|
||||||
|
model BROADCOM2 BCM5906 0x0004 BCM5906 10/100baseTX PHY
|
||||||
|
|
||||||
/* Cicada Semiconductor PHYs (now owned by Vitesse?) */
|
/* Cicada Semiconductor PHYs (now owned by Vitesse?) */
|
||||||
model CICADA CS8201 0x0001 Cicada CS8201 10/100/1000TX PHY
|
model CICADA CS8201 0x0001 Cicada CS8201 10/100/1000TX PHY
|
||||||
|
Loading…
x
Reference in New Issue
Block a user