www.pudn.com > MPC8241BSP.rar > sysEnd.c


/* sysEnd.c - system configuration module for END devices */ 
  
/* Copyright 1984-1999 Wind River Systems, Inc. */ 
/* Copyright 1999-2000 Motorola, Inc., All Rights Reserved */ 
  
/* 
modification history 
-------------------- 
01a,24apr00,rhk  Created (from version 01c of mv5100/sysEnd.c). 
*/ 
 
 
/* 
DESCRIPTION 
This is the WRS-supplied configuration module for the VxWorks  
END drivers.  It performs the dynamic parameterization  
specific to the End drivers.  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 "./pci/pciAutoConfigLib.h" 
#include "drv/pci/pciConfigLib.h" 
 
/* defines */ 
 
#ifdef INCLUDE_SECONDARY_ENET 
#define NUM_END_DEVICES		2  
#else 
#define NUM_END_DEVICES		1 
#endif /* INCLUDE_SECONDARY_ENET */  
 
/* forward declarations */ 
 
/* locals */ 
 
typedef struct endInfo  
    { 
    PCI_ID  pciId; 
    UINT32	bar0Csr; 
    UINT32	bar1Csr; 
    UINT8	irqnum; 
    UINT8	irqvec; 
    } endInfoType; 
  
LOCAL endInfoType endDevices[NUM_END_DEVICES];  
LOCAL char dbgMsg[100]; 
LOCAL initUnit = 0;	/* initialization unit - not sent by end interface */ 
 
/* imports */ 
 
 
IMPORT END_OBJ* i82559DrvEndLoad (char *); 
 
IMPORT void sysDebugMsg (char * str, UINT32  recovery); 
 
 
/****************************************************************************** 
* 
* sysEndLoad - create load string and load the END devices. 
* 
* This routine loads the END devices with initial parameters. 
* 
* RETURNS: pointer to END object or ERROR. 
* 
* SEE ALSO: driver xxxEndLoad() functions. 
*/ 
 
END_OBJ * sysEndLoad 
    ( 
    char * pParamStr,   /* ptr to initialization parameter string */ 
    void * unused       /* unused optional argument */ 
    ) 
    { 
    /* 
     * The End driver END_LOAD_STRING should be: 
     * The format of the parameter string is: 
     * 
     * ":::::: 
     * ::" 
     * 
     * Note that unit number is prepended in muxDevLoad, so we  
     * don't put it here! 
     */ 
 
    char * cp; 			 
    char paramStr [END_INIT_STR_MAX];   	/* end.h */ 
    END_OBJ * pEnd = (END_OBJ *)NULL; 
    UINT32  unit = 0; 
    char unitString[3]; 
 
    /* read PCI configuration and initialize endDevices[] */ 
 
    sysPciInit (); 
 
    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. 
         */ 
 
        switch (endDevices[initUnit].pciId.devVend) 
            { 
            case PCI_ID_LN_I82559: 
            case PCI_ID_LN_I82559ER: 
                pEnd = i82559DrvEndLoad (pParamStr); 
                break; 
            default: 
                sprintf(dbgMsg, "Unknown End device %x unit %d\r\n", 
                       endDevices[initUnit].pciId.devVend, initUnit); 
                /*sysDebugMsg(dbgMsg, 0);*/ 
                return ((END_OBJ *)NULL); 
            } 
            initUnit++; 
 
            /* never go past the end of the list */ 
 
            if (initUnit == NUM_END_DEVICES) 
                initUnit = 0; 
        } 
    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 */ 
 
        unitString[0] = paramStr[0]; 
        unitString[1] = '\0'; 
 
        unit = atoi(unitString); 
 
        /* Now, we advance cp, by finding the end the string */ 
 
        cp += strlen (paramStr); 
         
        /* finish off the initialization parameter string */ 
 
        switch (endDevices[unit].pciId.devVend) 
            { 
            case PCI_ID_LN_I82559: 
            case PCI_ID_LN_I82559ER: 
                sprintf (cp, "%d:%d:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x",  
                         unit, 
                         0, 
                         endDevices[unit].pciId.loc.bus, 
                         endDevices[unit].pciId.loc.device, 
                         endDevices[unit].pciId.loc.function, 
                         endDevices[unit].irqvec,/*PCI_82559_INT_VEC,*/ 
                         endDevices[unit].irqnum,/*PCI_82559_INT_VEC,*/ 
                         endDevices[unit].bar1Csr, /* device io base */ 
                         (UINT) PCI_SLV_MEM_BUS,   /* pciMemBase */ 
                         0); /* user flags */ 
                if ((pEnd = i82559DrvEndLoad (paramStr)) == (END_OBJ *)ERROR) 
                    { 
                    sprintf(dbgMsg, "Failed i82559DrvEndLoad.\r\n"); 
                    /*sysDebugMsg(dbgMsg, 0);*/ 
                    return ((END_OBJ *)NULL); 
                    } 
                break; 
 
            default: 
                sprintf(dbgMsg, "Unknown End device %x unit %d\r\n", 
                       endDevices[unit].pciId.devVend, unit); 
                /*sysDebugMsg(dbgMsg, 0);*/ 
                return ((END_OBJ *)NULL); 
            } 
        } 
 
    return (pEnd); 
    } 
 
 
/******************************************************************************* 
* 
* sysPciInit - prepare LAN adapters for initialization 
* 
* This routine finds the PCI device, and maps its memory and IO address. 
* 
* RETURNS: N/A 
*/ 
 
STATUS sysPciInit (void) 
    { 
    UINT32 pciBus; 
    UINT32 unit = 0; 
 
    endDevices[0].pciId.loc.device = PCI_IDSEL_PRI_LAN; 
 
    /* limit search to bus 0 */ 
 
    pciBus = 0; 
 
#ifdef INCLUDE_SECONDARY_ENET 
    for (;unit < NUM_END_DEVICES; unit++) 
        { 
        if (unit) 
            endDevices[unit].pciId.loc.device = PCI_IDSEL_SEC_LAN; 
 
#endif /* INCLUDE_SECONDARY_ENET */ 
 
        endDevices[unit].pciId.loc.bus = pciBus; 
 
        pciConfigInLong (pciBus, endDevices[unit].pciId.loc.device,  
                         0, PCI_CFG_VENDOR_ID,  
                         &(endDevices[unit].pciId.devVend)); 
 
        /* get memory base address, IO base address, and interrupt line */ 
 
        pciConfigInLong (endDevices[unit].pciId.loc.bus,  
                         endDevices[unit].pciId.loc.device,  
                         endDevices[unit].pciId.loc.function, 
                         PCI_CFG_BASE_ADDRESS_0, &(endDevices[unit].bar0Csr)); 
        pciConfigInLong (endDevices[unit].pciId.loc.bus,  
                         endDevices[unit].pciId.loc.device,  
                         endDevices[unit].pciId.loc.function, 
                         PCI_CFG_BASE_ADDRESS_1, &(endDevices[unit].bar1Csr)); 
        pciConfigInByte (endDevices[unit].pciId.loc.bus,  
                         endDevices[unit].pciId.loc.device,  
                         endDevices[unit].pciId.loc.function, 
                         PCI_CFG_DEV_INT_LINE, &(endDevices[unit].irqvec)); 
 
 
 	endDevices[unit].irqnum = endDevices[unit].irqvec; 
 
        switch (endDevices[unit].pciId.devVend) 
            { 
            case PCI_ID_LN_I82559: 
            case PCI_ID_LN_I82559ER: 
                /* convert Memory base addresses from PCI space to CPU space */ 
 
                endDevices[unit].bar0Csr = TRANSLATE( 
                                            (endDevices[unit].bar0Csr &  
                                             PCI_MEMBASE_MASK), 
                                             PCI_MSTR_MEMIO_BUS,  
                                             PCI_MSTR_MEMIO_LOCAL); 
 
                /* convert I/O base addresses from PCI space to CPU space */ 
 
                endDevices[unit].bar1Csr = TRANSLATE( 
                                             (endDevices[unit].bar1Csr &  
                                             PCI_IOBASE_MASK), 
                                             PCI_MSTR_IO_BUS,PCI_MSTR_IO_LOCAL); 
                break; 
 
#ifdef INCLUDE_DEC_END 
            case PCI_ID_LN_DEC21040: 
            case PCI_ID_LN_DEC21140: 
            case PCI_ID_LN_DEC21143:  
 
                /* convert I/O and Memory base from PCI space to CPU space */ 
 
                endDevices[unit].bar0Csr = TRANSLATE( 
                                           (endDevices[unit].bar0Csr &  
                                           PCI_IOBASE_MASK), 
                                           PCI_MSTR_IO_BUS,PCI_MSTR_IO_LOCAL); 
 
                endDevices[unit].bar1Csr = TRANSLATE( 
                                           (endDevices[unit].bar1Csr &  
                                           PCI_MEMBASE_MASK), 
                                           PCI_MSTR_MEMIO_BUS,  
                                           PCI_MSTR_MEMIO_LOCAL); 
 
                if (endDevices[unit].pciId.devVend == PCI_ID_LN_DEC21143) 
                    {  
                    /* disable sleep mode */ 
 
                    pciConfigOutByte (endDevices[unit].pciId.loc.bus,  
                                      endDevices[unit].pciId.loc.device,  
                                      endDevices[unit].pciId.loc.function,  
                                      PCI_CFG_MODE,  
                                      SLEEP_MODE_DIS); 
 
                    pciConfigOutLong (endDevices[unit].pciId.loc.bus, 
                                      endDevices[unit].pciId.loc.device, 
                                      endDevices[unit].pciId.loc.function,  
                                      PCI_CFG_21143_DA, 0 ); 
                    } 
                break; 
#endif /* INCLUDE_DEC_END */ 
 
            default: 
                sprintf(dbgMsg, "Unknown End device %x unit %d\r\n", 
                       endDevices[unit].pciId.devVend, unit); 
                /*sysDebugMsg(dbgMsg, 0);*/ 
                break; 
            } 
 
#ifdef INCLUDE_SECONDARY_ENET 
        } 
#endif /* INCLUDE_SECONDARY_ENET */ 
 
    return (OK); 
    } 
 
 
/******************************************************************************* 
* 
* sysDec21x40EnetAddrGet - gets the ethernet address from the ROM register 
* 
* This routine returns ERROR.  It is legacy and should never be called. 
* 
* RETURNS: ERROR 
*/ 
 
STATUS sysDec21x40EnetAddrGet 
    ( 
    ) 
    { 
    return (ERROR); 
    } 
 
#endif /* defined(INCLUDE_NETWORK) && defined (INCLUDE_END) */