summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/dc/dcphy.c31
-rw-r--r--sys/dev/dc/if_dc.c15
-rw-r--r--sys/dev/dc/if_dcreg.h1
-rw-r--r--sys/dev/mii/dcphy.c31
-rw-r--r--sys/pci/if_dc.c15
-rw-r--r--sys/pci/if_dcreg.h1
6 files changed, 74 insertions, 20 deletions
diff --git a/sys/dev/dc/dcphy.c b/sys/dev/dc/dcphy.c
index 2543e87..8576d84 100644
--- a/sys/dev/dc/dcphy.c
+++ b/sys/dev/dc/dcphy.c
@@ -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);
diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c
index a01fa73..cc7eee6 100644
--- a/sys/dev/dc/if_dc.c
+++ b/sys/dev/dc/if_dc.c
@@ -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;
diff --git a/sys/dev/dc/if_dcreg.h b/sys/dev/dc/if_dcreg.h
index 7994e94..804668b 100644
--- a/sys/dev/dc/if_dcreg.h
+++ b/sys/dev/dc/if_dcreg.h
@@ -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
diff --git a/sys/dev/mii/dcphy.c b/sys/dev/mii/dcphy.c
index 2543e87..8576d84 100644
--- a/sys/dev/mii/dcphy.c
+++ b/sys/dev/mii/dcphy.c
@@ -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);
diff --git a/sys/pci/if_dc.c b/sys/pci/if_dc.c
index a01fa73..cc7eee6 100644
--- a/sys/pci/if_dc.c
+++ b/sys/pci/if_dc.c
@@ -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;
diff --git a/sys/pci/if_dcreg.h b/sys/pci/if_dcreg.h
index 7994e94..804668b 100644
--- a/sys/pci/if_dcreg.h
+++ b/sys/pci/if_dcreg.h
@@ -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
OpenPOWER on IntegriCloud