📄 ether_test.c
字号:
//=============================================================================
//
// 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 + -