Date: Sun, 26 Apr 2015 15:40:59 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r282021 - projects/ifnet/sys/net Message-ID: <201504261540.t3QFexFv000257@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Sun Apr 26 15:40:58 2015 New Revision: 282021 URL: https://svnweb.freebsd.org/changeset/base/282021 Log: Tie ifmedia to the generic framework of new ifnet KPI. Implementation: o struct if_media goes opaque into if_media.c o ifmedia is an optional softc (keyword IF_MEDIA) of an interface. o if_media.h declares just preprocessor defines to manipulate media bits. Since a conservative decision was taken in r281236, the media information remains a single 32-bit word. However, to improve type checking it is declared as if_media_t, not a bare integer. if_media.h is now automatically included from if.h o if_attach() calls ifmedia_alloc(). if_free() calls ifmedia_free(). Driver changes: o Drivers supply ifop_media_change and ifop_media_status callbacks in their ifdriver ifops. This were arguments to ifmedia_init() before. The ifop_media_change() callback gets additional argument of the new media, we are trying to swtich to. o On attach, drivers supply array of supported media words in ifat_mediae, currently chose media in ifat_media and optional ifat_mediamask. Drivers may change the media array later via if_media_change(). o Drivers don't need to support SIOCSIFMEDIA, SIOCGIFMEDIA. The stack does now. o Drivers may call if_media_status() if they are running autonegotiation and wish to report new status. The function updates link state and baudrate of the interface. Sponsored by: Netflix Sponsored by: Nginx, Inc. Modified: projects/ifnet/sys/net/if.c projects/ifnet/sys/net/if.h projects/ifnet/sys/net/if_media.c projects/ifnet/sys/net/if_media.h Modified: projects/ifnet/sys/net/if.c ============================================================================== --- projects/ifnet/sys/net/if.c Sun Apr 26 12:24:42 2015 (r282020) +++ projects/ifnet/sys/net/if.c Sun Apr 26 15:40:58 2015 (r282021) @@ -100,6 +100,11 @@ #include <compat/freebsd32/freebsd32.h> #endif +/* Interface media functions, living in if_media.c. */ +extern void ifmedia_alloc(struct ifnet *, struct if_attach_args *); +extern void ifmedia_free(struct ifnet *); +extern int ifmedia_ioctl(struct ifnet *, struct ifreq *, u_long); + SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers"); SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management"); @@ -543,6 +548,7 @@ if_attach(struct if_attach_args *ifat) mac_ifnet_init(ifp); mac_ifnet_create(ifp); #endif + rw_init(&ifp->if_lock, "if_lock"); ifp->if_ops = &ifdrv->ifdrv_ops; ifp->if_drv = ifdrv; @@ -558,6 +564,13 @@ if_attach(struct if_attach_args *ifat) COPY(baudrate); #undef COPY + if (ifat->ifat_mediae) { + KASSERT(ifp->if_ops->ifop_media_change != NULL && + ifp->if_ops->ifop_media_status != NULL, + ("%s: media array but no callbacks", ifdrv->ifdrv_name)); + ifmedia_alloc(ifp, ifat); + } + if (ifat->ifat_tsomax) { /* * Driver wants dynamic tsomax on this interface, we @@ -578,7 +591,6 @@ if_attach(struct if_attach_args *ifat) if (ifdrv->ifdrv_maxqlen > 0) ifp->if_snd = if_snd_alloc(ifdrv->ifdrv_maxqlen); - rw_init(&ifp->if_lock, "if_lock"); IF_AFDATA_LOCK_INIT(ifp); TASK_INIT(&ifp->if_linktask, 0, do_link_state_change, ifp); TAILQ_INIT(&ifp->if_addrhead); @@ -670,6 +682,8 @@ if_free_internal(struct ifnet *ifp) if (ifp->if_tsomax != ifp->if_drv->ifdrv_tsomax) free(ifp->if_tsomax, M_IFNET); + ifmedia_free(ifp); + free(ifp, M_IFNET); } @@ -2749,7 +2763,6 @@ if_drvioctl(struct ifnet *ifp, u_long cm #ifdef INET6 case SIOCSIFPHYADDR_IN6: #endif - case SIOCSIFMEDIA: case SIOCSIFGENERIC: error = priv_check(td, PRIV_NET_HWIOCTL); if (error) @@ -2762,8 +2775,6 @@ if_drvioctl(struct ifnet *ifp, u_long cm case SIOCGIFSTATUS: case SIOCGIFPSRCADDR: case SIOCGIFPDSTADDR: - case SIOCGIFMEDIA: - case SIOCGIFXMEDIA: case SIOCGIFGENERIC: error = if_ioctl(ifp, cmd, data, td); break; @@ -2806,6 +2817,15 @@ if_drvioctl(struct ifnet *ifp, u_long cm break; } + case SIOCSIFMEDIA: + error = priv_check(td, PRIV_NET_HWIOCTL); + if (error) + return (error); + /* FALLTHROUGH */ + case SIOCGIFMEDIA: + case SIOCGIFXMEDIA: + return (ifmedia_ioctl(ifp, ifr, cmd)); + default: error = ENOIOCTL; break; Modified: projects/ifnet/sys/net/if.h ============================================================================== --- projects/ifnet/sys/net/if.h Sun Apr 26 12:24:42 2015 (r282020) +++ projects/ifnet/sys/net/if.h Sun Apr 26 15:40:58 2015 (r282021) @@ -539,6 +539,7 @@ __END_DECLS #ifdef _KERNEL #include <net/if_types.h> +#include <net/if_media.h> /* * Under _KERNEL there live declarations from net/if.c, that are public * and available to network device drivers. Declarations that are protected @@ -586,6 +587,7 @@ typedef enum { IF_CARP, IF_VLAN, IF_TOEDEV, + IF_MEDIA, /* * Space above 99999 is split among different vendors. * @@ -603,6 +605,8 @@ typedef int (*if_output_t)(if_t, struct typedef int (*if_ioctl_t)(if_t, u_long, void *, struct thread *); typedef uint64_t (*if_get_counter_t)(if_t, ift_counter); typedef void (*if_qflush_t)(if_t); +typedef int (*if_media_change_t)(if_t, if_media_t); +typedef void (*if_media_status_t)(if_t, struct ifmediareq *); typedef int (*if_resolvemulti_t)(if_t, struct sockaddr **, struct sockaddr *); typedef void (*if_reassign_t)(if_t, struct vnet *); @@ -623,6 +627,8 @@ struct ifops { if_ioctl_t ifop_ioctl; /* ioctl routine */ if_get_counter_t ifop_get_counter; /* get counter values */ if_qflush_t ifop_qflush; /* flush any queue */ + if_media_change_t ifop_media_change; /* change media */ + if_media_status_t ifop_media_status; /* query media */ if_resolvemulti_t ifop_resolvemulti; /* validate/resolve multicast */ if_reassign_t ifop_reassign; /* reassign to vnet routine */ if_vlan_event_t ifop_vlan_event;/* VLAN config/unconfig */ @@ -694,11 +700,18 @@ struct if_attach_args { #define IFAT_DUNIT_NONE (-1) char * ifat_name; /* If driver wants a specific name. */ /* - * Variables that may differ between two instances of a same - * driver, but are constant within instance lifetime. + * Capabilities can be different for two interfaces of the same + * driver, e.g. different chip revisions. */ uint64_t ifat_capabilities; /* + * Pointer to static array of supported mediae, current media + * word, and ignore mask for ifmedia_match(). + */ + if_media_t *ifat_mediae; + if_media_t ifat_media; + if_media_t ifat_mediamask; + /* * MTU, flags, capabilities at attach time. Driver * can change them later. */ @@ -732,6 +745,12 @@ int if_drvioctl(if_t, u_long, void *, st uint64_t if_get_counter_default(if_t, ift_counter); /* + * Interface media manipulation by drivers. + */ +void if_media_status(if_t, if_media_t); +void if_media_change(if_t, if_media_t *, if_media_t); + +/* * Interface if_ops that are available for drivers. */ void if_input_noinline(if_t, struct mbuf *); Modified: projects/ifnet/sys/net/if_media.c ============================================================================== --- projects/ifnet/sys/net/if_media.c Sun Apr 26 12:24:42 2015 (r282020) +++ projects/ifnet/sys/net/if_media.c Sun Apr 26 15:40:58 2015 (r282021) @@ -1,6 +1,3 @@ -/* $NetBSD: if_media.c,v 1.1 1997/03/17 02:55:15 thorpej Exp $ */ -/* $FreeBSD$ */ - /*- * Copyright (c) 1997 * Jonathan Stone and Jason R. Thorpe. All rights reserved. @@ -33,218 +30,106 @@ * 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. - */ - -/* - * BSD/OS-compatible network interface media selection. * - * Where it is safe to do so, this code strays slightly from the BSD/OS - * design. Software which uses the API (device drivers, basically) - * shouldn't notice any difference. - * - * Many thanks to Matt Thomas for providing the information necessary - * to implement this interface. + * $NetBSD: if_media.c,v 1.1 1997/03/17 02:55:15 thorpej Exp $ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #include "opt_ifmedia.h" #include <sys/param.h> #include <sys/systm.h> #include <sys/socket.h> #include <sys/sockio.h> +#include <sys/kernel.h> #include <sys/malloc.h> #include <sys/module.h> #include <sys/sysctl.h> #include <net/if.h> -#include <net/if_media.h> +#include <net/if_var.h> -/* - * Compile-time options: - * IFMEDIA_DEBUG: - * turn on implementation-level debug printfs. - * Useful for debugging newly-ported drivers. - */ +static MALLOC_DEFINE(M_IFMEDIA, "if_media", "interface media info"); -static struct ifmedia_entry *ifmedia_match(struct ifmedia *ifm, - int flags, int mask); +struct ifmedia { + if_media_t ifm_media; /* current user-set media word */ + if_media_t ifm_mask; /* mask of changes we don't care */ + if_media_t *ifm_array; /* array of all supported mediae */ + if_media_t *ifm_cur; /* currently selected media */ +}; +void ifmedia_alloc(struct ifnet *, struct if_attach_args *); +void ifmedia_free(struct ifnet *); +int ifmedia_ioctl(struct ifnet *, struct ifreq *, u_long); + +static if_media_t * ifmedia_match(struct ifmedia *, if_media_t); +static if_media_t ifmedia_compat(if_media_t media); +static uint64_t ifmedia_baudrate(if_media_t); +static int ifmedia_link_state(u_int); #ifdef IFMEDIA_DEBUG -#include <net/if_var.h> -int ifmedia_debug = 0; -SYSCTL_INT(_debug, OID_AUTO, ifmedia, CTLFLAG_RW, &ifmedia_debug, - 0, "if_media debugging msgs"); -static void ifmedia_printword(int); +static void ifmedia_printword(int); +static int ifmedia_debug; #endif /* - * Initialize if_media struct for a specific interface instance. + * Called by if_attach(), if interface reports media. */ void -ifmedia_init(ifm, dontcare_mask, change_callback, status_callback) - struct ifmedia *ifm; - int dontcare_mask; - ifm_change_cb_t change_callback; - ifm_stat_cb_t status_callback; +ifmedia_alloc(struct ifnet *ifp, struct if_attach_args *ifat) { - - LIST_INIT(&ifm->ifm_list); - ifm->ifm_cur = NULL; - ifm->ifm_media = 0; - ifm->ifm_mask = dontcare_mask; /* IF don't-care bits */ - ifm->ifm_change = change_callback; - ifm->ifm_status = status_callback; -} - -void -ifmedia_removeall(ifm) - struct ifmedia *ifm; -{ - struct ifmedia_entry *entry; - - for (entry = LIST_FIRST(&ifm->ifm_list); entry; - entry = LIST_FIRST(&ifm->ifm_list)) { - LIST_REMOVE(entry, ifm_list); - free(entry, M_IFADDR); - } -} - -/* - * Add a media configuration to the list of supported media - * for a specific interface instance. - */ -void -ifmedia_add(ifm, mword, data, aux) struct ifmedia *ifm; - int mword; - int data; - void *aux; -{ - register struct ifmedia_entry *entry; - -#ifdef IFMEDIA_DEBUG - if (ifmedia_debug) { - if (ifm == NULL) { - printf("ifmedia_add: null ifm\n"); - return; - } - printf("Adding entry for "); - ifmedia_printword(mword); - } -#endif - entry = malloc(sizeof(*entry), M_IFADDR, M_NOWAIT); - if (entry == NULL) - panic("ifmedia_add: can't malloc entry"); - - entry->ifm_media = mword; - entry->ifm_data = data; - entry->ifm_aux = aux; + ifm = malloc(sizeof(struct ifmedia), M_IFMEDIA, M_WAITOK); + ifm->ifm_array = ifat->ifat_mediae; + ifm->ifm_mask = ifat->ifat_mediamask; + ifm->ifm_cur = ifmedia_match(ifm, ifat->ifat_media); + ifm->ifm_media = *ifm->ifm_cur; - LIST_INSERT_HEAD(&ifm->ifm_list, entry, ifm_list); -} + if_setsoftc(ifp, IF_MEDIA, ifm); -/* - * Add an array of media configurations to the list of - * supported media for a specific interface instance. - */ -void -ifmedia_list_add(ifm, lp, count) - struct ifmedia *ifm; - struct ifmedia_entry *lp; - int count; -{ - int i; - - for (i = 0; i < count; i++) - ifmedia_add(ifm, lp[i].ifm_media, lp[i].ifm_data, - lp[i].ifm_aux); + ifp->if_baudrate = ifmedia_baudrate(ifm->ifm_media); } /* - * Set the default active media. - * - * Called by device-specific code which is assumed to have already - * selected the default media in hardware. We do _not_ call the - * media-change callback. + * Called by if_free(). */ void -ifmedia_set(ifm, target) - struct ifmedia *ifm; - int target; - -{ - struct ifmedia_entry *match; - - match = ifmedia_match(ifm, target, ifm->ifm_mask); - - if (match == NULL) { - printf("ifmedia_set: no match for 0x%x/0x%x\n", - target, ~ifm->ifm_mask); - panic("ifmedia_set"); - } - ifm->ifm_cur = match; - -#ifdef IFMEDIA_DEBUG - if (ifmedia_debug) { - printf("ifmedia_set: target "); - ifmedia_printword(target); - printf("ifmedia_set: setting to "); - ifmedia_printword(ifm->ifm_cur->ifm_media); - } -#endif -} - -/* - * Given a media word, return one suitable for an application - * using the original encoding. - */ -static int -compat_media(int media) +ifmedia_free(struct ifnet *ifp) { + struct ifmedia *ifm; - if (IFM_TYPE(media) == IFM_ETHER && IFM_SUBTYPE(media) > IFM_OTHER) { - media &= ~(IFM_ETH_XTYPE|IFM_TMASK); - media |= IFM_OTHER; - } - return (media); + ifm = if_getsoftc(ifp, IF_MEDIA); + if_setsoftc(ifp, IF_MEDIA, NULL); + free(ifm, M_IFMEDIA); } /* * Device-independent media ioctl support function. */ int -ifmedia_ioctl(ifp, ifr, ifm, cmd) - struct ifnet *ifp; - struct ifreq *ifr; - struct ifmedia *ifm; - u_long cmd; +ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, u_long cmd) { - struct ifmedia_entry *match; struct ifmediareq *ifmr = (struct ifmediareq *) ifr; - int error = 0; + struct ifmedia *ifm; + if_media_t newmedia, *match; + int i, error; - if (ifp == NULL || ifr == NULL || ifm == NULL) - return(EINVAL); + ifm = if_getsoftc(ifp, IF_MEDIA); + if (ifm == NULL) + return (ENODEV); + error = 0; switch (cmd) { - - /* - * Set the current media. - */ case SIOCSIFMEDIA: - { - struct ifmedia_entry *oldentry; - int oldmedia; - int newmedia = ifr->ifr_media; - - match = ifmedia_match(ifm, newmedia, ifm->ifm_mask); + newmedia = ifr->ifr_media; + match = ifmedia_match(ifm, newmedia); if (match == NULL) { #ifdef IFMEDIA_DEBUG if (ifmedia_debug) { - printf( - "ifmedia_ioctl: no media found for 0x%x\n", - newmedia); + printf("%s: no media found for 0x%x\n", + __func__, newmedia); } #endif return (ENXIO); @@ -252,14 +137,11 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd) /* * If no change, we're done. - * XXX Automedia may invole software intervention. - * Keep going in case the connected media changed. - * Similarly, if best match changed (kernel debugger?). */ if ((IFM_SUBTYPE(newmedia) != IFM_AUTO) && (newmedia == ifm->ifm_media) && (match == ifm->ifm_cur)) - return 0; + return (0); /* * We found a match, now make the driver switch to it. @@ -268,57 +150,52 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd) */ #ifdef IFMEDIA_DEBUG if (ifmedia_debug) { - printf("ifmedia_ioctl: switching %s to ", - ifp->if_xname); - ifmedia_printword(match->ifm_media); + printf("%s: switching %s to ", __func__, ifp->if_xname); + ifmedia_printword(*match); } #endif - oldentry = ifm->ifm_cur; - oldmedia = ifm->ifm_media; + error = ifp->if_ops->ifop_media_change(ifp, newmedia); + if (error) + break; ifm->ifm_cur = match; ifm->ifm_media = newmedia; - error = (*ifm->ifm_change)(ifp); - if (error) { - ifm->ifm_cur = oldentry; - ifm->ifm_media = oldmedia; - } + /* + * Some drivers, e.g. miibus(4) enabled, already set the + * baudrate in ifop_media_change, but some may not. + */ + ifp->if_baudrate = ifmedia_baudrate(newmedia); + break; - } /* * Get list of available media and current media on interface. */ case SIOCGIFMEDIA: case SIOCGIFXMEDIA: - { - struct ifmedia_entry *ep; - int i; - if (ifmr->ifm_count < 0) return (EINVAL); if (cmd == SIOCGIFMEDIA) { ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ? - compat_media(ifm->ifm_cur->ifm_media) : IFM_NONE; + ifmedia_compat(*ifm->ifm_cur) : IFM_NONE; } else { ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ? - ifm->ifm_cur->ifm_media : IFM_NONE; + *ifm->ifm_cur : IFM_NONE; } ifmr->ifm_mask = ifm->ifm_mask; ifmr->ifm_status = 0; - (*ifm->ifm_status)(ifp, ifmr); + ifp->if_ops->ifop_media_status(ifp, ifmr); /* - * If there are more interfaces on the list, count + * If there are more supported mediae on the list, count * them. This allows the caller to set ifmr->ifm_count * to 0 on the first call to know how much space to * allocate. */ - i = 0; - LIST_FOREACH(ep, &ifm->ifm_list, ifm_list) - if (i++ < ifmr->ifm_count) { - error = copyout(&ep->ifm_media, - ifmr->ifm_ulist + i - 1, sizeof(int)); + for (i = 0; ifm->ifm_array[i] != 0; i++) + if (i < ifmr->ifm_count) { + error = copyout(&ifm->ifm_array[i], + ifmr->ifm_ulist + i, sizeof(if_media_t)); if (error) break; } @@ -326,7 +203,6 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd) error = ifmr->ifm_count ? E2BIG : 0; ifmr->ifm_count = i; break; - } default: return (EINVAL); @@ -336,33 +212,71 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd) } /* - * Find media entry matching a given ifm word. - * + * Upcall from driver to report new media status. + * We intentionally don't change ifm_cur or ifm_media, since this + * upcall should come only in case if media is set to autonegotiation. + */ +void +if_media_status(struct ifnet *ifp, if_media_t media) +{ + + if_setbaudrate(ifp, ifmedia_baudrate(media)); + if_link_state_change(ifp, ifmedia_link_state(media)); +} + +/* + * Interface wants to change its media list. */ -static struct ifmedia_entry * -ifmedia_match(ifm, target, mask) - struct ifmedia *ifm; - int target; - int mask; +void +if_media_change(struct ifnet *ifp, if_media_t *array, if_media_t cur) { - struct ifmedia_entry *match, *next; + struct ifmedia *ifm; + + ifm = if_getsoftc(ifp, IF_MEDIA); + ifm->ifm_array = array; + ifm->ifm_cur = ifmedia_match(ifm, cur); + ifm->ifm_media = *ifm->ifm_cur; + + ifp->if_baudrate = ifmedia_baudrate(ifm->ifm_media); +} +/* + * Find media entry index matching a given ifm word. + */ +static if_media_t * +ifmedia_match(struct ifmedia *ifm, if_media_t target) +{ + if_media_t *match, mask; + + mask = ~ifm->ifm_mask; match = NULL; - mask = ~mask; - LIST_FOREACH(next, &ifm->ifm_list, ifm_list) { - if ((next->ifm_media & mask) == (target & mask)) { + for (int i = 0; ifm->ifm_array[i] != 0; i++) + if ((ifm->ifm_array[i] & mask) == (target & mask)) { #if defined(IFMEDIA_DEBUG) || defined(DIAGNOSTIC) - if (match) { - printf("ifmedia_match: multiple match for " - "0x%x/0x%x\n", target, mask); - } + if (match != NULL) + printf("%s: multiple match for " + "0x%x/0x%x\n", __func__, target, mask); #endif - match = next; + match = &ifm->ifm_array[i]; } - } - return match; + return (match); +} + +/* + * Given a media word, return one suitable for an application + * using the original encoding. + */ +static if_media_t +ifmedia_compat(if_media_t media) +{ + + if (IFM_TYPE(media) == IFM_ETHER && IFM_SUBTYPE(media) > IFM_OTHER) { + media &= ~(IFM_ETH_XTYPE|IFM_TMASK); + media |= IFM_OTHER; + } + return (media); } /* @@ -372,8 +286,8 @@ ifmedia_match(ifm, target, mask) static const struct ifmedia_baudrate ifmedia_baudrate_descriptions[] = IFM_BAUDRATE_DESCRIPTIONS; -uint64_t -ifmedia_baudrate(int mword) +static uint64_t +ifmedia_baudrate(if_media_t mword) { int i; @@ -386,7 +300,7 @@ ifmedia_baudrate(int mword) return (0); } -int +static int ifmedia_link_state(u_int mstatus) { @@ -400,6 +314,9 @@ ifmedia_link_state(u_int mstatus) } #ifdef IFMEDIA_DEBUG +SYSCTL_INT(_debug, OID_AUTO, ifmedia, CTLFLAG_RW, &ifmedia_debug, + 0, "if_media debugging msgs"); + struct ifmedia_description ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS; Modified: projects/ifnet/sys/net/if_media.h ============================================================================== --- projects/ifnet/sys/net/if_media.h Sun Apr 26 12:24:42 2015 (r282020) +++ projects/ifnet/sys/net/if_media.h Sun Apr 26 15:40:58 2015 (r282021) @@ -39,83 +39,10 @@ #define _NET_IF_MEDIA_H_ /* - * Prototypes and definitions for BSD/OS-compatible network interface - * media selection. + * Interface media description could be bigger than a 32-bit word, + * but a conservative decision was taken in r281236. * - * Where it is safe to do so, this code strays slightly from the BSD/OS - * design. Software which uses the API (device drivers, basically) - * shouldn't notice any difference. - * - * Many thanks to Matt Thomas for providing the information necessary - * to implement this interface. - */ - -#ifdef _KERNEL - -#include <sys/queue.h> - -struct ifnet; - -/* - * Driver callbacks for media status and change requests. - */ -typedef int (*ifm_change_cb_t)(struct ifnet *); -typedef void (*ifm_stat_cb_t)(struct ifnet *, struct ifmediareq *req); - -/* - * In-kernel representation of a single supported media type. - */ -struct ifmedia_entry { - LIST_ENTRY(ifmedia_entry) ifm_list; - int ifm_media; /* description of this media attachment */ - int ifm_data; /* for driver-specific use */ - void *ifm_aux; /* for driver-specific use */ -}; - -/* - * One of these goes into a network interface's softc structure. - * It is used to keep general media state. - */ -struct ifmedia { - int ifm_mask; /* mask of changes we don't care about */ - int ifm_media; /* current user-set media word */ - struct ifmedia_entry *ifm_cur; /* currently selected media */ - LIST_HEAD(, ifmedia_entry) ifm_list; /* list of all supported media */ - ifm_change_cb_t ifm_change; /* media change driver callback */ - ifm_stat_cb_t ifm_status; /* media status driver callback */ -}; - -/* Initialize an interface's struct if_media field. */ -void ifmedia_init(struct ifmedia *ifm, int dontcare_mask, - ifm_change_cb_t change_callback, ifm_stat_cb_t status_callback); - -/* Remove all mediums from a struct ifmedia. */ -void ifmedia_removeall( struct ifmedia *ifm); - -/* Add one supported medium to a struct ifmedia. */ -void ifmedia_add(struct ifmedia *ifm, int mword, int data, void *aux); - -/* Add an array (of ifmedia_entry) media to a struct ifmedia. */ -void ifmedia_list_add(struct ifmedia *mp, struct ifmedia_entry *lp, - int count); - -/* Set default media type on initialization. */ -void ifmedia_set(struct ifmedia *ifm, int mword); - -/* Common ioctl function for getting/setting media, called by driver. */ -int ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, - struct ifmedia *ifm, u_long cmd); - -/* Compute baudrate for a given media. */ -uint64_t ifmedia_baudrate(int); - -/* Convert media status to link state. */ -int ifmedia_link_state(u_int); - -#endif /*_KERNEL */ - -/* - * if_media Options word: + * Options word: * Bits Use * ---- ------- * 0-4 Media variant @@ -126,6 +53,7 @@ int ifmedia_link_state(u_int); * 20-27 Shared (global) options * 28-31 Instance */ +typedef int if_media_t; /* * Ethernet
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504261540.t3QFexFv000257>