⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysln97xend.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 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 failure
01a,10oct99,mtl   written from yk 750 by teamF1
*/


/*
DESCRIPTION
This 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 + -