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

📄 if_de.c

📁 很好的一个嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
/*	$OpenBSD: if_de.c,v 1.31 1998/05/28 20:25:51 deraadt Exp $	*//*	$NetBSD: if_de.c,v 1.45 1997/06/09 00:34:18 thorpej Exp $	*//*- * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) * All rights reserved. * * 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. The name of the author may not be used to endorse or promote products *    derived from this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. * * Id: if_de.c,v 1.89 1997/06/03 19:19:55 thomas Exp * *//* * DEC 21040 PCI Ethernet Controller * * Written by Matt Thomas * BPF support code stolen directly from if_ec.c * *   This driver supports the DEC DE435 or any other PCI *   board which support 21040, 21041, or 21140 (mostly). */#define	TULIP_HDR_DATA#include <sys/param.h>#include <sys/systm.h>#include <sys/mbuf.h>#include <sys/protosw.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/errno.h>#include <sys/malloc.h>#include <sys/kernel.h>#include <sys/proc.h>	/* only for declaration of wakeup() used by vm.h */#if defined(__FreeBSD__)#include <machine/clock.h>#elif defined(__bsdi__) || defined(__NetBSD__) || defined(__OpenBSD__)#include <sys/device.h>#endif#include <net/if.h>#if defined(SIOCSIFMEDIA) && !defined(TULIP_NOIFMEDIA)#include <net/if_media.h>#endif#include <net/if_types.h>#include <net/if_dl.h>#include <net/route.h>#include <net/netisr.h>#if defined(__bsdi__) && _BSDI_VERSION >= 199701#include <dev/mii/mii.h>#include <dev/mii/miivar.h>#endif#include "bpfilter.h"#if NBPFILTER > 0#include <net/bpf.h>#include <net/bpfdesc.h>#endif#ifdef INET#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/in_var.h>#include <netinet/ip.h>#endif#ifdef NS#include <netns/ns.h>#include <netns/ns_if.h>#endif#include <vm/vm.h>#include <vm/vm_param.h>#include <vm/vm_kern.h>#if defined(__FreeBSD__)#include <vm/pmap.h>#include <pci.h>#include <netinet/if_ether.h>#if NPCI > 0#include <pci/pcivar.h>#include <pci/dc21040reg.h>#define	DEVAR_INCLUDE	"pci/if_devar.h"#endif#endif /* __FreeBSD__ */#if defined(__bsdi__)#include <netinet/if_ether.h>#include <i386/pci/ic/dc21040reg.h>#include <i386/isa/isa.h>#include <i386/isa/icu.h>#include <i386/isa/dma.h>#include <i386/isa/isavar.h>#include <i386/pci/pci.h>#if _BSDI_VERSION < 199510#include <eisa.h>#else#define	NEISA 0#endif#if NEISA > 0 && _BSDI_VERSION >= 199401#include <i386/eisa/eisa.h>#define	TULIP_EISA#endif#define	DEVAR_INCLUDE	"i386/pci/if_devar.h"#endif /* __bsdi__ */#if defined(__NetBSD__) #include <net/if_ether.h>#if defined(INET)#include <netinet/if_inarp.h>#endif#endif#if defined(__OpenBSD__)#include <netinet/if_ether.h>#endif#if defined(__NetBSD__) || defined(__OpenBSD__)#include <machine/bus.h>#if defined(__alpha__)#include <machine/intr.h>#endif#include <dev/pci/pcireg.h>#include <dev/pci/pcivar.h>#include <dev/ic/dc21040reg.h>#define	DEVAR_INCLUDE	"dev/pci/if_devar.h"#endif /* __NetBSD__ */#if defined(PROM)#include <machine/endian.h>#include <netinet/if_ether.h>#include <sys/syslog.h>#include "pci/pcivar.h"#include "pci/device.h"#include "dc21040reg.h"#include "mips.h"#include "sbd.h"#define	DEVAR_INCLUDE	"if_devar.h"/*#define vtophys(va)	KVA_TO_PA(va)*/#ifndef sbd_clean_dcache#ifdef R4000#define sbd_clean_dcache	mips_clean_dcache#define sbd_inval_dcache	mips_clean_dcache#else#define sbd_clean_dcache	r3k_dclean#define sbd_inval_dcache	r3k_dclean#endif#endif#define clean_dcache		sbd_clean_dcache#define inval_dcache		sbd_inval_dcachetypedef int ifnet_ret_t;typedef int ioctl_cmd_t;extern struct cfdriver decd;#define	TULIP_UNIT_TO_SOFTC(unit)	((tulip_softc_t *) decd.cd_devs[unit])#define TULIP_IFP_TO_SOFTC(ifp) TULIP_UNIT_TO_SOFTC((ifp)->if_unit)#define IFF_LINK0	IFF_LLC0#define IFF_LINK1	IFF_LLC1#define IFF_LINK2	IFF_LLC2#define loudprintf printf#define __BROKEN_INDIRECT_CONFIG#endif/* * Intel CPUs should use I/O mapped access. */#if defined(__i386__) || defined(TULIP_EISA)#define	TULIP_IOMAPPED#endif#if 0/* * This turns on all sort of debugging stuff and make the * driver much larger. */#define TULIP_DEBUG/* * This turns on even more debug code to find out why * the driver does stupid things sometimes  */#if 1#define TULIP_MEGADEBUG#endif#endif#if 0#define	TULIP_USE_SOFTINTR#endif#define	TULIP_HZ	10#include DEVAR_INCLUDE/* * This module supports *	the DEC 21040 PCI Ethernet Controller. *	the DEC 21041 PCI Ethernet Controller. *	the DEC 21140 PCI Fast Ethernet Controller. */static void tulip_mii_autonegotiate(tulip_softc_t * const sc, const unsigned phyaddr);static tulip_intrfunc_t tulip_intr_shared(void *arg);static tulip_intrfunc_t tulip_intr_normal(void *arg);static void tulip_init(tulip_softc_t * const sc);static void tulip_reset(tulip_softc_t * const sc);static ifnet_ret_t tulip_ifstart_one(struct ifnet *ifp);static ifnet_ret_t tulip_ifstart(struct ifnet *ifp);static struct mbuf *tulip_txput(tulip_softc_t * const sc, struct mbuf *m);static void tulip_txput_setup(tulip_softc_t * const sc);static void tulip_rx_intr(tulip_softc_t * const sc);static void tulip_addr_filter(tulip_softc_t * const sc);static unsigned tulip_mii_readreg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno);static void tulip_mii_writereg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno, unsigned data);static int tulip_mii_map_abilities(tulip_softc_t * const sc, unsigned abilities);static tulip_media_t tulip_mii_phy_readspecific(tulip_softc_t * const sc);static int tulip_srom_decode(tulip_softc_t * const sc);#if defined(IFM_ETHER)static int tulip_ifmedia_change(struct ifnet * const ifp);static void tulip_ifmedia_status(struct ifnet * const ifp, struct ifmediareq *req);#endif/* static void tulip_21140_map_media(tulip_softc_t *sc); */static voidtulip_timeout_callback(    void *arg){    tulip_softc_t * const sc = arg;    tulip_spl_t s = TULIP_RAISESPL();    sc->tulip_flags &= ~TULIP_TIMEOUTPENDING;    sc->tulip_probe_timeout -= 1000 / TULIP_HZ;    (sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_TIMER);    TULIP_RESTORESPL(s);}static voidtulip_timeout(    tulip_softc_t * const sc){    if (sc->tulip_flags & TULIP_TIMEOUTPENDING)	return;    sc->tulip_flags |= TULIP_TIMEOUTPENDING;    timeout(tulip_timeout_callback, sc, (hz + TULIP_HZ / 2) / TULIP_HZ);}#if defined(TULIP_NEED_FASTTIMEOUT)static voidtulip_fasttimeout_callback(    void *arg){    tulip_softc_t * const sc = arg;    tulip_spl_t s = TULIP_RAISESPL();    sc->tulip_flags &= ~TULIP_FASTTIMEOUTPENDING;    (sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_FASTTIMER);    TULIP_RESTORESPL(s);}static voidtulip_fasttimeout(    tulip_softc_t * const sc){    if (sc->tulip_flags & TULIP_FASTTIMEOUTPENDING)	return;    sc->tulip_flags |= TULIP_FASTTIMEOUTPENDING;    timeout(tulip_fasttimeout_callback, sc, 1);}#endifstatic inttulip_txprobe(    tulip_softc_t * const sc){    struct mbuf *m;    /*     * Before we are sure this is the right media we need     * to send a small packet to make sure there's carrier.     * Strangely, BNC and AUI will "see" receive data if     * either is connected so the transmit is the only way     * to verify the connectivity.     */    MGETHDR(m, M_DONTWAIT, MT_DATA);    if (m == NULL)	return 0;    /*     * Construct a LLC TEST message which will point to ourselves.     */    bcopy(sc->tulip_enaddr, mtod(m, struct ether_header *)->ether_dhost, 6);    bcopy(sc->tulip_enaddr, mtod(m, struct ether_header *)->ether_shost, 6);    mtod(m, struct ether_header *)->ether_type = htons(3);    mtod(m, unsigned char *)[14] = 0;    mtod(m, unsigned char *)[15] = 0;    mtod(m, unsigned char *)[16] = 0xE3;	/* LLC Class1 TEST (no poll) */    m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3;    /*     * send it!     */    sc->tulip_cmdmode |= TULIP_CMD_TXRUN;    sc->tulip_intrmask |= TULIP_STS_TXINTR;    sc->tulip_flags |= TULIP_TXPROBE_ACTIVE;    TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);    TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);    if ((m = tulip_txput(sc, m)) != NULL)	m_freem(m);    sc->tulip_probe.probe_txprobes++;    return 1;}#ifdef BIG_PACKET#define TULIP_SIAGEN_WATCHDOG	(sc->tulip_if.if_mtu > ETHERMTU ? TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE : 0)#else#define	TULIP_SIAGEN_WATCHDOG	0#endifstatic voidtulip_media_set(    tulip_softc_t * const sc,    tulip_media_t media){    const tulip_media_info_t *mi = sc->tulip_mediums[media];    if (mi == NULL)	return;    /*     * If we are switching media, make sure we don't think there's     * any stale RX activity     */    sc->tulip_flags &= ~TULIP_RXACT;    if (mi->mi_type == TULIP_MEDIAINFO_SIA) {	TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);	TULIP_CSR_WRITE(sc, csr_sia_tx_rx,        mi->mi_sia_tx_rx);	if (sc->tulip_features & TULIP_HAVE_SIAGP) {	    TULIP_CSR_WRITE(sc, csr_sia_general,  mi->mi_sia_gp_control|mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);	    DELAY(50);	    TULIP_CSR_WRITE(sc, csr_sia_general,  mi->mi_sia_gp_data|mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);	} else {	    TULIP_CSR_WRITE(sc, csr_sia_general,  mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);	}	TULIP_CSR_WRITE(sc, csr_sia_connectivity, mi->mi_sia_connectivity);    } else if (mi->mi_type == TULIP_MEDIAINFO_GPR) {#define	TULIP_GPR_CMDBITS	(TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER|TULIP_CMD_TXTHRSHLDCTL)	/*	 * If the cmdmode bits don't match the currently operating mode,	 * set the cmdmode appropriately and reset the chip.	 */	if (((mi->mi_cmdmode ^ TULIP_CSR_READ(sc, csr_command)) & TULIP_GPR_CMDBITS) != 0) {	    sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS;	    sc->tulip_cmdmode |= mi->mi_cmdmode;#if defined(TULIP_MEGADEBUG)	    printf ("tulip_reset: tulip_media_set/TULIP_MEDIAINFO_GPR\n");#endif	    tulip_reset(sc);	}	TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET|sc->tulip_gpinit);	DELAY(10);	TULIP_CSR_WRITE(sc, csr_gp, (u_int8_t) mi->mi_gpdata);    } else if (mi->mi_type == TULIP_MEDIAINFO_SYM) {	/*	 * If the cmdmode bits don't match the currently operating mode,	 * set the cmdmode appropriately and reset the chip.	 */	if (((mi->mi_cmdmode ^ TULIP_CSR_READ(sc, csr_command)) & TULIP_GPR_CMDBITS) != 0) {	    sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS;	    sc->tulip_cmdmode |= mi->mi_cmdmode;#if defined(TULIP_MEGADEBUG)	    printf ("tulip_reset: tulip_media_set/TULIP_MEDIAINFO_SYM\n");#endif	    tulip_reset(sc);	}	TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpcontrol);	TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpdata);    } else if (mi->mi_type == TULIP_MEDIAINFO_MII	       && sc->tulip_probe_state != TULIP_PROBE_INACTIVE) {	int idx;	if (sc->tulip_features & TULIP_HAVE_SIAGP) {	    const u_int8_t *dp;	    dp = &sc->tulip_rombuf[mi->mi_reset_offset];	    for (idx = 0; idx < mi->mi_reset_length; idx++, dp += 2) {		DELAY(10);		TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16);	    }	    sc->tulip_phyaddr = mi->mi_phyaddr;	    dp = &sc->tulip_rombuf[mi->mi_gpr_offset];	    for (idx = 0; idx < mi->mi_gpr_length; idx++, dp += 2) {		DELAY(10);		TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16);	    }	} else {	    for (idx = 0; idx < mi->mi_reset_length; idx++) {		DELAY(10);		TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_reset_offset + idx]);	    }	    sc->tulip_phyaddr = mi->mi_phyaddr;	    for (idx = 0; idx < mi->mi_gpr_length; idx++) {		DELAY(10);		TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_gpr_offset + idx]);	    }	}	if (sc->tulip_flags & TULIP_TRYNWAY) {	    tulip_mii_autonegotiate(sc, sc->tulip_phyaddr);	} else if ((sc->tulip_flags & TULIP_DIDNWAY) == 0) {	    u_int32_t data = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_CONTROL);	    data &= ~(PHYCTL_SELECT_100MB|PHYCTL_AUTONEG_ENABLE|PHYCTL_FULL_DUPLEX);	    data &= ~(PHYCTL_POWERDOWN|PHYCTL_ISOLATE);	    sc->tulip_flags &= ~TULIP_DIDNWAY;	    if (TULIP_IS_MEDIA_FD(media))		data |= PHYCTL_FULL_DUPLEX;	    if (TULIP_IS_MEDIA_100MB(media))		data |= PHYCTL_SELECT_100MB;	    tulip_mii_writereg(sc, sc->tulip_phyaddr, PHYREG_CONTROL, data);	}    }}static voidtulip_linkup(    tulip_softc_t * const sc,

⌨️ 快捷键说明

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