diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-11-04 11:33:00 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-11-04 15:28:21 +0100 |
commit | af5333e0a02b2295304d4e029b15ee15a4fe2b3a (patch) | |
tree | c5c43680d374f58b487eeeaf18fb7ec6b84ba074 /freebsd/sys/dev/mii | |
parent | BUS_SPACE(9): Use simple memory model for ARM (diff) | |
download | rtems-libbsd-af5333e0a02b2295304d4e029b15ee15a4fe2b3a.tar.bz2 |
Update to FreeBSD 8.4
Diffstat (limited to 'freebsd/sys/dev/mii')
-rw-r--r-- | freebsd/sys/dev/mii/brgphy.c | 93 | ||||
-rw-r--r-- | freebsd/sys/dev/mii/brgphyreg.h | 2 | ||||
-rw-r--r-- | freebsd/sys/dev/mii/icsphy.c | 7 | ||||
-rw-r--r-- | freebsd/sys/dev/mii/mii.c | 174 | ||||
-rw-r--r-- | freebsd/sys/dev/mii/mii.h | 6 | ||||
-rw-r--r-- | freebsd/sys/dev/mii/mii_bitbang.h | 54 | ||||
-rw-r--r-- | freebsd/sys/dev/mii/mii_physubr.c | 29 | ||||
-rw-r--r-- | freebsd/sys/dev/mii/miivar.h | 53 |
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); |