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

📄 sysgei82543end.c

📁 Freescale mpc834x 的VxWorks平台的BSP源代码。
💻 C
📖 第 1 页 / 共 4 页
字号:
    UINT32        deviceId;    /* store a PCI device ID */    UINT8         revisionId;  /* store a PCI revision ID */    pciConfigInLong (pciBus, pciDevice, pciFunc,                      PCI_CFG_VENDOR_ID, &vendorId);    pciConfigInByte (pciBus, pciDevice, pciFunc,                         PCI_CFG_REVISION, &revisionId);    deviceId = ((vendorId >> 16) & 0x0000ffff);    vendorId = (vendorId & 0x0000ffff);    if ((boardType = sysGeiDevToType (vendorId, deviceId, revisionId))                  != (UINT32)(BOARD_TYPE_UNKNOWN))        {        int pciSysNum = *(int *)pPciSysNum;        sys543PciInit (pciBus, pciDevice, pciFunc, vendorId,                        deviceId, revisionId, boardType, pciSysNum);        }    return OK;    }/******************************************************************************* sys543PciInit - initialize a GEI 8254x PCI ethernet device** This routine performs basic PCI initialization for 8254x ethernet* devices supported by the gei82543End END driver.  Parameters to this* routine specify a PCI function, including PCI ID registers, to* initialize.  If supported,  the device memory and I/O addresses are* mapped into the local CPU address space and an internal board-specific* PCI resources table is updated with information on the board type,* memory address, and IO address.** RETURNS:* OK, or ERROR if the specified device is not supported, or if* the device could not be mapped into the local CPU memory space.*/STATUS sys543PciInit    (    UINT32         pciBus,      /* store a PCI bus number */    UINT32         pciDevice,   /* store a PCI device number */    UINT32         pciFunc,     /* store a PCI function number */    UINT32         vendorId,    /* store a PCI vendor ID */    UINT32         deviceId,    /* store a PCI device ID */    UINT8          revisionId,  /* store a PCI revision ID */    UINT32         boardType,   /* board type */    int            pciSysNum    /* PCI system number */    )    {    UINT32         memBaseLo;   /* temporary BAR storage */    UINT32         memBaseHi;    UINT32         flashBase;    UINT8          irq;         /* store PCI interrupt line (IRQ) number */    GEI_RESOURCE * pReso;       /* alias extended resource table */    /* number of physical units exceeded the number supported ? */    if (geiUnits >= GEI_MAX_DEV)        {        return (ERROR);        }    if (pciSysNum != PCI_1_BUS && pciSysNum != PCI_2_BUS)        return ERROR;    /* BAR information will be saved in the extended resource table */    /*      * Note to enable configuration of PCI1 and PCI2 gei pciSysNum is used     *  to distinguish. It is assumed only one gei is available for either.     */    pReso = (GEI_RESOURCE *)(geiPciResources[geiUnits].pExtended);    geiPciResources[geiUnits].pciSysNum = pciSysNum;#if (PCI_CFG_TYPE != PCI_CFG_AUTO)	{	pciConfigOutLong (pciBus, pciDevice, pciFunc,			  PCI_CFG_BASE_ADDRESS_0, pReso->memBaseLow);	if (pReso->adr64)	    {	    pciConfigOutLong (pciBus, pciDevice,			      pciFunc,PCI_CFG_BASE_ADDRESS_1,			      pReso->memBaseHigh);	    pciConfigOutLong (pciBus, pciDevice,			      pciFunc, PCI_CFG_BASE_ADDRESS_2,			      pReso->flashBase);	    }	    {	    pciConfigOutLong (pciBus, pciDevice,			      pciFunc, PCI_CFG_BASE_ADDRESS_1,			      pReso->flashBase);	    pciConfigOutLong (pciBus, pciDevice,			      pciFunc, PCI_CFG_BASE_ADDRESS_2,			      pReso->flashBase);	    }	pciConfigOutByte (pciBus, pciDevice, pciFunc,			  PCI_CFG_DEV_INT_LINE, geiPciResources[geiUnits].irq);	}#endif    /*     * BAR0: [32:17]: memory base     *       [16:4] : read as "0";     *       [3]    : 0 - device is not prefetchable     *       [2:1]  : 00b - 32-bit address space, or     *                01b - 64-bit address space     *       [0]    : 0 - memory map decoded     *     * BAR1: if BAR0[2:1] == 00b, optional flash memory base     *       if BAR0[2:1] == 01b, high portion of memory base     *                            for 64-bit address space     *     * BAR2: if BAR0[2:1] == 01b, optional flash memory base     *       if BAR0[2:1] == 00b, behaves as BAR-1 when BAR-0 is     *                            a 32-bit value     */    pciConfigInLong  (pciBus, pciDevice, pciFunc,                      PCI_CFG_BASE_ADDRESS_0, &memBaseLo);    pReso->adr64 = ((memBaseLo & BAR0_64_BIT) == BAR0_64_BIT)                   ? TRUE : FALSE;    if (pReso->adr64)        {        pciConfigInLong  (pciBus, pciDevice, pciFunc,                          PCI_CFG_BASE_ADDRESS_1, &memBaseHi);        pciConfigInLong  (pciBus, pciDevice, pciFunc,                          PCI_CFG_BASE_ADDRESS_2, &flashBase);        }    else        {        memBaseHi = 0x0;        pciConfigInLong  (pciBus, pciDevice, pciFunc,                          PCI_CFG_BASE_ADDRESS_1, &flashBase);        }    memBaseLo &= PCI_MEMBASE_MASK;    flashBase &= PCI_MEMBASE_MASK;    /* get the device's interrupt line (IRQ) number */    pciConfigInByte (pciBus, pciDevice, pciFunc,                     PCI_CFG_DEV_INT_LINE, &irq);    /* update the board-specific resource tables */    pReso->memBaseLow  = memBaseLo;    pReso->memBaseHigh = memBaseHi;    pReso->flashBase   = flashBase;    geiPciResources[geiUnits].irq        = irq;    geiPciResources[geiUnits].irqvec     = irq;    geiPciResources[geiUnits].vendorID   = vendorId;    geiPciResources[geiUnits].deviceID   = deviceId;    geiPciResources[geiUnits].revisionID = revisionId;    geiPciResources[geiUnits].boardType  = boardType;   /* the following support legacy interfaces and data structures */    geiPciResources[geiUnits].pciBus     = pciBus;    geiPciResources[geiUnits].pciDevice  = pciDevice;    geiPciResources[geiUnits].pciFunc    = pciFunc;    /* enable mapped memory and IO decoders */    pciConfigOutWord (pciBus, pciDevice, pciFunc, PCI_CFG_COMMAND,                      PCI_CMD_MEM_ENABLE | PCI_CMD_IO_ENABLE |                      PCI_CMD_MASTER_ENABLE);    /* disable sleep mode */    pciConfigOutByte (pciBus, pciDevice, pciFunc, PCI_CFG_MODE,                      SLEEP_MODE_DIS);    ++geiUnits;  /* increment number of units initialized */    return (OK);    }/******************************************************************************** sysGei8254xEndLoad - create load string and load a gei driver.** This routine will be invoked by the MUX for the purpose of loading an* gei82543End (gei) device with initial parameters.  This routine is* constructed as an interface wrapper for the driver load routine.  Thus,* the arguments and return values are consistent with any xxxEndLoad()* routine defined for an END driver and the MUX API.** INTERNAL* The muxDevLoad() operation calls this routine twice.  A zero length* <pParamStr> parameter string indicates that this is the first time* through this routine.  The driver load routine should return the* driver name in <pParamStr>.** On the second pass though this routine, the initialization parameter* string is constructed.  Note that on the second pass, the <pParamStr>* consists of a colon-delimited END device unit number and rudimentary* initialization string (often empty) constructed from entries in the* BSP END Device Table such that:**     <pParamStr> = "<unit>:<default initialization string>"** In the process of building the rest of <pParamStr>, the prepended unit* number must be preserved and passed to the driver load routine.  The* <default initialization string> portion mentioned above is discarded,* but future versions of this routine may use it.** The complete gei82543End driver load string has format:**     <unit>:<shMemBase>:<shMemSize>:<rxDesNum>:<txDesNum>:<usrFlags>:*     <offset>:<mtu>** RETURNS: An END object pointer, or NULL on error, or 0 and the name of the* device if the <pParamStr> was NULL.** SEE ALSO: gei82543EndLoad()*/END_OBJ * sysGei8254xEndLoad    (    char *    pParamStr,   /* ptr to initialization parameter string */    void *    unused       /* unused optional argument */    )    {    END_OBJ * pEnd;    char      paramStr [END_INIT_STR_MAX];    if (strlen (pParamStr) == 0)        {        /* PASS (1)         * The driver load routine returns the driver name in <pParamStr>.         */        pEnd = gei82543EndLoad (pParamStr);        }    else        {        /* PASS (2)         * The END <unit> number is prepended to <pParamStr>.  Construct         * the rest of the driver load string based on physical devices         * discovered in sys543PciInit().  When this routine is called         * to process a particular END <unit> number, use the END <unit> as         * an index into the PCI "resources" table to build the driver         * parameter string.         */        GEI_RESOURCE *  pReso;        char * holder = NULL;        int    unit   = atoi (strtok_r (pParamStr, ":", &holder));        /* is there a PCI resource associated with this END unit ? */        if (unit >= geiUnits)            {            return NULL;            }        pReso = (GEI_RESOURCE *)(geiPciResources[unit].pExtended);        /* finish off the initialization parameter string */        sprintf (paramStr,"%d:0x%x:0x%x:0x%x:0x%x:0x%x:%d:%d",                 unit,                          /* END unit number */                 pReso->shMemBase,              /* share memory base */                 pReso->shMemSize,              /* share memory size */                 pReso->rxDesNum,               /* RX Descriptor Number*/                 pReso->txDesNum,               /* TX Descriptor Number*/                 pReso->usrFlags,               /* user's flags */                 GEI_OFFSET_VALUE,              /* offset value */                 GEI_JUMBO_MTU_VALUE            /* mtu value */                );        if ((pEnd = gei82543EndLoad (paramStr)) == (END_OBJ *)NULL)            {            printf ("ERROR: sysGei8254xEndLoad fails to load gei %d\n", unit);            }        }    return (pEnd);    }/******************************************************************************* sys82543BoardInit - Adaptor initialization for 8254x chip** This routine is expected to perform any adapter-specific or target-specific* initialization that must be done prior to initializing the 8254x chip.** The 82543 driver calls this routine from the driver load routine before* any other routines.** RETURNS: OK or ERROR*/STATUS sys82543BoardInit    (    int            unit,      /* unit number */    ADAPTOR_INFO * pBoard     /* board information for the GEI driver */    )    {    PCI_BOARD_RESOURCE * pRsrc;    GEI_RESOURCE *       pReso;    BOOL                 lanB = FALSE;    /* sanity check */    if (unit >= geiUnits)        return (ERROR);    pRsrc = &geiPciResources[unit];    pReso = (GEI_RESOURCE *)(pRsrc->pExtended);    if (pRsrc->boardType != PRO1000_543_BOARD &&        pRsrc->boardType != PRO1000_544_BOARD &&        pRsrc->boardType != PRO1000_546_BOARD)         return ERROR;    if (pRsrc->pciSysNum != PCI_1_BUS &&        pRsrc->pciSysNum != PCI_2_BUS)        {        printf ("ERROR: UNKNOWN PCI system number %d in gei unit %d \n",                 pRsrc->pciSysNum, unit);        return ERROR;        }    /* configure the PCI system number */    sysPciConfigEnable (pRsrc->pciSysNum);    if (pRsrc->boardType == PRO1000_546_BOARD)        {        UINT32 eecd;        UINT16 devId;        if (!((eecd = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD))  	& EECD_PRES_BIT))            {            printf ("ERROR: gei unit %d eeprom not presented\n", unit);            return ERROR;            }        pReso->eepromSize = (eecd & EECD_SIZE_BIT)? 256 : 64;        /* detect if this is one of 82546EB dual ports */        pciConfigInWord (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc,                          PCI_CFG_DEVICE_ID, &devId);        if (devId == PRO1000_546_PCI_DEVICE_ID_XT ||            devId == PRO1000_546_PCI_DEVICE_ID_MF)	    {            UINT8 headerType;            pciConfigInByte (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc,                             PCI_CFG_HEADER_TYPE, &headerType);            if (headerType == 0x80)  	        lanB = (pRsrc->pciFunc == 1)? TRUE : FALSE;            else if (pRsrc->pciFunc != 0) 	        {                printf ("Error in detecting 82546 dual port: header type =%2d, "                         "pci func=%2d\n", (UINT32)headerType,  			 (UINT32)(pRsrc->pciFunc)); 	        }            }        }    /* perform EEPROM checksum */    if (sys543eepromCheckSum (unit) != OK)        {        printf ("ERROR: gei unit=%d, EEPROM checksum error!\n", unit);        }    /* get the Ethernet Address from eeprom */    if (sys543EtherAdrGet (unit) == OK)        {        if (pRsrc->boardType == PRO1000_546_BOARD && lanB == TRUE)           {           int   ix;	   /* update LANB address */           for (ix = 5; ix >= 0; ix--)	        {		if (pReso->enetAddr[ix] != 0xff)		    {                    pReso->enetAddr[ix]++;                    break;                    }                else                    pReso->enetAddr[ix] = 0;                }           }        }    else         printf ("ERROR: gei unit=%d, Invalid Ethernet Address!\n", unit);    /* get the initialization control word 1 (ICW1) in EEPROM */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -