summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/mii
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-11-06 16:20:21 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-11-11 10:08:08 +0100
commit66659ff1ad6831b0ea7425fa6ecd8a8687523658 (patch)
tree48e22b475fa8854128e0861a33fed6f78c8094b5 /freebsd/sys/dev/mii
parentDefine __GLOBL1() and __GLOBL() (diff)
downloadrtems-libbsd-66659ff1ad6831b0ea7425fa6ecd8a8687523658.tar.bz2
Update to FreeBSD 9.2
Diffstat (limited to 'freebsd/sys/dev/mii')
-rw-r--r--freebsd/sys/dev/mii/brgphy.c186
-rw-r--r--freebsd/sys/dev/mii/icsphy.c67
-rw-r--r--freebsd/sys/dev/mii/mii.c60
-rw-r--r--freebsd/sys/dev/mii/mii.h4
-rw-r--r--freebsd/sys/dev/mii/mii_physubr.c144
-rw-r--r--freebsd/sys/dev/mii/miivar.h40
6 files changed, 208 insertions, 293 deletions
diff --git a/freebsd/sys/dev/mii/brgphy.c b/freebsd/sys/dev/mii/brgphy.c
index e21e783e..de1249c3 100644
--- a/freebsd/sys/dev/mii/brgphy.c
+++ b/freebsd/sys/dev/mii/brgphy.c
@@ -70,9 +70,6 @@ static int brgphy_attach(device_t);
struct brgphy_softc {
struct mii_softc mii_sc;
- int mii_oui;
- int mii_model;
- int mii_rev;
int serdes_flags; /* Keeps track of the serdes type used */
#define BRGPHY_5706S 0x0001
#define BRGPHY_5708S 0x0002
@@ -119,39 +116,49 @@ static void brgphy_ethernet_wirespeed(struct mii_softc *);
static void brgphy_jumbo_settings(struct mii_softc *, u_long);
static const struct mii_phydesc brgphys[] = {
- MII_PHY_DESC(xxBROADCOM, BCM5400),
- MII_PHY_DESC(xxBROADCOM, BCM5401),
- MII_PHY_DESC(xxBROADCOM, BCM5411),
- MII_PHY_DESC(xxBROADCOM, BCM54K2),
- MII_PHY_DESC(xxBROADCOM, BCM5701),
- MII_PHY_DESC(xxBROADCOM, BCM5703),
- MII_PHY_DESC(xxBROADCOM, BCM5704),
- MII_PHY_DESC(xxBROADCOM, BCM5705),
- MII_PHY_DESC(xxBROADCOM, BCM5706),
- MII_PHY_DESC(xxBROADCOM, BCM5714),
- MII_PHY_DESC(xxBROADCOM, BCM5750),
- MII_PHY_DESC(xxBROADCOM, BCM5752),
- MII_PHY_DESC(xxBROADCOM, BCM5754),
- MII_PHY_DESC(xxBROADCOM, BCM5780),
- MII_PHY_DESC(xxBROADCOM, BCM5708C),
- MII_PHY_DESC(xxBROADCOM_ALT1, BCM5755),
- MII_PHY_DESC(xxBROADCOM_ALT1, BCM5787),
- MII_PHY_DESC(xxBROADCOM_ALT1, BCM5708S),
- MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709CAX),
- MII_PHY_DESC(xxBROADCOM_ALT1, BCM5722),
- MII_PHY_DESC(xxBROADCOM_ALT1, BCM5784),
- MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C),
- 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_DESC(BROADCOM, BCM5400),
+ MII_PHY_DESC(BROADCOM, BCM5401),
+ MII_PHY_DESC(BROADCOM, BCM5411),
+ MII_PHY_DESC(BROADCOM, BCM54K2),
+ MII_PHY_DESC(BROADCOM, BCM5701),
+ MII_PHY_DESC(BROADCOM, BCM5703),
+ MII_PHY_DESC(BROADCOM, BCM5704),
+ MII_PHY_DESC(BROADCOM, BCM5705),
+ MII_PHY_DESC(BROADCOM, BCM5706),
+ MII_PHY_DESC(BROADCOM, BCM5714),
+ MII_PHY_DESC(BROADCOM, BCM5421),
+ MII_PHY_DESC(BROADCOM, BCM5750),
+ MII_PHY_DESC(BROADCOM, BCM5752),
+ MII_PHY_DESC(BROADCOM, BCM5780),
+ MII_PHY_DESC(BROADCOM, BCM5708C),
+ MII_PHY_DESC(BROADCOM2, BCM5482),
+ MII_PHY_DESC(BROADCOM2, BCM5708S),
+ MII_PHY_DESC(BROADCOM2, BCM5709C),
+ MII_PHY_DESC(BROADCOM2, BCM5709S),
+ MII_PHY_DESC(BROADCOM2, BCM5709CAX),
+ MII_PHY_DESC(BROADCOM2, BCM5722),
+ MII_PHY_DESC(BROADCOM2, BCM5755),
+ MII_PHY_DESC(BROADCOM2, BCM5754),
+ MII_PHY_DESC(BROADCOM2, BCM5761),
+ MII_PHY_DESC(BROADCOM2, BCM5784),
+#ifdef notyet /* better handled by ukphy(4) until WARs are implemented */
+ MII_PHY_DESC(BROADCOM2, BCM5785),
+#endif
+ MII_PHY_DESC(BROADCOM3, BCM5717C),
+ MII_PHY_DESC(BROADCOM3, BCM5719C),
+ MII_PHY_DESC(BROADCOM3, BCM5720C),
+ MII_PHY_DESC(BROADCOM3, BCM57765),
+ MII_PHY_DESC(BROADCOM3, BCM57780),
+ MII_PHY_DESC(xxBROADCOM_ALT1, BCM5906),
MII_PHY_END
};
+static const struct mii_phy_funcs brgphy_funcs = {
+ brgphy_service,
+ brgphy_status,
+ brgphy_reset
+};
+
#define HS21_PRODUCT_ID "IBM eServer BladeCenter HS21"
#define HS21_BCM_CHIPID 0x57081021
@@ -190,41 +197,17 @@ brgphy_attach(device_t dev)
struct bge_softc *bge_sc = NULL;
struct bce_softc *bce_sc = NULL;
struct mii_softc *sc;
- struct mii_attach_args *ma;
- struct mii_data *mii;
struct ifnet *ifp;
bsc = device_get_softc(dev);
sc = &bsc->mii_sc;
- ma = device_get_ivars(dev);
- sc->mii_dev = device_get_parent(dev);
- mii = ma->mii_data;
- LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
-
- /* Initialize mii_softc structure */
- sc->mii_flags = miibus_get_flags(dev);
- sc->mii_inst = mii->mii_instance++;
- sc->mii_phy = ma->mii_phyno;
- sc->mii_service = brgphy_service;
- sc->mii_pdata = mii;
- /*
- * At least some variants wedge when isolating, at least some also
- * don't support loopback.
- */
- sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP | MIIF_NOMANPAUSE;
+ mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE,
+ &brgphy_funcs, 0);
- /* Initialize brgphy_softc structure */
- bsc->mii_oui = MII_OUI(ma->mii_id1, ma->mii_id2);
- 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;
@@ -232,11 +215,11 @@ brgphy_attach(device_t dev)
bce_sc = ifp->if_softc;
/* Handle any special cases based on the PHY ID */
- switch (bsc->mii_oui) {
- case MII_OUI_xxBROADCOM:
- switch (bsc->mii_model) {
- case MII_MODEL_xxBROADCOM_BCM5706:
- case MII_MODEL_xxBROADCOM_BCM5714:
+ switch (sc->mii_mpd_oui) {
+ case MII_OUI_BROADCOM:
+ switch (sc->mii_mpd_model) {
+ case MII_MODEL_BROADCOM_BCM5706:
+ case MII_MODEL_BROADCOM_BCM5714:
/*
* The 5464 PHY used in the 5706 supports both copper
* and fiber interfaces over GMII. Need to check the
@@ -254,13 +237,13 @@ brgphy_attach(device_t dev)
break;
}
break;
- case MII_OUI_xxBROADCOM_ALT1:
- switch (bsc->mii_model) {
- case MII_MODEL_xxBROADCOM_ALT1_BCM5708S:
+ case MII_OUI_BROADCOM2:
+ switch (sc->mii_mpd_model) {
+ case MII_MODEL_BROADCOM2_BCM5708S:
bsc->serdes_flags |= BRGPHY_5708S;
sc->mii_flags |= MIIF_HAVEFIBER;
break;
- case MII_MODEL_xxBROADCOM_ALT1_BCM5709S:
+ case MII_MODEL_BROADCOM2_BCM5709S:
/*
* XXX
* 5720S and 5709S shares the same PHY id.
@@ -276,15 +259,15 @@ brgphy_attach(device_t dev)
break;
}
- brgphy_reset(sc);
+ PHY_RESET(sc);
/* Read the PHY's capabilities. */
- sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
+ sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & sc->mii_capmask;
if (sc->mii_capabilities & BMSR_EXTSTAT)
sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
device_printf(dev, " ");
-#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
+#define ADD(m, c) ifmedia_add(&sc->mii_pdata->mii_media, (m), (c), NULL)
/* Add the supported media types */
if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
@@ -325,7 +308,6 @@ brgphy_attach(device_t dev)
static int
brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
- struct brgphy_softc *bsc = (struct brgphy_softc *)sc;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
int val;
@@ -338,7 +320,7 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
break;
/* Todo: Why is this here? Is it really needed? */
- brgphy_reset(sc); /* XXX hardware bug work-around */
+ PHY_RESET(sc); /* XXX hardware bug work-around */
switch (IFM_SUBTYPE(ife->ifm_media)) {
case IFM_AUTO:
@@ -393,7 +375,7 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
}
/* Update the media status. */
- brgphy_status(sc);
+ PHY_STATUS(sc);
/*
* Callback if something changed. Note that we need to poke
@@ -402,20 +384,20 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
if (sc->mii_media_active != mii->mii_media_active ||
sc->mii_media_status != mii->mii_media_status ||
cmd == MII_MEDIACHG) {
- switch (bsc->mii_oui) {
- case MII_OUI_xxBROADCOM:
- switch (bsc->mii_model) {
- case MII_MODEL_xxBROADCOM_BCM5400:
+ switch (sc->mii_mpd_oui) {
+ case MII_OUI_BROADCOM:
+ switch (sc->mii_mpd_model) {
+ case MII_MODEL_BROADCOM_BCM5400:
bcm5401_load_dspcode(sc);
break;
- case MII_MODEL_xxBROADCOM_BCM5401:
- if (bsc->mii_rev == 1 || bsc->mii_rev == 3)
+ case MII_MODEL_BROADCOM_BCM5401:
+ if (sc->mii_mpd_rev == 1 || sc->mii_mpd_rev == 3)
bcm5401_load_dspcode(sc);
break;
- case MII_MODEL_xxBROADCOM_BCM5411:
+ case MII_MODEL_BROADCOM_BCM5411:
bcm5411_load_dspcode(sc);
break;
- case MII_MODEL_xxBROADCOM_BCM54K2:
+ case MII_MODEL_BROADCOM_BCM54K2:
bcm54k2_load_dspcode(sc);
break;
}
@@ -474,8 +456,7 @@ brgphy_setmedia(struct mii_softc *sc, int media)
if (IFM_SUBTYPE(media) == IFM_1000_T) {
gig |= BRGPHY_1000CTL_MSE;
- if ((media & IFM_ETH_MASTER) != 0 ||
- (sc->mii_pdata->mii_ifp->if_flags & IFF_LINK0) != 0)
+ if ((media & IFM_ETH_MASTER) != 0)
gig |= BRGPHY_1000CTL_MSC;
}
PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig);
@@ -625,10 +606,9 @@ brgphy_status(struct mii_softc *sc)
static void
brgphy_mii_phy_auto(struct mii_softc *sc, int media)
{
- struct brgphy_softc *bsc = (struct brgphy_softc *)sc;
int anar, ktcr = 0;
- brgphy_reset(sc);
+ PHY_RESET(sc);
if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA;
@@ -637,7 +617,7 @@ brgphy_mii_phy_auto(struct mii_softc *sc, int media)
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)
+ if (sc->mii_mpd_model == MII_MODEL_BROADCOM_BCM5701)
ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC;
PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr);
PHY_READ(sc, BRGPHY_MII_1000CTL);
@@ -874,12 +854,11 @@ brgphy_ethernet_wirespeed(struct mii_softc *sc)
static void
brgphy_jumbo_settings(struct mii_softc *sc, u_long mtu)
{
- struct brgphy_softc *bsc = (struct brgphy_softc *)sc;
uint32_t val;
/* Set or clear jumbo frame settings in the PHY. */
if (mtu > ETHER_MAX_LEN) {
- if (bsc->mii_model == MII_MODEL_xxBROADCOM_BCM5401) {
+ if (sc->mii_mpd_model == MII_MODEL_BROADCOM_BCM5401) {
/* BCM5401 PHY cannot read-modify-write. */
PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x4c20);
} else {
@@ -907,7 +886,6 @@ brgphy_jumbo_settings(struct mii_softc *sc, u_long mtu)
static void
brgphy_reset(struct mii_softc *sc)
{
- struct brgphy_softc *bsc = (struct brgphy_softc *)sc;
struct bge_softc *bge_sc = NULL;
struct bce_softc *bce_sc = NULL;
struct ifnet *ifp;
@@ -929,30 +907,30 @@ brgphy_reset(struct mii_softc *sc)
}
/* Handle any PHY specific procedures following the reset. */
- switch (bsc->mii_oui) {
- case MII_OUI_xxBROADCOM:
- switch (bsc->mii_model) {
- case MII_MODEL_xxBROADCOM_BCM5400:
+ switch (sc->mii_mpd_oui) {
+ case MII_OUI_BROADCOM:
+ switch (sc->mii_mpd_model) {
+ case MII_MODEL_BROADCOM_BCM5400:
bcm5401_load_dspcode(sc);
break;
- case MII_MODEL_xxBROADCOM_BCM5401:
- if (bsc->mii_rev == 1 || bsc->mii_rev == 3)
+ case MII_MODEL_BROADCOM_BCM5401:
+ if (sc->mii_mpd_rev == 1 || sc->mii_mpd_rev == 3)
bcm5401_load_dspcode(sc);
break;
- case MII_MODEL_xxBROADCOM_BCM5411:
+ case MII_MODEL_BROADCOM_BCM5411:
bcm5411_load_dspcode(sc);
break;
- case MII_MODEL_xxBROADCOM_BCM54K2:
+ case MII_MODEL_BROADCOM_BCM54K2:
bcm54k2_load_dspcode(sc);
break;
}
break;
- 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:
+ case MII_OUI_BROADCOM3:
+ switch (sc->mii_mpd_model) {
+ case MII_MODEL_BROADCOM3_BCM5717C:
+ case MII_MODEL_BROADCOM3_BCM5719C:
+ case MII_MODEL_BROADCOM3_BCM5720C:
+ case MII_MODEL_BROADCOM3_BCM57765:
return;
}
break;
diff --git a/freebsd/sys/dev/mii/icsphy.c b/freebsd/sys/dev/mii/icsphy.c
index 47474db7..3d5e6384 100644
--- a/freebsd/sys/dev/mii/icsphy.c
+++ b/freebsd/sys/dev/mii/icsphy.c
@@ -85,11 +85,6 @@ __FBSDID("$FreeBSD$");
static int icsphy_probe(device_t dev);
static int icsphy_attach(device_t dev);
-struct icsphy_softc {
- struct mii_softc mii_sc;
- int mii_model;
-};
-
static device_method_t icsphy_methods[] = {
/* device interface */
DEVMETHOD(device_probe, icsphy_probe),
@@ -104,7 +99,7 @@ static devclass_t icsphy_devclass;
static driver_t icsphy_driver = {
"icsphy",
icsphy_methods,
- sizeof(struct icsphy_softc)
+ sizeof(struct mii_softc)
};
DRIVER_MODULE(icsphy, miibus, icsphy_driver, icsphy_devclass, 0, 0);
@@ -114,13 +109,19 @@ static void icsphy_status(struct mii_softc *);
static void icsphy_reset(struct mii_softc *);
static const struct mii_phydesc icsphys[] = {
- MII_PHY_DESC(xxICS, 1889),
- MII_PHY_DESC(xxICS, 1890),
- MII_PHY_DESC(xxICS, 1892),
- MII_PHY_DESC(xxICS, 1893),
+ MII_PHY_DESC(ICS, 1889),
+ MII_PHY_DESC(ICS, 1890),
+ MII_PHY_DESC(ICS, 1892),
+ MII_PHY_DESC(ICS, 1893),
MII_PHY_END
};
+static const struct mii_phy_funcs icsphy_funcs = {
+ icsphy_service,
+ icsphy_status,
+ icsphy_reset
+};
+
static int
icsphy_probe(device_t dev)
{
@@ -131,40 +132,9 @@ icsphy_probe(device_t dev)
static int
icsphy_attach(device_t dev)
{
- struct icsphy_softc *isc;
- struct mii_softc *sc;
- struct mii_attach_args *ma;
- struct mii_data *mii;
-
- isc = device_get_softc(dev);
- sc = &isc->mii_sc;
- ma = device_get_ivars(dev);
- sc->mii_dev = device_get_parent(dev);
- mii = ma->mii_data;
- LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
-
- sc->mii_flags = miibus_get_flags(dev);
- sc->mii_inst = mii->mii_instance++;
- sc->mii_phy = ma->mii_phyno;
- sc->mii_service = icsphy_service;
- sc->mii_pdata = mii;
-
- sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOMANPAUSE;
-
- ifmedia_add(&mii->mii_media,
- IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
- MII_MEDIA_100_TX, NULL);
-
- isc->mii_model = MII_MODEL(ma->mii_id2);
- icsphy_reset(sc);
-
- sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
- device_printf(dev, " ");
- mii_phy_add_media(sc);
- printf("\n");
-
- MIIBUS_MEDIAINIT(sc->mii_dev);
+ mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE,
+ &icsphy_funcs, 1);
return (0);
}
@@ -193,7 +163,7 @@ icsphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
}
/* Update the media status. */
- icsphy_status(sc);
+ PHY_STATUS(sc);
/* Callback if something changed. */
mii_phy_update(sc, cmd);
@@ -253,16 +223,15 @@ icsphy_status(struct mii_softc *sc)
static void
icsphy_reset(struct mii_softc *sc)
{
- struct icsphy_softc *isc = (struct icsphy_softc *)sc;
mii_phy_reset(sc);
/* set powerdown feature */
- switch (isc->mii_model) {
- case MII_MODEL_xxICS_1890:
- case MII_MODEL_xxICS_1893:
+ switch (sc->mii_mpd_model) {
+ case MII_MODEL_ICS_1890:
+ case MII_MODEL_ICS_1893:
PHY_WRITE(sc, MII_ICSPHY_ECR2, ECR2_100AUTOPWRDN);
break;
- case MII_MODEL_xxICS_1892:
+ case MII_MODEL_ICS_1892:
PHY_WRITE(sc, MII_ICSPHY_ECR2,
ECR2_10AUTOPWRDN|ECR2_100AUTOPWRDN);
break;
diff --git a/freebsd/sys/dev/mii/mii.c b/freebsd/sys/dev/mii/mii.c
index e3a3ec84..d1f55cb0 100644
--- a/freebsd/sys/dev/mii/mii.c
+++ b/freebsd/sys/dev/mii/mii.c
@@ -72,6 +72,7 @@ static miibus_writereg_t miibus_writereg;
static miibus_linkchg_t miibus_linkchg;
static miibus_mediainit_t miibus_mediainit;
+static unsigned char mii_bitreverse(unsigned char x);
static device_method_t miibus_methods[] = {
/* device interface */
@@ -303,19 +304,12 @@ miibus_statchg(device_t dev)
{
device_t parent;
struct mii_data *mii;
- struct ifnet *ifp;
parent = device_get_parent(dev);
MIIBUS_STATCHG(parent);
mii = device_get_softc(dev);
-
- /*
- * Note that each NIC's softc must start with an ifnet pointer.
- * XXX: EVIL HACK!
- */
- ifp = *(struct ifnet **)device_get_softc(parent);
- ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active);
+ mii->mii_ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active);
}
static void
@@ -337,11 +331,7 @@ miibus_linkchg(device_t dev)
link_state = LINK_STATE_DOWN;
} else
link_state = LINK_STATE_UNKNOWN;
- /*
- * Note that each NIC's softc must start with an ifnet pointer.
- * XXX: EVIL HACK!
- */
- if_link_state_change(*(struct ifnet**)device_get_softc(parent), link_state);
+ if_link_state_change(mii->mii_ifp, link_state);
}
static void
@@ -493,6 +483,7 @@ mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp,
ma.mii_id1 = MIIBUS_READREG(dev, ma.mii_phyno, MII_PHYIDR1);
ma.mii_id2 = MIIBUS_READREG(dev, ma.mii_phyno, MII_PHYIDR2);
+ ma.mii_offset = ivars->mii_offset;
args = malloc(sizeof(struct mii_attach_args), M_DEVBUF,
M_NOWAIT);
if (args == NULL)
@@ -544,21 +535,6 @@ mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp,
return (rv);
}
-int
-mii_phy_probe(device_t dev, device_t *child, ifm_change_cb_t ifmedia_upd,
- ifm_stat_cb_t ifmedia_sts)
-{
- struct ifnet *ifp;
-
- /*
- * Note that each NIC's softc must start with an ifnet pointer.
- * XXX: EVIL HACK!
- */
- ifp = *(struct ifnet **)device_get_softc(dev);
- return (mii_attach(dev, child, ifp, ifmedia_upd, ifmedia_sts,
- BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0));
-}
-
/*
* Media changed; notify all PHYs.
*/
@@ -588,7 +564,7 @@ mii_mediachg(struct mii_data *mii)
BMCR_ISO);
continue;
}
- rv = (*child->mii_service)(child, mii, MII_MEDIACHG);
+ rv = PHY_SERVICE(child, mii, MII_MEDIACHG);
if (rv)
return (rv);
}
@@ -611,7 +587,7 @@ mii_tick(struct mii_data *mii)
*/
if (IFM_INST(ife->ifm_media) != child->mii_inst)
continue;
- (void)(*child->mii_service)(child, mii, MII_TICK);
+ (void)PHY_SERVICE(child, mii, MII_TICK);
}
}
@@ -633,7 +609,7 @@ mii_pollstat(struct mii_data *mii)
*/
if (IFM_INST(ife->ifm_media) != child->mii_inst)
continue;
- (void)(*child->mii_service)(child, mii, MII_POLLSTAT);
+ (void)PHY_SERVICE(child, mii, MII_POLLSTAT);
}
}
@@ -648,3 +624,25 @@ mii_down(struct mii_data *mii)
LIST_FOREACH(child, &mii->mii_phys, mii_list)
mii_phy_down(child);
}
+
+static unsigned char
+mii_bitreverse(unsigned char x)
+{
+ static unsigned const char nibbletab[16] = {
+ 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
+ };
+
+ return ((nibbletab[x & 15] << 4) | nibbletab[x >> 4]);
+}
+
+u_int
+mii_oui(u_int id1, u_int id2)
+{
+ u_int h;
+
+ h = (id1 << 6) | (id2 >> 10);
+
+ return ((mii_bitreverse(h >> 16) << 16) |
+ (mii_bitreverse((h >> 8) & 0xff) << 8) |
+ mii_bitreverse(h & 0xff));
+}
diff --git a/freebsd/sys/dev/mii/mii.h b/freebsd/sys/dev/mii/mii.h
index 5316f1eb..668fb8fb 100644
--- a/freebsd/sys/dev/mii/mii.h
+++ b/freebsd/sys/dev/mii/mii.h
@@ -106,10 +106,6 @@
#define IDR2_MODEL 0x03f0 /* vendor model */
#define IDR2_REV 0x000f /* vendor revision */
-#define MII_OUI(id1, id2) (((id1) << 6) | ((id2) >> 10))
-#define MII_MODEL(id2) (((id2) & IDR2_MODEL) >> 4)
-#define MII_REV(id2) ((id2) & IDR2_REV)
-
#define MII_ANAR 0x04 /* Autonegotiation advertisement (rw) */
/* section 28.2.4.1 and 37.2.6.1 */
#define ANAR_NP 0x8000 /* Next page (ro) */
diff --git a/freebsd/sys/dev/mii/mii_physubr.c b/freebsd/sys/dev/mii/mii_physubr.c
index 7fc4135c..e2725ba6 100644
--- a/freebsd/sys/dev/mii/mii_physubr.c
+++ b/freebsd/sys/dev/mii/mii_physubr.c
@@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$");
/*
* Media to register setting conversion table. Order matters.
*/
-const struct mii_media mii_media_table[MII_NMEDIA] = {
+static const struct mii_media mii_media_table[MII_NMEDIA] = {
/* None */
{ BMCR_ISO, ANAR_CSMA,
0, },
@@ -152,9 +152,6 @@ mii_phy_setmedia(struct mii_softc *sc)
}
}
- if ((ife->ifm_media & IFM_LOOP) != 0)
- bmcr |= BMCR_LOOP;
-
PHY_WRITE(sc, MII_ANAR, anar);
PHY_WRITE(sc, MII_BMCR, bmcr);
if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0)
@@ -253,7 +250,7 @@ mii_phy_tick(struct mii_softc *sc)
return (EJUSTRETURN);
sc->mii_ticks = 0;
- mii_phy_reset(sc);
+ PHY_RESET(sc);
mii_phy_auto(sc);
return (0);
}
@@ -311,99 +308,6 @@ mii_phy_update(struct mii_softc *sc, int cmd)
}
/*
- * Given an ifmedia word, return the corresponding ANAR value.
- */
-int
-mii_anar(int media)
-{
- int rv;
-
- switch (media & (IFM_TMASK|IFM_NMASK|IFM_FDX)) {
- case IFM_ETHER|IFM_10_T:
- rv = ANAR_10|ANAR_CSMA;
- break;
- case IFM_ETHER|IFM_10_T|IFM_FDX:
- rv = ANAR_10_FD|ANAR_CSMA;
- break;
- case IFM_ETHER|IFM_100_TX:
- rv = ANAR_TX|ANAR_CSMA;
- break;
- case IFM_ETHER|IFM_100_TX|IFM_FDX:
- rv = ANAR_TX_FD|ANAR_CSMA;
- break;
- case IFM_ETHER|IFM_100_T4:
- rv = ANAR_T4|ANAR_CSMA;
- break;
- default:
- rv = 0;
- break;
- }
-
- return (rv);
-}
-
-/*
- * Initialize generic PHY media based on BMSR, called when a PHY is
- * attached. We expect to be set up to print a comma-separated list
- * of media names. Does not print a newline.
- */
-void
-mii_add_media(struct mii_softc *sc)
-{
- struct mii_data *mii = sc->mii_pdata;
- const char *sep = "";
-
- if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0) {
- printf("no media present");
- return;
- }
-
-#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
-#define PRINT(s) printf("%s%s", sep, s); sep = ", "
-
- if (sc->mii_capabilities & BMSR_10THDX) {
- ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), 0);
- PRINT("10baseT");
- }
- if (sc->mii_capabilities & BMSR_10TFDX) {
- ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst),
- BMCR_FDX);
- PRINT("10baseT-FDX");
- }
- if (sc->mii_capabilities & BMSR_100TXHDX) {
- ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst),
- BMCR_S100);
- PRINT("100baseTX");
- }
- if (sc->mii_capabilities & BMSR_100TXFDX) {
- ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst),
- BMCR_S100|BMCR_FDX);
- PRINT("100baseTX-FDX");
- }
- if (sc->mii_capabilities & BMSR_100T4) {
- /*
- * XXX How do you enable 100baseT4? I assume we set
- * XXX BMCR_S100 and then assume the PHYs will take
- * XXX watever action is necessary to switch themselves
- * XXX into T4 mode.
- */
- ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_T4, 0, sc->mii_inst),
- BMCR_S100);
- PRINT("100baseT4");
- }
- if (sc->mii_capabilities & BMSR_ANEG) {
- ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst),
- BMCR_AUTOEN);
- PRINT("auto");
- }
-
-
-
-#undef ADD
-#undef PRINT
-}
-
-/*
* Initialize generic PHY media based on BMSR, called when a PHY is
* attached. We expect to be set up to print a comma-separated list
* of media names. Does not print a newline.
@@ -621,6 +525,50 @@ mii_phy_dev_probe(device_t dev, const struct mii_phydesc *mpd, int mrv)
return (ENXIO);
}
+void
+mii_phy_dev_attach(device_t dev, u_int flags, const struct mii_phy_funcs *mpf,
+ int add_media)
+{
+ struct mii_softc *sc;
+ struct mii_attach_args *ma;
+ struct mii_data *mii;
+
+ sc = device_get_softc(dev);
+ ma = device_get_ivars(dev);
+ sc->mii_dev = device_get_parent(dev);
+ mii = ma->mii_data;
+ LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
+
+ sc->mii_flags = flags | miibus_get_flags(dev);
+ sc->mii_mpd_oui = MII_OUI(ma->mii_id1, ma->mii_id2);
+ sc->mii_mpd_model = MII_MODEL(ma->mii_id2);
+ sc->mii_mpd_rev = MII_REV(ma->mii_id2);
+ sc->mii_capmask = ma->mii_capmask;
+ sc->mii_inst = mii->mii_instance++;
+ sc->mii_phy = ma->mii_phyno;
+ sc->mii_offset = ma->mii_offset;
+ sc->mii_funcs = mpf;
+ sc->mii_pdata = mii;
+
+ if (bootverbose)
+ device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n",
+ sc->mii_mpd_oui, sc->mii_mpd_model, sc->mii_mpd_rev);
+
+ if (add_media == 0)
+ return;
+
+ PHY_RESET(sc);
+
+ sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & sc->mii_capmask;
+ if (sc->mii_capabilities & BMSR_EXTSTAT)
+ sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
+ device_printf(dev, " ");
+ mii_phy_add_media(sc);
+ printf("\n");
+
+ MIIBUS_MEDIAINIT(sc->mii_dev);
+}
+
/*
* Return the flow control status flag from MII_ANAR & MII_ANLPAR.
*/
diff --git a/freebsd/sys/dev/mii/miivar.h b/freebsd/sys/dev/mii/miivar.h
index ac58ac20..34b0e9ed 100644
--- a/freebsd/sys/dev/mii/miivar.h
+++ b/freebsd/sys/dev/mii/miivar.h
@@ -83,10 +83,13 @@ struct mii_data {
typedef struct mii_data mii_data_t;
/*
- * This call is used by the MII layer to call into the PHY driver
- * to perform a `service request'.
+ * Functions provided by the PHY to perform various functions.
*/
-typedef int (*mii_downcall_t)(struct mii_softc *, struct mii_data *, int);
+struct mii_phy_funcs {
+ int (*pf_service)(struct mii_softc *, struct mii_data *, int);
+ void (*pf_status)(struct mii_softc *);
+ void (*pf_reset)(struct mii_softc *);
+};
/*
* Requests that can be made to the downcall.
@@ -105,10 +108,17 @@ struct mii_softc {
LIST_ENTRY(mii_softc) mii_list; /* entry on parent's PHY list */
+ uint32_t mii_mpd_oui; /* the PHY's OUI (MII_OUI())*/
+ uint32_t mii_mpd_model; /* the PHY's model (MII_MODEL())*/
+ uint32_t mii_mpd_rev; /* the PHY's revision (MII_REV())*/
+ u_int mii_capmask; /* capability mask for BMSR */
u_int mii_phy; /* our MII address */
+ u_int mii_offset; /* first PHY, second PHY, etc. */
u_int mii_inst; /* instance for ifmedia */
- mii_downcall_t mii_service; /* our downcall */
+ /* Our PHY functions. */
+ const struct mii_phy_funcs *mii_funcs;
+
struct mii_data *mii_pdata; /* pointer to parent's mii_data */
u_int mii_flags; /* misc. flags; see below */
@@ -124,7 +134,9 @@ typedef struct mii_softc mii_softc_t;
/* mii_flags */
#define MIIF_INITDONE 0x00000001 /* has been initialized (mii_data) */
#define MIIF_NOISOLATE 0x00000002 /* do not isolate the PHY */
+#if 0
#define MIIF_NOLOOP 0x00000004 /* no loopback capability */
+#endif
#define MIIF_DOINGAUTO 0x00000008 /* doing autonegotiation (mii_softc) */
#define MIIF_AUTOTSLEEP 0x00000010 /* use tsleep(), not callout() */
#define MIIF_HAVEFIBER 0x00000020 /* from parent: has fiber interface */
@@ -210,6 +222,15 @@ struct mii_media {
#define PHY_WRITE(p, r, v) \
MIIBUS_WRITEREG((p)->mii_dev, (p)->mii_phy, (r), (v))
+#define PHY_SERVICE(p, d, o) \
+ (*(p)->mii_funcs->pf_service)((p), (d), (o))
+
+#define PHY_STATUS(p) \
+ (*(p)->mii_funcs->pf_status)(p)
+
+#define PHY_RESET(p) \
+ (*(p)->mii_funcs->pf_reset)(p)
+
enum miibus_device_ivars {
MIIBUS_IVAR_FLAGS
};
@@ -227,13 +248,10 @@ extern driver_t miibus_driver;
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);
void mii_down(struct mii_data *);
int mii_mediachg(struct mii_data *);
void mii_tick(struct mii_data *);
void mii_pollstat(struct mii_data *);
-int mii_phy_probe(device_t, device_t *, ifm_change_cb_t, ifm_stat_cb_t);
-void mii_add_media(struct mii_softc *);
void mii_phy_add_media(struct mii_softc *);
int mii_phy_auto(struct mii_softc *);
@@ -250,8 +268,16 @@ const struct mii_phydesc * mii_phy_match(const struct mii_attach_args *ma,
const struct mii_phydesc * mii_phy_match_gen(const struct mii_attach_args *ma,
const struct mii_phydesc *mpd, size_t endlen);
int mii_phy_dev_probe(device_t dev, const struct mii_phydesc *mpd, int mrv);
+void mii_phy_dev_attach(device_t dev, u_int flags,
+ const struct mii_phy_funcs *mpf, int add_media);
void ukphy_status(struct mii_softc *);
+
+u_int mii_oui(u_int, u_int);
+#define MII_OUI(id1, id2) mii_oui(id1, id2)
+#define MII_MODEL(id2) (((id2) & IDR2_MODEL) >> 4)
+#define MII_REV(id2) ((id2) & IDR2_REV)
+
#endif /* _KERNEL */
#endif /* _DEV_MII_MIIVAR_H_ */