summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1999-12-13 21:45:13 +0000
committerwpaul <wpaul@FreeBSD.org>1999-12-13 21:45:13 +0000
commit20bb20f965ea57ffac6e8a464c771b59a0d22e6b (patch)
tree8e7df981fa76eac21a7e2c85af5773bd74d5fe66 /sys/pci
parent81282dc10393616ec15c86c322ca38f186c34da5 (diff)
downloadFreeBSD-src-20bb20f965ea57ffac6e8a464c771b59a0d22e6b.zip
FreeBSD-src-20bb20f965ea57ffac6e8a464c771b59a0d22e6b.tar.gz
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.
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/if_dc.c15
-rw-r--r--sys/pci/if_dcreg.h1
2 files changed, 15 insertions, 1 deletions
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