summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/if_ste.c141
1 files changed, 74 insertions, 67 deletions
diff --git a/sys/dev/pci/if_ste.c b/sys/dev/pci/if_ste.c
index 4ee46800cc5..9ae281c5cbb 100644
--- a/sys/dev/pci/if_ste.c
+++ b/sys/dev/pci/if_ste.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ste.c,v 1.32 2005/08/09 04:10:12 mickey Exp $ */
+/* $OpenBSD: if_ste.c,v 1.33 2005/09/10 23:21:05 brad Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -84,6 +84,7 @@ void ste_attach(struct device *, struct device *, void *);
int ste_intr(void *);
void ste_shutdown(void *);
void ste_init(void *);
+void ste_rxeoc(struct ste_softc *);
void ste_rxeof(struct ste_softc *);
void ste_txeoc(struct ste_softc *);
void ste_txeof(struct ste_softc *);
@@ -537,8 +538,7 @@ allmulti:
ifp->if_flags |= IFF_ALLMULTI;
goto allmulti;
}
- h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) &
- 0x0000003F;
+ h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) & 0x3F;
if (h < 32)
hashes[0] |= (1 << h);
else
@@ -579,8 +579,10 @@ int ste_intr(xsc)
claimed = 1;
- if (status & STE_ISR_RX_DMADONE)
+ if (status & STE_ISR_RX_DMADONE) {
+ ste_rxeoc(sc);
ste_rxeof(sc);
+ }
if (status & STE_ISR_TX_DMADONE)
ste_txeof(sc);
@@ -588,6 +590,11 @@ int ste_intr(xsc)
if (status & STE_ISR_TX_DONE)
ste_txeoc(sc);
+ if (status & STE_ISR_STATS_OFLOW) {
+ timeout_del(&sc->sc_stats_tmo);
+ ste_stats_update(sc);
+ }
+
if (status & STE_ISR_LINKEVENT)
mii_pollstat(&sc->sc_mii);
@@ -606,6 +613,26 @@ int ste_intr(xsc)
return claimed;
}
+void
+ste_rxeoc(struct ste_softc *sc)
+{
+ struct ste_chain_onefrag *cur_rx;
+
+ if (sc->ste_cdata.ste_rx_head->ste_ptr->ste_status == 0) {
+ cur_rx = sc->ste_cdata.ste_rx_head;
+ do {
+ cur_rx = cur_rx->ste_next;
+ /* If the ring is empty, just return. */
+ if (cur_rx == sc->ste_cdata.ste_rx_head)
+ return;
+ } while (cur_rx->ste_ptr->ste_status == 0);
+ if (sc->ste_cdata.ste_rx_head->ste_ptr->ste_status == 0) {
+ /* We've fallen behind the chip: catch it. */
+ sc->ste_cdata.ste_rx_head = cur_rx;
+ }
+ }
+}
+
/*
* A frame has been uploaded: pass the resulting mbuf chain up to
* the higher level protocols.
@@ -621,20 +648,6 @@ void ste_rxeof(sc)
ifp = &sc->arpcom.ac_if;
- if (sc->ste_cdata.ste_rx_head->ste_ptr->ste_status == 0) {
- cur_rx = sc->ste_cdata.ste_rx_head;
- do {
- cur_rx = cur_rx->ste_next;
- /* If the ring is empty, just return. */
- if (cur_rx == sc->ste_cdata.ste_rx_head)
- return;
- } while (cur_rx->ste_ptr->ste_status == 0);
-
- if (sc->ste_cdata.ste_rx_head->ste_ptr->ste_status == 0)
- /* We've fallen behind the chip: catch it. */
- sc->ste_cdata.ste_rx_head = cur_rx;
- }
-
while((rxstat = sc->ste_cdata.ste_rx_head->ste_ptr->ste_status)
& STE_RXSTAT_DMADONE) {
if ((STE_RX_LIST_CNT - count) < 3)
@@ -685,10 +698,11 @@ void ste_rxeof(sc)
continue;
}
- ifp->if_ipackets++;
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = total_len;
+ ifp->if_ipackets++;
+
#if NBPFILTER > 0
if (ifp->if_bpf)
bpf_mtap(ifp->if_bpf, m);
@@ -758,12 +772,9 @@ void ste_txeof(sc)
if (!(cur_tx->ste_ptr->ste_ctl & STE_TXCTL_DMADONE))
break;
- if (cur_tx->ste_mbuf != NULL) {
- m_freem(cur_tx->ste_mbuf);
- cur_tx->ste_mbuf = NULL;
- ifp->if_flags &= ~IFF_OACTIVE;
- }
-
+ m_freem(cur_tx->ste_mbuf);
+ cur_tx->ste_mbuf = NULL;
+ ifp->if_flags &= ~IFF_OACTIVE;
ifp->if_opackets++;
STE_INC(idx, STE_TX_LIST_CNT);
@@ -794,12 +805,21 @@ void ste_stats_update(xsc)
+ CSR_READ_1(sc, STE_MULTI_COLLS)
+ CSR_READ_1(sc, STE_SINGLE_COLLS);
- mii_tick(mii);
- if (!sc->ste_link && mii->mii_media_status & IFM_ACTIVE &&
- IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
- sc->ste_link++;
- if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
- ste_start(ifp);
+ if (!sc->ste_link) {
+ mii_pollstat(mii);
+ if (mii->mii_media_status & IFM_ACTIVE &&
+ IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
+ sc->ste_link++;
+ /*
+ * we don't get a call-back on re-init so do it
+ * otherwise we get stuck in the wrong link state
+ */
+#if 0
+ ste_miibus_statchg(&mii->mii_dev.dv_parent);
+#endif
+ if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
+ ste_start(ifp);
+ }
}
timeout_add(&sc->sc_stats_tmo, hz);
@@ -840,8 +860,7 @@ void ste_attach(parent, self, aux)
pci_chipset_tag_t pc = pa->pa_pc;
pci_intr_handle_t ih;
struct ifnet *ifp;
- bus_addr_t iobase;
- bus_size_t iosize;
+ bus_size_t size;
/*
* Handle power management nonsense.
@@ -884,42 +903,27 @@ void ste_attach(parent, self, aux)
/*
* Map control/status registers.
*/
- command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
#ifdef STE_USEIOSPACE
- if (!(command & PCI_COMMAND_IO_ENABLE)) {
- printf(": failed to enable I/O ports\n");
- goto fail;
- }
- if (pci_io_find(pc, pa->pa_tag, STE_PCI_LOIO, &iobase, &iosize)) {
- printf(": can't find I/O space\n");
- goto fail;
- }
- if (bus_space_map(pa->pa_iot, iobase, iosize, 0, &sc->ste_bhandle)) {
- printf(": can't map I/O space\n");
- goto fail;
- }
- sc->ste_btag = pa->pa_iot;
-#else
- if (!(command & PCI_COMMAND_MEM_ENABLE)) {
- printf(": failed to enable memory mapping\n");
- goto fail;
- }
- if (pci_mem_find(pc, pa->pa_tag, STE_PCI_LOMEM, &iobase, &iosize,NULL)){
- printf(": can't find mem space\n");
- goto fail;
+ if (pci_mapreg_map(pa, STE_PCI_LOIO,
+ PCI_MAPREG_TYPE_IO, 0,
+ &sc->ste_btag, &sc->ste_bhandle, NULL, &size, 0)) {
+ printf(": can't map i/o space\n");
+ return;
}
- if (bus_space_map(pa->pa_memt, iobase, iosize, 0, &sc->ste_bhandle)) {
+ #else
+ if (pci_mapreg_map(pa, STE_PCI_LOMEM,
+ PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
+ &sc->ste_btag, &sc->ste_bhandle, NULL, &size, 0)) {
printf(": can't map mem space\n");
- goto fail;
+ return;
}
- sc->ste_btag = pa->pa_memt;
#endif
/* Allocate interrupt */
if (pci_intr_map(pa, &ih)) {
printf(": couldn't map interrupt\n");
- goto fail;
+ goto fail_1;
}
intrstr = pci_intr_string(pc, ih);
sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ste_intr, sc,
@@ -929,7 +933,7 @@ void ste_attach(parent, self, aux)
if (intrstr != NULL)
printf(" at %s", intrstr);
printf("\n");
- goto fail;
+ goto fail_1;
}
printf(": %s", intrstr);
@@ -943,17 +947,17 @@ void ste_attach(parent, self, aux)
STE_EEADDR_NODE0, 3, 0)) {
printf("%s: failed to read station address\n",
sc->sc_dev.dv_xname);
- goto fail_1;
+ goto fail_2;
}
- printf(" address %s\n", ether_sprintf(sc->arpcom.ac_enaddr));
+ printf(", address %s\n", ether_sprintf(sc->arpcom.ac_enaddr));
sc->ste_ldata_ptr = malloc(sizeof(struct ste_list_data) + 8,
M_DEVBUF, M_DONTWAIT);
if (sc->ste_ldata_ptr == NULL) {
printf("%s: no memory for list buffers!\n",
sc->sc_dev.dv_xname);
- goto fail_1;
+ goto fail_2;
}
sc->ste_ldata = (struct ste_list_data *)sc->ste_ldata_ptr;
@@ -994,11 +998,13 @@ void ste_attach(parent, self, aux)
shutdownhook_establish(ste_shutdown, sc);
-fail:
return;
-fail_1:
+fail_2:
pci_intr_disestablish(pc, sc->sc_ih);
+
+fail_1:
+ bus_space_unmap(sc->ste_btag, sc->ste_bhandle, size);
}
int ste_newbuf(sc, c, m)
@@ -1433,7 +1439,7 @@ void ste_start(ifp)
{
struct ste_softc *sc;
struct mbuf *m_head = NULL;
- struct ste_chain *cur_tx = NULL;
+ struct ste_chain *cur_tx;
int idx;
sc = ifp->if_softc;
@@ -1501,8 +1507,8 @@ void ste_start(ifp)
STE_INC(idx, STE_TX_LIST_CNT);
ifp->if_timer = 5;
- sc->ste_cdata.ste_tx_prod = idx;
}
+ sc->ste_cdata.ste_tx_prod = idx;
return;
}
@@ -1519,6 +1525,7 @@ void ste_watchdog(ifp)
ste_txeoc(sc);
ste_txeof(sc);
+ ste_rxeoc(sc);
ste_rxeof(sc);
ste_reset(sc);
ste_init(sc);