diff options
-rw-r--r-- | sys/dev/dc/dcphy.c | 31 | ||||
-rw-r--r-- | sys/dev/dc/if_dc.c | 15 | ||||
-rw-r--r-- | sys/dev/dc/if_dcreg.h | 1 | ||||
-rw-r--r-- | sys/dev/mii/dcphy.c | 31 | ||||
-rw-r--r-- | sys/pci/if_dc.c | 15 | ||||
-rw-r--r-- | sys/pci/if_dcreg.h | 1 |
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 |