diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-02-19 19:55:40 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-02-19 19:55:40 +0000 |
commit | 89376b7141edb6f927fb940c27391cda6e67c785 (patch) | |
tree | 57dd01fd9328b879289493ba848ae5c34c607b91 /bsd_eth_drivers/libbsdport/ifmedia.c | |
download | libbsdport-89376b7141edb6f927fb940c27391cda6e67c785.tar.bz2 |
Initial import.initial
Diffstat (limited to 'bsd_eth_drivers/libbsdport/ifmedia.c')
-rw-r--r-- | bsd_eth_drivers/libbsdport/ifmedia.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/bsd_eth_drivers/libbsdport/ifmedia.c b/bsd_eth_drivers/libbsdport/ifmedia.c new file mode 100644 index 0000000..77c3bd3 --- /dev/null +++ b/bsd_eth_drivers/libbsdport/ifmedia.c @@ -0,0 +1,91 @@ +#include <rtems.h> +#define _KERNEL +#include <rtems/rtems_bsdnet.h> +#include <rtems/rtems_bsdnet_internal.h> + +#include <bsp/rtems_verscheck.h> + +#if RTEMS_REV_AT_LEAST(4,8,99) +#include <rtems/bsd/sys/queue.h> +#else +#include <sys/queue.h> +#endif + +#include <sys/malloc.h> +#include <sys/errno.h> +#include <sys/socket.h> +#include <sys/sockio.h> +#include <net/if.h> +#include <net/if_media.h> +#include <rtems/rtems_mii_ioctl.h> + +void +ifmedia_init(struct ifmedia *ifm, int dontcare_mask, + ifm_change_cb_t change_callback, ifm_stat_cb_t status_callback) +{ + ifm->ifm_mask = dontcare_mask; + ifm->ifm_media = 0; + ifm->ifm_cur = 0; + ifm->ifm_list.lh_first = NULL; + ifm->ifm_change = change_callback; + ifm->ifm_status = status_callback; +} + +void +ifmedia_add(struct ifmedia *ifm, int mword, int data, void *aux) +{ +struct ifmedia_entry *ifmen, *ifmep, *ifme; + if ( ( ifme = malloc(sizeof(*ifme), M_DEVBUF, M_NOWAIT) ) ) { + ifme->ifm_media = mword; + ifme->ifm_data = data; + ifme->ifm_aux = aux; + for ( ifmep = LIST_FIRST(&ifm->ifm_list); ifmep; ifmep = ifmen ) { + if ( !(ifmen = LIST_NEXT(ifmep, ifm_list)) ) + break; + } + if ( ifmep ) + LIST_INSERT_AFTER(ifmep, ifme, ifm_list); + else + LIST_INSERT_HEAD( &ifm->ifm_list, ifme, ifm_list); + } +} + +int +ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm, u_long cmd) +{ +int rval = 0; +struct ifmediareq ifmr; + if ( SIOCGIFMEDIA == cmd ) { + if ( !ifm->ifm_status ) + return ENOTSUP; + ifm->ifm_status(ifp, &ifmr); + if ( ! (IFM_AVALID & ifmr.ifm_status) ) + return EINVAL; + /* translate */ + ifr->ifr_media = ifmr.ifm_active; + if ( IFM_ACTIVE & ifmr.ifm_status ) + ifr->ifr_media |= IFM_LINK_OK; + /* no way to determine if autoneg is forcefully disabled + * from ifmr :-( + * Look at current ifm_media for now. + */ + if ( IFM_SUBTYPE(ifm->ifm_media) != IFM_AUTO ) + ifr->ifr_media |= IFM_ANEG_DIS; + } else { + if ( !ifm->ifm_change ) + return ENOTSUP; + ifm->ifm_media = ifr->ifr_media; + rval = ifm->ifm_change(ifp); + } + return rval; +} + +void +ifmedia_set(struct ifmedia *ifm, int mword) +{ + ifm->ifm_media = mword; + /* cannot invoke the ifm_change callback because we have + * no ifp here. + */ +} + |