diff options
author | Christian Mauderer <Christian.Mauderer@embedded-brains.de> | 2017-09-22 09:41:20 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-09-22 10:19:25 +0200 |
commit | c6f4aa65ffd809b56e23843bec9451a325caf061 (patch) | |
tree | 88b7681ca8e6160e4d8c9a206b03ed1fc162b7be /rtemsbsd/sys | |
parent | if_atsam: Move statistics to sysctl. (diff) | |
download | rtems-libbsd-c6f4aa65ffd809b56e23843bec9451a325caf061.tar.bz2 |
if_atsam: Allow fixed MII settings.
Diffstat (limited to 'rtemsbsd/sys')
-rw-r--r-- | rtemsbsd/sys/dev/atsam/if_atsam.c | 194 | ||||
-rw-r--r-- | rtemsbsd/sys/dev/atsam/if_atsam_media.c | 44 |
2 files changed, 173 insertions, 65 deletions
diff --git a/rtemsbsd/sys/dev/atsam/if_atsam.c b/rtemsbsd/sys/dev/atsam/if_atsam.c index d5975498..794937be 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 00000000..e6ea3dbf --- /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@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; +} |