[rtems-libbsd commit] if_atsam: Allow fixed MII settings.

Sebastian Huber sebh at rtems.org
Fri Sep 22 12:41:34 UTC 2017


Module:    rtems-libbsd
Branch:    master
Commit:    c6f4aa65ffd809b56e23843bec9451a325caf061
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=c6f4aa65ffd809b56e23843bec9451a325caf061

Author:    Christian Mauderer <Christian.Mauderer at embedded-brains.de>
Date:      Fri Sep 22 09:41:20 2017 +0200

if_atsam: Allow fixed MII settings.

---

 libbsd.py                               |   1 +
 libbsd_waf.py                           |   1 +
 rtemsbsd/include/rtems/bsd/if_atsam.h   |  53 +++++++++
 rtemsbsd/sys/dev/atsam/if_atsam.c       | 194 +++++++++++++++++++++-----------
 rtemsbsd/sys/dev/atsam/if_atsam_media.c |  44 ++++++++
 5 files changed, 228 insertions(+), 65 deletions(-)

diff --git a/libbsd.py b/libbsd.py
index 78d65e7..536ed5f 100644
--- a/libbsd.py
+++ b/libbsd.py
@@ -161,6 +161,7 @@ def rtems(mm):
             'sys/dev/smc/if_smc_nexus.c',
             'sys/dev/ffec/if_ffec_mcf548x.c',
             'sys/dev/atsam/if_atsam.c',
+            'sys/dev/atsam/if_atsam_media.c',
             'sys/dev/dw_mmc/dw_mmc.c',
             'sys/fs/devfs/devfs_devs.c',
             'sys/net/if_ppp.c',
diff --git a/libbsd_waf.py b/libbsd_waf.py
index fe24e71..e5d07a6 100644
--- a/libbsd_waf.py
+++ b/libbsd_waf.py
@@ -2222,6 +2222,7 @@ def build(bld):
               'rtemsbsd/rtems/rtems-routes.c',
               'rtemsbsd/rtems/syslog.c',
               'rtemsbsd/sys/dev/atsam/if_atsam.c',
+              'rtemsbsd/sys/dev/atsam/if_atsam_media.c',
               'rtemsbsd/sys/dev/dw_mmc/dw_mmc.c',
               'rtemsbsd/sys/dev/ffec/if_ffec_mcf548x.c',
               'rtemsbsd/sys/dev/input/touchscreen/tsc_lpc32xx.c',
diff --git a/rtemsbsd/include/rtems/bsd/if_atsam.h b/rtemsbsd/include/rtems/bsd/if_atsam.h
new file mode 100644
index 0000000..15e2ff6
--- /dev/null
+++ b/rtemsbsd/include/rtems/bsd/if_atsam.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#ifndef RTEMS_BSD_IF_ATSAM_H
+#define RTEMS_BSD_IF_ATSAM_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * If @a is_fixed is set to true, no mii bus will be instantiated. Instead a
+ * fake medium with @a media (for example IFM_100_TX) and @a duplex (for
+ * example IFM_HDX) will be used.
+ */
+void	rtems_bsd_if_atsam_get_if_media_props(const char *name, int unit,
+	    bool *is_fixed, uint32_t *media, uint32_t *duplex);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_BSD_IF_ATSAM_H */
diff --git a/rtemsbsd/sys/dev/atsam/if_atsam.c b/rtemsbsd/sys/dev/atsam/if_atsam.c
index d597549..794937b 100644
--- a/rtemsbsd/sys/dev/atsam/if_atsam.c
+++ b/rtemsbsd/sys/dev/atsam/if_atsam.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2016 - 2017 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -64,8 +64,8 @@
 #include <libchip/include/gmacd.h>
 #include <libchip/include/pio.h>
 
-#include <rtems/rtems_mii_ioctl.h>
 #include <rtems/bsd/local/miibus_if.h>
+#include <rtems/bsd/if_atsam.h>
 
 /*
  * Number of interfaces supported by the driver
@@ -130,7 +130,6 @@
 #define TXBUF_COUNT 64
 #define IGNORE_RX_ERR false
 
-
 /** The PINs for GMAC */
 static const Pin gmacPins[] = { BOARD_GMAC_RUN_PINS };
 
@@ -171,7 +170,15 @@ typedef struct if_atsam_softc {
 	struct callout tick_ch;
 
 	/*
-	 * mii bus
+	 * Settings for a fixed speed.
+	 */
+	bool fixed_speed;
+	uint32_t media;
+	uint32_t duplex;
+	struct ifmedia ifmedia;
+
+	/*
+	 * MII bus (only used if no fixed speed)
 	 */
 	device_t miibus;
 	uint8_t link_speed;
@@ -285,7 +292,6 @@ static struct mbuf *if_atsam_new_mbuf(struct ifnet *ifp)
 	return (m);
 }
 
-
 static uint8_t if_atsam_wait_phy(Gmac *pHw, uint32_t retry)
 {
 	volatile uint32_t retry_count = 0;
@@ -331,35 +337,6 @@ if_atsam_read_phy(Gmac *pHw,
 }
 
 
-static uint8_t
-if_atsam_init_phy(if_atsam_gmac *gmac_inst, uint32_t mck,
-    const Pin *pResetPins, uint32_t nbResetPins, const Pin *pGmacPins,
-    uint32_t nbGmacPins)
-{
-	uint8_t rc = 1;
-	Gmac *pHw = gmac_inst->gGmacd.pHw;
-
-	/* Perform RESET */
-	if (pResetPins) {
-		/* Configure PINS */
-		PIO_Configure(pResetPins, nbResetPins);
-		PIO_Clear(pResetPins);
-		rtems_task_wake_after(1);
-		PIO_Set(pResetPins);
-	}
-	/* Configure GMAC runtime pins */
-	if (rc) {
-		PIO_Configure(pGmacPins, nbGmacPins);
-		rc = GMAC_SetMdcClock(pHw, mck);
-
-		if (!rc) {
-			return (0);
-		}
-	}
-	return (rc);
-}
-
-
 static int
 if_atsam_miibus_readreg(device_t dev, int phy, int reg)
 {
@@ -391,6 +368,35 @@ if_atsam_miibus_writereg(device_t dev, int phy, int reg, int data)
 }
 
 
+static uint8_t
+if_atsam_init_phy(if_atsam_gmac *gmac_inst, uint32_t mck,
+    const Pin *pResetPins, uint32_t nbResetPins, const Pin *pGmacPins,
+    uint32_t nbGmacPins)
+{
+	uint8_t rc = 1;
+	Gmac *pHw = gmac_inst->gGmacd.pHw;
+
+	/* Perform RESET */
+	if (pResetPins) {
+		/* Configure PINS */
+		PIO_Configure(pResetPins, nbResetPins);
+		PIO_Clear(pResetPins);
+		rtems_task_wake_after(1);
+		PIO_Set(pResetPins);
+	}
+	/* Configure GMAC runtime pins */
+	if (rc) {
+		PIO_Configure(pGmacPins, nbGmacPins);
+		rc = GMAC_SetMdcClock(pHw, mck);
+
+		if (!rc) {
+			return (0);
+		}
+	}
+	return (rc);
+}
+
+
 /*
  * Interrupt Handler for the network driver
  */
@@ -821,35 +827,52 @@ static void if_atsam_enet_start(struct ifnet *ifp)
 }
 
 
-static void if_atsam_miibus_statchg(device_t dev)
+static uint8_t if_atsam_get_gmac_linkspeed_from_media(uint32_t media_subtype)
 {
-	uint8_t link_speed = GMAC_SPEED_100M;
-	uint8_t link_duplex = GMAC_DUPLEX_FULL;
-	if_atsam_softc *sc = device_get_softc(dev);
-	struct mii_data *mii = device_get_softc(sc->miibus);
-
-	Gmac *pHw = sc->Gmac_inst.gGmacd.pHw;
-
-	if (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) {
-		link_duplex = GMAC_DUPLEX_FULL;
-	} else {
-		link_duplex = GMAC_DUPLEX_HALF;
-	}
-
-	switch (IFM_SUBTYPE(mii->mii_media_active)) {
+	switch (media_subtype) {
 	case IFM_10_T:
-		link_speed = GMAC_SPEED_10M;
+		return GMAC_SPEED_10M;
 		break;
 	case IFM_100_TX:
-		link_speed = GMAC_SPEED_100M;
+		return GMAC_SPEED_100M;
 		break;
 	case IFM_1000_T:
-		link_speed = GMAC_SPEED_1000M;
+		return GMAC_SPEED_1000M;
 		break;
 	default:
-		/* FIXME: What to do in that case? */
+		return 0xFF;
 		break;
 	}
+}
+
+
+static uint8_t if_atsam_get_gmac_duplex_from_media(uint32_t media_options)
+{
+	if (media_options & IFM_FDX) {
+		return GMAC_DUPLEX_FULL;
+	} else {
+		return GMAC_DUPLEX_HALF;
+	}
+}
+
+
+static void if_atsam_miibus_statchg(device_t dev)
+{
+	uint8_t link_speed = GMAC_SPEED_100M;
+	uint8_t link_duplex = GMAC_DUPLEX_FULL;
+	if_atsam_softc *sc = device_get_softc(dev);
+	struct mii_data *mii = device_get_softc(sc->miibus);
+
+	if(sc->fixed_speed)
+		return;
+
+	Gmac *pHw = sc->Gmac_inst.gGmacd.pHw;
+
+	link_duplex = if_atsam_get_gmac_duplex_from_media(
+	    IFM_OPTIONS(mii->mii_media_active));
+
+	link_speed = if_atsam_get_gmac_linkspeed_from_media(
+	    IFM_SUBTYPE(mii->mii_media_active));
 
 	if (sc->link_speed != link_speed || sc->link_duplex != link_duplex) {
 		GMAC_SetLinkSpeed(pHw, link_speed, link_duplex);
@@ -866,7 +889,7 @@ if_atsam_mii_ifmedia_upd(struct ifnet *ifp)
 	struct mii_data *mii;
 
 	sc = ifp->if_softc;
-	if (sc->miibus == NULL)
+	if (sc->fixed_speed || sc->miibus == NULL)
 		return (ENXIO);
 
 	mii = device_get_softc(sc->miibus);
@@ -881,7 +904,7 @@ if_atsam_mii_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 	struct mii_data *mii;
 
 	sc = ifp->if_softc;
-	if (sc->miibus == NULL)
+	if (sc->fixed_speed || sc->miibus == NULL)
 		return;
 
 	mii = device_get_softc(sc->miibus);
@@ -891,6 +914,24 @@ if_atsam_mii_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 }
 
 
+static int
+if_atsam_media_change(struct ifnet *ifp __unused)
+{
+	/* Do nothing. */
+	return (0);
+}
+
+
+static void
+if_atsam_media_status(struct ifnet *ifp, struct ifmediareq *imr)
+{
+	if_atsam_softc *sc = (if_atsam_softc *)ifp->if_softc;
+
+	imr->ifm_status = IFM_AVALID | IFM_ACTIVE;
+	imr->ifm_active = IFM_ETHER | sc->media | sc->duplex;
+}
+
+
 static void
 if_atsam_tick(void *context)
 {
@@ -900,7 +941,9 @@ if_atsam_tick(void *context)
 
 	IF_ATSAM_UNLOCK(sc);
 
-	mii_tick(device_get_softc(sc->miibus));
+	if (!sc->fixed_speed) {
+		mii_tick(device_get_softc(sc->miibus));
+	}
 	callout_reset(&sc->tick_ch, hz, if_atsam_tick, sc);
 }
 
@@ -1285,13 +1328,17 @@ static void if_atsam_promiscuous_mode(if_atsam_softc *sc, bool enable)
 static int
 if_atsam_mediaioctl(if_atsam_softc *sc, struct ifreq *ifr, u_long command)
 {
-	struct mii_data *mii;
+	if (sc->fixed_speed) {
+		return ifmedia_ioctl(sc->ifp, ifr, &sc->ifmedia, command);
+	} else {
+		struct mii_data *mii;
 
-	if (sc->miibus == NULL)
-		return (EINVAL);
+		if (sc->miibus == NULL)
+			return (EINVAL);
 
-	mii = device_get_softc(sc->miibus);
-	return (ifmedia_ioctl(sc->ifp, ifr, &mii->mii_media, command));
+		mii = device_get_softc(sc->miibus);
+		return (ifmedia_ioctl(sc->ifp, ifr, &mii->mii_media, command));
+	}
 }
 
 
@@ -1353,6 +1400,8 @@ static int if_atsam_driver_attach(device_t dev)
 	mtx_init(&sc->mtx, device_get_nameunit(sc->dev), MTX_NETWORK_LOCK,
 	    MTX_DEF);
 
+	rtems_bsd_if_atsam_get_if_media_props(device_get_name(sc->dev), unit,
+	    &sc->fixed_speed, &sc->media, &sc->duplex);
 	rtems_bsd_get_mac_address(device_get_name(sc->dev), unit, eaddr);
 
 	sc->Gmac_inst.retries = MDIO_RETRIES;
@@ -1384,9 +1433,24 @@ static int if_atsam_driver_attach(device_t dev)
 	 * MII Bus
 	 */
 	callout_init_mtx(&sc->tick_ch, &sc->mtx, CALLOUT_RETURNUNLOCKED);
-	mii_attach(dev, &sc->miibus, ifp,
-	    if_atsam_mii_ifmedia_upd, if_atsam_mii_ifmedia_sts, BMSR_DEFCAPMASK,
-	    MDIO_PHY, MII_OFFSET_ANY, 0);
+	if (!sc->fixed_speed) {
+		mii_attach(dev, &sc->miibus, ifp, if_atsam_mii_ifmedia_upd,
+		    if_atsam_mii_ifmedia_sts, BMSR_DEFCAPMASK,
+		    MDIO_PHY, MII_OFFSET_ANY, 0);
+	} else {
+		ifmedia_init(&sc->ifmedia, 0, if_atsam_media_change,
+		    if_atsam_media_status);
+		ifmedia_add(&sc->ifmedia, IFM_ETHER | sc->media
+		    | sc->duplex, 0, NULL);
+		ifmedia_set(&sc->ifmedia, IFM_ETHER | sc->media
+		    | sc->duplex);
+
+		GMAC_SetLinkSpeed(sc->Gmac_inst.gGmacd.pHw,
+		    if_atsam_get_gmac_linkspeed_from_media(sc->media),
+		    if_atsam_get_gmac_duplex_from_media(sc->duplex));
+
+		if_link_state_change(sc->ifp, LINK_STATE_UP);
+	}
 
 	/*
 	 * Set up network interface values
@@ -1443,9 +1507,9 @@ static driver_t if_atsam_nexus_driver = {
 
 static devclass_t if_atsam_devclass;
 DRIVER_MODULE(if_atsam, nexus, if_atsam_nexus_driver, if_atsam_devclass, 0, 0);
-MODULE_DEPEND(if_atsam, miibus, 1, 1, 1);
 MODULE_DEPEND(if_atsam, nexus, 1, 1, 1);
 MODULE_DEPEND(if_atsam, ether, 1, 1, 1);
+MODULE_DEPEND(if_atsam, miibus, 1, 1, 1);
 DRIVER_MODULE(miibus, if_atsam, miibus_driver, miibus_devclass, NULL, NULL);
 
 #endif /* LIBBSP_ARM_ATSAM_BSP_H */
diff --git a/rtemsbsd/sys/dev/atsam/if_atsam_media.c b/rtemsbsd/sys/dev/atsam/if_atsam_media.c
new file mode 100644
index 0000000..e6ea3db
--- /dev/null
+++ b/rtemsbsd/sys/dev/atsam/if_atsam_media.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <rtems/bsd/if_atsam.h>
+#include <net/if_media.h>
+
+void
+rtems_bsd_if_atsam_get_if_media_props(const char *name, int unit,
+    bool *is_fixed, uint32_t *media, uint32_t *duplex)
+{
+	(void) name;
+	(void) unit;
+	*is_fixed = false;
+	*media = IFM_100_TX;
+	*duplex = IFM_HDX;
+}



More information about the vc mailing list