summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/mii
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-11-04 11:33:00 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-11-04 15:28:21 +0100
commitaf5333e0a02b2295304d4e029b15ee15a4fe2b3a (patch)
treec5c43680d374f58b487eeeaf18fb7ec6b84ba074 /freebsd/sys/dev/mii
parentBUS_SPACE(9): Use simple memory model for ARM (diff)
downloadrtems-libbsd-af5333e0a02b2295304d4e029b15ee15a4fe2b3a.tar.bz2
Update to FreeBSD 8.4
Diffstat (limited to 'freebsd/sys/dev/mii')
-rw-r--r--freebsd/sys/dev/mii/brgphy.c93
-rw-r--r--freebsd/sys/dev/mii/brgphyreg.h2
-rw-r--r--freebsd/sys/dev/mii/icsphy.c7
-rw-r--r--freebsd/sys/dev/mii/mii.c174
-rw-r--r--freebsd/sys/dev/mii/mii.h6
-rw-r--r--freebsd/sys/dev/mii/mii_bitbang.h54
-rw-r--r--freebsd/sys/dev/mii/mii_physubr.c29
-rw-r--r--freebsd/sys/dev/mii/miivar.h53
8 files changed, 280 insertions, 138 deletions
diff --git a/freebsd/sys/dev/mii/brgphy.c b/freebsd/sys/dev/mii/brgphy.c
index 5633413c..bd80e61e 100644
--- a/freebsd/sys/dev/mii/brgphy.c
+++ b/freebsd/sys/dev/mii/brgphy.c
@@ -87,7 +87,7 @@ static device_method_t brgphy_methods[] = {
DEVMETHOD(device_attach, brgphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
- { 0, 0 }
+ DEVMETHOD_END
};
static devclass_t brgphy_devclass;
@@ -144,6 +144,10 @@ static const struct mii_phydesc brgphys[] = {
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5761),
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709S),
MII_PHY_DESC(xxBROADCOM_ALT2, BCM5717C),
+ MII_PHY_DESC(xxBROADCOM_ALT2, BCM5719C),
+ MII_PHY_DESC(xxBROADCOM_ALT2, BCM5720C),
+ MII_PHY_DESC(xxBROADCOM_ALT2, BCM57765),
+ MII_PHY_DESC(xxBROADCOM_ALT2, BCM57780),
MII_PHY_DESC(BROADCOM2, BCM5906),
MII_PHY_END
};
@@ -215,16 +219,20 @@ brgphy_attach(device_t dev)
bsc->mii_model = MII_MODEL(ma->mii_id2);
bsc->mii_rev = MII_REV(ma->mii_id2);
bsc->serdes_flags = 0;
+ ifp = sc->mii_pdata->mii_ifp;
if (bootverbose)
device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n",
bsc->mii_oui, bsc->mii_model, bsc->mii_rev);
+ /* Find the MAC driver associated with this PHY. */
+ if (strcmp(ifp->if_dname, "bge") == 0)
+ bge_sc = ifp->if_softc;
+ else if (strcmp(ifp->if_dname, "bce") == 0)
+ bce_sc = ifp->if_softc;
+
/* Handle any special cases based on the PHY ID */
switch (bsc->mii_oui) {
- case MII_OUI_BROADCOM:
- case MII_OUI_BROADCOM2:
- break;
case MII_OUI_xxBROADCOM:
switch (bsc->mii_model) {
case MII_MODEL_xxBROADCOM_BCM5706:
@@ -244,7 +252,8 @@ brgphy_attach(device_t dev)
sc->mii_flags |= MIIF_HAVEFIBER;
}
break;
- } break;
+ }
+ break;
case MII_OUI_xxBROADCOM_ALT1:
switch (bsc->mii_model) {
case MII_MODEL_xxBROADCOM_ALT1_BCM5708S:
@@ -252,25 +261,19 @@ brgphy_attach(device_t dev)
sc->mii_flags |= MIIF_HAVEFIBER;
break;
case MII_MODEL_xxBROADCOM_ALT1_BCM5709S:
- bsc->serdes_flags |= BRGPHY_5709S;
+ /*
+ * XXX
+ * 5720S and 5709S shares the same PHY id.
+ * Assume 5720S PHY if parent device is bge(4).
+ */
+ if (bge_sc != NULL)
+ bsc->serdes_flags |= BRGPHY_5708S;
+ else
+ bsc->serdes_flags |= BRGPHY_5709S;
sc->mii_flags |= MIIF_HAVEFIBER;
break;
}
break;
- case MII_OUI_xxBROADCOM_ALT2:
- /* No special handling yet. */
- break;
- default:
- device_printf(dev, "Unrecognized OUI for PHY!\n");
- }
-
- ifp = sc->mii_pdata->mii_ifp;
-
- /* Find the MAC driver associated with this PHY. */
- if (strcmp(ifp->if_dname, "bge") == 0) {
- bge_sc = ifp->if_softc;
- } else if (strcmp(ifp->if_dname, "bce") == 0) {
- bce_sc = ifp->if_softc;
}
brgphy_reset(sc);
@@ -400,8 +403,6 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
sc->mii_media_status != mii->mii_media_status ||
cmd == MII_MEDIACHG) {
switch (bsc->mii_oui) {
- case MII_OUI_BROADCOM:
- break;
case MII_OUI_xxBROADCOM:
switch (bsc->mii_model) {
case MII_MODEL_xxBROADCOM_BCM5400:
@@ -419,8 +420,6 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
break;
}
break;
- case MII_OUI_xxBROADCOM_ALT1:
- break;
}
}
mii_phy_update(sc, cmd);
@@ -454,7 +453,7 @@ brgphy_setmedia(struct mii_softc *sc, int media)
break;
}
- if ((media & IFM_GMASK) == IFM_FDX) {
+ if ((media & IFM_FDX) != 0) {
bmcr |= BRGPHY_BMCR_FDX;
gig = BRGPHY_1000CTL_AFD;
} else {
@@ -637,6 +636,11 @@ brgphy_mii_phy_auto(struct mii_softc *sc, int media)
(sc->mii_flags & MIIF_FORCEPAUSE) != 0)
anar |= BRGPHY_ANAR_PC | BRGPHY_ANAR_ASP;
PHY_WRITE(sc, BRGPHY_MII_ANAR, anar);
+ ktcr = BRGPHY_1000CTL_AFD | BRGPHY_1000CTL_AHD;
+ if (bsc->mii_model == MII_MODEL_xxBROADCOM_BCM5701)
+ ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC;
+ PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr);
+ PHY_READ(sc, BRGPHY_MII_1000CTL);
} else {
anar = BRGPHY_SERDES_ANAR_FDX | BRGPHY_SERDES_ANAR_HDX;
if ((media & IFM_FLOW) != 0 ||
@@ -645,12 +649,6 @@ brgphy_mii_phy_auto(struct mii_softc *sc, int media)
PHY_WRITE(sc, BRGPHY_SERDES_ANAR, anar);
}
- ktcr = BRGPHY_1000CTL_AFD | BRGPHY_1000CTL_AHD;
- if (bsc->mii_model == MII_MODEL_xxBROADCOM_BCM5701)
- ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC;
- PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr);
- ktcr = PHY_READ(sc, BRGPHY_MII_1000CTL);
-
PHY_WRITE(sc, BRGPHY_MII_BMCR, BRGPHY_BMCR_AUTOEN |
BRGPHY_BMCR_STARTNEG);
PHY_WRITE(sc, BRGPHY_MII_IMR, 0xFF00);
@@ -913,15 +911,25 @@ brgphy_reset(struct mii_softc *sc)
struct bge_softc *bge_sc = NULL;
struct bce_softc *bce_sc = NULL;
struct ifnet *ifp;
- int val;
+ int i, val;
+
+ /*
+ * Perform a reset. Note that at least some Broadcom PHYs default to
+ * being powered down as well as isolated after a reset but don't work
+ * if one or both of these bits are cleared. However, they just work
+ * fine if both bits remain set, so we don't use mii_phy_reset() here.
+ */
+ PHY_WRITE(sc, BRGPHY_MII_BMCR, BRGPHY_BMCR_RESET);
- /* Perform a standard PHY reset. */
- mii_phy_reset(sc);
+ /* Wait 100ms for it to complete. */
+ for (i = 0; i < 100; i++) {
+ if ((PHY_READ(sc, BRGPHY_MII_BMCR) & BRGPHY_BMCR_RESET) == 0)
+ break;
+ DELAY(1000);
+ }
/* Handle any PHY specific procedures following the reset. */
switch (bsc->mii_oui) {
- case MII_OUI_BROADCOM:
- break;
case MII_OUI_xxBROADCOM:
switch (bsc->mii_model) {
case MII_MODEL_xxBROADCOM_BCM5400:
@@ -939,8 +947,14 @@ brgphy_reset(struct mii_softc *sc)
break;
}
break;
- case MII_OUI_xxBROADCOM_ALT1:
case MII_OUI_xxBROADCOM_ALT2:
+ switch (bsc->mii_model) {
+ case MII_MODEL_xxBROADCOM_ALT2_BCM5717C:
+ case MII_MODEL_xxBROADCOM_ALT2_BCM5719C:
+ case MII_MODEL_xxBROADCOM_ALT2_BCM5720C:
+ case MII_MODEL_xxBROADCOM_ALT2_BCM57765:
+ return;
+ }
break;
}
@@ -968,9 +982,10 @@ brgphy_reset(struct mii_softc *sc)
if (bge_sc->bge_phy_flags & BGE_PHY_JITTER_BUG)
brgphy_fixup_jitter_bug(sc);
- brgphy_jumbo_settings(sc, ifp->if_mtu);
+ if (bge_sc->bge_flags & BGE_FLAG_JUMBO)
+ brgphy_jumbo_settings(sc, ifp->if_mtu);
- if (bge_sc->bge_phy_flags & BGE_PHY_WIRESPEED)
+ if ((bge_sc->bge_phy_flags & BGE_PHY_NO_WIRESPEED) == 0)
brgphy_ethernet_wirespeed(sc);
/* Enable Link LED on Dell boxes */
diff --git a/freebsd/sys/dev/mii/brgphyreg.h b/freebsd/sys/dev/mii/brgphyreg.h
index 3f5ee5df..b3535d59 100644
--- a/freebsd/sys/dev/mii/brgphyreg.h
+++ b/freebsd/sys/dev/mii/brgphyreg.h
@@ -59,7 +59,7 @@
#define BRGPHY_BMSR_EXTSTS 0x0100 /* Extended status present */
#define BRGPHY_BMSR_PRESUB 0x0040 /* Preamble surpression */
#define BRGPHY_BMSR_ACOMP 0x0020 /* Autoneg complete */
-#define BRGPHY_BMSR_RFAULT 0x0010 /* Remote fault condition occured */
+#define BRGPHY_BMSR_RFAULT 0x0010 /* Remote fault condition occurred */
#define BRGPHY_BMSR_ANEG 0x0008 /* Autoneg capable */
#define BRGPHY_BMSR_LINK 0x0004 /* Link status */
#define BRGPHY_BMSR_JABBER 0x0002 /* Jabber detected */
diff --git a/freebsd/sys/dev/mii/icsphy.c b/freebsd/sys/dev/mii/icsphy.c
index e2315bc8..3c178c52 100644
--- a/freebsd/sys/dev/mii/icsphy.c
+++ b/freebsd/sys/dev/mii/icsphy.c
@@ -96,7 +96,7 @@ static device_method_t icsphy_methods[] = {
DEVMETHOD(device_attach, icsphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
- { 0, 0 }
+ DEVMETHOD_END
};
static devclass_t icsphy_devclass;
@@ -149,7 +149,7 @@ icsphy_attach(device_t dev)
sc->mii_service = icsphy_service;
sc->mii_pdata = mii;
- sc->mii_flags |= MIIF_NOISOLATE;
+ sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOMANPAUSE;
ifmedia_add(&mii->mii_media,
IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
@@ -242,7 +242,8 @@ icsphy_status(struct mii_softc *sc)
else
mii->mii_media_active |= IFM_10_T;
if (qpr & QPR_FDX)
- mii->mii_media_active |= IFM_FDX;
+ mii->mii_media_active |=
+ IFM_FDX | mii_phy_flowstatus(sc);
else
mii->mii_media_active |= IFM_HDX;
} else
diff --git a/freebsd/sys/dev/mii/mii.c b/freebsd/sys/dev/mii/mii.c
index 5b949156..2e2e6c79 100644
--- a/freebsd/sys/dev/mii/mii.c
+++ b/freebsd/sys/dev/mii/mii.c
@@ -46,11 +46,10 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/malloc.h>
#include <sys/module.h>
-#include <sys/bus.h>
+#include <sys/bus.h>
#include <net/if.h>
#include <net/if_media.h>
-#include <net/route.h>
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>
@@ -59,18 +58,20 @@ MODULE_VERSION(miibus, 1);
#include <rtems/bsd/local/miibus_if.h>
-static int miibus_print_child(device_t dev, device_t child);
-static int miibus_read_ivar(device_t dev, device_t child, int which,
- uintptr_t *result);
-static int miibus_child_location_str(device_t bus, device_t child, char *buf,
- size_t buflen);
-static int miibus_child_pnpinfo_str(device_t bus, device_t child, char *buf,
- size_t buflen);
-static int miibus_readreg(device_t, int, int);
-static int miibus_writereg(device_t, int, int, int);
-static void miibus_statchg(device_t);
-static void miibus_linkchg(device_t);
-static void miibus_mediainit(device_t);
+static device_attach_t miibus_attach;
+static bus_child_location_str_t miibus_child_location_str;
+static bus_child_pnpinfo_str_t miibus_child_pnpinfo_str;
+static device_detach_t miibus_detach;
+static bus_hinted_child_t miibus_hinted_child;
+static bus_print_child_t miibus_print_child;
+static device_probe_t miibus_probe;
+static bus_read_ivar_t miibus_read_ivar;
+static miibus_readreg_t miibus_readreg;
+static miibus_statchg_t miibus_statchg;
+static miibus_writereg_t miibus_writereg;
+static miibus_linkchg_t miibus_linkchg;
+static miibus_mediainit_t miibus_mediainit;
+
static device_method_t miibus_methods[] = {
/* device interface */
@@ -82,18 +83,18 @@ static device_method_t miibus_methods[] = {
/* bus interface */
DEVMETHOD(bus_print_child, miibus_print_child),
DEVMETHOD(bus_read_ivar, miibus_read_ivar),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
DEVMETHOD(bus_child_pnpinfo_str, miibus_child_pnpinfo_str),
DEVMETHOD(bus_child_location_str, miibus_child_location_str),
+ DEVMETHOD(bus_hinted_child, miibus_hinted_child),
/* MII interface */
DEVMETHOD(miibus_readreg, miibus_readreg),
DEVMETHOD(miibus_writereg, miibus_writereg),
- DEVMETHOD(miibus_statchg, miibus_statchg),
- DEVMETHOD(miibus_linkchg, miibus_linkchg),
- DEVMETHOD(miibus_mediainit, miibus_mediainit),
+ DEVMETHOD(miibus_statchg, miibus_statchg),
+ DEVMETHOD(miibus_linkchg, miibus_linkchg),
+ DEVMETHOD(miibus_mediainit, miibus_mediainit),
- { 0, 0 }
+ DEVMETHOD_END
};
devclass_t miibus_devclass;
@@ -108,10 +109,11 @@ struct miibus_ivars {
struct ifnet *ifp;
ifm_change_cb_t ifmedia_upd;
ifm_stat_cb_t ifmedia_sts;
- int mii_flags;
+ u_int mii_flags;
+ u_int mii_offset;
};
-int
+static int
miibus_probe(device_t dev)
{
@@ -120,7 +122,7 @@ miibus_probe(device_t dev)
return (BUS_PROBE_SPECIFIC);
}
-int
+static int
miibus_attach(device_t dev)
{
struct miibus_ivars *ivars;
@@ -130,7 +132,6 @@ miibus_attach(device_t dev)
int i, nchildren;
mii = device_get_softc(dev);
- nchildren = 0;
if (device_get_children(dev, &children, &nchildren) == 0) {
for (i = 0; i < nchildren; i++) {
ma = device_get_ivars(children[i]);
@@ -153,7 +154,7 @@ miibus_attach(device_t dev)
return (bus_generic_attach(dev));
}
-int
+static int
miibus_detach(device_t dev)
{
struct mii_data *mii;
@@ -202,7 +203,7 @@ miibus_read_ivar(device_t dev, device_t child __unused, int which,
}
static int
-miibus_child_pnpinfo_str(device_t bus __unused, device_t child, char *buf,
+miibus_child_pnpinfo_str(device_t dev __unused, device_t child, char *buf,
size_t buflen)
{
struct mii_attach_args *ma;
@@ -215,7 +216,7 @@ miibus_child_pnpinfo_str(device_t bus __unused, device_t child, char *buf,
}
static int
-miibus_child_location_str(device_t bus __unused, device_t child, char *buf,
+miibus_child_location_str(device_t dev __unused, device_t child, char *buf,
size_t buflen)
{
struct mii_attach_args *ma;
@@ -225,6 +226,60 @@ miibus_child_location_str(device_t bus __unused, device_t child, char *buf,
return (0);
}
+static void
+miibus_hinted_child(device_t dev, const char *name, int unit)
+{
+ struct miibus_ivars *ivars;
+ struct mii_attach_args *args, *ma;
+ device_t *children, phy;
+ int i, nchildren;
+ u_int val;
+
+ if (resource_int_value(name, unit, "phyno", &val) != 0)
+ return;
+ if (device_get_children(dev, &children, &nchildren) != 0)
+ return;
+ ma = NULL;
+ for (i = 0; i < nchildren; i++) {
+ args = device_get_ivars(children[i]);
+ if (args->mii_phyno == val) {
+ ma = args;
+ break;
+ }
+ }
+ free(children, M_TEMP);
+
+ /*
+ * Don't add a PHY that was automatically identified by having media
+ * in its BMSR twice, only allow to alter its attach arguments.
+ */
+ if (ma == NULL) {
+ ma = malloc(sizeof(struct mii_attach_args), M_DEVBUF,
+ M_NOWAIT);
+ if (ma == NULL)
+ return;
+ phy = device_add_child(dev, name, unit);
+ if (phy == NULL) {
+ free(ma, M_DEVBUF);
+ return;
+ }
+ ivars = device_get_ivars(dev);
+ ma->mii_phyno = val;
+ ma->mii_offset = ivars->mii_offset++;
+ ma->mii_id1 = 0;
+ ma->mii_id2 = 0;
+ ma->mii_capmask = BMSR_DEFCAPMASK;
+ device_set_ivars(phy, ma);
+ }
+
+ if (resource_int_value(name, unit, "id1", &val) == 0)
+ ma->mii_id1 = val;
+ if (resource_int_value(name, unit, "id2", &val) == 0)
+ ma->mii_id2 = val;
+ if (resource_int_value(name, unit, "capmask", &val) == 0)
+ ma->mii_capmask = val;
+}
+
static int
miibus_readreg(device_t dev, int phy, int reg)
{
@@ -274,7 +329,7 @@ miibus_linkchg(device_t dev)
MIIBUS_LINKCHG(parent);
mii = device_get_softc(dev);
-
+
if (mii->mii_media_status & IFM_AVALID) {
if (mii->mii_media_status & IFM_ACTIVE)
link_state = LINK_STATE_UP;
@@ -319,9 +374,10 @@ mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp,
int phyloc, int offloc, int flags)
{
struct miibus_ivars *ivars;
- struct mii_attach_args ma, *args;
+ struct mii_attach_args *args, ma;
device_t *children, phy;
- int bmsr, first, i, nchildren, offset, phymax, phymin, rv;
+ int bmsr, first, i, nchildren, phymax, phymin, rv;
+ uint32_t phymask;
if (phyloc != MII_PHY_ANY && offloc != MII_OFFSET_ANY) {
printf("%s: phyloc and offloc specified\n", __func__);
@@ -374,38 +430,41 @@ mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp,
* has been allocated.
*/
ma.mii_data = device_get_softc(*miibus);
- }
+ }
ma.mii_capmask = capmask;
- phy = NULL;
- offset = 0;
+ if (resource_int_value(device_get_name(*miibus),
+ device_get_unit(*miibus), "phymask", &phymask) != 0)
+ phymask = 0xffffffff;
+
+ if (device_get_children(*miibus, &children, &nchildren) != 0) {
+ children = NULL;
+ nchildren = 0;
+ }
+ ivars->mii_offset = 0;
for (ma.mii_phyno = phymin; ma.mii_phyno <= phymax; ma.mii_phyno++) {
/*
* Make sure we haven't already configured a PHY at this
* address. This allows mii_attach() to be called
* multiple times.
*/
- if (device_get_children(*miibus, &children, &nchildren) == 0) {
- for (i = 0; i < nchildren; i++) {
- args = device_get_ivars(children[i]);
- if (args->mii_phyno == ma.mii_phyno) {
- /*
- * Yes, there is already something
- * configured at this address.
- */
- free(children, M_TEMP);
- goto skip;
- }
+ for (i = 0; i < nchildren; i++) {
+ args = device_get_ivars(children[i]);
+ if (args->mii_phyno == ma.mii_phyno) {
+ /*
+ * Yes, there is already something
+ * configured at this address.
+ */
+ goto skip;
}
- free(children, M_TEMP);
}
/*
* Check to see if there is a PHY at this address. Note,
* many braindead PHYs report 0/0 in their ID registers,
* so we test for media in the BMSR.
- */
+ */
bmsr = MIIBUS_READREG(dev, ma.mii_phyno, MII_BMSR);
if (bmsr == 0 || bmsr == 0xffff ||
(bmsr & (BMSR_EXTSTAT | BMSR_MEDIAMASK)) == 0) {
@@ -417,14 +476,20 @@ mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp,
* There is a PHY at this address. If we were given an
* `offset' locator, skip this PHY if it doesn't match.
*/
- if (offloc != MII_OFFSET_ANY && offloc != offset)
+ if (offloc != MII_OFFSET_ANY && offloc != ivars->mii_offset)
+ goto skip;
+
+ /*
+ * Skip this PHY if it's not included in the phymask hint.
+ */
+ if ((phymask & (1 << ma.mii_phyno)) == 0)
goto skip;
/*
- * Extract the IDs. Braindead PHYs will be handled by
+ * Extract the IDs. Braindead PHYs will be handled by
* the `ukphy' driver, as we have no ID information to
* match on.
- */
+ */
ma.mii_id1 = MIIBUS_READREG(dev, ma.mii_phyno, MII_PHYIDR1);
ma.mii_id2 = MIIBUS_READREG(dev, ma.mii_phyno, MII_PHYIDR2);
@@ -440,11 +505,20 @@ mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp,
}
device_set_ivars(phy, args);
skip:
- offset++;
+ ivars->mii_offset++;
}
+ free(children, M_TEMP);
if (first != 0) {
- if (phy == NULL) {
+ rv = device_set_driver(*miibus, &miibus_driver);
+ if (rv != 0)
+ goto fail;
+ bus_enumerate_hinted_children(*miibus);
+ rv = device_get_children(*miibus, &children, &nchildren);
+ if (rv != 0)
+ goto fail;
+ free(children, M_TEMP);
+ if (nchildren == 0) {
rv = ENXIO;
goto fail;
}
diff --git a/freebsd/sys/dev/mii/mii.h b/freebsd/sys/dev/mii/mii.h
index 1d887d23..5316f1eb 100644
--- a/freebsd/sys/dev/mii/mii.h
+++ b/freebsd/sys/dev/mii/mii.h
@@ -89,15 +89,9 @@
* info available in register 15, but 802.3 section 22.2.4.3 also
* states that that all 1000 Mb/s capable PHYs will set this bit to 1.
*/
-#if 0
-#define BMSR_MEDIAMASK (BMSR_100T4|BMSR_100TXFDX|BMSR_100TXHDX|BMSR_10TFDX| \
- BMSR_10THDX|BMSR_ANEG)
-#else
-/* NetBSD uses: */
#define BMSR_MEDIAMASK (BMSR_100T4|BMSR_100TXFDX|BMSR_100TXHDX| \
BMSR_10TFDX|BMSR_10THDX|BMSR_100T2FDX|BMSR_100T2HDX)
-#endif
/*
* Convert BMSR media capabilities to ANAR bits for autonegotiation.
diff --git a/freebsd/sys/dev/mii/mii_bitbang.h b/freebsd/sys/dev/mii/mii_bitbang.h
new file mode 100644
index 00000000..2bc74276
--- /dev/null
+++ b/freebsd/sys/dev/mii/mii_bitbang.h
@@ -0,0 +1,54 @@
+/* $NetBSD: mii_bitbang.h,v 1.6 2009/05/12 14:31:27 cegger Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#define MII_BIT_MDO 0 /* data out (host->PHY) */
+#define MII_BIT_MDI 1 /* data in (PHY->host) */
+#define MII_BIT_MDC 2 /* clock */
+#define MII_BIT_DIR_HOST_PHY 3 /* set direction: host->PHY */
+#define MII_BIT_DIR_PHY_HOST 4 /* set direction: PHY->host */
+#define MII_NBITS 5
+
+struct mii_bitbang_ops {
+ uint32_t (*mbo_read)(device_t);
+ void (*mbo_write)(device_t, uint32_t);
+ uint32_t mbo_bits[MII_NBITS];
+};
+
+typedef const struct mii_bitbang_ops *mii_bitbang_ops_t;
+
+int mii_bitbang_readreg(device_t dev, mii_bitbang_ops_t ops,
+ int phy, int reg);
+void mii_bitbang_sync(device_t dev, mii_bitbang_ops_t ops);
+void mii_bitbang_writereg(device_t dev, mii_bitbang_ops_t ops,
+ int phy, int reg, int val);
diff --git a/freebsd/sys/dev/mii/mii_physubr.c b/freebsd/sys/dev/mii/mii_physubr.c
index 3b6e0042..80996d38 100644
--- a/freebsd/sys/dev/mii/mii_physubr.c
+++ b/freebsd/sys/dev/mii/mii_physubr.c
@@ -111,7 +111,7 @@ mii_phy_setmedia(struct mii_softc *sc)
/*
* Force renegotiation if MIIF_DOPAUSE or MIIF_FORCEANEG.
* The former is necessary as we might switch from flow-
- * control advertisment being off to on or vice versa.
+ * control advertisement being off to on or vice versa.
*/
if ((PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN) == 0 ||
(sc->mii_flags & (MIIF_DOPAUSE | MIIF_FORCEANEG)) != 0)
@@ -137,8 +137,9 @@ mii_phy_setmedia(struct mii_softc *sc)
gtcr |= GTCR_ADV_MS;
}
- if ((ife->ifm_media & IFM_GMASK) == (IFM_FDX | IFM_FLOW) ||
- (sc->mii_flags & MIIF_FORCEPAUSE) != 0) {
+ if ((ife->ifm_media & IFM_FDX) != 0 &&
+ ((ife->ifm_media & IFM_FLOW) != 0 ||
+ (sc->mii_flags & MIIF_FORCEPAUSE) != 0)) {
if ((sc->mii_flags & MIIF_IS_1000X) != 0)
anar |= ANAR_X_PAUSE_TOWARDS;
else {
@@ -186,7 +187,8 @@ mii_phy_auto(struct mii_softc *sc)
ANAR_CSMA;
if ((ife->ifm_media & IFM_FLOW) != 0 ||
(sc->mii_flags & MIIF_FORCEPAUSE) != 0) {
- if ((sc->mii_capabilities & BMSR_100TXFDX) != 0)
+ if ((sc->mii_capabilities &
+ (BMSR_10TFDX | BMSR_100TXFDX)) != 0)
anar |= ANAR_FC;
/* XXX Only 1000BASE-T has PAUSE_ASYM? */
if (((sc->mii_flags & MIIF_HAVE_GTCR) != 0) &&
@@ -260,7 +262,7 @@ void
mii_phy_reset(struct mii_softc *sc)
{
struct ifmedia_entry *ife = sc->mii_pdata->mii_media.ifm_cur;
- int reg, i;
+ int i, reg;
if ((sc->mii_flags & MIIF_NOISOLATE) != 0)
reg = BMCR_RESET;
@@ -276,11 +278,14 @@ mii_phy_reset(struct mii_softc *sc)
DELAY(1000);
}
- if ((sc->mii_flags & MIIF_NOISOLATE) == 0) {
- if ((ife == NULL && sc->mii_inst != 0) ||
- (ife != NULL && IFM_INST(ife->ifm_media) != sc->mii_inst))
- PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
- }
+ /* NB: a PHY may default to being powered down and/or isolated. */
+ reg &= ~(BMCR_PDOWN | BMCR_ISO);
+ if ((sc->mii_flags & MIIF_NOISOLATE) == 0 &&
+ ((ife == NULL && sc->mii_inst != 0) ||
+ (ife != NULL && IFM_INST(ife->ifm_media) != sc->mii_inst)))
+ reg |= BMCR_ISO;
+ if (PHY_READ(sc, MII_BMCR) != reg)
+ PHY_WRITE(sc, MII_BMCR, reg);
}
void
@@ -425,9 +430,11 @@ mii_phy_add_media(struct mii_softc *sc)
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
#define PRINT(s) printf("%s%s", sep, s); sep = ", "
- if ((sc->mii_flags & MIIF_NOISOLATE) == 0)
+ if ((sc->mii_flags & MIIF_NOISOLATE) == 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst),
MII_MEDIA_NONE);
+ PRINT("none");
+ }
/*
* There are different interpretations for the bits in
diff --git a/freebsd/sys/dev/mii/miivar.h b/freebsd/sys/dev/mii/miivar.h
index d56ea18d..ac58ac20 100644
--- a/freebsd/sys/dev/mii/miivar.h
+++ b/freebsd/sys/dev/mii/miivar.h
@@ -38,7 +38,7 @@
#include <sys/queue.h>
/*
- * Media Independent Interface configuration defintions.
+ * Media Independent Interface data structure defintions
*/
struct mii_softc;
@@ -65,13 +65,13 @@ struct mii_data {
* request is made.
*/
LIST_HEAD(mii_listhead, mii_softc) mii_phys;
- int mii_instance;
+ u_int mii_instance;
/*
* PHY driver fills this in with active media status.
*/
- int mii_media_status;
- int mii_media_active;
+ u_int mii_media_status;
+ u_int mii_media_active;
/*
* Calls from MII layer into network interface driver.
@@ -105,19 +105,19 @@ struct mii_softc {
LIST_ENTRY(mii_softc) mii_list; /* entry on parent's PHY list */
- int mii_phy; /* our MII address */
- int mii_inst; /* instance for ifmedia */
+ u_int mii_phy; /* our MII address */
+ u_int mii_inst; /* instance for ifmedia */
mii_downcall_t mii_service; /* our downcall */
struct mii_data *mii_pdata; /* pointer to parent's mii_data */
- int mii_flags; /* misc. flags; see below */
- int mii_capabilities; /* capabilities from BMSR */
- int mii_extcapabilities; /* extended capabilities */
- int mii_ticks; /* MII_TICK counter */
- int mii_anegticks; /* ticks before retrying aneg */
- int mii_media_active; /* last active media */
- int mii_media_status; /* last active status */
+ u_int mii_flags; /* misc. flags; see below */
+ u_int mii_capabilities; /* capabilities from BMSR */
+ u_int mii_extcapabilities; /* extended capabilities */
+ u_int mii_ticks; /* MII_TICK counter */
+ u_int mii_anegticks; /* ticks before retrying aneg */
+ u_int mii_media_active; /* last active media */
+ u_int mii_media_status; /* last active status */
};
typedef struct mii_softc mii_softc_t;
@@ -134,7 +134,7 @@ typedef struct mii_softc mii_softc_t;
#define MIIF_IS_HPNA 0x00000200 /* is a HomePNA device */
#define MIIF_FORCEANEG 0x00000400 /* force auto-negotiation */
#define MIIF_NOMANPAUSE 0x00100000 /* no manual PAUSE selection */
-#define MIIF_FORCEPAUSE 0x00200000 /* force PAUSE advertisment */
+#define MIIF_FORCEPAUSE 0x00200000 /* force PAUSE advertisement */
#define MIIF_MACPRIV0 0x01000000 /* private to the MAC driver */
#define MIIF_MACPRIV1 0x02000000 /* private to the MAC driver */
#define MIIF_MACPRIV2 0x04000000 /* private to the MAC driver */
@@ -161,10 +161,11 @@ typedef struct mii_softc mii_softc_t;
*/
struct mii_attach_args {
struct mii_data *mii_data; /* pointer to parent data */
- int mii_phyno; /* MII address */
- int mii_id1; /* PHY ID register 1 */
- int mii_id2; /* PHY ID register 2 */
- int mii_capmask; /* capability mask from BMSR */
+ u_int mii_phyno; /* MII address */
+ u_int mii_offset; /* first PHY, second PHY, etc. */
+ uint32_t mii_id1; /* PHY ID register 1 */
+ uint32_t mii_id2; /* PHY ID register 2 */
+ u_int mii_capmask; /* capability mask for BMSR */
};
typedef struct mii_attach_args mii_attach_args_t;
@@ -172,8 +173,8 @@ typedef struct mii_attach_args mii_attach_args_t;
* Used to match a PHY.
*/
struct mii_phydesc {
- u_int32_t mpd_oui; /* the PHY's OUI */
- u_int32_t mpd_model; /* the PHY's model */
+ uint32_t mpd_oui; /* the PHY's OUI */
+ uint32_t mpd_model; /* the PHY's model */
const char *mpd_name; /* the PHY's name */
};
#define MII_PHY_DESC(a, b) { MII_OUI_ ## a, MII_MODEL_ ## a ## _ ## b, \
@@ -184,9 +185,9 @@ struct mii_phydesc {
* An array of these structures map MII media types to BMCR/ANAR settings.
*/
struct mii_media {
- int mm_bmcr; /* BMCR settings for this media */
- int mm_anar; /* ANAR settings for this media */
- int mm_gtcr; /* 100base-T2 or 1000base-T CR */
+ u_int mm_bmcr; /* BMCR settings for this media */
+ u_int mm_anar; /* ANAR settings for this media */
+ u_int mm_gtcr; /* 100base-T2 or 1000base-T CR */
};
#define MII_MEDIA_NONE 0
@@ -219,15 +220,11 @@ enum miibus_device_ivars {
#define MIIBUS_ACCESSOR(var, ivar, type) \
__BUS_ACCESSOR(miibus, var, MIIBUS, ivar, type)
-MIIBUS_ACCESSOR(flags, FLAGS, int)
+MIIBUS_ACCESSOR(flags, FLAGS, u_int)
extern devclass_t miibus_devclass;
extern driver_t miibus_driver;
-int miibus_probe(device_t);
-int miibus_attach(device_t);
-int miibus_detach(device_t);
-
int mii_attach(device_t, device_t *, struct ifnet *, ifm_change_cb_t,
ifm_stat_cb_t, int, int, int, int);
int mii_anar(int);