summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorAaron Campbell <aaron@cvs.openbsd.org>1999-12-08 00:25:55 +0000
committerAaron Campbell <aaron@cvs.openbsd.org>1999-12-08 00:25:55 +0000
commitf51370fc86258c3833f6802d2f6a9b299b6b75f5 (patch)
tree5c97e16148693ffdbb086b045e6bc4cdc8a682d8 /sys/dev
parentecfa7aea870d9dc067cdc38893700d5327b71f82 (diff)
Sync with FreeBSD:
- Reset the PHY before selecting a mode. - Program IPG register to match duplex setting in accordance with Adaptec manual recommendations.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_sf.c45
-rw-r--r--sys/dev/pci/if_sfreg.h10
2 files changed, 45 insertions, 10 deletions
diff --git a/sys/dev/pci/if_sf.c b/sys/dev/pci/if_sf.c
index e3417d2d43a..56892f8300f 100644
--- a/sys/dev/pci/if_sf.c
+++ b/sys/dev/pci/if_sf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sf.c,v 1.1 1999/11/03 02:45:08 aaron Exp $ */
+/* $OpenBSD: if_sf.c,v 1.2 1999/12/08 00:25:54 aaron Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -372,8 +372,10 @@ void sf_miibus_statchg(self)
if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
SF_SETBIT(sc, SF_MACCFG_1, SF_MACCFG1_FULLDUPLEX);
+ csr_write_4(sc, SF_BKTOBKIPG, SF_IPGT_FDX);
} else {
SF_CLRBIT(sc, SF_MACCFG_1, SF_MACCFG1_FULLDUPLEX);
+ csr_write_4(sc, SF_BKTOBKIPG, SF_IPGT_HDX);
}
return;
@@ -443,6 +445,13 @@ int sf_ifmedia_upd(ifp)
sc = ifp->if_softc;
mii = &sc->sc_mii;
+ sc->sf_link = 0;
+ if (mii->mii_instance) {
+ struct mii_softc *miisc;
+ for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
+ miisc = LIST_NEXT(miisc, mii_list))
+ mii_phy_reset(miisc);
+ }
mii_mediachg(mii);
return(0);
@@ -501,11 +510,21 @@ int sf_ioctl(ifp, command, data)
break;
case SIOCSIFFLAGS:
if (ifp->if_flags & IFF_UP) {
- sf_init(sc);
+ if (ifp->if_flags & IFF_RUNNING &&
+ ifp->if_flags & IFF_PROMISC &&
+ !(sc->sf_if_flags & IFF_PROMISC)) {
+ SF_SETBIT(sc, SF_RXFILT, SF_RXFILT_PROMISC);
+ } else if (ifp->if_flags & IFF_RUNNING &&
+ !(ifp->if_flags & IFF_PROMISC) &&
+ sc->sf_if_flags & IFF_PROMISC) {
+ SF_CLRBIT(sc, SF_RXFILT, SF_RXFILT_PROMISC);
+ } else if (!(ifp->if_flags & IFF_RUNNING))
+ sf_init(sc);
} else {
if (ifp->if_flags & IFF_RUNNING)
sf_stop(sc);
}
+ sc->sf_if_flags = ifp->if_flags;
error = 0;
break;
case SIOCADDMULTI:
@@ -1107,13 +1126,6 @@ void sf_init(xsc)
/* Enable autopadding of short TX frames. */
SF_SETBIT(sc, SF_MACCFG_1, SF_MACCFG1_AUTOPAD);
- /* Make sure the duplex mode is set correctly. */
- if ((mii->mii_media.ifm_media & IFM_GMASK) == IFM_FDX) {
- SF_SETBIT(sc, SF_MACCFG_1, SF_MACCFG1_FULLDUPLEX);
- } else {
- SF_CLRBIT(sc, SF_MACCFG_1, SF_MACCFG1_FULLDUPLEX);
- }
-
/* Enable interrupts. */
csr_write_4(sc, SF_IMR, SF_INTRS);
SF_SETBIT(sc, SF_PCI_DEVCFG, SF_PCIDEVCFG_INTR_ENB);
@@ -1122,7 +1134,7 @@ void sf_init(xsc)
SF_SETBIT(sc, SF_GEN_ETH_CTL, SF_ETHCTL_RX_ENB|SF_ETHCTL_RXDMA_ENB);
SF_SETBIT(sc, SF_GEN_ETH_CTL, SF_ETHCTL_TX_ENB|SF_ETHCTL_TXDMA_ENB);
- mii_mediachg(mii);
+ sf_ifmedia_upd(ifp);
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
@@ -1207,6 +1219,9 @@ void sf_start(ifp)
sc = ifp->if_softc;
+ if (!sc->sf_link)
+ return;
+
if (ifp->if_flags & IFF_OACTIVE)
return;
@@ -1270,6 +1285,8 @@ void sf_stop(sc)
csr_write_4(sc, SF_TXDQ_CTL, 0);
sf_reset(sc);
+ sc->sf_link = 0;
+
for (i = 0; i < SF_RX_DLIST_CNT; i++) {
if (sc->sf_ldata->sf_rx_dlist_big[i].sf_mbuf != NULL) {
m_freem(sc->sf_ldata->sf_rx_dlist_big[i].sf_mbuf);
@@ -1325,6 +1342,14 @@ void sf_stats_update(xsc)
stats.sf_tx_multi_colls + stats.sf_tx_excess_colls;
mii_tick(mii);
+ if (!sc->sf_link) {
+ mii_pollstat(mii);
+ if (mii->mii_media_status & IFM_ACTIVE &&
+ IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
+ sc->sf_link++;
+ if (ifp->if_snd.ifq_head != NULL)
+ sf_start(ifp);
+ }
timeout(sf_stats_update, sc, hz);
diff --git a/sys/dev/pci/if_sfreg.h b/sys/dev/pci/if_sfreg.h
index b76206cf321..9736dfd456a 100644
--- a/sys/dev/pci/if_sfreg.h
+++ b/sys/dev/pci/if_sfreg.h
@@ -610,6 +610,14 @@
#define SF_MACCFG1_SOFTRESET 0x00008000
/*
+ * These are the recommended IPG nibble counter settings
+ * specified in the Adaptec manual for full duplex and
+ * half duplex operation.
+ */
+#define SF_IPGT_FDX 0x15
+#define SF_IPGT_HDX 0x11
+
+/*
* RX filter registers 0x6000 to 0x6FFF
*/
#define SF_RXFILT_PERFECT_BASE 0x6000
@@ -1038,6 +1046,8 @@ struct sf_softc {
struct sf_list_data *sf_ldata;
caddr_t sf_ldata_ptr;
int sf_tx_cnt;
+ u_int8_t sf_link;
+ int sf_if_flags;
};
#define SF_TIMEOUT 1000