diff options
author | wpaul <wpaul@FreeBSD.org> | 1999-05-06 15:32:52 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 1999-05-06 15:32:52 +0000 |
commit | 8b3db0e8228985fa682b3e2e72ab560619831fbc (patch) | |
tree | b1e9c98fdbbad66727def9852b5bb7c672d71f45 /sys/pci/if_mx.c | |
parent | 14f270d531fd127b5de0e208cc9d44257284ec35 (diff) | |
download | FreeBSD-src-8b3db0e8228985fa682b3e2e72ab560619831fbc.zip FreeBSD-src-8b3db0e8228985fa682b3e2e72ab560619831fbc.tar.gz |
Tweak the Macronix driver to hopefully make it more reliable:
- Change to the same transmit scheme as the PNIC driver.
- Dynamically set the cache alignment, and set burst size the same as
the PNIC driver in mx_init().
- Enable 'store and forward' mode by default. This is the slowest option
and it does reduce 100Mbps performance somewhat, but it's the most
reliable setting I can find. I'm more interested in having the driver
work reliably than trying to squeeze the best performance out of it.
The reason I'm doing this is that on *some* systems you may see a lot
of transmit underruns (which I can't explain: these are *fast* test
systems) and these errors seem to cause unusual and decidedly
non-tulip-like behavior. In normal 10Mbps mode, performance is fine
(you can easily saturate a 10Mbps link).
Also tweak some of the other drivers:
- Increase the size of the TX ring for the Winbond, ASIX, VIA Rhine
and PNIC drivers.
- Set a larger value for ifq_maxlen in the ThunderLAN driver. The setting
of TL_TX_LIST_CNT - 1 is too low (the ThunderLAN driver only allocates
20 transmit descriptors, and I don't want to fiddle with that now
because the ThunderLAN's descriptor structure is an oddball size
compared to the others).
Diffstat (limited to 'sys/pci/if_mx.c')
-rw-r--r-- | sys/pci/if_mx.c | 108 |
1 files changed, 43 insertions, 65 deletions
diff --git a/sys/pci/if_mx.c b/sys/pci/if_mx.c index f3abc5a..1d73b3b 100644 --- a/sys/pci/if_mx.c +++ b/sys/pci/if_mx.c @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: if_mx.c,v 1.14 1999/04/16 01:56:06 ghelmer Exp $ + * $Id: if_mx.c,v 1.41 1999/05/06 15:07:10 wpaul Exp $ */ /* @@ -76,11 +76,6 @@ #include <net/bpf.h> #endif -#include "opt_bdg.h" -#ifdef BRIDGE -#include <net/bridge.h> -#endif - #include <vm/vm.h> /* for vtophys */ #include <vm/pmap.h> /* for vtophys */ #include <machine/clock.h> /* for DELAY */ @@ -99,7 +94,7 @@ #ifndef lint static const char rcsid[] = - "$Id: if_mx.c,v 1.14 1999/04/16 01:56:06 ghelmer Exp $"; + "$Id: if_mx.c,v 1.41 1999/05/06 15:07:10 wpaul Exp $"; #endif /* @@ -1406,6 +1401,9 @@ mx_attach(config_id, unit) else sc->mx_type = MX_TYPE_987x5; + /* Save the cache line size. */ + sc->mx_cachesize = pci_conf_read(config_id, MX_PCI_CACHELEN) & 0xFF; + /* Reset the adapter. */ mx_reset(sc); @@ -1754,44 +1752,21 @@ static void mx_rxeof(sc) #if NBPFILTER > 0 /* - * Handle BPF listeners. Let the BPF user see the packet. - */ - if (ifp->if_bpf) - bpf_mtap(ifp, m); -#endif -#ifdef BRIDGE - if (do_bridge) { - struct ifnet *bdg_ifp ; - bdg_ifp = bridge_in(m); - if (bdg_ifp == BDG_DROP) - goto dropit ; - if (bdg_ifp != BDG_LOCAL) - bdg_forward(&m, bdg_ifp); - if (bdg_ifp != BDG_LOCAL && - bdg_ifp != BDG_BCAST && - bdg_ifp != BDG_MCAST) - goto dropit ; - goto getit ; - } -#endif - /* - * Don't pass packet up to the ether_input() layer unless it's + * Handle BPF listeners. Let the BPF user see the packet, but + * don't pass it up to the ether_input() layer unless it's * a broadcast packet, multicast packet, matches our ethernet * address or the interface is in promiscuous mode. */ - if (ifp->if_flags & IFF_PROMISC && - (bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, - ETHER_ADDR_LEN) && - (eh->ether_dhost[0] & 1) == 0)) { -#ifdef BRIDGE -dropit: -#endif - if (m) + if (ifp->if_bpf) { + bpf_mtap(ifp, m); + if (ifp->if_flags & IFF_PROMISC && + (bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, + ETHER_ADDR_LEN) && + (eh->ether_dhost[0] & 1) == 0)) { m_freem(m); - continue; + continue; + } } -#ifdef BRIDGE -getit: #endif /* Remove header from mbuf and pass it on. */ m_adj(m, sizeof(struct ether_header)); @@ -1843,7 +1818,7 @@ static void mx_txeof(sc) cur_tx = sc->mx_cdata.mx_tx_head; txstat = MX_TXSTATUS(cur_tx); - if ((txstat & MX_TXSTAT_OWN) || MX_TXOWN(cur_tx) == MX_UNSENT) + if (txstat & MX_TXSTAT_OWN) break; if (txstat & MX_TXSTAT_ERRSUM) { @@ -1894,12 +1869,6 @@ static void mx_txeoc(sc) else mx_autoneg(sc, MX_FLAG_DELAYTIMEO, 1); } - } else { - if (MX_TXOWN(sc->mx_cdata.mx_tx_head) == MX_UNSENT) { - MX_TXOWN(sc->mx_cdata.mx_tx_head) = MX_TXSTAT_OWN; - ifp->if_timer = 5; - CSR_WRITE_4(sc, MX_TXSTART, 0xFFFFFFFF); - } } return; @@ -2068,7 +2037,7 @@ static int mx_encap(sc, c, m_head) c->mx_mbuf = m_head; c->mx_lastdesc = frag - 1; - MX_TXCTL(c) |= MX_TXCTL_LASTFRAG; + MX_TXCTL(c) |= MX_TXCTL_LASTFRAG|MX_TXCTL_FINT; MX_TXNEXT(c) = vtophys(&c->mx_nextdesc->mx_ptr->mx_frag[0]); return(0); } @@ -2094,6 +2063,9 @@ static void mx_start(ifp) return; } + if (ifp->if_flags & IFF_OACTIVE) + return; + /* * Check for an available queue slot. If there are none, * punt. @@ -2127,6 +2099,9 @@ static void mx_start(ifp) if (ifp->if_bpf) bpf_mtap(ifp, cur_tx->mx_mbuf); #endif + MX_TXOWN(cur_tx) = MX_TXSTAT_OWN; + CSR_WRITE_4(sc, MX_TXSTART, 0xFFFFFFFF); + } /* @@ -2135,23 +2110,10 @@ static void mx_start(ifp) if (cur_tx == NULL) return; - /* - * Place the request for the upload interrupt - * in the last descriptor in the chain. This way, if - * we're chaining several packets at once, we'll only - * get an interupt once for the whole chain rather than - * once for each packet. - */ - MX_TXCTL(cur_tx) |= MX_TXCTL_FINT; sc->mx_cdata.mx_tx_tail = cur_tx; - if (sc->mx_cdata.mx_tx_head == NULL) { + if (sc->mx_cdata.mx_tx_head == NULL) sc->mx_cdata.mx_tx_head = start_tx; - MX_TXOWN(start_tx) = MX_TXSTAT_OWN; - CSR_WRITE_4(sc, MX_TXSTART, 0xFFFFFFFF); - } else { - MX_TXOWN(start_tx) = MX_UNSENT; - } /* * Set a timeout in case the chip goes out to lunch. @@ -2186,11 +2148,27 @@ static void mx_init(xsc) /* * Set cache alignment and burst length. */ - CSR_WRITE_4(sc, MX_BUSCTL, MX_BUSCTL_CONFIG); + CSR_WRITE_4(sc, MX_BUSCTL, MX_BUSCTL_MUSTBEONE|MX_BUSCTL_ARBITRATION); + MX_SETBIT(sc, MX_BUSCTL, MX_BURSTLEN_16LONG); + switch(sc->mx_cachesize) { + case 32: + MX_SETBIT(sc, MX_BUSCTL, MX_CACHEALIGN_32LONG); + break; + case 16: + MX_SETBIT(sc, MX_BUSCTL, MX_CACHEALIGN_16LONG); + break; + case 8: + MX_SETBIT(sc, MX_BUSCTL, MX_CACHEALIGN_8LONG); + break; + case 0: + default: + MX_SETBIT(sc, MX_BUSCTL, MX_CACHEALIGN_NONE); + break; + } MX_SETBIT(sc, MX_NETCFG, MX_NETCFG_NO_RXCRC); MX_CLRBIT(sc, MX_NETCFG, MX_NETCFG_HEARTBEAT); - MX_CLRBIT(sc, MX_NETCFG, MX_NETCFG_STORENFWD); + MX_SETBIT(sc, MX_NETCFG, MX_NETCFG_STORENFWD); MX_CLRBIT(sc, MX_NETCFG, MX_NETCFG_TX_BACKOFF); /* @@ -2214,7 +2192,7 @@ static void mx_init(xsc) mx_setmode(sc, sc->ifmedia.ifm_media, 0); MX_CLRBIT(sc, MX_NETCFG, MX_NETCFG_TX_THRESH); - MX_CLRBIT(sc, MX_NETCFG, MX_NETCFG_SPEEDSEL); + /*MX_CLRBIT(sc, MX_NETCFG, MX_NETCFG_SPEEDSEL);*/ if (IFM_SUBTYPE(sc->ifmedia.ifm_media) == IFM_10_T) MX_SETBIT(sc, MX_NETCFG, MX_TXTHRESH_160BYTES); |