Fix some problems reported by Mike Pritchard:
- Add a flag DC_TX_INTR_ALWAYS which causes the transmit code to request a TX done interrupt for every packet. The PNIC seems to need this to insure that the sent TX buffers get reaped in a timely fashion. - Try to unreset the SIA as soon as possible after resetting the whole chip. - Change dcphy to support either 10/100 or 10Mbps only NICs. The built-in 21143 ethernet in Compaq Presario machines is 10Mbps only and it doesn't work right if we try to advertise 100Mbps modes during autoneg. When restricted to only 10mbps modes, it works fine. Note that for now, I detect this condition by checking the PCI subsystem ID on this NIC (which has a Compaq vendor/device ID). Yes, I know that's what the SROM is supposed to be for. I'm deliberately ignoring the SROM wherever possible. Sue me. The latter two fixes allow if_dc to work correctly with the built-in ethernet on certain Compaq Presario boxes. There are liable to be quite a few people using these as their home systems who might want to try FreeBSD; may as well be nice to them. Now if anybody out there has an Alpha miata with 10Mbps ethernet and can show me the output from pciconf -l on their system, I'd be grateful.
This commit is contained in:
parent
81282dc103
commit
20bb20f965
@ -86,6 +86,13 @@ static const char rcsid[] =
|
||||
|
||||
#define MIIF_AUTOTIMEOUT 0x0004
|
||||
|
||||
/*
|
||||
* This is the subsystem ID for the built-in 21143 ethernet
|
||||
* in several Compaq Presario systems. Apparently these are
|
||||
* 10Mbps only, so we need to treat them specially.
|
||||
*/
|
||||
#define COMPAQ_PRESARIO_ID 0xb0bb0e11
|
||||
|
||||
static int dcphy_probe __P((device_t));
|
||||
static int dcphy_attach __P((device_t));
|
||||
static int dcphy_detach __P((device_t));
|
||||
@ -161,9 +168,6 @@ static int dcphy_attach(dev)
|
||||
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst),
|
||||
BMCR_ISO);
|
||||
|
||||
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
|
||||
BMCR_LOOP|BMCR_S100);
|
||||
|
||||
/*dcphy_reset(sc);*/
|
||||
dc_sc = mii->mii_ifp->if_softc;
|
||||
CSR_WRITE_4(dc_sc, DC_10BTSTAT, 0);
|
||||
@ -171,11 +175,14 @@ static int dcphy_attach(dev)
|
||||
|
||||
switch(pci_read_config(device_get_parent(sc->mii_dev),
|
||||
DC_PCI_CSID, 4)) {
|
||||
case 0x99999999:
|
||||
case COMPAQ_PRESARIO_ID:
|
||||
/* Example of how to only allow 10Mbps modes. */
|
||||
sc->mii_capabilities = BMSR_10TFDX|BMSR_10THDX;
|
||||
sc->mii_capabilities = BMSR_ANEG|BMSR_10TFDX|BMSR_10THDX;
|
||||
break;
|
||||
default:
|
||||
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP,
|
||||
sc->mii_inst), BMCR_LOOP|BMCR_S100);
|
||||
|
||||
sc->mii_capabilities =
|
||||
BMSR_ANEG|BMSR_100TXFDX|BMSR_100TXHDX|
|
||||
BMSR_10TFDX|BMSR_10THDX;
|
||||
@ -418,11 +425,14 @@ dcphy_status(sc)
|
||||
|
||||
if (CSR_READ_4(dc_sc, DC_10BTSTAT) & DC_TSTAT_LP_CAN_NWAY) {
|
||||
anlpar = CSR_READ_4(dc_sc, DC_10BTSTAT) >> 16;
|
||||
if (anlpar & ANLPAR_T4)
|
||||
if (anlpar & ANLPAR_T4 &&
|
||||
sc->mii_capabilities & BMSR_100TXHDX)
|
||||
mii->mii_media_active |= IFM_100_T4;
|
||||
else if (anlpar & ANLPAR_TX_FD)
|
||||
else if (anlpar & ANLPAR_TX_FD &&
|
||||
sc->mii_capabilities & BMSR_100TXHDX)
|
||||
mii->mii_media_active |= IFM_100_TX|IFM_FDX;
|
||||
else if (anlpar & ANLPAR_TX)
|
||||
else if (anlpar & ANLPAR_TX &&
|
||||
sc->mii_capabilities & BMSR_100TXHDX)
|
||||
mii->mii_media_active |= IFM_100_TX;
|
||||
else if (anlpar & ANLPAR_10_FD)
|
||||
mii->mii_media_active |= IFM_10_T|IFM_FDX;
|
||||
@ -478,7 +488,10 @@ dcphy_auto(mii, waitfor)
|
||||
DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
|
||||
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_FULLDUPLEX);
|
||||
DC_CLRBIT(sc, DC_SIARESET, DC_SIA_RESET);
|
||||
CSR_WRITE_4(sc, DC_10BTCTRL, 0x3FFFF);
|
||||
if (mii->mii_capabilities & BMSR_100TXHDX)
|
||||
CSR_WRITE_4(sc, DC_10BTCTRL, 0x3FFFF);
|
||||
else
|
||||
CSR_WRITE_4(sc, DC_10BTCTRL, 0xFFFF);
|
||||
DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET);
|
||||
DC_SETBIT(sc, DC_10BTCTRL, DC_TCTL_AUTONEGENBL);
|
||||
DC_SETBIT(sc, DC_10BTSTAT, DC_ASTAT_TXDISABLE);
|
||||
|
@ -1247,6 +1247,15 @@ static void dc_reset(sc)
|
||||
CSR_WRITE_4(sc, DC_BUSCTL, 0x00000000);
|
||||
CSR_WRITE_4(sc, DC_NETCFG, 0x00000000);
|
||||
|
||||
/*
|
||||
* Bring the SIA out of reset. In some cases, it looks
|
||||
* like failing to unreset the SIA soon enough gets it
|
||||
* into a state where it will never come out of reset
|
||||
* until we reset the whole chip again.
|
||||
*/
|
||||
if (DC_IS_INTEL(sc))
|
||||
DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1480,7 +1489,7 @@ static int dc_attach(dev)
|
||||
break;
|
||||
case DC_DEVICEID_82C168:
|
||||
sc->dc_type = DC_TYPE_PNIC;
|
||||
sc->dc_flags |= DC_TX_STORENFWD|DC_TX_USE_TX_INTR;
|
||||
sc->dc_flags |= DC_TX_STORENFWD|DC_TX_INTR_ALWAYS;
|
||||
sc->dc_flags |= DC_PNIC_RX_BUG_WAR;
|
||||
sc->dc_pnic_rx_buf = malloc(DC_RXLEN * 5, M_DEVBUF, M_NOWAIT);
|
||||
if (revision < DC_REVISION_82C169)
|
||||
@ -2220,6 +2229,8 @@ static void dc_intr(arg)
|
||||
if (sc->dc_txthresh == DC_TXTHRESH_160BYTES) {
|
||||
printf("using store and forward mode\n");
|
||||
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_STORENFWD);
|
||||
} else if (sc->dc_flags & DC_TX_STORENFWD) {
|
||||
printf("resetting\n");
|
||||
} else {
|
||||
sc->dc_txthresh += 0x4000;
|
||||
printf("increasing TX threshold\n");
|
||||
@ -2302,6 +2313,8 @@ static int dc_encap(sc, m_head, txidx)
|
||||
sc->dc_ldata->dc_tx_list[cur].dc_ctl |= DC_TXCTL_LASTFRAG;
|
||||
if (sc->dc_flags & DC_TX_INTR_FIRSTFRAG)
|
||||
sc->dc_ldata->dc_tx_list[*txidx].dc_ctl |= DC_TXCTL_FINT;
|
||||
if (sc->dc_flags & DC_TX_INTR_ALWAYS)
|
||||
sc->dc_ldata->dc_tx_list[cur].dc_ctl |= DC_TXCTL_FINT;
|
||||
if (sc->dc_flags & DC_TX_USE_TX_INTR && sc->dc_cdata.dc_tx_cnt > 64)
|
||||
sc->dc_ldata->dc_tx_list[cur].dc_ctl |= DC_TXCTL_FINT;
|
||||
sc->dc_ldata->dc_tx_list[*txidx].dc_status = DC_TXSTAT_OWN;
|
||||
|
@ -667,6 +667,7 @@ struct dc_softc {
|
||||
#define DC_TX_FIXED_RING 0x00000080
|
||||
#define DC_TX_STORENFWD 0x00000100
|
||||
#define DC_REDUCED_MII_POLL 0x00000200
|
||||
#define DC_TX_INTR_ALWAYS 0x00000400
|
||||
|
||||
/*
|
||||
* register space access macros
|
||||
|
@ -86,6 +86,13 @@ static const char rcsid[] =
|
||||
|
||||
#define MIIF_AUTOTIMEOUT 0x0004
|
||||
|
||||
/*
|
||||
* This is the subsystem ID for the built-in 21143 ethernet
|
||||
* in several Compaq Presario systems. Apparently these are
|
||||
* 10Mbps only, so we need to treat them specially.
|
||||
*/
|
||||
#define COMPAQ_PRESARIO_ID 0xb0bb0e11
|
||||
|
||||
static int dcphy_probe __P((device_t));
|
||||
static int dcphy_attach __P((device_t));
|
||||
static int dcphy_detach __P((device_t));
|
||||
@ -161,9 +168,6 @@ static int dcphy_attach(dev)
|
||||
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst),
|
||||
BMCR_ISO);
|
||||
|
||||
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
|
||||
BMCR_LOOP|BMCR_S100);
|
||||
|
||||
/*dcphy_reset(sc);*/
|
||||
dc_sc = mii->mii_ifp->if_softc;
|
||||
CSR_WRITE_4(dc_sc, DC_10BTSTAT, 0);
|
||||
@ -171,11 +175,14 @@ static int dcphy_attach(dev)
|
||||
|
||||
switch(pci_read_config(device_get_parent(sc->mii_dev),
|
||||
DC_PCI_CSID, 4)) {
|
||||
case 0x99999999:
|
||||
case COMPAQ_PRESARIO_ID:
|
||||
/* Example of how to only allow 10Mbps modes. */
|
||||
sc->mii_capabilities = BMSR_10TFDX|BMSR_10THDX;
|
||||
sc->mii_capabilities = BMSR_ANEG|BMSR_10TFDX|BMSR_10THDX;
|
||||
break;
|
||||
default:
|
||||
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP,
|
||||
sc->mii_inst), BMCR_LOOP|BMCR_S100);
|
||||
|
||||
sc->mii_capabilities =
|
||||
BMSR_ANEG|BMSR_100TXFDX|BMSR_100TXHDX|
|
||||
BMSR_10TFDX|BMSR_10THDX;
|
||||
@ -418,11 +425,14 @@ dcphy_status(sc)
|
||||
|
||||
if (CSR_READ_4(dc_sc, DC_10BTSTAT) & DC_TSTAT_LP_CAN_NWAY) {
|
||||
anlpar = CSR_READ_4(dc_sc, DC_10BTSTAT) >> 16;
|
||||
if (anlpar & ANLPAR_T4)
|
||||
if (anlpar & ANLPAR_T4 &&
|
||||
sc->mii_capabilities & BMSR_100TXHDX)
|
||||
mii->mii_media_active |= IFM_100_T4;
|
||||
else if (anlpar & ANLPAR_TX_FD)
|
||||
else if (anlpar & ANLPAR_TX_FD &&
|
||||
sc->mii_capabilities & BMSR_100TXHDX)
|
||||
mii->mii_media_active |= IFM_100_TX|IFM_FDX;
|
||||
else if (anlpar & ANLPAR_TX)
|
||||
else if (anlpar & ANLPAR_TX &&
|
||||
sc->mii_capabilities & BMSR_100TXHDX)
|
||||
mii->mii_media_active |= IFM_100_TX;
|
||||
else if (anlpar & ANLPAR_10_FD)
|
||||
mii->mii_media_active |= IFM_10_T|IFM_FDX;
|
||||
@ -478,7 +488,10 @@ dcphy_auto(mii, waitfor)
|
||||
DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
|
||||
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_FULLDUPLEX);
|
||||
DC_CLRBIT(sc, DC_SIARESET, DC_SIA_RESET);
|
||||
CSR_WRITE_4(sc, DC_10BTCTRL, 0x3FFFF);
|
||||
if (mii->mii_capabilities & BMSR_100TXHDX)
|
||||
CSR_WRITE_4(sc, DC_10BTCTRL, 0x3FFFF);
|
||||
else
|
||||
CSR_WRITE_4(sc, DC_10BTCTRL, 0xFFFF);
|
||||
DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET);
|
||||
DC_SETBIT(sc, DC_10BTCTRL, DC_TCTL_AUTONEGENBL);
|
||||
DC_SETBIT(sc, DC_10BTSTAT, DC_ASTAT_TXDISABLE);
|
||||
|
@ -1247,6 +1247,15 @@ static void dc_reset(sc)
|
||||
CSR_WRITE_4(sc, DC_BUSCTL, 0x00000000);
|
||||
CSR_WRITE_4(sc, DC_NETCFG, 0x00000000);
|
||||
|
||||
/*
|
||||
* Bring the SIA out of reset. In some cases, it looks
|
||||
* like failing to unreset the SIA soon enough gets it
|
||||
* into a state where it will never come out of reset
|
||||
* until we reset the whole chip again.
|
||||
*/
|
||||
if (DC_IS_INTEL(sc))
|
||||
DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1480,7 +1489,7 @@ static int dc_attach(dev)
|
||||
break;
|
||||
case DC_DEVICEID_82C168:
|
||||
sc->dc_type = DC_TYPE_PNIC;
|
||||
sc->dc_flags |= DC_TX_STORENFWD|DC_TX_USE_TX_INTR;
|
||||
sc->dc_flags |= DC_TX_STORENFWD|DC_TX_INTR_ALWAYS;
|
||||
sc->dc_flags |= DC_PNIC_RX_BUG_WAR;
|
||||
sc->dc_pnic_rx_buf = malloc(DC_RXLEN * 5, M_DEVBUF, M_NOWAIT);
|
||||
if (revision < DC_REVISION_82C169)
|
||||
@ -2220,6 +2229,8 @@ static void dc_intr(arg)
|
||||
if (sc->dc_txthresh == DC_TXTHRESH_160BYTES) {
|
||||
printf("using store and forward mode\n");
|
||||
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_STORENFWD);
|
||||
} else if (sc->dc_flags & DC_TX_STORENFWD) {
|
||||
printf("resetting\n");
|
||||
} else {
|
||||
sc->dc_txthresh += 0x4000;
|
||||
printf("increasing TX threshold\n");
|
||||
@ -2302,6 +2313,8 @@ static int dc_encap(sc, m_head, txidx)
|
||||
sc->dc_ldata->dc_tx_list[cur].dc_ctl |= DC_TXCTL_LASTFRAG;
|
||||
if (sc->dc_flags & DC_TX_INTR_FIRSTFRAG)
|
||||
sc->dc_ldata->dc_tx_list[*txidx].dc_ctl |= DC_TXCTL_FINT;
|
||||
if (sc->dc_flags & DC_TX_INTR_ALWAYS)
|
||||
sc->dc_ldata->dc_tx_list[cur].dc_ctl |= DC_TXCTL_FINT;
|
||||
if (sc->dc_flags & DC_TX_USE_TX_INTR && sc->dc_cdata.dc_tx_cnt > 64)
|
||||
sc->dc_ldata->dc_tx_list[cur].dc_ctl |= DC_TXCTL_FINT;
|
||||
sc->dc_ldata->dc_tx_list[*txidx].dc_status = DC_TXSTAT_OWN;
|
||||
|
@ -667,6 +667,7 @@ struct dc_softc {
|
||||
#define DC_TX_FIXED_RING 0x00000080
|
||||
#define DC_TX_STORENFWD 0x00000100
|
||||
#define DC_REDUCED_MII_POLL 0x00000200
|
||||
#define DC_TX_INTR_ALWAYS 0x00000400
|
||||
|
||||
/*
|
||||
* register space access macros
|
||||
|
Loading…
x
Reference in New Issue
Block a user