Add workaround for embedded NICs, in particular, the 815E boards.

There appears to be a bug where the chip will lock up when running
in 10Mb/s mode.
This commit is contained in:
Jonathan Lemon 2001-05-17 23:50:24 +00:00
parent 120bcabcbf
commit 2e2b823898
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=76777
2 changed files with 44 additions and 17 deletions

View File

@ -199,6 +199,7 @@ static void fxp_miibus_writereg(device_t dev, int phy, int reg,
static __inline void fxp_lwcopy(volatile u_int32_t *src,
volatile u_int32_t *dst);
static __inline void fxp_scb_wait(struct fxp_softc *sc);
static __inline void fxp_scb_cmd(struct fxp_softc *sc, int cmd);
static __inline void fxp_dma_wait(volatile u_int16_t *status,
struct fxp_softc *sc);
@ -266,6 +267,17 @@ fxp_scb_wait(struct fxp_softc *sc)
CSR_READ_2(sc, FXP_CSR_FLOWCONTROL));
}
static __inline void
fxp_scb_cmd(struct fxp_softc *sc, int cmd)
{
if (cmd == FXP_SCB_COMMAND_CU_RESUME && sc->cu_resume_bug) {
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_CB_COMMAND_NOP);
fxp_scb_wait(sc);
}
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, cmd);
}
static __inline void
fxp_dma_wait(volatile u_int16_t *status, struct fxp_softc *sc)
{
@ -458,6 +470,13 @@ fxp_attach(device_t dev)
if ((data >> 8) == 1)
sc->chip = FXP_CHIP_82557;
/*
* Enable workarounds for certain chip revision deficiencies.
*/
i = pci_get_device(dev);
if (i == 0x2449 || (i > 0x1030 && i < 0x1039))
sc->flags |= FXP_FLAG_CU_RESUME_BUG;
/*
* If we are not a 82557 chip, we can enable extended features.
*/
@ -485,9 +504,10 @@ fxp_attach(device_t dev)
sc->arpcom.ac_enaddr, ":",
sc->flags & FXP_FLAG_SERIAL_MEDIA ? ", 10Mbps" : "");
if (bootverbose) {
device_printf(dev, "PCI IDs: %04x %04x %04x %04x\n",
device_printf(dev, "PCI IDs: %04x %04x %04x %04x %04x\n",
pci_get_vendor(dev), pci_get_device(dev),
pci_get_subvendor(dev), pci_get_subdevice(dev));
pci_get_subvendor(dev), pci_get_subdevice(dev),
pci_get_revid(dev));
device_printf(dev, "Chip Type: %d\n", sc->chip);
}
@ -594,6 +614,9 @@ fxp_detach(device_t dev)
struct fxp_softc *sc = device_get_softc(dev);
int s;
/* disable interrupts */
CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE);
s = splimp();
/*
@ -968,7 +991,7 @@ fxp_start(struct ifnet *ifp)
*/
if (txp != NULL) {
fxp_scb_wait(sc);
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_RESUME);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
}
}
@ -982,7 +1005,6 @@ fxp_intr(void *xsc)
struct ifnet *ifp = &sc->sc_if;
u_int8_t statack;
if (sc->suspended) {
return;
}
@ -1096,8 +1118,7 @@ fxp_intr(void *xsc)
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
vtophys(sc->rfa_headm->m_ext.ext_buf) +
RFA_ALIGNMENT_FUDGE);
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND,
FXP_SCB_COMMAND_RU_START);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
}
}
}
@ -1188,8 +1209,7 @@ fxp_tick(void *xsc)
/*
* Start another stats dump.
*/
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND,
FXP_SCB_COMMAND_CU_DUMPRESET);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMPRESET);
} else {
/*
* A previous command is still waiting to be accepted.
@ -1315,17 +1335,17 @@ fxp_init(void *xsc)
* sets it up for regular linear addressing.
*/
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0);
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_BASE);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_BASE);
fxp_scb_wait(sc);
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_BASE);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_BASE);
/*
* Initialize base of dump-stats buffer.
*/
fxp_scb_wait(sc);
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(sc->fxp_stats));
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_DUMP_ADR);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMP_ADR);
/*
* We temporarily use memory that contains the TxCB list to
@ -1434,7 +1454,7 @@ fxp_init(void *xsc)
*/
fxp_scb_wait(sc);
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&cbp->cb_status));
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
/* ...and wait for it to complete. */
fxp_dma_wait(&cbp->cb_status, sc);
@ -1454,7 +1474,7 @@ fxp_init(void *xsc)
* Start the IAS (Individual Address Setup) command/DMA.
*/
fxp_scb_wait(sc);
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
/* ...and wait for it to complete. */
fxp_dma_wait(&cb_ias->cb_status, sc);
@ -1484,7 +1504,7 @@ fxp_init(void *xsc)
sc->tx_queued = 1;
fxp_scb_wait(sc);
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
/*
* Initialize receiver buffer area - RFA.
@ -1492,7 +1512,7 @@ fxp_init(void *xsc)
fxp_scb_wait(sc);
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
vtophys(sc->rfa_headm->m_ext.ext_buf) + RFA_ALIGNMENT_FUDGE);
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_START);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
/*
* Set current media.
@ -1556,6 +1576,11 @@ fxp_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
mii_pollstat(mii);
ifmr->ifm_active = mii->mii_media_active;
ifmr->ifm_status = mii->mii_media_status;
if (ifmr->ifm_status & IFM_10_T && sc->flags & FXP_FLAG_CU_RESUME_BUG)
sc->cu_resume_bug = 1;
else
sc->cu_resume_bug = 0;
}
/*
@ -1811,7 +1836,7 @@ fxp_mc_setup(struct fxp_softc *sc)
* Issue a resume in case the CU has just suspended.
*/
fxp_scb_wait(sc);
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_RESUME);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
/*
* Set a 5 second timer just in case we don't hear from the
* card again.
@ -1874,7 +1899,7 @@ fxp_mc_setup(struct fxp_softc *sc)
*/
fxp_scb_wait(sc);
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&mcsp->cb_status));
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
ifp->if_timer = 2;
return;

View File

@ -113,6 +113,7 @@ struct fxp_softc {
device_t dev;
int eeprom_size; /* size of serial EEPROM */
int suspended; /* 0 = normal 1 = suspended (APM) */
int cu_resume_bug;
int chip;
int flags;
u_int32_t saved_maps[5]; /* pci data */
@ -131,6 +132,7 @@ struct fxp_softc {
#define FXP_FLAG_SERIAL_MEDIA 0x0010 /* 10Mbps serial interface */
#define FXP_FLAG_LONG_PKT_EN 0x0020 /* enable long packet reception */
#define FXP_FLAG_ALL_MCAST 0x0040 /* accept all multicast frames */
#define FXP_FLAG_CU_RESUME_BUG 0x0080 /* requires workaround for CU_RESUME */
/* Macros to ease CSR access. */
#define CSR_READ_1(sc, reg) \