📄 sysdec21x40end.c
字号:
/* sysDec21x40End.c - system configuration module for Dec21x40 END */ /* Copyright 1984 - 1999 Wind River Systems, Inc. */ /*modification history--------------------01h,13may02,mil Added auto negotiate and full duplex to MII flags.01g,04feb02,mil Updated DEC_MII_PHY_ADDR to start at 0x8 for mcpn750.01f,01nov01,mil Cleaned up compiler warnings.01e,22nov99,tm merged in miiLib support01d,19sep99,tm adapted for mcp75001c,01jul99,tm adapted (simplified) for planar DEC 21143-based mv240001b,29apr99,jkf merged with T2.01a,01apr99,jkf written *//*DESCRIPTIONThis is the WRS-supplied configuration module for the VxWorks dec21x40End (dc) END driver. It performs the dynamic parameterization of the dec21x40End 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. */ #if (defined(INCLUDE_NETWORK) && defined (INCLUDE_END))/* includes */#include "vxWorks.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include "end.h"#include "config.h"#include "drv/end/dec21x40End.h" /* DEC driver user flags */#define DEC_USR_FLAGS_143 (DEC_USR_21143 | DEC_USR_MII)#define DEC_USR_FLAGS_140 (DEC_USR_BAR_RX | DEC_USR_RML | DEC_USR_CAL_08 | \ DEC_USR_PBL_04 | DEC_USR_21140 | DEC_USR_MII)#define DEC_USR_MII_FLAGS (MII_PHY_AUTO | DEC_USR_MII_BUS_MON | \ DEC_USR_MII_10MB | DEC_USR_MII_100MB | \ DEC_USR_MII_HD | DEC_USR_MII_FD)#if defined(MCP750)# define DEC_MII_PHY_ADDR 1 /* PHY's address on the MII bus */#elif defined(MCPN750)# define DEC_MII_PHY_ADDR 8 /* PHY's address on the MII bus */#else /* MCP750/MCPN750 */# define DEC_MII_PHY_ADDR 0 /* PHY's address on the MII bus */#endif /* MCP750/MCPN750 *//* * this table may be customized by the user to force a * particular order how different technology abilities may be * negotiated by the PHY. Entries in this table may be freely combined * and even OR'd together. */ LOCAL INT16 motFccAnOrderTbl [] = { MII_TECH_100BASE_TX, /* 100Base-T */ MII_TECH_100BASE_T4, /* 10Base-T */ MII_TECH_10BASE_T, /* 100Base-T4 */ MII_TECH_100BASE_TX_FD, /* 100Base-T FD */ MII_TECH_10BASE_FD, /* 10Base-T FD*/ -1 /* end of table */ };/* Adapter-specific definitions */#ifdef CONFIG1_PLANAR_PCI# define NET_END_USER_FLAGS (DEC_USR_FLAGS_140)#endif#ifdef CONFIG2_PLANAR_PCI# define NET_END_USER_FLAGS (DEC_USR_FLAGS_143)#endif/* forward declarations */STATUS sysDec21x40EnetAddrGet ( DEC21X40_DRV_CTRL *pDrvCtrl, char *enetAdrs );STATUS sysDec21143MediaSelect (DEC21X40_DRV_CTRL *, UINT *);STATUS sysDec21x40DynEnetFind ( UINT, UINT, UINT *, UINT *, UINT *); /* locals *//* imports */IMPORT END_OBJ* dec21x40EndLoad (char *);IMPORT void (*_func_motorola21143SromFix) ( UCHAR * );IMPORT USHORT dec21140SromWordRead ( DEC21X40_DRV_CTRL *pDrvCtrl, UCHAR lineCnt );IMPORT END_TBL_ENTRY endDevTbl[];/******************************************************************************** sysDec21x40EndLoad - create load string and load a dec21x40 (dc) device.** This routine loads the dc device with initial parameters probed* during dec21x40PciInit().** RETURNS: pointer to END object or ERROR.** SEE ALSO: dec21x40EndLoad()*/ LOCAL char paramStr [END_INIT_STR_MAX]; /* end.h */static char decParamTemplate[] = "0x%x:0x%x:0x%x:0x%x:-1:-1:-1:0:0x%x:0x%x:0x%x:0x%x"; END_OBJ * sysDec21x40EndLoad ( char * pParamStr, /* ptr to initialization parameter string */ void * unused /* unused optional argument */ ) { /* * The dec21x40End driver END_LOAD_STRING should be: * The format of the parameter string is: * * "<device_addr>:<PCI_addr>:<ivec>:<ilevel>:<num_rds>:<num_tds>: * <mem_base>:<mem_size>:<user_flags>:<phyAddr>:<pPhyTbl>:<phyFlags>" * * Note that dec21x40 unit number is prepended in muxDevLoad, so we * don't put it here! */ char * cp; END_OBJ * pEnd; char* tok; char* ptmpholder=NULL; char** holder = &ptmpholder; /* temp string holder */ UINT instance, unit; BOOL found = FALSE; UINT32 pciBus = 0; /* this is ignored by modified dynfind routine */ UINT32 pciDevice; UINT32 pciFunc; UCHAR intLine; UINT32 muxFlags; int ivec, ilevel; UINT32 membaseCsr; UINT32 iobaseCsr; bzero((char *)paramStr, END_INIT_STR_MAX); 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 = dec21x40EndLoad (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 */ /* Assume that initial paramStr is of the form "<unitNum>:" and parse */ tok = strtok_r(pParamStr, ":", holder); if (tok == NULL) { return (NULL); } /* * NOTE: this makes a rough correlation between unit number and * device instance. This is not optimal. */ unit = strtoul(tok, NULL, 10); instance = unit; /* Now, we advance cp, by finding the end the string */ cp += strlen (paramStr); /* EnetFind args: unit, instance, bus, pDev, pFunc */ if (sysDec21x40DynEnetFind (unit,instance,&pciBus,&pciDevice,&pciFunc) == OK) { found = TRUE; /* board detected */ } if (!found || (pciDevice > PCI_MAX_DEV)) return (NULL); /* get memory base address and IO base address */ pciConfigInLong (pciBus, pciDevice, pciFunc, PCI_CFG_BASE_ADDRESS_0, &iobaseCsr); pciConfigInLong (pciBus, pciDevice, pciFunc, PCI_CFG_BASE_ADDRESS_1, &membaseCsr); pciConfigInByte (pciBus, pciDevice, pciFunc, PCI_CFG_DEV_INT_LINE, &intLine); iobaseCsr = (iobaseCsr & PCI_IOBASE_MASK) - PCI_MSTR_IO_BUS + PCI_MSTR_IO_LOCAL; membaseCsr &= PCI_MEMBASE_MASK; ivec = (int)( intLine + INT_VEC_IRQ0 + EXT_INTERRUPT_BASE ); ilevel = (int)( intLine + EXT_INTERRUPT_BASE ); /* finish off the initialization parameter string */ muxFlags = NET_END_USER_FLAGS; sprintf ( cp, decParamTemplate, (UINT) (iobaseCsr), /* device io base */ (UINT) PCI_SLV_MEM_BUS, /* pciMemBase */ ivec, /* interrupt irq vector */ ilevel, /* interrupt irq number */ muxFlags, DEC_MII_PHY_ADDR, (int) motFccAnOrderTbl, DEC_USR_MII_FLAGS ); pEnd = dec21x40EndLoad (paramStr); } return (pEnd); }/********************************************************************************* sysDec21x40PciInit - prepare LAN adapter for DEC21X4X initialization** This routine finds the PCI device, and maps its memory and IO address.* It must be done prior to initializing the DEC21X4X, sysDec21x40Init(). ** RETURNS: N/A*/STATUS sysDec21x40PciInit ( int unit, /* input: unit number */ UINT instance /* input: instance number */ ) { BOOL found = FALSE; UINT32 pciBus; UINT32 pciDevice; UINT32 pciFunc; pciBus = 0; /* EnetFind args: unit, instance, bus, pDev, pFunc */ if (sysDec21x40DynEnetFind(unit,instance,&pciBus,&pciDevice,&pciFunc) == OK) { /* board detected */ found = TRUE; } if (!found || (pciDevice > PCI_MAX_DEV)) return (ERROR); /* disable sleep mode */ pciConfigOutByte (pciBus, pciDevice, pciFunc, PCI_CFG_MODE, SLEEP_MODE_DIS); if (NET_END_USER_FLAGS == DEC_USR_FLAGS_143) { pciConfigOutLong ( pciBus, pciDevice, pciFunc, PCI_CFG_21143_DA, 0 ); } return (OK); }/********************************************************************************* sysDec21x40Init - prepare LAN adapter for dec21X4X initialization** This routine is expected to perform any adapter-specific or target-specific* initialization that must be done prior to initializing the dec21X4X.** The dec21X4X driver calls this routine from the driver endLoad routine before* any other routines in this library.** This routine determines the base address, the main memory address over * the PCI bus, the interrupt level and the interrupt vector parameter.** RETURNS: OK or ERROR if the adapter could not be prepared for initialization.*/ STATUS sysDec21x40Init ( DEC21X40_DRV_CTRL * pDrvCtrl ) { return (OK); } /********************************************************************************* sysDec21x40EnetAddrGet - gets the ethernet address from the ROM register ** This routine reads an ethernet address from the serial ROM. It supports* legacy, ver 1/A, and 3.0 serial ROM formats.* * RETURNS: OK on success, and ERROR if the ethernet address bytes cannot be* read.*/STATUS sysDec21x40EnetAddrGet ( DEC21X40_DRV_CTRL * pDrvCtrl, char * enetAdrs /* pointer to the ethernet address */ ) { USHORT sromData; int adrsOffset; int len; /* Check if SROM is programmed. */ sromData = dec21140SromWordRead (pDrvCtrl, 0); if ( sromData == 0xFFFF ) { /* SROM is unprogrammed, get MAC address from NVRAM. */ if (( sysNvRamGet ((char *)enetAdrs, 6, (int) ((int) BB_ENET - NV_BOOT_OFFSET)) ) == ERROR ) return (ERROR); } else { sromData = dec21140SromWordRead (pDrvCtrl, 13); /* * Set MAC address offset from the ROM format. * Legacy ROMs have ethernet address start at offset 0, * while the rest (ver 1/A and 3.0) have it at byte offset 20. */ adrsOffset = (sromData == 0xAA55) ? 0: 10; for (len=EADDR_LEN; len; len-=2, adrsOffset++) { sromData = dec21140SromWordRead (pDrvCtrl, adrsOffset); *enetAdrs++ = MSB(sromData); *enetAdrs++ = LSB(sromData); } } return (OK); }/********************************************************************************* sysDec21143MediaSelect - hook routine for dec21x40Start** This is hook routine for dec21x40Start(). This routine selects a media for* dec21143 board.** RETURNS: OK, always.*/ STATUS sysDec21143MediaSelect ( DEC21X40_DRV_CTRL * pDrvCtrl, /* Driver control */ UINT * pCsr6Val /* CSR6 return value */ ) { ULONG * csrReg; ULONG csrData; /* set CSR6 value */ *pCsr6Val |= CSR6_21140_MB1; /* Led/Control selection */ csrReg = (ULONG *)(pDrvCtrl->devAdrs + (CSR15 * DECPCI_REG_OFFSET)); csrData = (CSR15_21143_CWE | CSR15_21143_LG3 | CSR15_21143_LG1 | CSR15_MD_MSK); *csrReg = PCISWAP (csrData); csrData = (CSR15_21143_LG3 | CSR15_21143_LG1 | CSR15_MODE_10); *csrReg = PCISWAP (csrData); /* force 10Base-T half duplex configuration */ /* set SIA registers */ csrReg = (ULONG *)(pDrvCtrl->devAdrs + (CSR14 * DECPCI_REG_OFFSET)); csrData = PCISWAP (*csrReg); csrData &= ~(CSR14_21143_T4 | CSR14_21143_TXF| CSR14_21143_TXH | CSR14_21143_TAS | CSR14_21143_TH | CSR14_21143_ANE); *csrReg = PCISWAP(csrData); csrReg = (ULONG *)(pDrvCtrl->devAdrs + (CSR13 * DECPCI_REG_OFFSET)); csrData = PCISWAP (*csrReg); csrData |= CSR13_SRL_SIA; *csrReg = PCISWAP (csrData); return (OK); }/******************************************************************************* sysDec21x40DynEnetFind - Find ethernet network device dynamically** This function dynamically finds the ethernet network device. The* encoded location is returned the 'pciLoc' output parameter if the* device is found. The constraints of the search require that the* device found be on the PCI bus number which matches the 'bus' input* parameter. In addition, if the 'unit' input parameter is zero, the* device/vendor ID must match the PCI_ID_PRI_LAN define, and if the* 'unit' parameter is nonzero, the device/vendor * ID must match the* PCI_ID_SEC_LAN define.** RETURNS: OK if ethernet device is found, ERROR otherwise*/STATUS sysDec21x40DynEnetFind ( UINT unit, /* input: unit number */ UINT instance, /* input: instance number */ UINT32 * pBus, /* output: bus number found */ UINT32 * pDev, /* output: device number found */ UINT32 * pFunc /* output: function number found */ ) { UINT32 findClass; int pciBus; UINT32 index; STATUS status = ERROR; index = instance; findClass = (UINT)((PCI_CLASS_NETWORK_CTLR << 16) | (PCI_SUBCLASS_NET_ETHERNET << 8) | (0 << 0) /* Prog I/F = 0 */ ); if (pciFindClass(findClass, index, &pciBus, (int *) pDev, (int *) pFunc) != ERROR) { status = OK; *pBus = pciBus; } return (status); }#endif /* defined(INCLUDE_NETWORK) && defined (INCLUDE_END) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -