ether_test.c

来自「eCos操作系统源码」· C语言 代码 · 共 1,146 行 · 第 1/3 页

C
1,146
字号
//=============================================================================////      ether_test.c - Cyclone Diagnostics////=============================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//=============================================================================//#####DESCRIPTIONBEGIN####//// Author(s):   Scott Coulter, Jeff Frazier, Eric Breeden// Contributors:// Date:        2001-01-25// Purpose:     // Description: ////####DESCRIPTIONEND####////===========================================================================*/#include <redboot.h>#include <cyg/io/pci_hw.h>#include <cyg/io/pci.h>#include "pci_bios.h"#include "iq80310.h"#include "ether_test.h"/* Forward declarations */static int i557SelfTest (void);static int i557Init (void);static int i557Config (UINT8 loopBackMode);static int i557AddrSet (void);static int i557RUStart (void);static void setUpPacket (char *p);static int txPacket (char *p);static char *malloc (int n);static int waitForRxInt(void);static int get_ether_addr(int unit, UINT8 *buf, int print_flag);/* Externals */extern long decIn(void);extern void sgets(char *s);extern int enable_external_interrupt (int int_id);extern int isr_connect(int int_num, void (*handler)(int), int arg);extern STATUS pci_isr_connect (int intline, int bus, int device, int (*handler)(int), int arg);extern void delay_ms(int msecs);extern int eeprom_read (UINT32 pci_base,/* PCI Base address */                 int eeprom_addr,       /* word offset from start of eeprom */                 UINT16 *p_data,/* where to put data in memory */                 int nwords             /* number of 16bit words to read */                 );extern int eeprom_write (UINT32 pci_base,/* PCI Base address */                 int eeprom_addr,       /* word offset from start of eeprom */                 UINT16 *p_data,/* data location in memory */                 int nwords             /* number of 16bit words to write */                 );/* Globals needed by both main program and irq handler */static volatile struct SCBtype *pSCB;	/* Pointer to SCB in use */static volatile UINT32 waitSem;	/* Used to block test until interrupt */static volatile UINT32 rxSem;	/* Used to block test until rx sinterrupt */static UINT16 i557Status;	/* Status code from SCB */static volatile char *mem_pool; /* Ptr to malloc's free memory pool */static UINT32 adapter[2];		/* Ptr to PCI Ethernet adapter */static UINT8 node_address[6];/*static long timer0_ticks = 0;*/static char buf[4];static int count = 0;static int forever_flag = FALSE;static UINT32 phy_id = 0;/* 82557 required data structures which must be allocated */static struct rfd *pRfd;static union cmdBlock *pCmdBlock;static char *pPacketBuf;#define SPEED_NOLINK	0#define SPEED_10M	10#define SPEED_100M	100static int link_speed = SPEED_NOLINK;UINT8 unit_intpin;int unit_devno, unit_busno, unit_funcno;#define BUSY_WAIT_LIMIT	 0xf000	 /* the upper limit on a busy wait				    for command completion, etc. */static void mask_557_ints (void){    pSCB->cmdStat.bits.m = 1;}static void unmask_557_ints (void){    pSCB->cmdStat.bits.m = 0;}/****************************************************************************** pci_ether_test - i8255x PCI Ethernet test** Main diagnostic routine for the Intel 8255x 10/100BaseT Ethernet Controller* family.  Arguments include the PCI bus, device and function numbers of the* controller that is to be tested.**/void pci_ether_test (UINT32 busno, UINT32 devno, UINT32 funcno){    volatile int i;    int ntimes;    int broadcom_flag =  FALSE;    UINT16 phy_addr_reg, temp1, temp2;    cyg_pci_device_id  devid;    count = 0;    devid = CYG_PCI_DEV_MAKE_ID(busno, CYG_PCI_DEV_MAKE_DEVFN(devno,funcno));    /* read the PCI BAR for the Ethernet controller */    cyg_pci_read_config_uint32(devid, 0x10, &adapter[0]);    /* strip off BAR indicator bits */    adapter[0] &= 0xfffffff0;    unit_devno	= devno;    unit_busno	= busno;    unit_funcno = funcno;    /* pointer to on-chip SCB */    pSCB = (struct SCBtype *)(adapter[0] + SCB_OFFSET);    unit_intpin = INTA;    printf ("PCI Base Address  = 0x%X\n", adapter[0]);    printf ("PCI Interrupt Pin = 0x%02X\n", unit_intpin);    /* Initialize malloc's memory pool pointer */    mem_pool = (char *) ETHER_MEM_POOL;	    /* Start the timer for delay implementation        printf("Starting timer... ");       StartTimer(); */    printf("Done.\n Resetting chip... ");    /* reset the 82557 to start with a clean slate */    resetChip();    printf("Done.\n");    /* Get the UUT's ethernet address */    if (get_ether_addr (0, node_address, TRUE) == ERROR) {	printf("Error Reading Adapter Ethernet Address\n");	return;    }    temp1 = readMDI(0, MDI_DEFAULT_PHY_ADDR, MDI_PHY_ID_1);    temp2 = readMDI(0, MDI_DEFAULT_PHY_ADDR, MDI_PHY_ID_2);    phy_id = ((temp1 << 16) | temp2);    if ((phy_id & 0xfffffff0) == I82555_PHY_ID)	{	printf ("Intel 82555/558 PHY detected...\n");	/* dummy read for reliable status */	(void)readMDI (0, MDI_DEFAULT_PHY_ADDR, MDI_PHY_STAT);    	temp1 = readMDI (0, MDI_DEFAULT_PHY_ADDR, MDI_PHY_STAT);	printf ("Status Register Link Status is %s\n", (temp1 & MDI_STAT_LINK) ? "UP" : "DOWN");	phy_addr_reg = readMDI (0, MDI_DEFAULT_PHY_ADDR, I82555_STATCTRL_REG);	if (temp1 & MDI_STAT_LINK) {	/* speed only valid with good LNK */	    printf ("Connect Speed is %s\n", (phy_addr_reg & I82555_100_MBPS) ? "100Mbps" : "10Mbps");	    link_speed = (phy_addr_reg & I82555_100_MBPS) ? SPEED_100M : SPEED_10M;	} else	    printf ("Connect Speed is NOT VALID\n");    }    if ((phy_id & 0xfffffff0) == ICS1890_PHY_ID) {	printf ("Integrated Circuit Systems ICS1890 PHY detected...\n");	printf ("Revision = %c\n", 'A' + (phy_id & REVISION_MASK));	/* dummy read for reliable status */	(void)readMDI (0, MDI_DEFAULT_PHY_ADDR, ICS1890_QUICKPOLL_REG);	temp1 = readMDI (0, MDI_DEFAULT_PHY_ADDR, ICS1890_QUICKPOLL_REG);	printf ("Status Register Link Status is %s\n", (temp1 & QUICK_LINK_VALID) ? "UP" : "DOWN");	if (temp1 & QUICK_LINK_VALID) { /* speed only valid with good LNK */	    printf ("Connect Speed is %s\n", (temp1 & QUICK_100_MBPS) ? "100Mbps" : "10Mbps");	    link_speed = (temp1 & QUICK_100_MBPS) ? 		SPEED_100M : SPEED_10M;	} else	    printf ("Connect Speed is NOT VALID\n");    }    if ((phy_id & 0xfffffff0) == DP83840_PHY_ID) {	printf ("National DP83840 PHY detected...\n");	printf ("Revision = %c\n", 'A' + (phy_id & REVISION_MASK));	/* dummy read for reliable status */	(void)readMDI (0, MDI_DEFAULT_PHY_ADDR, MDI_PHY_STAT);	temp1 = readMDI (0, MDI_DEFAULT_PHY_ADDR, MDI_PHY_STAT);	printf ("Status Register Link Status is %s\n", (temp1 & MDI_STAT_LINK) ? "UP" : "DOWN");	phy_addr_reg = readMDI (0 ,MDI_DEFAULT_PHY_ADDR, DP83840_PHY_ADDR_REG);	if (temp1 & MDI_STAT_LINK) {	/* speed only valid with good LNK */	    printf ("Connect Speed is %s\n", (phy_addr_reg & PHY_ADDR_SPEED_10_MBPS) ? "10Mbps" : "100Mbps");	    link_speed = (phy_addr_reg & PHY_ADDR_SPEED_10_MBPS) ? SPEED_10M : SPEED_100M;	}	else printf ("Connect Speed is NOT VALID\n");    }    if ((phy_id & 0xfffffff0) == I82553_PHY_ID) {	printf ("Intel 82553 PHY detected...\n");	printf ("Revision = %c\n", 'A' + (phy_id & REVISION_MASK));	broadcom_flag = TRUE;    }    if (phy_id == I82553_REVAB_PHY_ID) {	printf ("Intel 82553 PHY detected...\n");	printf ("Revision = B\n");	broadcom_flag = TRUE;    }    if (broadcom_flag == TRUE) {	temp2 = readMDI (0,MDI_DEFAULT_PHY_ADDR, I82553_PHY_EXT_REG0);	printf ("Stepping = %02X\n", GET_REV_CNTR(temp2));	/* dummy read for reliable status */	(void)readMDI (0 ,MDI_DEFAULT_PHY_ADDR, MDI_PHY_STAT);	temp1 = readMDI (0 ,MDI_DEFAULT_PHY_ADDR, MDI_PHY_STAT);	printf ("Status Register Link Status is %s\n", (temp1 & MDI_STAT_LINK) ? "UP" : "DOWN");	if (temp1 & MDI_STAT_LINK) {	/* speed only valid with good LNK */	    printf ("Connect Speed is %s\n", (temp2 & EXT_REG0_100_MBPS) ? "100Mbps" : "10Mbps");	    link_speed = (temp2 & EXT_REG0_100_MBPS) ? SPEED_100M : SPEED_10M;	} else	    printf ("Connect Speed is NOT VALID\n");    }    printf ("\n");    /* Run the built-in self test through the port register */    if (i557SelfTest () == ERROR) {	mask_557_ints ();      /* Disable 557 interrupt */	return;    }    /* Reset clears the interrupt mask */    mask_557_ints();    printf ("Press return to initialize ethernet controller.\n");    sgets (buf);    /* Initialize data structures */    if (i557Init () == ERROR) {	mask_557_ints ();      /* Disable 557 interrupt */	return;    }    /* Set hardware address */    if (i557AddrSet () == ERROR) {	mask_557_ints ();      /* Disable 557 interrupt */	return;    }    printf ("Press return to perform internal loopback test.\n");    sgets (buf);    /* Configure for internal loopback */    if (i557Config (INT_LOOP_BACK) == ERROR) {	mask_557_ints ();      /* Disable 557 interrupt */	return;    }    delay_ms(100);    /* Initialize receive buffer and enable receiver */    if (i557RUStart () == ERROR) {	mask_557_ints ();      /* Disable 557 interrupt */	return;    }    /* Send a packet */    setUpPacket (pPacketBuf);    if (txPacket (pPacketBuf) == ERROR)	{	mask_557_ints ();      /* Disable 557 interrupt */	return;    }    printf ("Press return to perform loopback through PHY.\n");    sgets (buf);    /* Configure for external loopback */    if (i557Config (EXT_LOOP_BACK) == ERROR) {	mask_557_ints ();      /* Disable 557 interrupt */	return;    }    delay_ms(100);    /* Initialize receive buffer and enable receiver */    if (i557RUStart () == ERROR) {	mask_557_ints ();      /* Disable 557 interrupt */	return;    }    /* Send a packet */    setUpPacket (pPacketBuf);    if (txPacket (pPacketBuf) == ERROR)	{	mask_557_ints ();      /* Disable 557 interrupt */	return;    }    printf ("Press return to perform external loopback through\n");    printf ("10/100 Base T Hub.  NOTE: If test duration is not forever,\n");    printf ("this test will work only if a properly functioning Hub\n");     printf ("and Twisted Pair cable are attached to the network connector\n");    printf ("on the front panel.\n");    sgets (buf);    printf ("Enter the number of times to run test (0 = forever): ");    ntimes = decIn();    printf ("\n\n");    if (i557RUStart () == ERROR) {	mask_557_ints ();      /* Disable 557 interrupt */	return;    }    setUpPacket (pPacketBuf);    if (ntimes == 0) {	forever_flag = TRUE;	while (1) {	    if ((i557RUStart() == ERROR)||(txPacket (pPacketBuf) == ERROR)) {		printf ("Double-check TP cable and 10/100 Base T Hub\n");		printf ("Try testing them with another system\n");		printf ("(such as a workstation) that is working correctly.\n");		mask_557_ints ();      /* Disable 557 interrupt */		return;	    }	    count++;	    if (((count) % 1000) == 0) 		printf("Loopback Cycle Count = %d\n", count);	}    } else {	forever_flag = FALSE;	for (i=0; i<ntimes; i++) {	    if ((i557RUStart() == ERROR)||(txPacket (pPacketBuf) == ERROR)) {		printf ("Double-check TP cable and 10/100 Base T Hub\n");		printf ("Try testing them with another system\n");

⌨️ 快捷键说明

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