📄 sysend.c
字号:
/* sysEnd.c - System Enhanced network interface support library *//* Copyright 1997-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01b,22aug03,scm bspcheck release test modifications...01a,27mar02,lagarwal created from ixp1200eb_be*//*DESCRIPTIONThis file contains the board-specific routines for Ethernet adapterinitialisation of Intel Pro 100+ based adapters.NOTEAt the time of writing, this module has only been tested with the followingEthernet cards: 82559 controller: Intel PRO/100+ Management Adapter Intel InBusiness 10/100 PCI Network AdapterRefer to the BSP reference entry for any eventual limitations orproblems related to the BSP.SEE ALSO: ifLib,.I "Intel 10/100 MBit Ethernet Family Software technical Reference Manual."*/#include "vxWorks.h"#include "config.h"#include "cacheLib.h"#include "stdio.h"#ifdef INCLUDE_END#include "drv/end/fei82557End.h"#include "ixdp2400Pci.h"#include "end.h"#ifdef END_DEBUG#undef LOCAL#define LOCAL#endif/* defines */#define INCLUDE_INTEL_HW_WORKAROUND#ifdef INCLUDE_INTEL_HW_WORKAROUND#define FEI_BUF_SIZE 0x48684#define FEI_NUM_CFDS 32#define FEI_NUM_RFDS 32#endif#define CSR_BASE_MSK 0x7f /* Mask Base Address Register */#define END_LD_STR_SIZE 80#if (_BYTE_ORDER == _BIG_ENDIAN)#define FEI_SWAP_LONG(x) LONGSWAP(x)#define FEI_SWAP_WORD(x) (MSB(x) | LSB(x) << 8)#else#define FEI_SWAP_LONG(x) (x)#define FEI_SWAP_WORD(x) (x)#endif /* _BYTE_ORDER == _BIG_ENDIAN */#if A0_REV#define CSR_WORD_RD(offset, value) \ FEI_WORD_RD(offset, (value))#define CSR_LONG_RD(offset, value) \ FEI_LONG_RD(offset, (value))#define CSR_WORD_WR(offset, value) \ do { \ UINT32 temp1; \ FEI_WORD_WR(offset, (value)); \ CSR_WORD_RD(offset, temp1); \ } while (0)#define CSR_LONG_WR(offset, value) \ do { \ UINT32 temp1; \ FEI_LONG_WR(offset, (value)); \ CSR_LONG_RD(offset, temp1); \ } while (0)#else#define CSR_WORD_RD(offset, value) \ FEI_WORD_RD(offset, (value))#define CSR_LONG_RD(offset, value) \ FEI_LONG_RD(offset, (value))#define CSR_WORD_WR(offset, value) \ do { \ FEI_WORD_WR(offset, (value)); \ } while (0)#define CSR_LONG_WR(offset, value) \ do { \ FEI_LONG_WR(offset, (value)); \ } while (0)#endif/* PCI memory base address register configuration mode */#define FORCE 0x00 /* overwrite membase address register */#define AUTO 0x01 /* read membase address register */#define MAX_END_DEV 4/* * Need to use automatic configuration mode using the resource assigning in * pciAssignResources(). */#define PCI_REG_MOD AUTO /* define the register configuration mode */#define TYPE_ALLOC 1000/* * FEI cards in range 1001 -> 2000 */#define FEI_START TYPE_ALLOC + 1#define PRO100B FEI_START /* Intel EtherExpress PRO-100B PCI */#define INBUSINESS FEI_START + 1 /* Intel InBusiness 10/100 PCI */#define XX82559ER FEI_START + 100 /* Arbitrary card with 82559ER */#define BOARD_TYPE_NB (NELEMENTS(boardResources))/* EEPROM control bits */#define EE_SK 0x01 /* shift clock */#define EE_CS 0x02 /* chip select */#define EE_DI 0x04 /* chip data in */#define EE_DO 0x08 /* chip data out *//* EEPROM opcode */#define EE_CMD_WRITE 0x05 /* WRITE opcode, 101 */#define EE_CMD_READ 0x06 /* READ opcode, 110 */#define EE_CMD_ERASE 0x07 /* ERASE opcode, 111 *//* EEPROM misc. defines */#define EE_CMD_BITS 3 /* number of opcode bits */#define EE_ADDR_BITS 6 /* number of address bits */#define EE_DATA_BITS 16 /* number of data bits */#define EE_SIZE 0x40 /* 0x40 words */#define EE_CHECKSUM 0xbaba /* checksum */#define FEI_MEMSIZE0 0x00001000#define FEI_INIT_STATE_MASK (VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE | VM_STATE_MASK_BUFFERABLE)#define FEI_INIT_STATE (VM_STATE_VALID | VM_STATE_WRITABLE | VM_STATE_CACHEABLE_NOT | VM_STATE_BUFFERABLE_NOT)#define UNKNOWN (-1)/* 82557/9 PCI specific definitions *//* Intel PRO-100B PCI specific definitions */#ifndef PRO100B_PCI_VENDOR_ID#define PRO100B_PCI_VENDOR_ID 0x8086 /* PCI vendor ID */#define PRO100B_PCI_DEVICE_ID 0x1229 /* PCI device ID */#endif /* PRO100B_PCI_VENDOR_ID *//* Intel InBusiness 10/100 PCI specific definitions */#ifndef INBUSINESS_PCI_VENDOR_ID#define INBUSINESS_PCI_VENDOR_ID PRO100B_PCI_VENDOR_ID /* PCI vendor ID */#define INBUSINESS_PCI_DEVICE_ID 0x1030 /* PCI device ID */#endif /* INBUSINESS_PCI_VENDOR_ID *//* Intel I82559ER 10/100 PCI specific definitions */#ifndef I82559ER_PCI_VENDOR_ID #define I82559ER_PCI_VENDOR_ID PRO100B_PCI_VENDOR_ID /* PCI vendor ID */#define I82559ER_PCI_DEVICE_ID 0x1209 /* PCI device ID */#endif /* I82559ER_PCI_VENDOR_ID */#define sysDelay() delayUSec(10)/* typedefs */typedef struct pciResource /* PCI_RESOURCES */{ 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 */ void * buf; /* any allocated buffer space */ UINT32 cpuToPciOffset; /* Any offset from CPU to PCI address */} PCI_RESOURCES;typedef struct boardResource /* BOARD_RESOURCES */{ UINT32 type; /* type of the board */ UINT32 vendorId; /* Vendor ID */ UINT32 deviceId; /* Device ID */} BOARD_RESOURCES;typedef struct feiResource /* FEI_RESOURCE */{ UINT32 membaseCsr; /* Base Address Register 0 */ UINT32 iobaseCsr; /* Base Address Register 1 */ UINT32 membaseFlash; /* Base Address Register 2 */ char irq; /* Interrupt Request Level */ 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 */ UINT16 eeprom[0x40]; /* Ethernet Address of this unit */ INT32 timeout; /* timeout for the self-test */ INT32 str[6]; /* storage for the self-test result */ volatile INT32 * pResults; /* pointer to the self-test result */ UINT memLength; /* required memory size */ UINT initialStateMask; /* mask parameter to vmStateSet */ UINT initialState; /* state parameter to vmStateSet */} FEI_RESOURCE;/* locals *//* * 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(). * * The mode is set as AUTO so this will be erased by the configuration read * from the card that is effectively set by pciAssignResources(). See * sysLanPciInit() for this. */LOCAL PCI_RESOURCES pciResources [MAX_END_DEV] ={ {PCI_IO_ADR0, PCI_MEM_ADR0, PCI_INT_LVL0, PCI_INT_VEC0, PCI_REG_MOD, 0, 0}, {PCI_IO_ADR1, PCI_MEM_ADR1, PCI_INT_LVL1, PCI_INT_VEC1, PCI_REG_MOD, 0, 0}, {PCI_IO_ADR2, PCI_MEM_ADR2, PCI_INT_LVL2, PCI_INT_VEC2, PCI_REG_MOD, 0, 0}, {PCI_IO_ADR3, PCI_MEM_ADR3, PCI_INT_LVL3, PCI_INT_VEC3, PCI_REG_MOD, 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 BOARD_RESOURCES boardResources [] ={ {PRO100B, PRO100B_PCI_VENDOR_ID, PRO100B_PCI_DEVICE_ID}, {INBUSINESS, INBUSINESS_PCI_VENDOR_ID, INBUSINESS_PCI_DEVICE_ID}, {XX82559ER, PRO100B_PCI_VENDOR_ID, I82559ER_PCI_DEVICE_ID} };/* END load strings */LOCAL char endLoadStr[MAX_END_DEV][END_LD_STR_SIZE];/* Index of devices */LOCAL int currentEndDevice = 0;LOCAL FEI_RESOURCE feiResources [MAX_END_DEV] ={ {UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, {UNKNOWN}, UNKNOWN, {UNKNOWN}, NULL, FEI_MEMSIZE0, FEI_INIT_STATE_MASK, FEI_INIT_STATE}, {UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, {UNKNOWN}, UNKNOWN, {UNKNOWN}, NULL, FEI_MEMSIZE0, FEI_INIT_STATE_MASK, FEI_INIT_STATE}, {UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, {UNKNOWN}, UNKNOWN, {UNKNOWN}, NULL, FEI_MEMSIZE0, FEI_INIT_STATE_MASK, FEI_INIT_STATE}, {UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, {UNKNOWN}, UNKNOWN, {UNKNOWN}, NULL, FEI_MEMSIZE0, FEI_INIT_STATE_MASK, FEI_INIT_STATE},};LOCAL const char * phys[] ={ "None", "i82553-A/B", "i82553-C", "i82503", "DP83840", "80c240", "80c24", "i82555", "unknown-8", "unknown-9", "DP83840A", "unknown-11", "unknown-12", "unknown-13", "unknown-14", "unknown-15"};enum phy_chips{ NonSuchPhy=0, I82553AB, I82553C, I82503, DP83840, S80C240, S80C24, I82555, DP83840A=10, UndefinedPhy};LOCAL const char *connectors[] = {" RJ45", " BNC", " AUI", " MII"};/* imports *//* FEI specific imports */IMPORT FUNCPTR feiEndIntConnect;IMPORT FUNCPTR feiEndIntDisconnect;IMPORT END_OBJ* fei82557EndLoad (char *, void *);IMPORT void sysFlashBoardDelay (void);IMPORT END_OBJ* endFindByName(char* pName, int unit);/* End device table - should be MAX_END_DEV+1 entries */IMPORT END_TBL_ENTRY endDevTbl[];/* forward declarations */LOCAL UINT16 sys557eepromRead (int unit, int location);LOCAL UINT32 sys557mdioRead (int unit, int phyId, int location);LOCAL UINT32 sys557mdioWrite (int unit, int phyId, int location, int value);LOCAL int sys557IntEnable (int unit);LOCAL int sys557IntDisable (int unit);LOCAL int sys557IntAck (int unit);UINT32 sys557EndPhysToPci ( int unit, UINT32 PhysAddr);UINT32 sys557EndPciToPhys ( int unit, UINT32 PciAddr);#ifdef INCLUDE_INTEL_HW_WORKAROUNDUINT32 sys557EndVirtToPci ( int unit, UINT32 VirtAddr);UINT32 sys557EndPciToVirt ( int unit, UINT32 PciAddr);#endif/********************************************************************************* sysLanPciInit - prepare LAN adapter for initialization** This routine find out the PCI device, and map its memory and I/O address.* It will understand FEI type cards.** RETURNS: N/A*/STATUS sysLanPciInit (void){ PCI_RESOURCES * pRsrc; /* dec resource */ UINT32 pciBus; /* PCI Bus number */ UINT32 pciDevice = 0; /* PCI Device number */ UINT32 pciFunc; /* PCI Function number */ unsigned int ix; /* counter */ int iy; /* counter */ UINT32 boardType = NONE; /* board type detected */ FEI_RESOURCE * pFeiRes; /* FEI specific info */ char *newdev = (char *)BOOT_LINE_ADRS; char *newname = "fei"; if(*newdev == 'e') for(ix = 0; ix < 3; ix++) *(newdev++) = *(newname++); /* Setup Interrupt Pointers */ feiEndIntConnect = (FUNCPTR) pciIntConnect; feiEndIntDisconnect = (FUNCPTR) pciIntDisconnect; /* * The following code tries to automatically detect and configure * all instances of supported Ethernet cards. */ for(ix = 0; ix < BOARD_TYPE_NB; ix++) { for(iy = 0;iy < PCI_MAX_DEV; iy++) { if(pciFindDevice(boardResources[ix].vendorId, boardResources[ix].deviceId, iy, &pciBus, &pciDevice, &pciFunc) == ERROR) break; /* skip to next vendor/product pair */ /* skip slave's NIC */ if(strapOptionsVal & CFG_PCI_BOOT_HOST) { if(pciDevice == 3) continue; } else { if(pciDevice != 3) continue; } /* board detected */ boardType = boardResources[ix].type; /* Update the END device table */ pRsrc = &(pciResources[pciDevice]); /* We only do Auto Configuration */ /* get memory base address and I/O base address */ if((boardType >= FEI_START) && (boardType < (FEI_START + TYPE_ALLOC))) { pFeiRes = &feiResources[currentEndDevice]; pFeiRes->pciBus = pciBus; pFeiRes->pciDevice = pciDevice; pFeiRes->pciFunc = pciFunc; pciConfigInLong(pciBus, pciDevice, pciFunc, PCI_CFG_BASE_ADDRESS_0, &(pFeiRes->membaseCsr)); /* Convert to CPU address */ pFeiRes->membaseCsr += CPU_PCI_MEM_ADRS;/*#define PCI_IO_ADRS_OK*/#ifdef PCI_IO_ADRS_OK pciConfigInLong(pciBus, pciDevice, pciFunc, (PCI_CFG_BASE_ADDRESS_0 + 4), &(pFeiRes->iobaseCsr)); pFeiRes->iobaseCsr &= ~PCI_BASE_IO; pFeiRes->iobaseCsr += CPU_PCI_IO_ADRS;#else pFeiRes->iobaseCsr = pFeiRes->membaseCsr;#endif pciConfigInLong(pciBus, pciDevice, pciFunc, (PCI_CFG_BASE_ADDRESS_0 + 8), &(pFeiRes->membaseFlash)); pFeiRes->membaseFlash += CPU_PCI_MEM_ADRS; if(pciDevice == 7) pFeiRes->irq = CPLD_PMC_INT; else pFeiRes->irq = CPLD_NIC_INT; pFeiRes->configType = boardType; } /* * Update the END device table & dynamically create the load * string we need for this device */ if((boardType >= FEI_START) && (boardType < (FEI_START + TYPE_ALLOC))) {#ifdef INCLUDE_INTEL_HW_WORKAROUND /* * The fei82557End initialization string format is: * * <memBase>:<memSize>:<rxDesNum>:<txDesNum>:<userFlags>:<offset> */ if (pRsrc->buf = cacheDmaXMalloc (FEI_BUF_SIZE), pRsrc->buf == NULL) { /* cannot log msg at this point in initialisation timeline*/ printf("fei%d cacheDmaXMalloc failed\n", currentEndDevice); return ERROR; } sprintf (endLoadStr[currentEndDevice], "0x%08X:0x%08X:0x%X:0x%X:0x00:2", (UINT32)pRsrc->buf, FEI_BUF_SIZE, FEI_NUM_CFDS, FEI_NUM_RFDS);#else pRsrc->buf = (void *)NONE; sprintf(endLoadStr[currentEndDevice], "0x%08X:0x0:0x0:0x0:0x00:2", (UINT32)pRsrc->buf);#endif endDevTbl[currentEndDevice].unit = currentEndDevice; endDevTbl[currentEndDevice].endLoadFunc = fei82557EndLoad; endDevTbl[currentEndDevice].endLoadString = endLoadStr[currentEndDevice]; endDevTbl[currentEndDevice].endLoan = 1; currentEndDevice++; /* enable mapped I/O addresses */ pciConfigOutWord (pciBus, pciDevice, pciFunc, PCI_CFG_COMMAND, PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE); } /* on master configure MAX_END_DEV devices */ if(strapOptionsVal & CFG_PCI_BOOT_HOST) { if(currentEndDevice == MAX_END_DEV) { return OK; } } else { /* on slave configure only 1 device */ if(currentEndDevice == 1) { return OK; } } } } if((currentEndDevice == 0) || (pciDevice > PCI_MAX_DEV)) { return ERROR; } return OK;}/********************************************************************************* sys557Init - prepare LAN adapter for 82557 initialization** This routine is expected to perform any adapter-specific or target-specific* initialization that must be done prior to initializing the 82557.** The 82557 driver calls this routine from the driver attach routine before* any other routines in this library.** This routine returns the interrupt level the <pIntLvl> parameter.** RETURNS: OK or ERROR if the adapter could not be prepared for initialization.*/STATUS sys557Init ( int unit, /* unit number */ FEI_BOARD_INFO * pBoard /* board information for the end driver */ ){ volatile FEI_RESOURCE * pReso = &feiResources [unit]; UINT16 sum = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -