📄 sysln97xend.c
字号:
/* sysLn97xEnd.c - system configuration module for ln97xEnd */ /* Copyright 1984 - 1999 Wind River Systems, Inc. */ /*modification history--------------------01b,07mar02,kab SPR 70817: *EndLoad returns NULL on failure01a,10oct99,mtl written from yk 750 by teamF1*//*DESCRIPTIONThis is the WRS-supplied configuration module for the VxWorks ln97xEnd (lnPci) END driver. It performs the dynamic parameterization of the ln97xEnd driver. This technique of 'just-in-time' parameterization allows driver parameter values to be declared as any other defined constants rather than as static strings. */ /* includes */#if (defined (INCLUDE_LN_97X_END) && defined (INCLUDE_NETWORK) \ && defined (INCLUDE_END))#include "vxWorks.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include "end.h"#include "config.h"#include "drv/end/ln97xEnd.h" /* defines */ /* AMD 7997x 10/100Base-TX Board type */ #define LN_TYPE_970 1 /* AMD 97c970 PCI Ethernet PCNet */#define LN_TYPE_971 2 /* AMD 97c970 PCI Ethernet PCNet Fast */#define LN_TYPE_972 3 /* AMD 97c970 PCI Ethernet PCNet Fast+ */#define LN_TYPE_7990 4 #define LN97X_MAX_UNITS 4 /* number of board types */ /* LN970 driver user flags */ #define LN_USR_FLAGS_970 0#define LN_USR_FLAGS_971 0#define LN_USR_FLAGS_972 0#define LN_USR_FLAGS_7990 0 /* PCI vendor/device Ids and rev mask */ #define LN97X_PCI_VENDOR_ID 0x1022 /* AMD */#define LN97X_PCI_DEVICE_ID 0x2000 /* PCI device ID */#define LN7990_PCI_DEVICE_ID 0x0000 /* PCI device ID */#define LN970_PCI_REV_MASK 0x10 /* 79970 pci rev mask */#define LN971_PCI_REV_MASK 0x20 /* 79971 pci rev mask */#define LN972_PCI_REV_MASK 0x30 /* 79972 pci rev mask */#define LN97X_CSR3_VALUE 0 /* csr3 value */ /* * default values if PCI_CFG_TYPE defined to be PCI_CFG_FORCE * note: memory addresses must be aligned on MMU page boundaries */ #define LN97X_IO_ADR0 0xf400#define LN97X_MEM_ADR0 0xfd000000#define LN97X_INT_LVL0 0x03#define LN97X_INT_VEC0 0x03 #define LN97X_IO_ADR1 0xf420#define LN97X_MEM_ADR1 0xfd200000#define LN97X_INT_LVL1 0x02#define LN97X_INT_VEC1 0x02 #define LN97X_IO_ADR2 0xf440#define LN97X_MEM_ADR2 0xfd300000#define LN97X_INT_LVL2 0x01#define LN97X_INT_VEC2 0x01 #define LN97X_IO_ADR3 0xf460#define LN97X_MEM_ADR3 0xfd400000#define LN97X_INT_LVL3 0x0#define LN97X_INT_VEC3 0 #define LN97X_MAX_DEV 4 #define NET_END_USER_FLAGS LN_USR_FLAGS_972#define NET_ADAPTER_VENDOR_ID LN97X_PCI_VENDOR_ID#define NET_ADAPTER_DEVICE_ID LN97X_PCI_DEVICE_ID #define LN_97X_LOAD_FUNC ln97xEndLoad /* externs */IMPORT END_OBJ* ln97xEndLoad (char *);/* typedefs */ typedef struct ln97xPciRsrc /* LN97X_PCI_RSRC */ { UINT32 iobaseCsr; /* Base Address Register 0 */ UINT32 membaseCsr; /* Base Address Register 1 */ char irq; /* Interrupt Request Level */ UINT32 irqvec; /* Interrupt Request vector */ UINT32 configType; /* type of configuration */ UINT32 boardType; /* type of LAN board this unit is */ UINT32 pciBus; /* PCI Bus number */ UINT32 pciDevice; /* PCI Device number */ UINT32 pciFunc; /* PCI Function number */ } LN97X_PCI_RSRC; typedef struct boardResource /* LN97X_BRD_RSRC */ { UINT32 type; /* type of the board */ UINT32 vendorId; /* Vendor ID */ UINT32 deviceId; /* Device ID */ UINT32 lnUsrFlags; /* LN driver user flags */ FUNCPTR mediaSelectFunc; /* media select routine */ } LN97X_BRD_RSRC; /* locals */LOCAL int ln97XUnits = 0;LOCAL LN97X_PCI_RSRC * pRsrc; /* pointer board resources */ /* * This array defines the board-specific PCI resources, the base address * register configuration mode and the Ethernet adapter type. It's indexed * using the device number returned from pciFindDevice(). */ LOCAL LN97X_PCI_RSRC ln97xPciRsrcs [LN97X_MAX_DEV] = { {LN97X_IO_ADR0, LN97X_MEM_ADR0, LN97X_INT_LVL0, LN97X_INT_VEC0, PCI_CFG_TYPE, LN_TYPE_970, 0, 0, 0}, {LN97X_IO_ADR1, LN97X_MEM_ADR1, LN97X_INT_LVL1, LN97X_INT_VEC1, PCI_CFG_TYPE, LN_TYPE_970, 0, 0, 0}, {LN97X_IO_ADR2, LN97X_MEM_ADR2, LN97X_INT_LVL2, LN97X_INT_VEC2, PCI_CFG_TYPE, LN_TYPE_970, 0, 0, 0}, {LN97X_IO_ADR3, LN97X_MEM_ADR3, LN97X_INT_LVL3, LN97X_INT_VEC3, PCI_CFG_TYPE, LN_TYPE_970, 0, 0, 0}, }; /* * This array defines board-specific vendor and device ids, flags to pass to * the drive load routine and the function used to select the media. */ LOCAL LN97X_BRD_RSRC ln97xBrdRsrc [LN97X_MAX_UNITS] = { {LN_TYPE_970, LN97X_PCI_VENDOR_ID, LN97X_PCI_DEVICE_ID, LN_USR_FLAGS_970, NULL}, {LN_TYPE_971, LN97X_PCI_VENDOR_ID, LN97X_PCI_DEVICE_ID, LN_USR_FLAGS_971, NULL}, {LN_TYPE_972, LN97X_PCI_VENDOR_ID, LN97X_PCI_DEVICE_ID, LN_USR_FLAGS_972, NULL}, {LN_TYPE_7990, LN97X_PCI_VENDOR_ID, LN7990_PCI_DEVICE_ID, LN_USR_FLAGS_7990, NULL}, };/******************************************************************************** sysLn97xEndLoad - load and create load string, for a ln97x (lnPci) device.** This routine loads the lnPci device with initial parameters. ** RETURNS: pointer to END object or NULL.** SEE ALSO: ln97xEndLoad()*/ END_OBJ * sysLn97xEndLoad ( char * pParamStr, /* ptr to initialization parameter string */ void * unused /* unused optional argument */ ) { /* * The ln97xEnd driver END_LOAD_STRING should be: * <unit>:<devMemAddr>:<devIoAddr>:<pciMemBase:<vecNum>:<intLvl>:<memAdrs>: * <memSize>:<memWidth>:<csr3b>:<offset>:<flags> * * Note that ln97xEnd unit number is prepended in muxDevLoad, so we * don't put it here! */ char * cp; char paramStr [END_INIT_STR_MAX]; /* from end.h */ END_OBJ * pEnd; static char ln97xParamTemplate[] = "0x%x:0x%x:0x%x:%d:%d:-1:-1:-1:0x%x:%d:0x%x"; if (strlen (pParamStr) == 0) { /* * muxDevLoad() calls us twice. If the string is * zero length, then this is the first time through * this routine, so we just return. */ pEnd = ln97xEndLoad (pParamStr); } else { /* * On the second pass though here, we actually create * the initialization parameter string on the fly. * Note that we will be handed our unit number on the * second pass through and we need to preserve that information. * So we use the unit number handed from the input string. */ cp = strcpy (paramStr, pParamStr); /* cp points to paramStr */ /* Now, we advance cp, by finding the end the string */ cp += strlen (paramStr); /* finish off the initialization parameter string */ sprintf (cp, ln97xParamTemplate, /* device memory Io base */ (UINT) PCI_MEMIO2LOCAL (pRsrc->membaseCsr), /* device Io base */ (UINT) PCI_IO2LOCAL (pRsrc->iobaseCsr), (UINT) PCI_SLV_MEM_LOCAL, /* pciMemBase */ pRsrc->irqvec, /* interrupt IRQ vector */ pRsrc->irq, /* interrupt irq number */ LN97X_CSR3_VALUE, /* csr3 register value */ 0, /* offset */ NET_END_USER_FLAGS /* flags */ ); if ((pEnd = ln97xEndLoad (paramStr)) == (END_OBJ *)NULL) { printf ("Error: device failed ln97xEndLoad routine.\n"); } } return (pEnd); } /********************************************************************************* sysLan97xPciInit - prepare LAN adapter for LN97X initialization** This routine finds out the PCI device, maps its memory and IO address.* It must be done prior to initializing the LN970, sysLn97XInit(). Also* must be done prior to MMU initialization, usrMmuInit().** RETURNS: OK/ERROR*/ STATUS sysLan97xPciInit (void) { UINT32 membaseCsr; UINT32 iobaseCsr; char irq; int pciBus; int pciDevice; int pciFunc; int unit; int found = 0; /* for all the support lan devices find if some of them exist */ for (unit = 0; unit < LN97X_MAX_UNITS; unit++) { if (pciFindDevice (ln97xBrdRsrc [unit].vendorId, ln97xBrdRsrc [unit].deviceId, unit, &pciBus, &pciDevice, &pciFunc) == OK) { /* board detected */ /* for now, we're ignoring the possibility of duplicates */ found = TRUE; /* load up the PCI device table */ pRsrc = ln97xPciRsrcs + ln97XUnits; /* get the pci entry */ pRsrc->pciBus = pciBus; pRsrc->pciDevice = pciDevice; pRsrc->pciFunc = pciFunc; ln97XUnits++; /* number of units found */ } } if ((found != TRUE) || (pciDevice > PCI_MAX_DEV)) return (ERROR); /* Now initialize all the units we found */ for (unit = 0; unit < ln97XUnits; unit++) { /* Fill in the resource entry */ pRsrc = ln97xPciRsrcs + unit; if (pRsrc->configType == PCI_CFG_FORCE) { /* write the iobase, membase, and irq */ pciConfigOutLong (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_BASE_ADDRESS_0, pRsrc->iobaseCsr | PCI_BASE_IO); pciConfigOutLong (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_BASE_ADDRESS_1, pRsrc->membaseCsr); pciConfigOutByte (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_DEV_INT_LINE, pRsrc->irq); } /* * get memory base address and IO base address * Note: we read it in again, even if we just wrote it out because the * device can change what we wrote */ pciConfigInLong (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_BASE_ADDRESS_0, &iobaseCsr); pciConfigInLong (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_BASE_ADDRESS_1, &membaseCsr); pciConfigInByte (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_DEV_INT_LINE, &irq); /* * mask off registers. IO base needs to be masked off because bit0 * will always be set to 1 */ membaseCsr &= PCI_MEMBASE_MASK; iobaseCsr &= PCI_IOBASE_MASK; /* over write the resource table with values read */ pRsrc->membaseCsr = membaseCsr; pRsrc->iobaseCsr = iobaseCsr; pRsrc->irq = irq; pRsrc->irqvec = IVEC_TO_INUM(irq); /* enable mapped memory and IO addresses */ pciConfigOutWord (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_COMMAND, PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE); /* disable sleep mode */ pciConfigOutWord (pciBus, pciDevice, pciFunc, PCI_CFG_MODE, SLEEP_MODE_DIS); } return (OK); }/********************************************************************************* sysLan97xIntEnable - enable Lan97x interrupts** This routine enables ln7997x interrupts. This may involve operations on* interrupt control hardware.** RETURNS: OK or ERROR for invalid arguments.*/ STATUS sysLan97xIntEnable ( int level /* level number */ ) { return (intEnable (level)); } /********************************************************************************* sysLan97xIntDisable - disable ln970 interrupts** This routine disables ln970 interrupts. This may involve operations on* interrupt control hardware.** RETURNS: OK or ERROR for invalid arguments.*/ STATUS sysLan97xIntDisable ( int level /* level number */ ) { return (intDisable(level)); } /********************************************************************************* sysLan97xEnetAddrGet - get Ethernet address** This routine provides a target-specific interface for accessing a* device Ethernet address.** -- Specific to 971 ldt** RETURNS: OK or ERROR if could not be obtained.*/ STATUS sysLan97xEnetAddrGet ( LN_97X_DRV_CTRL * pDrvCtrl, /* Driver control */ char * enetAdrs ) { char aprom [LN_97X_APROM_SIZE]; /* copy of address prom space */ char * ioaddr; int ix; /* get IO address of unit */ ioaddr = (char *)(pDrvCtrl->devAdrs); /* load aprom into an array */ for (ix=0; ix<32; ix++) { aprom [ix] = sysInByte((int)(ioaddr + ix)); } /* check for 'w's at end of list */ if ((aprom [0xe] != 'W') || (aprom [0xf] != 'W')) { /* should set errno here ? ldt */ logMsg ("sysLn97XEnetAddrGet W's not stored in aprom\n", 0, 1, 2, 3, 4, 5); return ERROR; } bcopy (aprom, enetAdrs, 6); return (OK); }#endif /* defined (INCLUDE_LN_97X_END) && defined (INCLUDE_NETWORK) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -