📄 sn83932end.c
字号:
/* sn83932End.c - Nat. Semi DP83932B SONIC Ethernet driver *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01u,15jan03,m_h IPv6 Support01t,20sep01,dat Removing ANSI errors for diab compiler01s,21jun01,rcs Merge SPR# 63876 fix to Tornado-Comp-Drv01r,16feb01,pai fixed mutual exclusion in sn83932Send().01q,16feb01,pai removed int[Lock|Unlock] frame around <txBlocked> flag set.01p,16feb01,pai fixed handling of IFF_UP and IFF_RUNNING flags (SPR #63876).01o,16feb01,pai made strtok_r arguments consistent with SPR 62224 fix.01n,16feb01,pai allocated DRV_CTRL structure from heap (SPR #32774).01m,16feb01,pai removed reference to etherLib.01l,16feb01,pai fixed use of NULL01k,16feb01,pai corrected return error codes and freed mBlk chain (SPR #28492)01j,22sep98,dat lint warnings removed01i,18aug98,fle doc : made first line in one-line01h,11dec97,kbw making man page edits01g,08dec97,gnn END code review fixes.01f,05dec97,pul restored sonic driver after major rework01e,20aug97,pul modified buffering scheme to use MBLKs01d,12aug97,gnn changes necessitated by MUX/END update.01c,02May97,sal Man page fix - SPR848701b,29Apr97,sal set LBR bit in snEndDcr by default01a,04Feb97,sal adapted from if_sn.c (01s,23apr96,wkm)*//*DESCRIPTIONThis module implements the National Semiconductor DP83932 SONIC Ethernet network interface driver.This driver is designed to be moderately generic. Thus, it operates unmodified across the range of architectures and targets supported by VxWorks. To achieve this, the driver load routine requires several target-specific parameters. The driver also depends on a few external support routines. These parameters and support routines are described below. If any of the assumptions stated below are not true foryour particular hardware, this driver probably cannot function correctlywith that hardware. This driver supports up to four individual units per CPU.BOARD LAYOUTThis device is on-board. No jumpering diagram is necessary.EXTERNAL INTERFACEThis driver provides the END external interface. Thus, the only normal external interface is the sn83932EndLoad() routine, although snEndClkEnable() and snEndClkDisable() are provided for the use (optional) of the internal clock. All required parameters are passed into the load function by means of a single colon-delimited string. The sn83932Load() function uses strtok() to parse the string,which it expects to be of the following format: <unit_ID>:<devIO_addr>:<ivec>:<e_addr>The entry point for sn83932EndLoad() is defined within the 'endDevTbl' in configNet.h.TARGET-SPECIFIC PARAMETERS.IP <unit_ID>A convenient holdover from the former model, this is only used in thestring name for the driver..IP <devIO_addr>Denotes the base address of the device's I/O register set. .IP <ivec>Denotes the interrupt vector to be used by the driver to service an interrupt from the SONIC device. The driver connects the interrupt handler to this vector by calling intConnect()..IP <e_addr>This parameter is obtained by calling sysEnetAddrGet(), an external support routine. It specifies the unique six-byte address assigned to the VxWorks target on the Ethernet..LPEXTERNAL SUPPORT REQUIREMENTSThis driver requires the following external support routines:.IP sysEnetInit().CS void sysEnetInit (int unit).CEThis routine performs any target-specificoperations that must be executed before the SONIC device is initialized.The driver calls this routine, once per unit, during the unit start-up phase..IP sysEnetAddrGet().CS STATUS sysEnetAddrGet (int unit, char *pCopy).CEThis routine provides the six-byte Ethernet address used by <unit>. Itmust copy the six-byte address to the space provided by <pCopy>. Thisroutine returns OK, or ERROR if it fails. The driver calls this routine, once per unit, during the unit start-up phase. .IP sysEnetIntEnable().CS void sysEnetIntEnable (int unit), void sysEnetIntDisable (int unit).CEThese routines enable or disable the interrupt fromthe SONIC device for the specified <unit>. Typically,this involves interrupt controller hardware,either internal or external to the CPU. The driver calls these routines only during initialization, during the unit start-up phase..IP sysEnetIntAck().CS void sysEnetIntAck (int unit).CEThis routine performs any interrupt acknowledgment orclearing that may be required. This typicallyinvolves an operation to some interrupt control hardware. The driver calls this routine from the interrupt handler..LPDEVICE CONFIGURATIONTwo global variables, 'snEndDcr' and 'snEndDcr2', are used to set the SONICdevice configuration registers. By default, the device is programmed in32-bit mode with zero-wait states. If these values are not suitable,the 'snEndDcr' and 'snEndDcr2' variables should be modified before loading the driver. See the SONIC manual for information on appropriatevalues for these parameters.SYSTEM RESOURCE USAGEWhen implemented, this driver requires the following system resources: - one interrupt vector - 0 bytes in the initialized data section (data) - 696 bytes in the uninitialized data section (BSS)The above data and BSS requirements are for the MC68020 architecture and can vary for other architectures. Code size (text) varies greatly between architectures and is therefore not quoted here.This driver uses cacheDmaMalloc() to allocate the memory to be shared with the SONIC device. The size requested is 117,188 bytes.The SONIC device can only be operated if the shared memory region iswrite-coherent with the data cache. The driver cannot maintain cachecoherency for the device for data that is written by the driverbecause fields within the shared structures are asynchronously modified bythe driver and the device, and these fields may share the same cacheline.SEE ALSO: ifLib*//*INTERNALThis driver contains conditional compilation switch DEBUG.If defined, adds debug output routines. Output is furtherselectable at run-time via the snDebug global variable.See also the NOTES section at the end of this file.Also contains LED DEBUG switch which enables the Led output.*/#include "vxWorks.h"#include "sys/types.h"#include "taskLib.h"#include "iv.h"#include "memLib.h"#include "sys/ioctl.h"#include "etherMultiLib.h"#include "net/protosw.h"#include "errno.h"#include "cacheLib.h"#include "stdio.h"#include "intLib.h"#include "logLib.h"#include "netLib.h"#include "netBufLib.h"#include "muxLib.h"#include "netinet/if_ether.h"#ifdef WR_IPV6#include "adv_net.h"#endif /*WR_IPV6*//* Include END specific headers */#include "endLib.h"/* Device Header File */#include "drv/end/sn83932End.h"/* CONDITIONAL SWITCHES */#undef DEBUG#undef LED_DEBUG#define SN_DEV_NAME "sn"#define SN_DEV_NAME_LEN 3#if defined(LED_DEBUG) #include "../../../config/p4000/p4000.h"#endif/* STDOUT MACRO */#define SN_LOGMSG(s,x1,x2,x3,x4,x5,x6) logMsg (s,x1,x2,x3,x4,x5,x6) /* LED */#if defined(LED_DEBUG) || defined(PULI_LED_DEBUG)#define PutLED(x,y) *P4000_ALPHAN_CHAR(y) = x << 24;#define ClrLED \ *P4000_ALPHAN_CLR_ = P4000_RESET_ONE; \ *P4000_ALPHAN_CHAR(0) = ' ' << 24; \ *P4000_ALPHAN_CHAR(1) = ' ' << 24; \ *P4000_ALPHAN_CHAR(2) = ' ' << 24; \ *P4000_ALPHAN_CHAR(3) = ' ' << 24#endif /* LOCAL DEFINITIONS *//* Maximum number of Multicast addresses supported */#define MAX_MCASTS 15/* configurable cluster sizes of the two cluster pools *//* one, optimal cluster size */#define OPTIMAL_CLUSTER_SIZE 128/*second, MTU cluster size */#define MTU_CLUSTER_SIZE (ETHERMTU + SIZEOF_ETHERHEADER + 6)/* 10 Mb */#define SN_SPEED 10000000/* Data Interrupt bits */#define SN_IMR_DATA (PRXEN | PTXEN | TXEREN)#define SN_IMR_INIT (SN_IMR_DATA | BREN)/* max number of units to support */#define MAX_UNITS 4 /* Minimum buffer fragment */#define MIN_1STXMTBUF_SIZE 4/* size of one receive buffer */#define RX_BUF_SIZE (0x2000) #define RX_BUF_EXTRA (0x200) /* Extra space needed to accomodate */ /* Sonic buffer overrun in Rev. C */ /* parts - found by Algorithmics *//* Total Receive Buffer Area */#define RBA_SIZE ((RX_BUF_SIZE + RX_BUF_EXTRA) * NUM_RRA_DESC)/*** END MACROS ***/ /* Should be in endlib.h in my opinion */#define END_M2_INUCAST(pEnd) (pEnd)->mib2Tbl.ifInUcastPkts++#define END_M2_INNUCAST(pEnd) (pEnd)->mib2Tbl.ifInNUcastPkts++#define END_M2_INERRORS(pEnd) (pEnd)->mib2Tbl.ifInErrors++#define END_M2_INDISCARDS(pEnd) (pEnd)->mib2Tbl.ifInDiscards++#define END_M2_INOCTETS(pEnd,bytes) (pEnd)->mib2Tbl.ifInOctets += bytes#define END_M2_OUTUCAST(pEnd) (pEnd)->mib2Tbl.ifOutUcastPkts++#define END_M2_OUTNUCAST(pEnd) (pEnd)->mib2Tbl.ifOutNUcastPkts++#define END_M2_OUTDISCARDS(pEnd) (pEnd)->mib2Tbl.ifOutDiscards++#define END_M2_OUTERRORS(pEnd) (pEnd)->mib2Tbl.ifOutErrors++#define END_M2_OUTOCTETS(pEnd,bytes) (pEnd)->mib2Tbl.ifOutOctets += bytes/* Struc to keep track of frag free routine: used in the driver struct below */typedef struct free_routine { FUNCPTR pfreeRtn; /* Free routine for the */ /* frag buffer */ void* pSpare1; /* Spare agurment */ void* pSpare2; /* Spare agurment */ }FREE_ROUTINE; /* Driver control structure. One per unit supported. */typedef struct drv_ctrl { END_OBJ endData; /* Enhance network driver */ /* structure */ SONIC* pDev; /* ptr to the device registers */ int unit; /* unit # of the device */ int ivec; /* interrupt vectore */ char* pMem; /* ptr to allocated chunk */ char* pShMem; /* ptr to area shared with */ /* device */ unsigned long shMemSize; /* size of the shared area */ unsigned long RSA; /* Start of Resource Area */ unsigned long REA; /* End of Resource Area */ unsigned long RBA1; /* Start of Receive Buffer Area */ unsigned long RBA2; /* Start of Receive Buffer Area */ unsigned long RBA3; /* Start of Receive Buffer Area */ unsigned long RBA4; /* Start of Receive Buffer Area */ unsigned long RDA; /* Start of Receive Desc Area */ unsigned long CDA; /* Start of CAM Desc Area */ TX_DESC* pTDA; /* Start of Transmit Desc Area */ TX_DESC* pTXDFree; /* ptr to next free TXD */ TX_DESC* pTXDReclaim; /* ptr to next reclaimable TXD */ TX_DESC* pTXDLast; /* ptr to last transmitted TXD */ BOOL txBlocked; /* transmit flow control */ RX_DESC* pRXDNext; /* Next Receive descriptor */ RX_DESC* pRXDLast; /* Last one in link */ u_long* pCamEnableMask; /* Pointer to CAM enable */ /* mask entry */ u_char mcastTable[MAX_MCASTS * 6]; /* Our own mcast table */ FUNCPTR timerIntHandler; /* Interrupt timer handler */ int ticks; /* number of interrupts */ /* generated per sec */ unsigned int imr; /* Record of interrupt mask */ BOOL online; /* Denotes device is */ /* online (started)*/ u_char flags; /* Local Flags */ UCHAR enetAddr[6]; /* ethernet address */ FREE_ROUTINE freeBuf[NUM_TX_DESC]; /* per Tx descriptor */ CL_POOL_ID pClPoolId[NUM_CLUSTER_POOLS]; /* array of cluster pools each */ /* of different size */ } DRV_CTRL;/*network buffer configuration */M_CL_CONFIG SnMclConfig = /*mBlk configuration table */ { 0, 0, NULL, 0 };/*network cluster pool configuration */CL_DESC SnClDescTbl []= { /* ClusterSize num memArea memsize ----------- --- ------- ------- */ { OPTIMAL_CLUSTER_SIZE, 0, NULL, 0 }, { MTU_CLUSTER_SIZE, 0, NULL, 0 } };/*Number of cluster pools */int SnClDescTblNumEnt = (NELEMENTS(SnClDescTbl));/* Initialization Parameters within InitString */typedef struct { int unit; int ivec; u_long devaddr; } INIT_PARM;/* GLOBALS */unsigned long snEndDcr = WAIT0 | DW_32 | LBR;unsigned long snEndDcr2 = 0;/* External function prototypes not defined in any header files. * Some of these are the functions required of the BSP modules. */IMPORT STATUS sysEnetAddrGet ();IMPORT STATUS sysEnetInit ();IMPORT STATUS sysEnetIntEnable ();IMPORT STATUS sysEnetIntDisable ();IMPORT STATUS sysEnetIntAck ();#if defined(LED_DEBUG) || defined(DEBUG)#undef LOCAL#define LOCAL #endif/* END EXTERNAL INTERFACE ROUTINES */END_OBJ* sn83932EndLoad (char* initString);/* REQUIRED END ENTRY POINTS */LOCAL STATUS sn83932Start (DRV_CTRL *);LOCAL STATUS sn83932Stop (DRV_CTRL *);LOCAL STATUS sn83932Unload (DRV_CTRL *);LOCAL int sn83932Ioctl (DRV_CTRL *, int, caddr_t);LOCAL STATUS sn83932Send (DRV_CTRL *, M_BLK_ID pBuf);LOCAL STATUS sn83932MCastAddrAdd (DRV_CTRL *, char*);LOCAL STATUS sn83932MCastAddrDel (DRV_CTRL *, char*);LOCAL STATUS sn83932MCastAddrGet (DRV_CTRL *, MULTI_TABLE*);LOCAL STATUS sn83932PollSend (DRV_CTRL *, M_BLK_ID pBuf);LOCAL STATUS sn83932PollRecv (DRV_CTRL *, M_BLK_ID pBuf);/* Interrupt Handler */LOCAL void sn83932Int (DRV_CTRL *);/* INTERNAL ROUTINES */LOCAL STATUS snInitParse (INIT_PARM *, char *);LOCAL STATUS snInitMem (DRV_CTRL *);LOCAL void snChipReset (DRV_CTRL *);LOCAL void snChipInit (DRV_CTRL *);LOCAL void snChipStart (DRV_CTRL *);LOCAL void snCamMacLoad (DRV_CTRL *);LOCAL void snCamMcastLoad (DRV_CTRL *);LOCAL void snPollStart (DRV_CTRL *);LOCAL void snPollStop (DRV_CTRL *);LOCAL void snIfConfig (DRV_CTRL *, int);LOCAL void snTxReclaim (DRV_CTRL *, int);LOCAL int snProcessRxPkts (DRV_CTRL *, int, M_BLK_ID pBuf);LOCAL void snEventHandler (DRV_CTRL *);/* SONIC Clock TIMER ENTRY POINTS */void snEndClkEnable (int, int, FUNCPTR);void snEndClkDisable (int);/* * Declare our function table. This is static across all driver * instances. */LOCAL NET_FUNCS snFuncTable = { (FUNCPTR)sn83932Start, /* Function to start the device. */ (FUNCPTR)sn83932Stop, /* Function to stop the device. */ (FUNCPTR)sn83932Unload, /* Unloading function for the driver. */ (FUNCPTR)sn83932Ioctl, /* Ioctl function for the driver. */ (FUNCPTR)sn83932Send, /* Send function for the driver. */ (FUNCPTR)sn83932MCastAddrAdd,/* Multicast address add function */ (FUNCPTR)sn83932MCastAddrDel,/* Multicast address delete function. */ (FUNCPTR)sn83932MCastAddrGet,/* Multicast table retrieve function. */ (FUNCPTR)sn83932PollSend, /* Polling send function. */ (FUNCPTR)sn83932PollRecv, /* Polling receive function. */ endEtherAddressForm, /* Put address info into a NET_BUFFER */ endEtherPacketDataGet, /* Get pointer to data in NET_BUFFER. */ endEtherPacketAddrGet };/* SECTION: Initialization and Start-Up Routines *//********************************************************************************* sn83932EndLoad - initialize the driver and device** This routine initializes the driver and the device to the operational state.* All of the device specific parameters are passed in the <initString> * parameter. This string must be of the format:** <unit_number>:<device_reg_addr>:<ivec>** These parameters are all individually described in the sn83932End man* page.** RETURNS: An END object pointer or NULL on error.*/END_OBJ * sn83932EndLoad ( char * initString /* String to be parse by the driver. */ ) { INIT_PARM initParm; DRV_CTRL * pDrvCtrl;#ifdef DEBUG SN_LOGMSG ("sn83932End Loading...\n", 0,0,0,0,0,0);#endif /* Parse the initString Parameters */ if (initString == NULL) return(NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -