Add support for the BCM5750/5751. Unfortunately the documentation

I have from Broadcom does not give much information on these devices,
so the Broadcom Linux driver was used for clues to what these chips
support.  It turns out they are similar to the 5705 with the 5751
being the PCI-Express version and needing special work-arounds and
settings.
This commit is contained in:
Paul Saab 2004-09-24 22:24:33 +00:00
parent 5f892a7ff0
commit e53d81eee9
4 changed files with 166 additions and 38 deletions

View File

@ -155,6 +155,12 @@ static struct bge_type bge_devs[] = {
"Broadcom BCM5705M Gigabit Ethernet" },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5705M_ALT,
"Broadcom BCM5705M Gigabit Ethernet" },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5750,
"Broadcom BCM5750 Gigabit Ethernet" },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5750M,
"Broadcom BCM5750M Gigabit Ethernet" },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5751,
"Broadcom BCM5751 Gigabit Ethernet" },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5782,
"Broadcom BCM5782 Gigabit Ethernet" },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5788,
@ -1216,7 +1222,11 @@ bge_chipinit(sc)
BGE_MEMWIN_WRITE(sc, i, 0);
/* Set up the PCI DMA control register. */
if (pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE, 4) &
if (sc->bge_pcie) {
dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
(0xf << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
(0x2 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);
} else if (pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE, 4) &
BGE_PCISTATE_PCI_BUSMODE) {
/* Conventional PCI bus */
dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
@ -1255,7 +1265,8 @@ bge_chipinit(sc)
if (sc->bge_asicrev == BGE_ASICREV_BCM5703 ||
sc->bge_asicrev == BGE_ASICREV_BCM5704 ||
sc->bge_asicrev == BGE_ASICREV_BCM5705)
sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
sc->bge_asicrev == BGE_ASICREV_BCM5750)
dma_rw_ctl &= ~BGE_PCIDMARWCTL_MINDMA;
pci_write_config(sc->bge_dev, BGE_PCI_DMA_RW_CTL, dma_rw_ctl, 4);
@ -1308,7 +1319,8 @@ bge_blockinit(sc)
/* Note: the BCM5704 has a smaller mbuf space than other chips. */
if (sc->bge_asicrev != BGE_ASICREV_BCM5705) {
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750) {
/* Configure mbuf memory pool */
if (sc->bge_extram) {
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_BASEADDR,
@ -1333,7 +1345,8 @@ bge_blockinit(sc)
}
/* Configure mbuf pool watermarks */
if (sc->bge_asicrev == BGE_ASICREV_BCM5705) {
if (sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
sc->bge_asicrev == BGE_ASICREV_BCM5750) {
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10);
} else {
@ -1347,7 +1360,8 @@ bge_blockinit(sc)
CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10);
/* Enable buffer manager */
if (sc->bge_asicrev != BGE_ASICREV_BCM5705) {
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750) {
CSR_WRITE_4(sc, BGE_BMAN_MODE,
BGE_BMANMODE_ENABLE|BGE_BMANMODE_LOMBUF_ATTN);
@ -1390,7 +1404,8 @@ bge_blockinit(sc)
BGE_ADDR_HI(sc->bge_ldata.bge_rx_std_ring_paddr);
bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_PREREAD);
if (sc->bge_asicrev == BGE_ASICREV_BCM5705)
if (sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
sc->bge_asicrev == BGE_ASICREV_BCM5750)
rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(512, 0);
else
rcb->bge_maxlen_flags =
@ -1412,7 +1427,8 @@ bge_blockinit(sc)
* using this ring (i.e. once we set the MTU
* high enough to require it).
*/
if (sc->bge_asicrev != BGE_ASICREV_BCM5705) {
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750) {
rcb = &sc->bge_ldata.bge_info.bge_jumbo_rx_rcb;
rcb->bge_hostaddr.bge_addr_lo =
@ -1476,7 +1492,8 @@ bge_blockinit(sc)
vrcb->bge_hostaddr.bge_addr_hi =
htole32(BGE_ADDR_HI(sc->bge_ldata.bge_tx_ring_paddr));
vrcb->bge_nicaddr = BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT);
if (sc->bge_asicrev != BGE_ASICREV_BCM5705)
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750)
vrcb->bge_maxlen_flags =
BGE_RCB_MAXLEN_FLAGS(BGE_TX_RING_CNT, 0);
@ -1565,7 +1582,8 @@ bge_blockinit(sc)
CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS, sc->bge_tx_coal_ticks);
CSR_WRITE_4(sc, BGE_HCC_RX_MAX_COAL_BDS, sc->bge_rx_max_coal_bds);
CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS, sc->bge_tx_max_coal_bds);
if (sc->bge_asicrev != BGE_ASICREV_BCM5705) {
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750) {
CSR_WRITE_4(sc, BGE_HCC_RX_COAL_TICKS_INT, 0);
CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS_INT, 0);
}
@ -1573,7 +1591,8 @@ bge_blockinit(sc)
CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS_INT, 0);
/* Set up address of statistics block */
if (sc->bge_asicrev != BGE_ASICREV_BCM5705) {
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750) {
CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_HI,
BGE_ADDR_HI(sc->bge_ldata.bge_stats_paddr));
CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_LO,
@ -1604,7 +1623,8 @@ bge_blockinit(sc)
CSR_WRITE_4(sc, BGE_RXLP_MODE, BGE_RXLPMODE_ENABLE);
/* Turn on RX list selector state machine. */
if (sc->bge_asicrev != BGE_ASICREV_BCM5705)
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750)
CSR_WRITE_4(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE);
/* Turn on DMA, clear stats */
@ -1626,7 +1646,8 @@ bge_blockinit(sc)
#endif
/* Turn on DMA completion state machine */
if (sc->bge_asicrev != BGE_ASICREV_BCM5705)
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750)
CSR_WRITE_4(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE);
/* Turn on write DMA state machine */
@ -1647,7 +1668,8 @@ bge_blockinit(sc)
CSR_WRITE_4(sc, BGE_RDBDI_MODE, BGE_RDBDIMODE_ENABLE);
/* Turn on Mbuf cluster free state machine */
if (sc->bge_asicrev != BGE_ASICREV_BCM5705)
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750)
CSR_WRITE_4(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE);
/* Turn on send BD completion state machine */
@ -1981,7 +2003,8 @@ bge_dma_alloc(dev)
sc->bge_ldata.bge_rx_std_ring_paddr = ctx.bge_busaddr;
if (sc->bge_asicrev != BGE_ASICREV_BCM5705) {
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750) {
/*
* Create tag for jumbo mbufs.
@ -2261,6 +2284,29 @@ bge_attach(dev)
BGE_LOCK_INIT(sc, device_get_nameunit(dev));
/* 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);
/*
* XXX: Broadcom Linux driver. Not in specs or eratta.
* PCI-Express?
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5750) {
u_int32_t v;
v = pci_read_config(dev, BGE_PCI_MSI_CAPID, 4);
if (((v >> 8) & 0xff) == BGE_PCIE_CAPID_REG) {
v = pci_read_config(dev, BGE_PCIE_CAPID_REG, 4);
if ((v & 0xff) == BGE_PCIE_CAPID)
sc->bge_pcie = 1;
}
}
/* Try to reset the chip. */
bge_reset(sc);
@ -2291,16 +2337,9 @@ bge_attach(dev)
goto fail;
}
/* 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);
/* 5705 limits RX return ring to 512 entries. */
if (sc->bge_asicrev == BGE_ASICREV_BCM5705)
if (sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
sc->bge_asicrev == BGE_ASICREV_BCM5750)
sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT_5705;
else
sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT;
@ -2317,7 +2356,8 @@ bge_attach(dev)
* Try to allocate memory for jumbo buffers.
* The 5705 does not appear to support jumbo frames.
*/
if (sc->bge_asicrev != BGE_ASICREV_BCM5705) {
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750) {
if (bge_alloc_jumbo_mem(sc)) {
printf("bge%d: jumbo buffer allocation "
"failed\n", sc->bge_unit);
@ -2465,7 +2505,8 @@ bge_detach(dev)
}
bge_release_resources(sc);
if (sc->bge_asicrev != BGE_ASICREV_BCM5705)
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750)
bge_free_jumbo_mem(sc);
return(0);
@ -2508,7 +2549,7 @@ bge_reset(sc)
struct bge_softc *sc;
{
device_t dev;
u_int32_t cachesize, command, pcistate;
u_int32_t cachesize, command, pcistate, reset;
int i, val = 0;
dev = sc->bge_dev;
@ -2522,12 +2563,37 @@ bge_reset(sc)
BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|
BGE_PCIMISCCTL_ENDIAN_WORDSWAP|BGE_PCIMISCCTL_PCISTATE_RW, 4);
reset = BGE_MISCCFG_RESET_CORE_CLOCKS|(65<<1);
/* XXX: Broadcom Linux driver. */
if (sc->bge_pcie) {
if (CSR_READ_4(sc, 0x7e2c) == 0x60) /* PCIE 1.0 */
CSR_WRITE_4(sc, 0x7e2c, 0x20);
if (sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {
/* Prevent PCIE link training during global reset */
CSR_WRITE_4(sc, BGE_MISC_CFG, (1<<29));
reset |= (1<<29);
}
}
/* Issue global reset */
bge_writereg_ind(sc, BGE_MISC_CFG,
BGE_MISCCFG_RESET_CORE_CLOCKS|(65<<1));
bge_writereg_ind(sc, BGE_MISC_CFG, reset);
DELAY(1000);
/* XXX: Broadcom Linux driver. */
if (sc->bge_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);
}
/* Set PCIE max payload size and clear error status. */
pci_write_config(dev, 0xd8, 0xf5000, 4);
}
/* Reset some of the PCI state that got zapped by reset */
pci_write_config(dev, BGE_PCI_MISC_CTL,
BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|
@ -2537,7 +2603,8 @@ bge_reset(sc)
bge_writereg_ind(sc, BGE_MISC_CFG, (65 << 1));
/* Enable memory arbiter. */
if (sc->bge_asicrev != BGE_ASICREV_BCM5705)
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750)
CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
/*
@ -2595,6 +2662,13 @@ bge_reset(sc)
CSR_WRITE_4(sc, BGE_SERDES_CFG, serdescfg);
}
/* XXX: Broadcom Linux driver. */
if (sc->bge_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));
}
DELAY(10000);
return;
@ -2624,7 +2698,8 @@ bge_rxeof(sc)
sc->bge_cdata.bge_rx_return_ring_map, BUS_DMASYNC_POSTWRITE);
bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_POSTREAD);
if (sc->bge_asicrev != BGE_ASICREV_BCM5705) {
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750) {
bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
sc->bge_cdata.bge_rx_jumbo_ring_map,
BUS_DMASYNC_POSTREAD);
@ -2740,7 +2815,8 @@ bge_rxeof(sc)
bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
sc->bge_cdata.bge_rx_std_ring_map,
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_PREWRITE);
if (sc->bge_asicrev != BGE_ASICREV_BCM5705) {
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750) {
bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
sc->bge_cdata.bge_rx_jumbo_ring_map,
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
@ -2926,7 +3002,8 @@ bge_tick_locked(sc)
BGE_LOCK_ASSERT(sc);
if (sc->bge_asicrev == BGE_ASICREV_BCM5705)
if (sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
sc->bge_asicrev == BGE_ASICREV_BCM5750)
bge_stats_update_regs(sc);
else
bge_stats_update(sc);
@ -3438,7 +3515,8 @@ bge_ioctl(ifp, command, data)
switch(command) {
case SIOCSIFMTU:
/* Disallow jumbo frames on 5705. */
if ((sc->bge_asicrev == BGE_ASICREV_BCM5705 &&
if (((sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
sc->bge_asicrev == BGE_ASICREV_BCM5750) &&
ifr->ifr_mtu > ETHERMTU) || ifr->ifr_mtu > BGE_JUMBO_MTU)
error = EINVAL;
else {
@ -3565,7 +3643,8 @@ bge_stop(sc)
BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
BGE_CLRBIT(sc, BGE_RBDI_MODE, BGE_RBDIMODE_ENABLE);
BGE_CLRBIT(sc, BGE_RXLP_MODE, BGE_RXLPMODE_ENABLE);
if (sc->bge_asicrev != BGE_ASICREV_BCM5705)
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750)
BGE_CLRBIT(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE);
BGE_CLRBIT(sc, BGE_RDBDI_MODE, BGE_RBDIMODE_ENABLE);
BGE_CLRBIT(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE);
@ -3579,7 +3658,8 @@ bge_stop(sc)
BGE_CLRBIT(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);
BGE_CLRBIT(sc, BGE_RDMA_MODE, BGE_RDMAMODE_ENABLE);
BGE_CLRBIT(sc, BGE_SDC_MODE, BGE_SDCMODE_ENABLE);
if (sc->bge_asicrev != BGE_ASICREV_BCM5705)
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750)
BGE_CLRBIT(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE);
BGE_CLRBIT(sc, BGE_SBDC_MODE, BGE_SBDCMODE_ENABLE);
@ -3589,11 +3669,13 @@ bge_stop(sc)
*/
BGE_CLRBIT(sc, BGE_HCC_MODE, BGE_HCCMODE_ENABLE);
BGE_CLRBIT(sc, BGE_WDMA_MODE, BGE_WDMAMODE_ENABLE);
if (sc->bge_asicrev != BGE_ASICREV_BCM5705)
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750)
BGE_CLRBIT(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE);
CSR_WRITE_4(sc, BGE_FTQ_RESET, 0xFFFFFFFF);
CSR_WRITE_4(sc, BGE_FTQ_RESET, 0);
if (sc->bge_asicrev != BGE_ASICREV_BCM5705) {
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750) {
BGE_CLRBIT(sc, BGE_BMAN_MODE, BGE_BMANMODE_ENABLE);
BGE_CLRBIT(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
}
@ -3611,7 +3693,8 @@ bge_stop(sc)
bge_free_rx_ring_std(sc);
/* Free jumbo RX list. */
if (sc->bge_asicrev != BGE_ASICREV_BCM5705)
if (sc->bge_asicrev != BGE_ASICREV_BCM5705 ||
sc->bge_asicrev != BGE_ASICREV_BCM5750)
bge_free_rx_ring_jumbo(sc);
/* Free TX buffers. */

View File

@ -169,6 +169,10 @@
#define BGE_PCI_MSI_ADDR_LO 0x60
#define BGE_PCI_MSI_DATA 0x64
/* PCI MSI. ??? */
#define BGE_PCIE_CAPID_REG 0xD0
#define BGE_PCIE_CAPID 0x10
/*
* PCI registers specific to the BCM570x family.
*/
@ -233,6 +237,8 @@
#define BGE_CHIPID_BCM5705_A1 0x30010000
#define BGE_CHIPID_BCM5705_A2 0x30020000
#define BGE_CHIPID_BCM5705_A3 0x30030000
#define BGE_CHIPID_BCM5750_A0 0x40000000
#define BGE_CHIPID_BCM5750_A1 0x40010000
/* shorthand one */
#define BGE_ASICREV(x) ((x) >> 28)
@ -241,6 +247,7 @@
#define BGE_ASICREV_BCM5703 0x01
#define BGE_ASICREV_BCM5704 0x02
#define BGE_ASICREV_BCM5705 0x03
#define BGE_ASICREV_BCM5750 0x04
/* chip revisions */
#define BGE_CHIPREV(x) ((x) >> 24)
@ -1860,6 +1867,9 @@ struct bge_status_block {
#define BCOM_DEVICEID_BCM5705K 0x1654
#define BCOM_DEVICEID_BCM5705M 0x165D
#define BCOM_DEVICEID_BCM5705M_ALT 0x165E
#define BCOM_DEVICEID_BCM5750 0x1676
#define BCOM_DEVICEID_BCM5750M 0x167C
#define BCOM_DEVICEID_BCM5751 0x1677
#define BCOM_DEVICEID_BCM5782 0x1696
#define BCOM_DEVICEID_BCM5788 0x169C
#define BCOM_DEVICEID_BCM5901 0x170D
@ -2316,6 +2326,7 @@ struct bge_softc {
u_int8_t bge_asicrev;
u_int8_t bge_chiprev;
u_int8_t bge_no_3_led;
u_int8_t bge_pcie;
struct bge_ring_data bge_ldata; /* rings */
struct bge_chain_data bge_cdata; /* mbufs */
u_int16_t bge_tx_saved_considx;

View File

@ -94,6 +94,7 @@ static void brgphy_loop(struct mii_softc *);
static void bcm5401_load_dspcode(struct mii_softc *);
static void bcm5411_load_dspcode(struct mii_softc *);
static void bcm5703_load_dspcode(struct mii_softc *);
static void bcm5750_load_dspcode(struct mii_softc *);
static int brgphy_mii_model;
static int
@ -146,6 +147,12 @@ brgphy_probe(dev)
return(0);
}
if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5750) {
device_set_desc(dev, MII_STR_xxBROADCOM_BCM5750);
return(0);
}
return(ENXIO);
}
@ -578,6 +585,29 @@ bcm5704_load_dspcode(struct mii_softc *sc)
PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
}
static void
bcm5750_load_dspcode(struct mii_softc *sc)
{
static const struct {
int reg;
u_int16_t val;
} dspcode[] = {
{ 0x18, 0x0c00 },
{ 0x17, 0x000a },
{ 0x15, 0x310b },
{ 0x17, 0x201f },
{ 0x15, 0x9506 },
{ 0x17, 0x401f },
{ 0x15, 0x14e2 },
{ 0x18, 0x0400 },
{ 0, 0 },
};
int i;
for (i = 0; dspcode[i].reg != 0; i++)
PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
}
static void
brgphy_reset(struct mii_softc *sc)
{
@ -600,6 +630,9 @@ brgphy_reset(struct mii_softc *sc)
case MII_MODEL_xxBROADCOM_BCM5704:
bcm5704_load_dspcode(sc);
break;
case MII_MODEL_xxBROADCOM_BCM5750:
bcm5750_load_dspcode(sc);
break;
}
ifp = sc->mii_pdata->mii_ifp;

View File

@ -121,6 +121,7 @@ model xxBROADCOM BCM5701 0x0011 BCM5701 10/100/1000baseTX PHY
model xxBROADCOM BCM5703 0x0016 BCM5703 10/100/1000baseTX PHY
model xxBROADCOM BCM5704 0x0019 BCM5704 10/100/1000baseTX PHY
model xxBROADCOM BCM5705 0x001a BCM5705 10/100/1000baseTX PHY
model xxBROADCOM BCM5750 0x0018 BCM5750 10/100/1000baseTX PHY
/* Cicada Semiconductor PHYs (now owned by Vitesse?) */
model CICADA CS8201 0x0001 Cicada CS8201 10/100/1000TX PHY