📄 if_sm.c
字号:
/* if_sm.c - shared memory backplane network interface driver *//* Copyright 1984-1995 Wind River Systems, Inc. *//*modification history--------------------01k,24jul96,vin upgraded to bsd4.4.01k,14dec96,dat fixed SPR 2258. chg'd inet_ntoa to inet_ntoa_b01j,11jan95,rhp remove reference to unpublished lib from man page.01i,19feb93,jdi documentation cleanup.01h,09sep92,gae documentation tweaks.01g,11jun92,elh added documentation, more cleanup, added parameter to smIfAttach.01f,02jun92,elh the tree shuffle01e,27may92,elh Incorperated the changes caused from restructuring the shared memory libraries.01d,17may92,elh renamed routines from sm to smIf01c,03may92,elh changed to use subnet in shared memory when calculating host address (smIfHwAddrSet).01b,12apr92,elh added in support for sequential addressing.01a,17nov90,elh written.*//*DESCRIPTIONThis module implements the VxWorks shared memory backplane networkinterface driver. This driver is designed to be moderately generic, operating unmodifiedacross the range of hosts and targets supported by VxWorks. To achieve this, the driver must be given several target-specific parameters, and some external support routines must be provided. These parameters are detailed below.The only user-callable routine is smIfAttach(), whichpublishes the `sm' interface and initializes the driver and device.This driver is layered between the shared memory packet library and the network modules. The backplane driver gives CPUs residing on a common backplane the ability to communicate using IP (via shared memory).This driver is used both under VxWorks and other host operating systems, e.g.,SunOs.BOARD LAYOUTThis device is "software only." There is no jumpering diagram required.INTERNALThis file runs under both SunOs and vxWorks. BEFORE MODIFYING THIS FILE, make sure the modifications are kosher for both. File Layout:This network interface driver has been physically split up into the the operating system specific code (smNetLib) and the common networkinterface code (if_sm). Dividing the driver up this way layers the driver and reduces the number of conditional compilations and thereby makes the code cleaner and more readable. ____________________ vxWorks interface |smNetLib (vxWorks) | |to backplane driver ____________________ |backplane | __________________ |driversunOs interface | _|smNetLib (sunOs) | |to backplane driver | / __________________ | v v |shared memory _______________ |backplane driver | if_sm | | _______________ | --------------------------------------- | | shared memory v | libraries ____________ | | smPktLib | ____________ smNetLib smNetLib implements the interface between the OS and the driver.There exists an smNetLib for both UNIX and VxWorks.Each smNetLib must implement how the OS initializes and attaches the driver, interrupt handling, etc as well as the OS dependent system calls. if_sm if_sm contains the network interface code that is common to most BSD based systems. It is the interface to the network modules and does the packet processing.OS Interface:The interfaces into this module from the OS specific modules follow. smIfAttach - attaches the shared memory network interface driver to the network modules. smIfAttach typically gets called once per backplane interface. The shared memory region must have been setup and initialized (via smPktSetup) prior to calling smIfAttach. smIfInput - gets called from the OS specific interrupt service handler to process input shared memory packets and to pass them up to the network modules. smIfLoanReturn - return a previously loaned shared memory buffer.OS Dependent Routines:The following routines/macros must be provided by the OS specific modules for this module: UNIT_TO_SOFTC convert unit to softc pointer outputHook output hook for packet inputHook input hook for packet etherAddrPtr return pointer to ethernet address copyFromMbufs copy from mbuf chain to passed buffer copyToMbufs copy from buffer to mbuf chain deviceValid if device is a valid device USE_CLUSTER use a cluster mbuf loanBuild build a loan mbuf bufferThere should be better documentation discussing the interfaces, functionality and expectations of the OS spcecific library.TARGET-SPECIFIC PARAMETERS.iP "local address of anchor"This parameter is passed to the driver by smIfAttach().It is the local address by which the local CPU accesses the shared memoryanchor..iP "maximum number of input packets"This parameter is passed to the driver by smIfAttach().It specifies the maximum number of incoming shared memory packets that can bequeued to this CPU at one time..iP "method of notification"These parameters are passed to the driver by smIfAttach().Four parameters can be used to allow a CPU to announce the method by which itis to be notified of input packets that have been queued to it..iP "heartbeat frequency"This parameter is passed to the driver by smIfAttach().It specifies the frequency of the shared memory anchor's heartbeat, which isexpressed in terms of the number of CPU ticks on the local CPU correspondingto one heartbeat period..iP "number of buffers to loan"This parameter is passed to the driver by smIfAttach().When the value is non-zero, this parameter specifies the number of sharedmemory packets available to be loaned out..LPSEE ALSO: ifLib, smNetLib*//* includes */#ifdef UNIX#include "smNetLib.h"#else#include "drv/netif/smNetLib.h"#endif#include "smLib.h"#include "smPktLib.h"#include "smUtilLib.h"/* globals */BOOL smIfVerbose = FALSE; /* verbose mode *//* forward declarations */ /* network hooks */LOCAL void smIfReset (int unit);LOCAL int smIfInit (int unit);LOCAL int smIfIoctl (struct ifnet * pIf, int cmd, caddr_t data);LOCAL void smIfRecv (SM_SOFTC * sm, SM_PKT * pPkt, BOOL * retBuffer);LOCAL void smIfHwAddrSet (int unit);LOCAL void smIfStartOutput (SM_SOFTC * xs);IMPORT void if_down (struct ifnet *);/********************************************************************************* smIfAttach - publish the `sm' interface and initialize the driver and device** This routine attaches an `sm' Ethernet interface to the network, if the* interface exists. This routine makes the interface available by filling in* the network interface record. The system will initialize the interface* when it is ready to accept packets.** The shared memory region must have been initialized, via smPktSetup(), prior* to calling this routine (typically by an OS-specific initialization routine).* The smIfAttach() routine can be called only once per unit number.** The <pAnchor> parameter is the local address by which the local CPU may* access the shared memory anchor.** The <maxInputPkts> parameter specifies the maximum number of incoming* shared memory packets which may be queued to this CPU at one time.** The <intType>, <intArg1>, <intArg2>, and <intArg3> parameters allow a* CPU to announce the method by which it is to be notified of input packets* which have been queued to it.** The <ticksPerBeat> parameter specifies the frequency of the shared memory* anchor's heartbeat. The frequency is expressed in terms of the number of CPU* ticks on the local CPU corresponding to one heartbeat period.** If <numLoan> is non-zero, it specifies the number of shared memory * packets available to be loaned out.** RETURNS: OK or ERROR.*/STATUS smIfAttach ( int unit, /* interface unit number */ SM_ANCHOR * pAnchor, /* local addr of anchor */ int maxInputPkts, /* max no. of input pkts */ int intType, /* method of notif. */ int intArg1, /* interrupt argument #1 */ int intArg2, /* interrupt argument #2 */ int intArg3, /* interrupt argument #3 */ int ticksPerBeat, /* heartbeat freq. */ int numLoan /* no. of buffers to loan */ ) { FAST SM_SOFTC * xs; /* softc pointer */ if ((xs = UNIT_TO_SOFTC (unit)) == NULL) return (ERROR); bzero ((caddr_t) xs, sizeof (SM_SOFTC)); /* Initialize the shared memory descriptor. */ smPktInit (&xs->smPktDesc, pAnchor, maxInputPkts, ticksPerBeat, intType, intArg1, intArg2, intArg3); if (numLoan) { xs->bufFree = numLoan; if (smIfVerbose) printf ("smIfAttach:%d loan buffers\n", xs->bufFree); } ether_attach ( &xs->xs_if, unit, "sm", smIfInit, smIfIoctl, (FUNCPTR) ether_output, /* generic ether_output */ (FUNCPTR) smIfReset ); xs->xs_if.if_start = (FUNCPTR) smIfStartOutput; return (OK); }/********************************************************************************* smIfInit - initialize the backplane interface** smIfInit initializes the backplane interface by attaching to shared memory* and by marking the interface as up and running. This routine gets called* (indirectly) through smIfIoctl which has the spl semaphore.** INTERNAL* We must attach to shared memory here (instead of smIfAttach) because we* can not wait around at boot time (in UNIX the case) waiting for shared* memory to become alive.** RETURNS: OK if successful, errno otherwise.*/LOCAL int smIfInit ( int unit /* unit number */ ) { FAST SM_SOFTC * xs; /* softc pointer */ SM_PKT_INFO smPktInfo; /* info structure */ xs = UNIT_TO_SOFTC (unit); /* attach to shared memory */ if (smPktAttach (&xs->smPktDesc) == ERROR) { if (smIfVerbose) printf ("smIfInit:couldn't attach [%x]\n", errno); return (errno); } smIfHwAddrSet (unit); /* set hardware address */ (void) smPktInfoGet (&xs->smPktDesc, &smPktInfo); xs->xs_if.if_mtu = smPktInfo.maxPktBytes - SIZEOF_ETHERHEADER; xs->xs_if.if_flags |= IFF_UP | IFF_RUNNING | IFF_MULTICAST; return (OK); }/********************************************************************************* smIfStartOutput - put packet in shared memory** This routine removes an mbuf chain from the interface send queue, copies* the data into a shared memory packet and calls smPktSend to send it off.* This routine gets called from ether_output, after it has taken the * spl semaphore.** RETURNS: N/A*/LOCAL void smIfStartOutput ( FAST SM_SOFTC * xs /* ptr to ctrl structure */ ) { FAST struct mbuf * pMbuf; /* mbuf pointer */ int len; /* data length */ int destCPU; /* destination cpu */ struct ether_header * pEh = NULL; /* enet header */ SM_PKT * pPkt = NULL; /* packet pointer */ BOOL retBuffer; /* return buffer */ while (xs->xs_if.if_snd.ifq_head != NULL) { /* dequeue mbuf chain, get a free shared memory packet */ IF_DEQUEUE (&xs->xs_if.if_snd, pMbuf); if ((smPktFreeGet (&xs->smPktDesc, &pPkt) == ERROR) || (pPkt == NULL)) { m_freem (pMbuf); if (smIfVerbose) printf ("smIfStartOutput:smPktFreeGet [%x]\n", errno); xs->xs_if.if_oerrors++; continue; } pEh = (struct ether_header *) pPkt->data; /* copy data to pkt */ copyFromMbufs (pEh, pMbuf, len); pPkt->header.nBytes = len; if (outputHook (&xs->xs_if, (char *)pEh, pPkt->header.nBytes) != 0) { (void) smPktFreePut (&xs->smPktDesc, pPkt); continue; } if (bcmp ((caddr_t) etherAddrPtr (pEh->ether_dhost), (caddr_t) etherAddrPtr (etherbroadcastaddr) , sizeof (pEh->ether_dhost)) == 0) destCPU = SM_BROADCAST; /* specify broadcast */ else { u_char * pEaddr; pEaddr = etherAddrPtr (pEh->ether_dhost); if (xs->masterAddr != 0) /* sequential addressing */ { destCPU = ((pEaddr [3] << 16)|(pEaddr [4] << 8)| pEaddr [5]) - xs->masterAddr; } else destCPU = pEaddr [5]; if (destCPU == xs->smPktDesc.smDesc.cpuNum) /* sending to myself */ { smIfRecv (xs, pPkt, &retBuffer); if (retBuffer)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -