Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Preserve the current PHY select bit in the MIF co...
details: https://anonhg.NetBSD.org/src/rev/735b1e29a6f3
branches: trunk
changeset: 542985:735b1e29a6f3
user: pk <pk%NetBSD.org@localhost>
date: Thu Feb 13 12:10:20 2003 +0000
description:
Preserve the current PHY select bit in the MIF configuration register
in mii_readreg()/mii_writereg(). Also restore this bit based on the
currently selected media instance every time we need to reinitialise
the interface.
diffstat:
sys/dev/ic/hme.c | 161 +++++++++++++++++++++++++++++++++------------------
sys/dev/ic/hmevar.h | 3 +-
2 files changed, 106 insertions(+), 58 deletions(-)
diffs (truncated from 320 to 300 lines):
diff -r c7d57d964629 -r 735b1e29a6f3 sys/dev/ic/hme.c
--- a/sys/dev/ic/hme.c Thu Feb 13 11:47:27 2003 +0000
+++ b/sys/dev/ic/hme.c Thu Feb 13 12:10:20 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hme.c,v 1.32 2002/12/18 23:13:02 martin Exp $ */
+/* $NetBSD: hme.c,v 1.33 2003/02/13 12:10:20 pk Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hme.c,v 1.32 2002/12/18 23:13:02 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hme.c,v 1.33 2003/02/13 12:10:20 pk Exp $");
#define HMEDEBUG
@@ -262,7 +262,7 @@
mii->mii_writereg = hme_mii_writereg;
mii->mii_statchg = hme_mii_statchg;
- ifmedia_init(&mii->mii_media, IFM_IMASK, hme_mediachange, hme_mediastatus);
+ ifmedia_init(&mii->mii_media, 0, hme_mediachange, hme_mediastatus);
hme_mifinit(sc);
@@ -318,15 +318,6 @@
if (sc->sc_sh == NULL)
panic("hme_config: can't establish shutdownhook");
-#if 0
- printf("%s: %d receive buffers, %d transmit buffers\n",
- sc->sc_dev.dv_xname, sc->sc_nrbuf, sc->sc_ntbuf);
- sc->sc_rbufaddr = malloc(sc->sc_nrbuf * sizeof(int), M_DEVBUF,
- M_WAITOK);
- sc->sc_tbufaddr = malloc(sc->sc_ntbuf * sizeof(int), M_DEVBUF,
- M_WAITOK);
-#endif
-
#if NRND > 0
rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
RND_TYPE_NET, 0);
@@ -371,6 +362,9 @@
callout_stop(&sc->sc_tick_ch);
mii_down(&sc->sc_mii);
+ /* Mask all interrupts */
+ bus_space_write_4(t, seb, HME_SEBI_IMASK, 0xffffffff);
+
/* Reset transmitter and receiver */
bus_space_write_4(t, seb, HME_SEBI_RESET,
(HME_SEB_RESET_ETX | HME_SEB_RESET_ERX));
@@ -555,6 +549,7 @@
HME_SEB_STAT_TXALL |
HME_SEB_STAT_TXPERR |
HME_SEB_STAT_RCNTEXP |
+ /*HME_SEB_STAT_MIFIRQ |*/
HME_SEB_STAT_ALL_ERRORS ));
switch (sc->sc_burst) {
@@ -970,7 +965,14 @@
char bits[128];
if ((status & HME_SEB_STAT_MIFIRQ) != 0) {
- printf("%s: XXXlink status changed\n", sc->sc_dev.dv_xname);
+ bus_space_tag_t t = sc->sc_bustag;
+ bus_space_handle_t mif = sc->sc_mif;
+ u_int32_t cf, st, sm;
+ cf = bus_space_read_4(t, mif, HME_MIFI_CFG);
+ st = bus_space_read_4(t, mif, HME_MIFI_STAT);
+ sm = bus_space_read_4(t, mif, HME_MIFI_SM);
+ printf("%s: XXXlink status changed: cfg=%x, stat %x, sm %x\n",
+ sc->sc_dev.dv_xname, cf, st, sm);
return (1);
}
@@ -1025,17 +1027,21 @@
{
bus_space_tag_t t = sc->sc_bustag;
bus_space_handle_t mif = sc->sc_mif;
+ int instance, phy;
u_int32_t v;
- /* Configure the MIF in frame mode */
- v = bus_space_read_4(t, mif, HME_MIFI_CFG);
- v &= ~HME_MIF_CFG_BBMODE;
- bus_space_write_4(t, mif, HME_MIFI_CFG, v);
+ if (sc->sc_media.ifm_cur != NULL) {
+ instance = IFM_INST(sc->sc_media.ifm_cur->ifm_media);
+ phy = sc->sc_phys[instance];
+ } else
+ /* No media set yet, pick phy arbitrarily.. */
+ phy = HME_PHYAD_EXTERNAL;
- if (v & HME_MIF_CFG_MDI1)
- sc->sc_tcvr = HME_PHYAD_EXTERNAL;
- else if (v & HME_MIF_CFG_MDI0)
- sc->sc_tcvr = HME_PHYAD_INTERNAL;
+ /* Configure the MIF in frame mode, no poll, current phy select */
+ v = 0;
+ if (phy == HME_PHYAD_EXTERNAL)
+ v |= HME_MIF_CFG_PHY;
+ bus_space_write_4(t, mif, HME_MIFI_CFG, v);
}
/*
@@ -1049,21 +1055,34 @@
struct hme_softc *sc = (void *)self;
bus_space_tag_t t = sc->sc_bustag;
bus_space_handle_t mif = sc->sc_mif;
+ u_int32_t v, mifi_cfg;
int n;
- u_int32_t v;
- if (sc->sc_tcvr != phy)
+ /* We can at most have two PHYs */
+ if (phy != HME_PHYAD_EXTERNAL && phy != HME_PHYAD_INTERNAL)
return (0);
/* Select the desired PHY in the MIF configuration register */
- v = bus_space_read_4(t, mif, HME_MIFI_CFG);
- /* Clear PHY select bit */
+ v = mifi_cfg = bus_space_read_4(t, mif, HME_MIFI_CFG);
v &= ~HME_MIF_CFG_PHY;
if (phy == HME_PHYAD_EXTERNAL)
- /* Set PHY select bit to get at external device */
v |= HME_MIF_CFG_PHY;
bus_space_write_4(t, mif, HME_MIFI_CFG, v);
+#if 0
+/* This doesn't work reliably; the MDIO_1 bit is off most of the time */
+ /*
+ * Check whether a transceiver is connected by testing
+ * the MIF configuration register's MDI_X bits. Note that
+ * MDI_0 (int) == 0x100 and MDI_1 (ext) == 0x200; see hmereg.h
+ */
+ mif_mdi_bit = 1 << (8 + (1 - phy));
+ delay(100);
+ v = bus_space_read_4(t, mif, HME_MIFI_CFG);
+ if ((v & mif_mdi_bit) == 0)
+ return (0);
+#endif
+
/* Construct the frame command */
v = (MII_COMMAND_START << HME_MIF_FO_ST_SHIFT) |
HME_MIF_FO_TAMSB |
@@ -1075,12 +1094,19 @@
for (n = 0; n < 100; n++) {
DELAY(1);
v = bus_space_read_4(t, mif, HME_MIFI_FO);
- if (v & HME_MIF_FO_TALSB)
- return (v & HME_MIF_FO_DATA);
+ if (v & HME_MIF_FO_TALSB) {
+ v &= HME_MIF_FO_DATA;
+ goto out;
+ }
}
+ v = 0;
printf("%s: mii_read timeout\n", sc->sc_dev.dv_xname);
- return (0);
+
+out:
+ /* Restore MIFI_CFG register */
+ bus_space_write_4(t, mif, HME_MIFI_CFG, mifi_cfg);
+ return (v);
}
static void
@@ -1091,21 +1117,34 @@
struct hme_softc *sc = (void *)self;
bus_space_tag_t t = sc->sc_bustag;
bus_space_handle_t mif = sc->sc_mif;
+ u_int32_t v, mifi_cfg;
int n;
- u_int32_t v;
- if (sc->sc_tcvr != phy)
+ /* We can at most have two PHYs */
+ if (phy != HME_PHYAD_EXTERNAL && phy != HME_PHYAD_INTERNAL)
return;
/* Select the desired PHY in the MIF configuration register */
- v = bus_space_read_4(t, mif, HME_MIFI_CFG);
- /* Clear PHY select bit */
+ v = mifi_cfg = bus_space_read_4(t, mif, HME_MIFI_CFG);
v &= ~HME_MIF_CFG_PHY;
if (phy == HME_PHYAD_EXTERNAL)
- /* Set PHY select bit to get at external device */
v |= HME_MIF_CFG_PHY;
bus_space_write_4(t, mif, HME_MIFI_CFG, v);
+#if 0
+/* This doesn't work reliably; the MDIO_1 bit is off most of the time */
+ /*
+ * Check whether a transceiver is connected by testing
+ * the MIF configuration register's MDI_X bits. Note that
+ * MDI_0 (int) == 0x100 and MDI_1 (ext) == 0x200; see hmereg.h
+ */
+ mif_mdi_bit = 1 << (8 + (1 - phy));
+ delay(100);
+ v = bus_space_read_4(t, mif, HME_MIFI_CFG);
+ if ((v & mif_mdi_bit) == 0)
+ return;
+#endif
+
/* Construct the frame command */
v = (MII_COMMAND_START << HME_MIF_FO_ST_SHIFT) |
HME_MIF_FO_TAMSB |
@@ -1119,10 +1158,13 @@
DELAY(1);
v = bus_space_read_4(t, mif, HME_MIFI_FO);
if (v & HME_MIF_FO_TALSB)
- return;
+ goto out;
}
printf("%s: mii_write timeout\n", sc->sc_dev.dv_xname);
+out:
+ /* Restore MIFI_CFG register */
+ bus_space_write_4(t, mif, HME_MIFI_CFG, mifi_cfg);
}
static void
@@ -1130,25 +1172,15 @@
struct device *dev;
{
struct hme_softc *sc = (void *)dev;
- int instance = IFM_INST(sc->sc_mii.mii_media.ifm_cur->ifm_media);
- int phy = sc->sc_phys[instance];
bus_space_tag_t t = sc->sc_bustag;
- bus_space_handle_t mif = sc->sc_mif;
bus_space_handle_t mac = sc->sc_mac;
u_int32_t v;
#ifdef HMEDEBUG
if (sc->sc_debug)
- printf("hme_mii_statchg: status change: phy = %d\n", phy);
+ printf("hme_mii_statchg: status change\n");
#endif
- /* Select the current PHY in the MIF configuration register */
- v = bus_space_read_4(t, mif, HME_MIFI_CFG);
- v &= ~HME_MIF_CFG_PHY;
- if (phy == HME_PHYAD_EXTERNAL)
- v |= HME_MIF_CFG_PHY;
- bus_space_write_4(t, mif, HME_MIFI_CFG, v);
-
/* Set the MAC Full Duplex bit appropriately */
/* Apparently the hme chip is SIMPLEX if working in full duplex mode,
but not otherwise. */
@@ -1161,6 +1193,33 @@
sc->sc_ethercom.ec_if.if_flags &= ~IFF_SIMPLEX;
}
bus_space_write_4(t, mac, HME_MACI_TXCFG, v);
+}
+
+int
+hme_mediachange(ifp)
+ struct ifnet *ifp;
+{
+ struct hme_softc *sc = ifp->if_softc;
+ bus_space_tag_t t = sc->sc_bustag;
+ bus_space_handle_t mif = sc->sc_mif;
+ bus_space_handle_t mac = sc->sc_mac;
+ int instance = IFM_INST(sc->sc_mii.mii_media.ifm_cur->ifm_media);
+ int phy = sc->sc_phys[instance];
+ u_int32_t v;
+
+#ifdef HMEDEBUG
+ if (sc->sc_debug)
+ printf("hme_mediachange: phy = %d\n", phy);
+#endif
+ if (IFM_TYPE(sc->sc_media.ifm_media) != IFM_ETHER)
+ return (EINVAL);
+
+ /* Select the current PHY in the MIF configuration register */
+ v = bus_space_read_4(t, mif, HME_MIFI_CFG);
+ v &= ~HME_MIF_CFG_PHY;
+ if (phy == HME_PHYAD_EXTERNAL)
+ v |= HME_MIF_CFG_PHY;
+ bus_space_write_4(t, mif, HME_MIFI_CFG, v);
/* If an external transceiver is selected, enable its MII drivers */
v = bus_space_read_4(t, mac, HME_MACI_XIF);
@@ -1168,16 +1227,6 @@
if (phy == HME_PHYAD_EXTERNAL)
v |= HME_MAC_XIF_MIIENABLE;
bus_space_write_4(t, mac, HME_MACI_XIF, v);
-}
-
-int
-hme_mediachange(ifp)
- struct ifnet *ifp;
-{
- struct hme_softc *sc = ifp->if_softc;
-
- if (IFM_TYPE(sc->sc_media.ifm_media) != IFM_ETHER)
- return (EINVAL);
Home |
Main Index |
Thread Index |
Old Index