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

📄 if_fza.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifndef lintstatic char *sccsid = "@(#)if_fza.c	4.14      (ULTRIX)        4/30/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1988 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//*----------------------------------------------------------------------- * Modification History:  * * 02-APR-91   jsd *	Allow packets to be looped back if COPYALL mode is set * * 27-FEB-91   chc *	Added code to make the interface state consitently before and *	after the EEPROM update. *       * 19-DEC-90   chc * 	Fixed the counter initialization problem. Also allow to *	read counter while the adapter is in the MAINTENANCE *      state. * * 31-Oct-90   chc *	Added code to fix the SMT chained and SMT 6.2 duplicated *	address detected problems. Also added code to support the *	read status.  * * 5-Oct-90	chc *	Added code to sync the firmware and fixed the counter. * * 7-Sep-90	chc *	Added code to support FDDI MIB * * 9-Aug-90	chc (Chran-Ham Chang) *	Bugs Fixed and support the EEPROM update * * 27-Apr-90 	chc (Chran-Ham Chang) *	Created the if_fza.c module    *	Derived from if_xna.c. * *---------------------------------------------------------------------- */#include "fza.h"#if NFZA > 0 || defined(BINARY)#include "packetfilter.h"       /* NPACKETFILTER */#include "../data/if_fza_data.c"#include "../h/types.h"#include "../h/errlog.h"extern	struct protosw *iftype_to_proto(), *iffamily_to_proto();extern	struct timeval	time;int	fzaattach(), fzaintr(), fzaprobe(),fzastart();int	fzainit(),fzaioctl(),fzareset(),fzawatch();u_short fzastd[] = { 0 };struct  uba_driver fzadriver =	{ fzaprobe, 0 ,fzaattach, 0 , fzastd, "fza", fzainfo };extern  int net_output();struct	mbuf *fzamkparam();FZACMDRING *fzamkcmd();u_char  fza_dbeacon[] = {0x01, 0x80, 0xc2, 0x00, 0x01, 0x00};u_char  fza_rpurge[] = {0x09, 0x00, 0x2b, 0x02, 0x01, 0x05};u_char  fza_notset[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};int fzadebug = 0 ;int dludebug = 0 ;#define XMTSEGSIZE	512#define FZAMCLGET(m) { \	register struct mbuf *p; \	MGET((m), M_DONTWAIT, MT_DATA); \	if ((m)) { \		MCLGET((m), p); \		if (p == 0) { \			m_freem((m)); \			(m) = (struct mbuf *)NULL; \		} \	} \}#define	FZATIMEOUT(cp,timeout ) { \	register int s = splnet(); \	register long sec0 = time.tv_sec; \	while ( !(cp->own) && ((time.tv_sec - sec0) < 15 )); \	if ( !(cp->own) ) \		timeout = 1; \	splx(s); \}/* * Probe the FZA to see if there  *  */fzaprobe(reg,ui)	caddr_t reg;	struct	uba_device *ui;{	register struct	fza_softc *sc = &fza_softc[ui->ui_unit];	register int delay;	union fzacmd_buf *cmdpt;	FZARCVRING *rp;	FZAXMTRING *tp;	struct rmbuf *bp;	struct mbuf *m,*m1;	int unit = ui->ui_unit;	caddr_t mp;	int i;	sc->basereg = PHYS_TO_K1((u_long)reg);	/* fill out the register address and others */	sc->resetaddr = (struct fzareg  *)(sc->basereg + FZA_RESET);		sc->ctlaaddr = (struct fzareg *)(sc->basereg + FZA_CTL_A);		sc->ctlbaddr = (struct fzareg *)(sc->basereg + FZA_CTL_B);		sc->intraddr = (struct fzareg *)(sc->basereg + FZA_INT_EVENT);		sc->maskaddr = (struct fzareg *)(sc->basereg + FZA_INT_MASK);		sc->statusaddr  = (struct fzareg *)(sc->basereg + FZA_STATUS );			/* fill out the cmd and unsolicited ring address */	sc->cmdring = (FZACMDRING *)(sc->basereg + FZACMD_PHY_ADDR);	sc->unsring = (FZACMDRING *)(sc->basereg + FZAUNS_PHY_ADDR); 	/* turn on the driver active mode */	sc->reg_ctlb = FZA_ACTIVE ;	/* Clear the interrupt event register */	sc->reg_mask = FZA_INTR_MASK;	sc->reg_intr = sc->reg_intr;	wbflush();	/*	 * perform the adapter self test	*/	if(!fzaselftest(sc,unit)) {		printf("fza%d: fzaprobe selftest fail \n",unit);		return(0);	}		/* set the interrup mask */	sc->reg_mask = FZA_INTR_MASK;	/*	 * Allocate space for the ctrblk, initblk and statusblk	 */	 KM_ALLOC(mp, caddr_t, 512 * 3  , KM_DEVBUF, KM_NOW_CL_CO_CA);	 if (mp == 0) {		printf("fza%d: Couldn't allocate memory for internal structure\n", unit);		return(0);	}	sc->ctrblk = (struct _fzactrs *)mp;	sc->initblk =  (struct fzainit *)(mp + 512);	sc->statusblk = (struct fzastatus *)(mp + 512 * 2);	/*	 * initialize all the indexes 	 *         * sc->tindex == index of next transmit desc. to activate         * sc->ltindex  == index of last transmit processed         * sc->nxmit  == # of transmit pending         * sc->rindex == index of next recv. descriptor to activate         * sc->tsmtindex  == index of next SMT tansmit to CNS         * sc->rsmtindex  == index of next SMT receive from CNS         * sc->cmdindex  == index of next command desc. to activate         * sc->lcmdindex  == index of last comman processed         * sc->unsindex ==  index of next unsolicited desc. to activate         */        sc->tindex = sc->nxmit = sc->rindex = 0;        sc->tsmtindex = sc->rsmtindex = 0;        sc->cmdindex = sc->unsindex = 0;        sc->ltindex = sc->lcmdindex = -1;		sc->smtrmcindex = sc->lsmtrmcindex = 0;		sc->initflag = 1;	/*	 * We are now guaranteed that the port has succesfully completed	 * self test and is in the "UNINITIALIZED" state. At this point,	 * we can prepare a command buffer to issue the INIT command	 * 	 */	if(!fzacmdinit(sc,unit)) {		printf("fzaprobe init command fail \n",unit);		KM_FREE(mp,KM_DEVBUF);		return(0);	}		sc->reg_intr = sc->reg_intr;	/* 	 * get the initial value from the INIT command	 * fill out the init value 	 */	fzafillinit(sc,sc->initblk);	sc->reg_mask = FZA_INTR_MASK;	/*	 * put two multicast addresses :	 *	 	 *	Ring Purger	: 09-00-2b-02-01-05	 *	Directed Beacon : 01-80-c2-00-01-00	 */	bcopy(fza_rpurge,&sc->is_multi[0][0],6);	bcopy(fza_dbeacon,&sc->is_multi[1][0],6);	sc->is_muse[0] = sc->is_muse[1] = 1;		/*	 * allocate mbufs for receive ring	 */	for (i = 0, rp = &sc->rring[0], bp = &sc->rmbuf[0]; (i < NFZARCV ); 					i++, rp++, bp++) {		FZAMCLGET(m)		if(m) {			FZAMCLGET(m1)			if (m1) {				fzainitdesc(rp, bp, m, m1);			} else {				goto fail;				break;			}		} else {			goto fail;				break;		}	}	/*	 * clear the transmit ring mbuf entry	 */	for ( i=0, tp = &sc->tring[0]; i < sc->nrmcxmt ; i++, tp++) 			tp->xmt_mbuf = (struct mbuf *)0;		return (sizeof(struct fza_softc));fail:	KM_FREE(mp,KM_DEVBUF);	for (i = 0, bp = &sc->rmbuf[0]; (i < NFZARCV ); i++, bp++) {		if(bp->mbufa != NULL)			m_freem(bp->mbufa);		if(bp->mbufb != NULL)			m_freem(bp->mbufb);	}	printf("fza%d: fzaprobe fail - can not allocate enough receive buffer",unit);	return(0);	}/* * Interface exists: make available by filling in network interface * record.  System will initialize the interface when it is ready * to accept packets. */fzaattach(ui)	struct uba_device *ui;{	register struct fza_softc *sc = &fza_softc[ui->ui_unit];	register struct ifnet *ifp = &sc->is_if;	struct sockaddr_in *sin;	register int i;	/* initialize the lock */	lockinit(&sc->lk_fza_softc, &lock_device15_d);		ifp->if_unit = ui->ui_unit;	ifp->if_name = "fza";	ifp->if_mtu = FDDIMTU;	ifp->if_flags |= IFF_BROADCAST|IFF_DYNPROTO|IFF_802HDR| IFF_NOTRAILERS;	ifp->if_type = IFT_FDDI;	ifp->lk_softc = &sc->lk_fza_softc;	((struct arpcom *)ifp)->ac_ipaddr.s_addr = 0;	ifp->if_sysid_type = 119; 	/*	 * Initialize multicast address table	 */	for (i = 2; i < NMULTI; i++) {		bcopy((caddr_t)etherbroadcastaddr, sc->is_multi[i], 6);		sc->is_muse[i] = 0;	}	/*	 * Set maxlen for the SMT receive queue; attach interface	 */	sc->is_smt.ifq_maxlen = IFQ_MAXLEN;	sin = (struct sockaddr_in *)&ifp->if_addr;	sin->sin_family = AF_INET;	ifp->if_output = net_output;	ifp->if_start = fzastart;	ifp->if_init = fzainit;	ifp->if_ioctl = fzaioctl;	ifp->if_reset = fzareset;	ifp->if_watchdog = fzawatch;	ifp->if_timer = 1;	ifp->d_affinity = ALLCPU;	/*	 * Hook up the device interrupt vector to begin allowing interrupts.	 * We know that the device has been successfully initialized at this	 * point. Initialize if_version string.	 */	bcopy("DEC DEFZA FDDI Interface", ifp->if_version, 25);	ifp->if_version[25] = '\0';	printf("fza%d: %s, hardware address %s ROM rev %c%c%c%c Firmware rev %c%c%c%c \n", 		ifp->if_unit, ifp->if_version, ether_sprintf(sc->is_dpaddr),		sc->phy_rev[0],sc->phy_rev[1],sc->phy_rev[2],sc->phy_rev[3],		sc->fw_rev[0],sc->fw_rev[1],sc->fw_rev[2],sc->fw_rev[3]);#if	NPACKETFILTER > 0	attachpfilter(&(sc->is_ed));#endif	NPACKETFILTER	if_attach(ifp);}/* * Initialize interface. May be called by a user process or a software * interrupt scheduled by fzareset(). */fzainit(unit)	int unit;{	register struct fza_softc *sc = &fza_softc[unit];	register union fzacmd_buf *xcmd;	register struct mbuf *m;	register int delay;	FZACMDRING *cp; 	struct ifnet *ifp = &sc->is_if;	int i, s, t,timeout=0;	/* not yet, if address still unknown */	if (ifp->if_addrlist == (struct ifaddr *)0)		return;	if (ifp->if_flags & IFF_RUNNING)		return;	/*	 * Lock the softc to ensure coherency of softc data needed to fill	 * out the command buffers by "fzamkcmd". 	 */	t = splnet();	s = splimp();	smp_lock(&sc->lk_fza_softc, LK_RETRY);	/* clear the interrupt event register */	sc->reg_intr = sc->reg_intr;	wbflush();		/*	 * Issue the MODCAM command to set up the CAM addresses         */	if(cp=fzamkcmd(sc,CMD_MODCAM,unit)) {		smp_unlock(&sc->lk_fza_softc);                splx(s);                FZATIMEOUT(cp,timeout)                s = splimp();                smp_lock(&sc->lk_fza_softc,LK_RETRY);                if(timeout) {			printf ("fza%d: port modify CAM command  timeout \n", unit);                        goto done;		 } else if ( cp->status_id != CMD_SUCCESS ) {                        printf("fza%d: port init failed\n", unit);                        goto done;                }        } else {                printf("fza%d: port init failed\n", unit);                goto done;        }						/*	 * Issue a "PARAM" command to fill in the initial  	 * system parameters. Wait for completion,	 * which will be signaled by the interrupt handler.	 */	if(cp=fzamkcmd(sc, CMD_PARAM, unit)) {  		smp_unlock(&sc->lk_fza_softc);                splx(s);                FZATIMEOUT(cp,timeout)                s = splimp();                smp_lock(&sc->lk_fza_softc, LK_RETRY);                if(timeout) {                        printf ("fza%d: port PARAM command  timeout \n", unit);                        goto done;                } else if ( cp->status_id != CMD_SUCCESS ) {                        printf("fza%d: port init failed\n", unit);                        goto done;                }        } else {                printf("fza%d: port init failed\n", unit);                goto done;        }	if (ifp->if_flags & IFF_PROMISC) {		if (cp =fzamkcmd(sc, CMD_MODPROM,ifp->if_unit)) {			smp_unlock(&sc->lk_fza_softc);			splx(s);			FZATIMEOUT(cp,timeout)			if(timeout) {				printf ("fza%d: port MODPROM command timeout \n",unit);				goto done;			} else if (cp->status_id != CMD_SUCCESS) {                         	printf("fza%d: port init failed\n", unit);                        	goto done;			}		} else {                        printf("fza%d: port init failed\n", unit);                        goto done;		}	}	/*	 * Mark interface up and running; start output	 * on device.	 */	sc->is_if.if_flags |= (IFF_UP|IFF_RUNNING);	sc->is_if.if_flags &= ~IFF_OACTIVE; 	if(sc->initflag) {		sc->ztime = time.tv_sec;		sc->initflag = 0;	}	if (sc->is_if.if_snd.ifq_head)		fzastart(unit);		/* queue output packets */done:	/*	 * Relinqusih softc lock, drop IPL.	 */	smp_unlock(&sc->lk_fza_softc);	splx(s); 	splx(t);	if(fzadebug >  0 )		PRT_REG(sc)	return;}/* * FZA  start routine. Strings output packets and SMT output packets   * onto the transmit ring.  */fzastart(unit)	int unit;{	register FZAXMTRING  *tp;	register struct mbuf *m;	register int index;	struct fza_softc *sc = &fza_softc[unit];	struct ifnet *ifp = &sc->is_if;	FZAXMTRING *tpstart;	struct mbuf *m0;	int last,totlen;	u_long tmp;	/*	 * Process the transmit queues.	 */	for (index = sc->tindex, tp = &sc->tring[index] ; index !=sc->ltindex && !(tp->own & FZA_RMC_OWN) ;	     index = ++index % sc->nrmcxmt , tp = &sc->tring[index]) {next_m:		if (sc->is_if.if_snd.ifq_head ) {			IF_DEQUEUE(&sc->is_if.if_snd, m0);		} else  {			sc->tindex = index;			return;		}		/* 		 * get the total packet size and check the owner ship 		 * bit for the required number of RMC descriptors		 */		m = m0;		totlen = 0;		while (m) {			totlen += m->m_len ;			m = m->m_next;		}		/*		 * two bytes Preamble and one byte starting delimiter 		 */		if ( totlen > FDDIMAX )  {			/* 			 * drop this packet for size too long *			 */ 

⌨️ 快捷键说明

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