sysEnd.c
资源名称:ixp425BSP.rar [点击查看]
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:35k
源码类别:
VxWorks
开发平台:
C/C++
- /* sysEnd.c - System Enhanced network interface support library */
- /* Copyright 2002 Wind River Systems, Inc. */
- #include "copyright_wrs.h"
- /*
- modification history
- --------------------
- 01e,05sep02,jb3 Merge in changes from w/ t2.1 ongiong development
- 01e,01aug02,jb Removing Dec device support
- 01d,30jul02,jb Removing debug code
- 01c,27jun02,jb Fix warnings
- 01b,18jun02,jb Changing size calculation to allow veloce driver to work
- 01a,05jun02,jb initial version...
- */
- /*
- DESCRIPTION
- This file contains the board-specific routines for Ethernet adapter
- initialisation of Intel Pro 100+ based adapters.
- NOTE
- At the time of writing, this module has only been tested with the following
- Ethernet cards:
- 82559 controller: Intel PRO/100+ Management Adapter
- Intel InBusiness 10/100 PCI Network Adapter
- Refer to the BSP reference entry for any eventual limitations or
- problems 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 "end.h"
- #include "netinet/if_ether.h"
- #include "drv/end/fei82557End.h"
- #include "ixp425Pci.h"
- #ifdef END_DEBUG
- #undef LOCAL
- #define LOCAL
- #endif
- /* defines */
- #define CSR_BASE_MSK 0x7f /* Mask Base Address Register */
- #define END_LD_STR_SIZE 80
- /* PCI memory base address register configuration mode */
- #define FORCE 0x00 /* overwrite membase address register */
- #define AUTO 0x01 /* read membase address register */
- /*
- * 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
- /*Everything tested & works fine with a delay of 1, but set to 3 in
- order to eliminate the possibility of any timing issues with temp. increase etc*/
- #define PCI_CONFIG_DELAY 3
- /*
- * 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))
- #ifdef INCLUDE_FEI82557END
- /*the following two are tunable parameters which specify the number of transmit and receive buffers
- to be allocated for use by an fei (82559) driver. These must never be set below 2, otherwise the
- driver will assume a default of 32, and our calculations of how much memory to allocate for the
- driver will be in error*/
- #define FEI_N_RDFS 32
- #define FEI_N_TFDS 32
- /*
- * FEI_RFD_MULTIPLIER is the multiplier that is applied to the number of RFDs requested
- * to determine the number of "spares" available for loaning to the network
- * stack. This value (4) was taken from the fei driver source code (its not
- * available in the header, so if this changes in future versions of the driver
- * this will break - if it is increased the driver will complain that we have not
- * given it enough memory, if it is decreased everything will work but we will be
- * wasting SDRAM.
- */
- #define FEI_RFD_MULTIPLIER 4
- #define FEI_N_RFD_LOAN (FEI_N_RDFS * FEI_RFD_MULTIPLIER)
- /*
- * Again FEI_CL_OVERHEAD has been taken from the fei source code (not specified in header),
- * so the caveats for the FEI_RFD_MULTIPLIER apply here too
- */
- #define FEI_CL_OVERHEAD 4 /* prepended cluster header */
- #define FEI_CL_RFD_SIZE (RFD_SIZE + FEI_CL_OVERHEAD)
- #define FEI_CFD_SIZE CFD_SIZE
- /*This calculation is taken from the fei driver source, again, if this changes, the driver will
- either complain that it has not been allocated enough memory, or will work fine but we will
- be wasting SDRAM*/
- #define FEI_TOTAL_SIZE ((FEI_N_RDFS * FEI_CL_RFD_SIZE) +
- (FEI_N_RFD_LOAN * FEI_CL_RFD_SIZE) +
- (FEI_N_TFDS * (FEI_CFD_SIZE +sizeof(long))) + 4)
- /* 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 */
- #define EE_ENB (0x4800 | EE_CS)
- /* 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 */
- #define EE_WRITE_0 0x4802
- #define EE_WRITE_1 0x4806
- /* 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 */
- /* PC compatibility macros */
- #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 */
- #define I82559ER_PCI_DEVICE_ID 0x1209
- #endif /* INCLUDE_FEI82557END */
- /* undef'ed PCI_IO_ADRS_OK here as IXP425 does not properly generate
- read/writes to IO address space, the FEI NIC also maps its IO space to
- a memory space, and can work without IO transactions
- */
- #undef PCI_IO_ADRS_OK
- /* 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 */
- UINT32 decUsrFlags; /* DEC driver user flags */
- } BOARD_RESOURCES;
- #ifdef INCLUDE_FEI82557END
- 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;
- #endif
- /* 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 [IXP425_PCI_MAX_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 [] =
- {
- #ifdef INCLUDE_FEI82557END
- {PRO100B, PRO100B_PCI_VENDOR_ID, PRO100B_PCI_DEVICE_ID, 0},
- {INBUSINESS, INBUSINESS_PCI_VENDOR_ID, INBUSINESS_PCI_DEVICE_ID, 0},
- {XX82559ER, PRO100B_PCI_VENDOR_ID, I82559ER_PCI_DEVICE_ID, 0},
- #endif /* INCLUDE_FEI82557END */
- };
- /* END load strings */
- LOCAL char endLoadStr[IXP425_PCI_MAX_DEV][END_LD_STR_SIZE];
- /* Index of devices */
- LOCAL int currentEndDevice = 0;
- #ifdef INCLUDE_FEI82557END
- LOCAL UINT32 feiUnits; /* number of FEIs we found */
- LOCAL FEI_RESOURCE feiResources [IXP425_PCI_MAX_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"};
- #endif /* INCLUDE_FEI82557END */
- /* imports */
- /* End device table - should be IXP425_PCI_MAX_DEV+1 entries */
- IMPORT END_TBL_ENTRY endDevTbl[];
- #ifdef INCLUDE_FEI82557END
- /* FEI specific imports */
- IMPORT FUNCPTR feiEndIntConnect;
- IMPORT FUNCPTR feiEndIntDisconnect;
- IMPORT END_OBJ* fei82557EndLoad (char *, void *);
- IMPORT void sysFlashBoardDelay (void);
- /*extern void sysDelay(void);*/
- extern void sysMicroDelay(int microseconds);
- /* 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 PhysAddr);
- #endif /* INCLUDE_FEI82557END */
- #define SWAP16(x) ((((x) << 8) | ((x) >> 8)) & 0xFFFF)
- #define SWAP32(x)
- (((x) << 24) |
- (((x) & 0x0000FF00) << 8) |
- (((x) & 0x00FF0000) >> 8) |
- (((unsigned int)(x)) >> 24))
- #ifdef PCI_IO_ADRS_OK
- #define sysPciOutWord(addr,data) PCI_OUT_WORD((void*)(addr-IXP425_PHYS_PCI_IO_BASE),data)
- #define sysPciOutLong(addr,data) PCI_OUT_LONG((void*)(addr-IXP425_PHYS_PCI_IO_BASE),data)
- #else
- #ifdef IXP425_PCI_ENABLE_BYTE_ROUTING
- #define sysPciOutWord(addr,data) *(volatile UINT16*)((addr)) = SWAP16((UINT16)data)
- #define sysPciOutLong(addr,data) *(volatile UINT32*)((addr)) = SWAP32((UINT32)data)
- #else
- #define sysPciOutWord(addr,data) *((volatile UINT16*)((addr) & ~3)) = (UINT16)data
- #define sysPciOutLong(addr,data) *(volatile UINT32*)((addr)) = (UINT32)data
- #endif
- #endif /*PCI_IO_ADRS_OK*/
- /*because we do not return read values as return codes in our
- pci IO config library, we must define these as functions, not macros*/
- UINT16 sysInWord(ULONG addr)
- {
- #ifdef PCI_IO_ADRS_OK
- UINT16 retval;
- pciIOInWord((void*)(addr-IXP425_PHYS_PCI_IO_BASE), &retval);
- return retval;
- #else
- UINT32 val;
- UINT16 retval;
- if (addr & 3)
- {
- addr=addr & ~3; /*round down to 32 bit align*/
- val = *((UINT32*)addr);
- #ifdef IXP425_PCI_ENABLE_BYTE_ROUTING
- val = SWAP32(val);
- #endif
- retval = val >> 16;
- return retval;
- }
- else
- {
- return *((UINT16*)addr);
- }
- #endif /*PCI_IO_ADRS_OK*/
- }
- ULONG sysInLong(ULONG addr)
- {
- #ifdef PCI_IO_ADRS_OK
- ULONG retval;
- pciIOInLong((void*)(addr-IXP425_PHYS_PCI_IO_BASE), &retval);
- return retval;
- #else
- #ifdef IXP425_PCI_ENABLE_BYTE_ROUTING
- return SWAP32(*((ULONG*)addr));
- #else
- return *((ULONG*)addr);
- #endif
- #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 both DEC21x4x and FEI type cards.
- *
- * RETURNS: N/A
- */
- STATUS sysLanPciInit (void)
- {
- PciDevice * pDev; /* Pci resources */
- 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 */
- int unit = 0; /* unit numbers */
- UINT32 boardType = NONE; /* board type detected */
- #ifdef INCLUDE_FEI82557END
- FEI_RESOURCE * pFeiRes; /* FEI specific info */
- #ifndef IXP425_PCI_SIMPLE_MAPPING
- void* feiMemBase=NULL;
- #endif
- #endif
- /* Setup Interrupt Pointers */
- feiEndIntConnect = (FUNCPTR) pciIntConnect;
- feiEndIntDisconnect = (FUNCPTR) pciIntDisconnect;
- /* Find the first empty entry in the endDevTable*/
- while(endDevTbl[currentEndDevice].endLoadFunc != END_TBL_END)
- {
- currentEndDevice++;
- }
- /*
- * 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 < IXP425_PCI_MAX_DEV; iy++)
- {
- if( (pDev = pciDeviceGet(boardResources[ix].vendorId,
- boardResources[ix].deviceId, iy) ) == NULL)
- break; /* skip to next vendor/product pair */
- if( pDev->error == TRUE )
- {
- break; /* Something wrong here */
- }
- /* board detected */
- boardType = boardResources[ix].type;
- pciBus = pDev->bus;
- pciDevice = pDev->device;
- pciFunc = pDev->func;
- /*
- * Update the END device table
- *
- * pciDevice for PCI cards plugged in is in the range 5 to 8.
- */
- pRsrc = &(pciResources[pciDevice]);
- /* We only do Auto Configuration */
- /* get memory base address and I/O base address */
- #ifdef INCLUDE_FEI82557END
- if ((boardType >= FEI_START) &&
- (boardType < (FEI_START + TYPE_ALLOC)))
- {
- pFeiRes = &feiResources [unit];
- pFeiRes->pciBus = pciBus;
- pFeiRes->pciDevice = pciDevice;
- pFeiRes->pciFunc = pciFunc;
- pFeiRes->membaseCsr = pDev->bar[0].address;
- /* Convert to CPU address */
- pFeiRes->membaseCsr += CPU_PCI_MEM_ADRS;
- #ifdef PCI_IO_ADRS_OK
- pFeiRes->iobaseCsr = pDev->bar[1].address;
- pFeiRes->iobaseCsr &= ~PCI_BASE_IO;
- pFeiRes->iobaseCsr += CPU_PCI_IO_ADRS;
- #else
- pFeiRes->iobaseCsr = pFeiRes->membaseCsr;
- #endif
- pFeiRes->membaseFlash = pDev->bar[2].address;
- pFeiRes->membaseFlash += CPU_PCI_MEM_ADRS;
- pFeiRes->irq = pDev->irq;
- pFeiRes->configType = boardType;
- }
- #endif /* INCLUDE_FEI82557END */
- /*
- * Update the END device table & dynamically create the load
- * string we need for this device
- */
- #ifdef INCLUDE_FEI82557END
- if ((boardType >= FEI_START) &&
- (boardType < (FEI_START + TYPE_ALLOC)))
- {
- pRsrc->buf = (void *)NONE;
- #ifndef IXP425_PCI_SIMPLE_MAPPING
- /*allocate memory for FEI END device*/
- feiMemBase = cacheDmaMalloc(FEI_TOTAL_SIZE);
- if (feiMemBase == NULL)
- {
- return ERROR;
- }
- sprintf (endLoadStr[currentEndDevice],
- "0x%x:0x%x:0x%x:0x%x:0x00:2", (UINT32)feiMemBase
- , (UINT32)FEI_TOTAL_SIZE, (UINT32)FEI_N_TFDS, (UINT32)FEI_N_RDFS);
- /* set up BAR in PCI controller so that the PCI device can access
- the memory that has just been set up for it*/
- if(sysPciMappingAdd((UINT32)feiMemBase, FEI_TOTAL_SIZE)!=OK)
- {
- printf("sysPciMappingAdd failed in sysLanPciInitn");
- return ERROR;
- }
- #else
- sprintf (endLoadStr[currentEndDevice],
- "-1:0x00:0x20:0x20:0x00:2");
- #endif
- endDevTbl[currentEndDevice].unit = unit++;
- 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);
- feiUnits++;
- }
- #endif /* INCLUDE_FEI82557END */
- }
- }
- return OK;
- }
- #ifdef INCLUDE_FEI82557END
- /*******************************************************************************
- *
- * 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;
- int ix;
- int iy;
- UINT16 value;
- void * testbuf = 0; /* keep compiler quiet */
- #ifdef PCI_END_DEBUG
- int errors;
- UINT32 testrepeat = 1000;
- #endif
- /*
- * Locate the 82557 based adapter - PRO100B, INBUSINESS and XXX.
- * Note that since the INBUSINESS adapter is based upon the PRO100B
- * board type, it is initialised and driven like one.
- */
- if (pReso->boardType != UNKNOWN) /* only setup once */
- {
- }
- else
- {
- /* read the configuration in EEPROM */
- #ifdef PCI_END_DEBUG
- printf("RFD_SIZE = 0x%xn",RFD_SIZE);
- printf("CFD_SIZE = 0x%xn",CFD_SIZE);
- printf("TOTAL FEI STORAGE: 0x%xn",FEI_TOTAL_SIZE);
- errors=0;
- for(ix=0;ix<testrepeat; ix++)
- {
- value = sys557eepromRead (unit, 0);
- if(value != 0x0200)
- {
- errors++;
- }
- }
- printf("Test of eeprom read resulted in %d errors from %d readsn",errors,testrepeat);
- #endif
- for (ix = 0; ix < EE_SIZE; ix++)
- {
- value = sys557eepromRead (unit, ix);
- pReso->eeprom[ix] = value;
- sum += value;
- #ifdef PCI_END_DEBUG
- printf("%4.4x ", value);
- if(ix % 4 ==0)
- {
- printf("n");
- }
- #endif
- }
- if (sum != EE_CHECKSUM)
- {
- printf ("nfei%d: Invalid EEPROM checksum %#4.4xn", unit, sum);
- }
- /* DP83840 specific setup */
- if (((pReso->eeprom[6]>>8) & 0x3f) == DP83840)
- {
- int reg23 = sys557mdioRead (unit, pReso->eeprom[6] & 0x1f, 23);
- sys557mdioWrite (unit, pReso->eeprom[6] & 0x1f, 23, reg23 | 0x0420);
- }
- /* perform a system self-test. */
- pReso->timeout = 16000; /* Timeout for self-test. */
- /*
- * No specific area specified, so we assume that cacheDmaMalloc() will
- * return a pointer to a suitable area. If the data cache is on,
- * this will be page-aligned, but if the data cache is off, then we
- * will just get whatever malloc returns.
- */
- if (testbuf = cacheDmaMalloc (32), testbuf == 0)
- {
- printf("fei%d cacheDmaMalloc failedn", unit);
- return ERROR;
- }
- pReso->pResults = (volatile INT32 *)testbuf;
- /* The chip requires the results buffer to be 16-byte aligned. */
- pReso->pResults = (volatile INT32 *)
- ((((int) pReso->pResults) + 0xf) & ~0xf);
- /* initialise results buffer */
- pReso->pResults[0] = 0;
- pReso->pResults[1] = -1;
- /* Issue the self-test command */
- if(sysPhysToPci((void*)pReso->pResults) == NULL)
- {
- printf("pReso->pResults does not reside in an area that the PCI devices can accessn");
- }
- /*reset the chip*/
- sysPciOutLong (pReso->iobaseCsr + 0x8, 0x0);
- sysDelay();
- /*perform self test*/
- sysPciOutLong (pReso->iobaseCsr + 0x8, sysPhysToPci((void*)pReso->pResults) | 1);
- #ifdef PCI_END_DEBUG
- printf("Asked the PCI NIC to write result of self test to PCI ADDR:0x%xn",(UINT32)sysPhysToPci((void*)pReso->pResults));
- printf("AHB address of results: 0x%xn", (UINT32)pReso->pResults);
- #endif
- /* wait for results */
- do
- {
- sysDelay(); /* cause a delay of at least an I/O cycle */
- }
- while ((pReso->pResults[1] == -1) && (--pReso->timeout >= 0));
- if (pReso->timeout < 0)
- { /* Test optimized out. */
- printf ("Self test failed, status %8.8x:n"
- " Failure to initialize the 82557.n"
- " Verify that the card is a bus-master capable slot.n",
- pReso->pResults[1]);
- }
- else
- {
- #ifdef PCI_END_DEBUG
- printf ("General self-test: %s.n"
- " Serial sub-system self-test: %s.n"
- " Internal registers self-test: %s.n"
- " ROM checksum self-test: %s (%#8.8x).n",
- pReso->pResults[1] & 0x1000 ? "failed" : "passed",
- pReso->pResults[1] & 0x0020 ? "failed" : "passed",
- pReso->pResults[1] & 0x0008 ? "failed" : "passed",
- pReso->pResults[1] & 0x0004 ? "failed" : "passed",
- pReso->pResults[0]);
- #endif
- }
- pReso->boardType = PRO100B; /* note that it is now initialised */
- /* Save results so we can refer to them again later */
- pReso->str[0] = pReso->pResults[0];
- pReso->str[1] = pReso->pResults[1];
- cacheDmaFree (testbuf);
- pReso->pResults = pReso->str;
- }
- /* initialise the board information structure */
- pBoard->vector = IVEC_TO_INUM(pReso->irq);
- pBoard->baseAddr = pReso->iobaseCsr;
- for (ix = 0, iy = 0; ix < 3; ix++)
- {
- pBoard->enetAddr[iy++] = pReso->eeprom[ix] & 0xff;
- pBoard->enetAddr[iy++] = (pReso->eeprom[ix] >> 8) & 0xff;
- }
- pBoard->intEnable = sys557IntEnable;
- pBoard->intDisable = sys557IntDisable;
- pBoard->intAck = sys557IntAck;
- /* install address conversion routines for driver
- The fei driver needs these to figure out what addresses it needs to
- tell the nic to write to (PCI addresses) in order to access the appropriate
- areas of the AHB*/
- pBoard->sysLocalToBus = sys557EndPhysToPci;
- pBoard->sysBusToLocal = sys557EndPciToPhys;
- #ifdef FEI_10MB
- pBoard->phySpeed = NULL;
- pBoard->phyDpx = NULL;
- #endif
- intEnable (pReso->irq);
- return (OK);
- }
- /*******************************************************************************
- *
- * sys557IntAck - acknowledge an 82557 interrupt
- *
- * This routine performs any 82557 interrupt acknowledge that may be
- * required. This typically involves an operation to some interrupt
- * control hardware.
- *
- * This routine gets called from the 82557 driver's interrupt handler.
- *
- * This routine assumes that the PCI configuration information has already
- * been setup.
- *
- * RETURNS: OK, or ERROR if the interrupt could not be acknowledged.
- */
- LOCAL STATUS sys557IntAck
- (
- int unit /* unit number */
- )
- {
- FEI_RESOURCE * pReso = &feiResources [unit];
- switch (pReso->boardType)
- {
- case PRO100B: /* handle PRO100B LAN Adapter */
- case INBUSINESS:
- case XX82559ER:
- /* no addition work necessary for the PRO100B */
- break;
- default:
- return (ERROR);
- }
- return (OK);
- }
- /*******************************************************************************
- *
- * sys557IntEnable - enable 82557 interrupts
- *
- * This routine enables 82557 interrupts. This may involve operations on
- * interrupt control hardware.
- *
- * The 82557 driver calls this routine throughout normal operation to terminate
- * critical sections of code.
- *
- * This routine assumes that the PCI configuration information has already
- * been setup.
- *
- * RETURNS: OK, or ERROR if interrupts could not be enabled.
- */
- LOCAL STATUS sys557IntEnable
- (
- int unit /* unit number */
- )
- {
- FEI_RESOURCE * pReso = &feiResources [unit];
- switch (pReso->boardType)
- {
- case PRO100B: /* handle PRO100B LAN Adapter */
- case INBUSINESS:
- case XX82559ER:
- intEnable (pReso->irq);
- break;
- default:
- return (ERROR);
- }
- return (OK);
- }
- /*******************************************************************************
- *
- * sys557IntDisable - disable 82557 interrupts
- *
- * This routine disables 82557 interrupts. This may involve operations on
- * interrupt control hardware.
- *
- * The 82557 driver calls this routine throughout normal operation to enter
- * critical sections of code.
- *
- * This routine assumes that the PCI configuration information has already
- * been setup.
- *
- * RETURNS: OK, or ERROR if interrupts could not be disabled.
- */
- LOCAL STATUS sys557IntDisable
- (
- int unit /* unit number */
- )
- {
- FEI_RESOURCE * pReso = &feiResources [unit];
- switch (pReso->boardType)
- {
- case PRO100B: /* handle PRO100B LAN Adapter */
- case INBUSINESS:
- case XX82559ER:
- intDisable (pReso->irq);
- break;
- default:
- return (ERROR);
- }
- return (OK);
- }
- /*******************************************************************************
- *
- * sys557eepromRead - read a word from the 82557 EEPROM
- *
- * RETURNS: the EEPROM data word read in.
- */
- LOCAL UINT16 sys557eepromRead
- (
- int unit, /* unit number */
- int location /* address of word to be read */
- )
- {
- UINT32 iobase = feiResources[unit].iobaseCsr;
- UINT16 retval = 0;
- UINT16 dataval;
- UINT32 eeaddr = iobase + SCB_EEPROM;
- int cmdlen = 27;
- int readcmd = EE_CMD_READ << 22;
- readcmd = readcmd | (location << 16);
- /*Enable EEPROM*/
- sysPciOutWord(eeaddr, EE_ENB | EE_SK);
- do
- {
- dataval = (readcmd & (1 << cmdlen)) ? EE_WRITE_1 : EE_WRITE_0;
- sysPciOutWord(eeaddr, dataval);
- sysDelay();
- sysPciOutWord(eeaddr, dataval | EE_SK);
- sysDelay();
- dataval=sysInWord(eeaddr);
- retval = (retval << 1) | ((dataval & EE_DO) ? 1 : 0);
- } while(cmdlen-- > 0);
- sysPciOutWord(eeaddr, EE_ENB);
- sysPciOutWord(eeaddr, EE_ENB & ~EE_CS);
- return retval;
- #if 0
- sysPciOutWord (iobase + SCB_EEPROM, EE_CS); /* enable EEPROM */
- /* write the READ opcode */
- for (ix = EE_CMD_BITS - 1; ix >= 0; ix--)
- {
- dataval = (EE_CMD_READ & (1 << ix)) ? EE_DI : 0;
- sysPciOutWord (iobase + SCB_EEPROM, EE_CS | dataval);
- sysDelay (); /* delay for one I/O READ cycle */
- sysPciOutWord (iobase + SCB_EEPROM, EE_CS | dataval | EE_SK);
- sysDelay (); /* delay for one I/O READ cycle */
- sysPciOutWord (iobase + SCB_EEPROM, EE_CS | dataval);
- sysDelay (); /* delay for one I/O READ cycle */
- }
- /* write the location */
- for (ix = EE_ADDR_BITS - 1; ix >= 0; ix--)
- {
- dataval = (location & (1 << ix)) ? EE_DI : 0;
- sysPciOutWord (iobase + SCB_EEPROM, EE_CS | dataval);
- sysDelay (); /* delay for one I/O READ cycle */
- sysPciOutWord (iobase + SCB_EEPROM, EE_CS | dataval | EE_SK);
- sysDelay (); /* delay for one I/O READ cycle */
- sysPciOutWord (iobase + SCB_EEPROM, EE_CS | dataval);
- sysDelay (); /* delay for one I/O READ cycle */
- dummy = sysInWord (iobase + SCB_EEPROM);
- }
- if ((dummy & EE_DO) == 0) /* dummy read */
- ;
- /* read the data */
- for (ix = EE_DATA_BITS - 1; ix >= 0; ix--)
- {
- sysPciOutWord (iobase + SCB_EEPROM, EE_CS | EE_SK);
- sysDelay (); /* delay for one I/O READ cycle */
- retval = (retval << 1) |
- ((sysInWord (iobase + SCB_EEPROM) & EE_DO) ? 1 : 0);
- sysPciOutWord (iobase + SCB_EEPROM, EE_CS);
- sysDelay (); /* delay for one I/O READ cycle */
- }
- sysPciOutWord (iobase + SCB_EEPROM, 0x00); /* disable EEPROM */
- return (retval);
- #endif
- }
- /*******************************************************************************
- *
- * sys557mdioRead - read MDIO
- *
- * RETURNS: read value
- */
- LOCAL UINT32 sys557mdioRead
- (
- int unit, /* unit number */
- int phyId, /* PHY ID */
- int location /* location to read */
- )
- {
- UINT32 iobase = feiResources[unit].iobaseCsr;
- int timeout = 64*4; /* <64 usec. to complete, typ 27 ticks */
- int val;
- sysPciOutLong (iobase + SCB_MDI, 0x08000000 | (location<<16) | (phyId<<21));
- do {
- sysDelay (); /* delay for one I/O READ cycle */
- val = sysInLong (iobase + SCB_MDI);
- if (--timeout < 0)
- printf ("sys557mdioRead() timed out with val = %8.8x.n", val);
- } while (! (val & 0x10000000));
- return (val & 0xffff);
- }
- /*******************************************************************************
- *
- * sys557mdioWrite - write MDIO
- *
- * RETURNS: write value
- */
- LOCAL UINT32 sys557mdioWrite
- (
- int unit, /* unit number */
- int phyId, /* PHY ID */
- int location, /* location to write */
- int value /* value to write */
- )
- {
- UINT32 iobase = feiResources[unit].iobaseCsr;
- int timeout = 64*4; /* <64 usec. to complete, typ 27 ticks */
- int val;
- sysPciOutLong (iobase + SCB_MDI,
- 0x04000000 | (location<<16) | (phyId<<21) | value);
- do {
- sysDelay (); /* delay for one I/O READ cycle */
- val = sysInLong (iobase + SCB_MDI);
- if (--timeout < 0)
- printf ("sys557mdioWrite() timed out with val = %8.8x.n", val);
- } while (! (val & 0x10000000));
- return (val & 0xffff);
- }
- /*******************************************************************************
- *
- * sys557Show - shows 82557 configuration
- *
- * This routine shows the (Intel Pro Express 100) configuration
- *
- * RETURNS: N/A
- */
- void sys557Show
- (
- int unit /* unit number */
- )
- {
- FEI_RESOURCE * pReso = &feiResources [unit];
- UINT32 iobase = pReso->iobaseCsr;
- UCHAR etheraddr[6];
- int ix;
- int iy;
- if (unit > IXP425_PCI_MAX_DEV)
- {
- printf ("Illegal unit number %dn", unit);
- return;
- }
- if (pReso->boardType == UNKNOWN)
- {
- printf ("Unit %d not an FEI devicen", unit);
- return;
- }
- for (ix = 0, iy = 0; ix < 3; ix++)
- {
- etheraddr[iy++] = pReso->eeprom[ix];
- etheraddr[iy++] = pReso->eeprom[ix] >> 8;
- }
- printf ("fei%d: Intel EtherExpress Pro 10/100 at %#8x ", unit, iobase);
- for (ix = 0; ix < 5; ix++)
- printf ("%2.2X:", etheraddr[ix]);
- printf ("%2.2Xn", etheraddr[ix]);
- printf ("CSR mem base address = %x, Flash mem base address = %xn",
- pReso->membaseCsr, pReso->membaseFlash);
- if (pReso->eeprom[3] & 0x03)
- printf ("Receiver lock-up bug exists -- enabling work-around.n");
- printf ("Board assembly %4.4x%2.2x-%3.3d, Physical connectors present:",
- pReso->eeprom[8], pReso->eeprom[9]>>8, pReso->eeprom[9] & 0xff);
- for (ix = 0; ix < 4; ix++)
- if (pReso->eeprom[5] & (1 << ix))
- printf ("%s", connectors [ix]);
- printf ("nPrimary interface chip %s PHY #%d.n",
- phys[(pReso->eeprom[6]>>8)&15], pReso->eeprom[6] & 0x1f);
- if (pReso->eeprom[7] & 0x0700)
- printf ("Secondary interface chip %s.n",
- phys[(pReso->eeprom[7]>>8)&7]);
- #if FALSE /* we don't show PHY specific info at this time */
- /* ToDo: Read and set PHY registers through MDIO port. */
- for (ix = 0; ix < 2; ix++)
- printf ("MDIO register %d is %4.4x.n",
- ix, sys557mdioRead (unit, pReso->eeprom[6] & 0x1f, ix));
- for (ix = 5; ix < 7; ix++)
- printf ("MDIO register %d is %4.4x.n",
- ix, sys557mdioRead (unit, pReso->eeprom[6] & 0x1f, ix));
- printf ("MDIO register %d is %4.4x.n",
- 25, sys557mdioRead (unit, pReso->eeprom[6] & 0x1f, 25));
- #endif /* FALSE */
- if (pReso->timeout < 0)
- { /* Test optimized out. */
- printf ("Self test failed, status %8.8x:n"
- " Failure to initialize the 82557.n"
- " Verify that the card is a bus-master capable slot.n",
- pReso->pResults[1]);
- }
- else
- {
- printf ("General self-test: %s.n"
- " Serial sub-system self-test: %s.n"
- " Internal registers self-test: %s.n"
- " ROM checksum self-test: %s (%#8.8x).n",
- pReso->pResults[1] & 0x1000 ? "failed" : "passed",
- pReso->pResults[1] & 0x0020 ? "failed" : "passed",
- pReso->pResults[1] & 0x0008 ? "failed" : "passed",
- pReso->pResults[1] & 0x0004 ? "failed" : "passed",
- pReso->pResults[0]);
- }
- }
- #endif /* INCLUDE_FEI82557END */
- /*******************************************************************************
- *
- * sysDelay - a small delay
- *
- */
- void sysDelay (void)
- {
- sysMicroDelay(PCI_CONFIG_DELAY);
- return;
- }
- /******************************************************************************
- *
- * sys557EndPciToPhys - translate a Pci address to a physical address
- *
- * This function converts a Pci address to a physical address. This only works
- * for PCI Memory space.
- *
- * RETURNS: the physical adddress
- */
- UINT32 sys557EndPciToPhys
- (
- int unit,
- UINT32 PciAddr /* PCI address */
- )
- {
- return((UINT32)sysPciToPhys((void *)PciAddr));
- }
- /******************************************************************************
- *
- * sys557EndPhysToPci - translate a physical address to a Pci address
- *
- * This function converts a physical address to a Pci address. This only works
- * for PCI Memory space.
- *
- * RETURNS: the Pci adddress
- */
- UINT32 sys557EndPhysToPci
- (
- int unit,
- UINT32 PhysAddr /* Physical address */
- )
- {
- return ((UINT32)sysPhysToPci((void *)PhysAddr));
- }
- #endif /* INCLUDE_END */