⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_media.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
字号:
/*	$OpenBSD: if_media.c,v 1.1 1998/09/03 06:24:20 jason Exp $	*//*	$NetBSD: if_media.c,v 1.3 1998/08/30 07:39:39 enami Exp $	*//*- * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, * NASA Ames Research Center. * * 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. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the NetBSD *	Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its *    contributors may be used to endorse or promote products derived *    from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. *//* * Copyright (c) 1997 *	Jonathan Stone and Jason R. Thorpe.  All rights reserved. * * This software is derived from information provided by Matt Thomas. * * 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. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *      This product includes software developed by Jonathan Stone *	and Jason R. Thorpe for the NetBSD Project. * 4. The names of the authors may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 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. *//* * 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. */#include <sys/param.h>#include <sys/systm.h>#include <sys/errno.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/malloc.h>#include <net/if.h>#include <net/if_media.h>#include <net/netisr.h>/* * Compile-time options: * IFMEDIA_DEBUG: *	turn on implementation-level debug printfs. * 	Useful for debugging newly-ported  drivers. */struct ifmedia_entry *ifmedia_match __P((struct ifmedia *ifm,    int flags, int mask));#ifdef IFMEDIA_DEBUGint	ifmedia_debug = 0;static	void ifmedia_printword __P((int));#endif/* * Initialize if_media struct for a specific interface instance. */voidifmedia_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;{	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;}/* * Add a media configuration to the list of supported media * for a specific interface instance. */voidifmedia_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;	LIST_INSERT_HEAD(&ifm->ifm_list, entry, ifm_list);}/* * Add an array of media configurations to the list of * supported media for a specific interface instance. */voidifmedia_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);}/* * 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. */voidifmedia_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}/* * Device-independent media ioctl support function. */intifmedia_ioctl(ifp, ifr, ifm, cmd)	struct ifnet *ifp;	struct ifreq *ifr;	struct ifmedia *ifm;	u_long cmd;{	struct ifmedia_entry *match;	struct ifmediareq *ifmr = (struct ifmediareq *) ifr;	int error = 0, sticky;	if (ifp == NULL || ifr == NULL || ifm == NULL)		return(EINVAL);	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);		if (match == NULL) {#ifdef IFMEDIA_DEBUG			if (ifmedia_debug) {				printf(				    "ifmedia_ioctl: no media found for 0x%x\n", 				    newmedia);			}#endif			return (ENXIO);		}		/*		 * If no change, we're done.		 * XXX Automedia may invole software intervention.		 *     Keep going in case the 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;		/*		 * We found a match, now make the driver switch to it.		 * Make sure to preserve our old media type in case the		 * driver can't switch.		 */#ifdef IFMEDIA_DEBUG		if (ifmedia_debug) {			printf("ifmedia_ioctl: switching %s to ",			    ifp->if_xname);			ifmedia_printword(match->ifm_media);		}#endif		oldentry = ifm->ifm_cur;		oldmedia = ifm->ifm_media;		ifm->ifm_cur = match;		ifm->ifm_media = newmedia;		error = (*ifm->ifm_change)(ifp);		if (error) {			ifm->ifm_cur = oldentry;			ifm->ifm_media = oldmedia;		}		break;	}	/*	 * Get list of available media and current media on interface.	 */	case  SIOCGIFMEDIA: 	{		struct ifmedia_entry *ep;		int *kptr, count;		kptr = NULL;		/* XXX gcc */		ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ?		    ifm->ifm_cur->ifm_media : IFM_NONE;		ifmr->ifm_mask = ifm->ifm_mask;		ifmr->ifm_status = 0;		(*ifm->ifm_status)(ifp, ifmr);		count = 0;		ep = ifm->ifm_list.lh_first;		if (ifmr->ifm_count != 0) {			kptr = (int *)malloc(ifmr->ifm_count * sizeof(int),			    M_TEMP, M_WAITOK);			/*			 * Get the media words from the interface's list.			 */			for (; ep != NULL && count < ifmr->ifm_count;			    ep = ep->ifm_list.le_next, count++)				kptr[count] = ep->ifm_media;			if (ep != NULL)				error = E2BIG;	/* oops! */		}		/*		 * If there are more interfaces 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		 * callocate.		 */		for (; ep != NULL; ep = ep->ifm_list.le_next)			count++;		/*		 * We do the copyout on E2BIG, because that's		 * just our way of telling userland that there		 * are more.  This is the behavior I've observed		 * under BSD/OS 3.0		 */		sticky = error;		if ((error == 0 || error == E2BIG) && ifmr->ifm_count != 0) {			error = copyout((caddr_t)kptr,			    (caddr_t)ifmr->ifm_ulist,			    ifmr->ifm_count * sizeof(int));		}		if (error == 0)			error = sticky;		if (ifmr->ifm_count != 0)			free(kptr, M_TEMP);		ifmr->ifm_count = count;		break;	}	default:		return (EINVAL);	}	return (error);}/* * Find media entry matching a given ifm word. * */struct ifmedia_entry *ifmedia_match(ifm, target, mask)	struct ifmedia *ifm; 	int target;	int mask;{	struct ifmedia_entry *match, *next;	match = NULL;	mask = ~mask;	for (next = ifm->ifm_list.lh_first; next != NULL;	    next = next->ifm_list.le_next) {		if ((next->ifm_media & mask) == (target & mask)) {#if defined(IFMEDIA_DEBUG) || defined(DIAGNOSTIC)			if (match) {				printf("ifmedia_match: multiple match for "				    "0x%x/0x%x\n", target, mask);			}#endif			match = next;		}	}	return match;}#ifdef IFMEDIA_DEBUGstruct ifmedia_description ifm_type_descriptions[] =    IFM_TYPE_DESCRIPTIONS;struct ifmedia_description ifm_subtype_descriptions[] =    IFM_SUBTYPE_DESCRIPTIONS;struct ifmedia_description ifm_option_descriptions[] =    IFM_OPTION_DESCRIPTIONS;/* * print a media word. */static voidifmedia_printword(ifmw)	int ifmw;{	struct ifmedia_description *desc;	int seen_option = 0;	/* Print the top-level interface type. */	for (desc = ifm_type_descriptions; desc->ifmt_string != NULL;	     desc++) {		if (IFM_TYPE(ifmw) == desc->ifmt_word)			break;	}	if (desc->ifmt_string == NULL)		printf("<unknown type> ");	else		printf("%s ", desc->ifmt_string);	/* Print the subtype. */	for (desc = ifm_subtype_descriptions; desc->ifmt_string != NULL;	     desc++) {		if (IFM_TYPE_MATCH(desc->ifmt_word, ifmw) &&		    IFM_SUBTYPE(desc->ifmt_word) == IFM_SUBTYPE(ifmw))			break;	}	if (desc->ifmt_string == NULL)		printf("<unknown subtype>");	else		printf("%s", desc->ifmt_string);	/* Print any options. */	for (desc = ifm_option_descriptions; desc->ifmt_string != NULL;	     desc++) {		if (IFM_TYPE_MATCH(desc->ifmt_word, ifmw) &&		    (ifmw & desc->ifmt_word) != 0 &&		    (seen_option & IFM_OPTIONS(desc->ifmt_word)) == 0) {			if (seen_option == 0)				printf(" <");			printf("%s%s", seen_option ? "," : "",			    desc->ifmt_string);			seen_option |= IFM_OPTIONS(desc->ifmt_word);		}	}	printf("%s\n", seen_option ? ">" : "");}#endif /* IFMEDIA_DEBUG */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -