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

📄 sysend.c

📁 ATMEL920T的BSP及ETH等已经设备驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef INTEGRATOR_ENET_FIXED_BUF_ADRS
    void *	testbuf = 0;	/* keep compiler quite */
#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.
     */


#ifdef SYS_FEI_DEBUG
    printf ("fei%d: I/O %08X membase %08X irq %d\n", unit, pReso->iobaseCsr,
	    pReso->membaseCsr, pReso->irq);
#endif

    if (pReso->boardType == PRO100B)		/* only setup once */
	{
	}
    else
	{
	/* read the configuration in EEPROM */

	for (ix = 0; ix < EE_SIZE; ix++)
	    {
	    value = sys557eepromRead (unit, ix);
	    pReso->eeprom[ix] = value;
	    sum += value;
	    }
	if (sum != EE_CHECKSUM)
	    printf ("fei%d: Invalid EEPROM checksum %#4.4x\n", 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. */

	/*
	 * We require either a cache-line sized buffer in order to be
	 * able to flush the cache, or use a buffer that is marked as
	 * non-cacheable. If the driver is configured to use a defined
	 * area of memory, we assume that it will be marked as
	 * non-cacheable. We will use that (temporarily).
	 */
#ifdef INTEGRATOR_ENET_FIXED_BUF_ADRS

	pReso->pResults = (volatile INT32 *)sysEnetBufAdrs [unit];
#else
	/*
	 * 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 failed\n", unit);
	    return ERROR;
	    }
	pReso->pResults = (volatile INT32 *)testbuf;

#ifdef INTEGRATOR_ENET_CHECK_BUFFERS
	if (((UINT32)pReso->pResults) < INTEGRATOR_HDR_SSRAM_SIZE)
	    {
	    printf("fei%d: cacheDmaMalloc() returned address in \
		    header card SSRAM\n", unit);
	    return ERROR;
	    }
#endif /* INTEGRATOR_ENET_CHECK_BUFFERS */
#endif /* INTEGRATOR_ENET_FIXED_BUF_ADRS */

	/* 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 */

#ifdef INTEGRATOR_ENET_FIXED_BUF_ADRS
	/* If fixed address specified, no address conversion will be required */

	sysOutLong (pReso->iobaseCsr + SCB_PORT, (int)pReso->pResults | 1);
#else /* INTEGRATOR_ENET_FIXED_BUF_ADRS */
	/*
	 * If using cacheDmaMalloc() it will return a "low-alias" address in
	 * SDRAM, and this will need converting to a "high-alias"
	 * address, so it can be accessed from the PCI bus.
	 */

	sysOutLong (pReso->iobaseCsr + SCB_PORT,
		    sys557CpuToPci(unit, (int)pReso->pResults) | 1);
#endif /* INTEGRATOR_ENET_FIXED_BUF_ADRS */

	/* wait for results */

	do
	    {
	    sysDelay();		/* cause a delay of at least an I/O cycle */
	    }
	while ((pReso->pResults[1] == -1) && (--pReso->timeout >= 0));

        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];

#ifndef INTEGRATOR_ENET_FIXED_BUF_ADRS
        cacheDmaFree (testbuf);
#endif

        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, if appropriate */

#ifndef INTEGRATOR_ENET_FIXED_BUF_ADRS
    pBoard->sysLocalToBus = sys557CpuToPci;
    pBoard->sysBusToLocal = sys557PciToCpu;
#else
    pBoard->sysLocalToBus = NULL;
    pBoard->sysBusToLocal = NULL;
#endif

#ifdef FEI_10MB
    pBoard->phySpeed	  = NULL;
    pBoard->phyDpx	  = NULL;
#endif

    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 */
	    /* 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 */
	    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 */
	    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;
    volatile UINT16 dummy;
    int ix;

    sysOutWord (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;
        sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval);
        sysDelay ();	/* delay for one I/O READ cycle */
        sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval | EE_SK);
        sysDelay ();	/* delay for one I/O READ cycle */
        sysOutWord (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;
        sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval);
        sysDelay ();	/* delay for one I/O READ cycle */
        sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval | EE_SK);
        sysDelay ();	/* delay for one I/O READ cycle */
        sysOutWord (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--)
	{
        sysOutWord (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);
        sysOutWord (iobase + SCB_EEPROM, EE_CS);
        sysDelay ();	/* delay for one I/O READ cycle */
        }

    sysOutWord (iobase + SCB_EEPROM, 0x00);	/* disable EEPROM */

    return (retval);
    }

/*******************************************************************************
*
* 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;

    sysOutLong (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;

    sysOutLong (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 > INTEGRATOR_MAX_END_DEVS)
	{
	printf ("Illegal unit number %d\n", unit);
	return;
	}

    if (pReso->boardType != PRO100B)
	{
	printf ("Unit %d not an FEI device\n", 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.2X\n", etheraddr[ix]);

    printf ("CSR mem base address = %x, Flash mem base address = %x\n",
	    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 */

#endif /* INCLUDE_END */

⌨️ 快捷键说明

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