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

📄 if_apx.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1982, 1990, 1993 *	The Regents of the University of California.  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. 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 University of *	California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. * *	@(#)if_apx.c	8.1 (Berkeley) 6/11/93 *//* * Driver for SGS-THOMSON MK5025 based Link level controller. * The chip will do LAPB in hardware, although this driver only * attempts to use it for HDLC framing. * * Driver written by Keith Sklower, based on lance AMD7990  * driver by Van Jacobsen, and information graciously supplied * by the ADAX corporation of Berkeley, CA. */#include "apx.h"#if NAPX > 0#include <sys/param.h>#include <sys/mbuf.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/errno.h>#include <sys/syslog.h>#include <net/if.h>#include <net/netisr.h>#include <net/if_types.h>#ifdef CCITT#include <netccitt/x25.h>int x25_rtrequest(), x25_ifoutput();#endif#include <i386/isa/if_apxreg.h>int	apxprobe(), apxattach(), apxstart(), apx_uprim(), apx_meminit();int	apxinit(), apxoutput(), apxioctl(), apxreset(), apxdebug = 0;void	apx_ifattach(), apxtest(), apxinput(), apxintr(), apxtint(), apxrint();struct apx_softc {	struct	ifnet apx_if;	caddr_t	apx_device;		/* e.g. isa_device, vme_device, etc. */	struct	apc_reg *apx_reg;	/* control regs for both subunits */	struct	apc_mem *apx_hmem;	/* Host addr for shared memory */	struct	apc_mem *apx_dmem;	/* Device (chip) addr for shared mem */	struct	sgcp *apx_sgcp;		/* IO control port for this subunit */	int	apx_flags;		/* Flags specific to this driver */#define APXF_CHIPHERE	0x01		/* mk5025 present */	int	apx_rxnum;		/* Last receiver dx we looked at */	int	apx_txnum;		/* Last tranmistter dx we stomped on */	int	apx_txcnt;		/* Number of packets queued for tx*/	u_int	apx_msize;	struct	sgae apx_csr23;		/* 24 bit init addr, as seen by chip */	u_short	apx_csr4;		/* byte gender, set in mach dep code */	struct	apc_modes apx_modes;	/* Parameters, as amended by ioctls */} apx_softc[2 * NAPX];struct apxstat {	int	rxnull;			/* no rx bufs ready this interrupt */	int	rxnrdy;			/* expected rx buf not ready */	int	rx2big;			/* expected rx buf not ready */	int	txnull;	int	pint;			/* new primitive available interrupt */	int	rint;			/* receive interrupts */	int	tint;			/* transmit interrupts */	int	anyint;			/* note all interrupts */	int	queued;			/* got through apxinput */	int	nxpctd;			/* received while if was down */	int	rstfld;			/* reset didn't work */} apxstat;/* default operating paramters for devices */struct	apc_modes apx_default_modes = { { 1,		/* apm_sgob.lsaddr; */   3,		/* apm_sgob.rsaddr; */   -SGMTU,	/* apm_sgob.n1; */   ((-10)<<8),	/* apm_sgob.n2_scale; */   -1250,	/* apm_sgob.t1; */   -10000,	/* apm_sgob.t3; */   -80,		/* apm_sgob.tp; */ }, 2,		/* apm_txwin; */ 1,		/* apm_apxmode: RS_232 connector and modem clock; */ 0,		/* apm_apxaltmode: enable dtr, disable X.21 connector; */ IFT_X25,	/* apm_iftype; */};/* Begin bus & endian dependence */#include <i386/isa/isa_device.h>struct	isa_driver apxdriver = {	apxprobe, apxattach, "apx",};#define SG_RCSR(apx, csrnum) \	 (outw(&(apx->apx_sgcp->sgcp_rap), csrnum << 1), \	  inw(&(apx->apx_sgcp->sgcp_rdp)))#define SG_WCSR(apx, csrnum, data) \	 (outw(&(apx->apx_sgcp->sgcp_rap), csrnum << 1), \	  outw(&(apx->apx_sgcp->sgcp_rdp), data))#define APX_RCSR(apx, csrname) inb(&(apx->apx_reg->csrname))#define APX_WCSR(apx, csrname, data) outb(&(apx->apx_reg->csrname), data)#define TIMO 10000 /* used in apx_uprim */apxprobe(id)	register struct	isa_device *id;{	int	moffset = 0, nchips = 2, unit = id->id_unit << 1, subunit;	struct	apc_reg *reg = (struct apc_reg *)id->id_iobase;	register struct	apx_softc *apx = apx_softc + unit;	/*	 * Probing for the second MK5025 on all ISA/EISA adax boards	 * manufactured prior to July 1992 (and some time following)	 * will hang the bus and the system.  Thus, it is essential	 * not to probe for the second mk5025 if it is known not to be there.	 * As the current config scheme for 386BSD does not have a flags	 * field, we adopt the convention of using the low order bit of	 * the memsize to warn us that we have a single chip board.	 */	if (id->id_msize & 1)		nchips = 1;	for (subunit = 0; subunit < nchips; subunit++) {		apx->apx_msize	= id->id_msize >> 1;		apx->apx_hmem	= (struct apc_mem *) (id->id_maddr + moffset);		apx->apx_dmem	= (struct apc_mem *) moffset;		apx->apx_device	= (caddr_t) id;		apx->apx_reg	= reg;		apx->apx_sgcp	= reg->axr_sgcp + subunit;		apx->apx_csr4	= 0x0210;	/* no byte swapping for PC-AT */		apx->apx_modes	= apx_default_modes;		apx->apx_if.if_unit = unit++;		moffset = apx->apx_msize;		apxtest(apx++);	}	return 1;}apxattach(id)	struct	isa_device *id;{	register struct	apx_softc *apx = apx_softc + (id->id_unit << 1);	apx_ifattach(&((apx++)->apx_if));	apx_ifattach(&(apx->apx_if));	return 0;}/* End bus & endian dependence *//* * Interface exists: make available by filling in network interface * record.  System will initialize the interface when it is ready * to accept packets. */voidapx_ifattach(ifp)	register struct ifnet *ifp;{	/*	 * Initialize ifnet structure	 */	ifp->if_name	= "apc";	ifp->if_mtu	= SGMTU;	ifp->if_init	= apxinit;	ifp->if_output	= apxoutput;	ifp->if_start	= apxstart;	ifp->if_ioctl	= apxioctl;	ifp->if_reset	= apxreset;	ifp->if_type	= apx_default_modes.apm_iftype;	ifp->if_hdrlen	= 5;	ifp->if_addrlen	= 8;	if_attach(ifp);}/* * Initialization of interface */apxinit(unit)	int unit;{	struct ifnet *ifp = &apx_softc[unit].apx_if;	int s = splimp();	ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);	if (apxreset(unit) && (ifp->if_flags & IFF_UP)) {		ifp->if_flags |= IFF_RUNNING;		(void)apxstart(ifp);	}	splx(s);	return 0;}apxctr(apx)	register struct apx_softc *apx;{	APX_WCSR(apx, axr_ccr, 0xB0); /* select ctr 2, write lsb+msb, mode 0 */	APX_WCSR(apx, axr_cnt2, 0x1);	APX_WCSR(apx, axr_cnt2, 0x0);	DELAY(50);	APX_WCSR(apx, axr_ccr, 0xE8); /* latch status, ctr 2; */	return (APX_RCSR(apx, axr_cnt2));}voidapxtest(apx)	register struct apx_softc *apx;{	int i =  0;	if ((apx->apx_if.if_unit & 1) == 0 && (i = apxctr(apx)) == 0)		apxerror(apx, "no response from timer chip", 0);	if (SG_RCSR(apx, 1) & 0x8000)		SG_WCSR(apx, 1, 0x8040);	SG_WCSR(apx, 4, apx->apx_csr4);	SG_WCSR(apx, 5, 0x08);		/* Set DTR mode in SGS thompson chip */	if (((i = SG_RCSR(apx, 5)) & 0xff08) != 0x08)		apxerror(apx, "no mk5025, csr5 high bits are", i);	else		apx->apx_flags |= APXF_CHIPHERE;	(void) apx_uprim(apx, SG_STOP, "stop after probing");}apxreset(unit)	int	unit;{	register struct apx_softc *apx = &apx_softc[unit ^ 1];	u_char apm_apxmode = 0, apm_apxaltmode = 0;#define MODE(m) (m |= apx->apx_modes.m << ((apx->apx_if.if_unit & 1) ? 1 : 0))	MODE(apm_apxmode);	MODE(apm_apxaltmode);	apx = apx_softc + unit;	MODE(apm_apxmode);	MODE(apm_apxaltmode);	APX_WCSR(apx, axr_mode, apm_apxmode);	APX_WCSR(apx, axr_altmode, apm_apxaltmode);	(void) apxctr(apx);	(void) apx_uprim(apx, SG_STOP, "stop to reset");	if ((apx->apx_if.if_flags & IFF_UP) == 0)		return 0;	apx_meminit(apx->apx_hmem, apx);	SG_WCSR(apx, 4, apx->apx_csr4);	SG_WCSR(apx, 2, apx->apx_csr23.f_hi);	SG_WCSR(apx, 3, apx->apx_csr23.lo);	if (apx_uprim(apx, SG_INIT, "init request") ||	    apx_uprim(apx, SG_STAT, "status request") ||	    apx_uprim(apx, SG_TRANS, "transparent mode"))		return 0;	SG_WCSR(apx, 0, SG_INEA);	return 1;}apx_uprim(apx, request, ident)	register struct apx_softc *apx;	char *ident;{	register int timo = 0;	int reply;	if ((apx->apx_flags & APXF_CHIPHERE) == 0)		return 1;	/* maybe even should panic . . . */	if ((reply = SG_RCSR(apx, 1)) & 0x8040)		SG_WCSR(apx, 1, 0x8040); /* Magic! */	if (request == SG_STOP && (SG_RCSR(apx, 0) & SG_STOPPED))		return 0;	SG_WCSR(apx, 1, request | SG_UAV);	do {		reply = SG_RCSR(apx, 1);		if (timo++ >= TIMO || (reply & 0x8000)) {				apxerror(apx, ident, reply);				return 1;		}	} while (reply & SG_UAV);	return 0;}apx_meminit(apc, apx)

⌨️ 快捷键说明

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