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

📄 ether_test.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 3 页
字号:
//=============================================================================
//
//      ether_test.c - Cyclone Diagnostics
//
//=============================================================================
//####COPYRIGHTBEGIN####
//                                                                          
// -------------------------------------------                              
// The contents of this file are subject to the Red Hat eCos Public License 
// Version 1.1 (the "License"); you may not use this file except in         
// compliance with the License.  You may obtain a copy of the License at    
// http://www.redhat.com/                                                   
//                                                                          
// Software distributed under the License is distributed on an "AS IS"      
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
// License for the specific language governing rights and limitations under 
// the License.                                                             
//                                                                          
// The Original Code is eCos - Embedded Configurable Operating System,      
// released September 30, 1998.                                             
//                                                                          
// The Initial Developer of the Original Code is Red Hat.                   
// Portions created by Red Hat are                                          
// Copyright (C) 2001 Red Hat, Inc.                             
// All Rights Reserved.                                                     
// -------------------------------------------                              
//                                                                          
//####COPYRIGHTEND####
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):   Scott Coulter, Jeff Frazier, Eric Breeden
// Contributors:
// Date:        2001-01-25
// Purpose:     
// Description: 
//
//####DESCRIPTIONEND####
//
//===========================================================================*/

#include "pci_bios.h"
#include "iq80310.h"
#include "ether_test.h"

/* Forward declarations */
static int i557SelfTest ();
static int i557Init ();
static int i557Config (UINT8 loopBackMode);
static int i557AddrSet ();
static int i557RUStart ();
static void setUpPacket ();
static int txPacket ();
static char *malloc ();
static void bzero ();
static void Wait();
static int waitForRxInt();
static int get_ether_addr();

/* Externals */
void printf();
void bcopy();
extern void sgets();
extern int atod();
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 ULONG sys_read_config_dword (UINT32 busno,UINT32 devno,UINT32 funcno,UINT32 offset,UINT32 *data);
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		100
static 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. */

#if 0
/* names for MDI registers */
static char *mdi_reg_name [] =
    {
	"MDI Control Register                               ",
	"MDI Status Register                                ",
	"MDI PHY Identification Register (Word 1)           ",
	"MDI PHY Identification Register (Word 2)           ",
	"MDI Auto-Negotiation Advertisement Register        ",
	"MDI Auto-Negotiation Link Partner Ability Register ",
	"MDI Auto-Negotiation Expansion Register            ",
    };
#endif

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;
	char inputLine[80];

	count = 0;

	/* read the PCI BAR for the Ethernet controller */
	if (sys_read_config_dword(busno, devno, funcno, 0x10, &adapter[0]) == ERROR)
	{
		printf ("Error Reading Adapter PCI Address\n");
		return;
	}

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

	Wait(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;
	}

	Wait(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 (atod (inputLine, &ntimes) == FALSE) 
		ntimes = 0;
*/
	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");
				printf ("(such as a workstation) that is working correctly.\n");
				mask_557_ints ();      /* Disable 557 interrupt */
				return;
			}
	  
			count++;
			printf("Loopback Cycle Count = %d\n", count);
		}

⌨️ 快捷键说明

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