diff options
Diffstat (limited to 'cpukit/libnetworking/rtems/rtems_mii_ioctl.c')
-rw-r--r-- | cpukit/libnetworking/rtems/rtems_mii_ioctl.c | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/cpukit/libnetworking/rtems/rtems_mii_ioctl.c b/cpukit/libnetworking/rtems/rtems_mii_ioctl.c new file mode 100644 index 0000000000..93e9a0d580 --- /dev/null +++ b/cpukit/libnetworking/rtems/rtems_mii_ioctl.c @@ -0,0 +1,172 @@ +/* $Id$ */ + +/* Simple (default) implementation for SIOCGIFMEDIA/SIOCSIFMEDIA + * to be used by ethernet drivers [from their ioctl]. + * + * USERSPACE UTILITIES + * + * NOTE: This much simpler than the BSD ifmedia API + */ + +/* + * Authorship + * ---------- + * This software was created by + * Till Straumann <strauman@slac.stanford.edu>, 2005, + * Stanford Linear Accelerator Center, Stanford University. + * + * Acknowledgement of sponsorship + * ------------------------------ + * This software was produced by + * the Stanford Linear Accelerator Center, Stanford University, + * under Contract DE-AC03-76SFO0515 with the Department of Energy. + * + * Government disclaimer of liability + * ---------------------------------- + * Neither the United States nor the United States Department of Energy, + * nor any of their employees, makes any warranty, express or implied, or + * assumes any legal liability or responsibility for the accuracy, + * completeness, or usefulness of any data, apparatus, product, or process + * disclosed, or represents that its use would not infringe privately owned + * rights. + * + * Stanford disclaimer of liability + * -------------------------------- + * Stanford University makes no representations or warranties, express or + * implied, nor assumes any liability for the use of this software. + * + * Stanford disclaimer of copyright + * -------------------------------- + * Stanford University, owner of the copyright, hereby disclaims its + * copyright and all other rights in this software. Hence, anyone may + * freely use it for any purpose without restriction. + * + * Maintenance of notices + * ---------------------- + * In the interest of clarity regarding the origin and status of this + * SLAC software, this and all the preceding Stanford University notices + * are to remain affixed to any copy or derivative of this software made + * or distributed by the recipient and are to be affixed to any copy of + * software made or distributed by the recipient that contains a copy or + * derivative of this software. + * + * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 + */ + +#include <rtems.h> +#include <inttypes.h> + +#undef _KERNEL + +#include <rtems/rtems_mii_ioctl.h> + +#include <stdlib.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +static struct ifmedia_description shared_media_strings[] = + IFM_SUBTYPE_SHARED_DESCRIPTIONS; +static struct ifmedia_description ethern_media_strings[] = + IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; +static struct ifmedia_description eth_al_media_strings[] = + IFM_SUBTYPE_ETHERNET_ALIASES; + +static const char * +find_desc (int tag, struct ifmedia_description *list) +{ + while (list->ifmt_string && tag != list->ifmt_word) + list++; + return list->ifmt_string; +} + +#define WHATPRINT(buf,sz,fmt...) \ + ( (sz) > 0 ? snprintf((buf),(sz),fmt) : fprintf((buf) ? (FILE*)(buf) : stdout, fmt) ) + +int +rtems_ifmedia2str (int media, char *buf, int bufsz) +{ + const char *mdesc; + const char *dupdesc = 0; + + /* only ethernet supported, so far */ + if (IFM_ETHER != IFM_TYPE (media)) + return -1; + + if (!(mdesc = find_desc (IFM_SUBTYPE (media), shared_media_strings))) + mdesc = find_desc (IFM_SUBTYPE (media), ethern_media_strings); + + if (!mdesc) + return -1; + + if (IFM_NONE != IFM_SUBTYPE (media)) + dupdesc = IFM_FDX & media ? " full-duplex" : " half-duplex"; + + return WHATPRINT (buf, bufsz, + "Ethernet [phy instance: %" PRId32 "]: (link %s, autoneg %s) -- media: %s%s", + (int32_t) IFM_INST (media), + IFM_LINK_OK & media ? "ok" : "down", + IFM_ANEG_DIS & media ? "off" : "on", + mdesc, dupdesc ? dupdesc : ""); +} + +static int +find_tag (const char *desc, struct ifmedia_description *list) +{ + while (list->ifmt_string) { + if (strstr (desc, list->ifmt_string)) + return list->ifmt_word; + list++; + } + return -1; +} + + +/* convert a string to a media word + * RETURNS: 0 on failure; valid results have always at least IFM_ETHER set + */ +int +rtems_str2ifmedia (const char *str, int phy) +{ + int sub, opt = 0; + char *chpt; + + if (!strncmp (str, "auto", 4)) { + sub = IFM_AUTO; + } else if ((sub = find_tag (str, ethern_media_strings)) < 0) { + if ((sub = find_tag (str, eth_al_media_strings)) < 0) { + /* allow more */ + + /* if no number, 0 is returned which will not pass the test */ + switch (strtol (str, &chpt, 10)) { + case 10: + sub = IFM_10_T; + break; + case 100: + sub = IFM_100_TX; + break; + case 1000: + sub = IFM_1000_T; + break; + default: + return 0; + } + + /* need 'b' or 'base' */ + if ('b' != *chpt++) + return 0; + if (!strncmp (chpt, "ase", 3)) + chpt += 3; + if (toupper ((unsigned char)*chpt++) != 'T') + return 0; + if (IFM_100_TX == sub && toupper ((unsigned char)*chpt++) != 'X') + return 0; + } + } + + if (strstr (str, "full") || strstr (str, "FDX") || strstr (str, "fdx")) + opt |= IFM_FDX; + + return IFM_MAKEWORD (IFM_ETHER, sub, opt, phy); +} |