📄 ether_test.c
字号:
status = ERROR;
}
if (pRfd->ok != 1) {
printf ("rx failed. Status: 0x%04X.\n", pSCB->cmdStat.words.status);
status = ERROR;
}
}
#endif
if (status == ERROR) {
printf ("\nTransmit Stats:\n");
printf ("---------------\n");
printf ("Transmit OK = %d\n", pCmdBlock->transmit.ok);
printf ("\nReceive Stats:\n");
printf ("---------------\n\n");
printf ("Receive OK = %d\n", pRfd->ok);
printf ("CRC Error = %d\n", pRfd->crcErr);
printf ("Alignment Error = %d\n", pRfd->alignErr);
printf ("Resource Error = %d\n", pRfd->noRsrc);
printf ("DMA Overrun Error = %d\n", pRfd->dmaOverrun);
printf ("Frame Too Short Error = %d\n", pRfd->frameTooshort);
printf ("Receive Collision Error = %d\n", pRfd->rxColl);
return (ERROR);
}
#if 0
printf ("Packet Actual Size = %d\n", pRfd->actCount);
#endif
if (checkPacket (pCmdBlock->transmit.txData, pRfd->rxData, ETHERMTU) == ERROR) {
printf ("data verify error.\n");
return (ERROR);
}
if (forever_flag == FALSE)
printf ("data OK.\n");
#endif
return (OK);
}
/*
* "Poor Man's Malloc" - return a pointer to a block of memory at least
* The block returned will have been zeroed.
*/
static char *malloc (int numBytes) /* number of bytes needed */
{
volatile char *rtnPtr; /* ptr to return to caller */
long new_mem_pool; /* For figuring new pool base address */
rtnPtr = mem_pool; /* Return pointer to start of free pool */
/* Now calculate new base of free memory pool (round to >= 16 bytes) */
new_mem_pool = (UINT32) mem_pool;
new_mem_pool = ((new_mem_pool + numBytes + 0x10) & (~((UINT32) 0x0f)));
mem_pool = (volatile char *) new_mem_pool;
memset(rtnPtr, 0, numBytes);
return ((char *) rtnPtr);
}
/*
* Write "value" to PORT register of PRO/100.
*/
static void portWrite (UINT32 value)
{
*PORT_REG(adapter[0]) = value;
}
/******************************************************************************
*
* sendCommand - send a command to the 82557 via the on-chip SCB
*
* Send a command to the 82557. On the 82557, the Channel Attention signal
* has been replaced by an on-chip SCB. Accesses to the Command Word portion
* of the SCB automatically forces the '557 to look at the various data
* structures which make up its interface.
*/
static void sendCommand (UINT8 cuc, UINT8 ruc, UINT32 scb_general_ptr)
{
register CMD_STAT_U temp_cmdStat;
volatile union cmdBlock *pBlock = (union cmdBlock *)scb_general_ptr;
volatile int loop_ctr;
/* Mask adapter interrupts to prevent the interrupt handler from
playing with the SCB */
mask_557_ints();
/* must wait for the Command Unit to become idle to prevent
us from issueing a CU_START to an active Command Unit */
for (loop_ctr = BUSY_WAIT_LIMIT; loop_ctr > 0; loop_ctr--) {
if ((pSCB->cmdStat.words.status & SCB_S_CUMASK) == SCB_S_CUIDLE)
break;
}
if (loop_ctr == 0) {
printf("sendCommand: CU won't go idle, command ignored\n");
unmask_557_ints();
return;
}
/* when setting the command word, read the current word from
the SCB and preserve the upper byte which contains the interrupt
mask bit */
temp_cmdStat.words.command = (pSCB->cmdStat.words.command & 0xff00);
temp_cmdStat.words.status = 0;
/* set up the Command and Receive unit commands */
temp_cmdStat.bits.cuc = cuc & 0x07;
temp_cmdStat.bits.ruc = ruc & 0x07;
/* Clear flag */
waitSem = 0;
/* write the General Pointer portion of the SCB first */
pSCB->scb_general_ptr = scb_general_ptr;
/* write the Command Word of the SCB */
pSCB->cmdStat.words.command = temp_cmdStat.words.command;
/* only wait for command which will complete immediately */
if ((scb_general_ptr != 0/* NULL*/) && (ruc != RU_START)) {
/* wait for command acceptance and completion */
for (loop_ctr = BUSY_WAIT_LIMIT; loop_ctr > 0; loop_ctr--) {
if ((pSCB->cmdStat.bits.cuc == 0) && (pBlock->nop.c == 1))
break;
}
if (loop_ctr == 0) {
printf("sendCommand: Timeout on command complete\n");
printf("Cmd Complete bit = %02X\n", pBlock->nop.c);
printf("CU command = 0x%02X\n", cuc);
printf("RU command = 0x%02X\n", ruc);
printf("SCB Gen Ptr = 0x%X\n", scb_general_ptr);
printf("scb status = 0x%04X\n", pSCB->cmdStat.words.status);
printf("scb command = 0x%04X\n", pSCB->cmdStat.words.command);
}
}
#if 0
/* DEBUG */
printf("scb command = 0x%04X\n", pSCB->cmdStat.words.command);
printf("scb status = 0x%04X\n", pSCB->cmdStat.words.status);
#endif
unmask_557_ints();
return;
}
/*
* Do a port reset on 82557.
*/
static void resetChip (void)
{
portWrite (PORT_RESET); /* bits 4-31 not used for reset */
/* wait 5 msec for device to stabilize */
delay_ms(5);
}
/*
* Setup contents of a packet.
*/
static void makePacket (UINT8 *pPacket, int length)
{
int byteNum; /* Current byte number */
for (byteNum = 0; byteNum < length; byteNum++)
*pPacket++ = byteNum + ' ';
}
/*
* Verify contents of a received packet to what was transmitted.
* Returns OK if they match, ERROR if not.
*/
static int checkPacket (UINT8 *pTxBuffer, UINT8 *pRxBuffer, int length)
{
int byteNum; /* Current byte number */
for (byteNum = 0; byteNum < length; byteNum++) {
if (*pTxBuffer++ != *pRxBuffer++) {
printf("Error at byte 0x%x\n", byteNum);
printf("Expected 0x%02X, got 0x%02X\n", *(pTxBuffer - 1), *(pRxBuffer - 1));
return (ERROR);
}
}
return (OK);
}
/*
* Interrupt handler for i82557. It acknowledges the interrupt
* by setting the ACK bits in the command word and issuing a
* channel attention. It then updates the global status variable
* and gives the semaphore to wake up the main routine.
*/
int i557IntHandler (int arg) /* should return int */
{
register CMD_STAT_U temp_cmdStat;
register int rxFlag = FALSE;
temp_cmdStat.words.status = pSCB->cmdStat.words.status;
/* check to see if it was the PRO/100 */
if (temp_cmdStat.words.status & I557_INT) {
/* Wait for command word to clear - indicates no pending commands */
while (pSCB->cmdStat.words.command)
;
/* Update global status variable */
i557Status = temp_cmdStat.words.status;
/* If the interrupt was due to a received frame... */
if (temp_cmdStat.bits.statack_fr)
rxFlag = TRUE;
temp_cmdStat.words.status = temp_cmdStat.words.status & I557_INT;
/* Acknowledge interrupt by setting ack bits */
pSCB->cmdStat.words.status = temp_cmdStat.words.status;
/* Wait for command word to clear - indicates IACK accepted */
while (pSCB->cmdStat.words.command)
;
/* Update global status variable and unblock task */
waitSem = 1;
if (rxFlag == TRUE)
rxSem = 1;
return(1); /* serviced - return 1 */
}
return(0); /* nothing serviced - return 0 */
}
/*
* Take the semaphore and block until i557 interrupt or timeout.
* Returns OK if an interrupt occured, ERROR if a timeout.
*/
static int waitForInt(void)
{
int num_ms = 0;
while ((waitSem == 0) && (num_ms != 2000)) { /* wait max 2secs for the interrupt */
delay_ms(1);
num_ms++;
}
if (!waitSem) {
printf("Wait error!\n");
return (ERROR);
} else
return (OK);
}
static int waitForRxInt(void)
{
int num_ms = 0;
while ((rxSem == 0) && (num_ms != 2000)) { /* wait max 2secs for the interrupt */
delay_ms(1);
num_ms++;
}
if (!rxSem) {
printf("Rx Wait error!\n");
return (ERROR);
} else
return (OK);
}
static UINT16 readMDI (int unit, UINT8 phyAdd, UINT8 regAdd)
{
register MDI_CONTROL_U mdiCtrl;
int num_ms = 0;
/* prepare for the MDI operation */
mdiCtrl.bits.ready = MDI_NOT_READY;
mdiCtrl.bits.intEnab = MDI_POLLED; /* no interrupts */
mdiCtrl.bits.op = MDI_READ_OP;
mdiCtrl.bits.phyAdd = phyAdd & 0x1f;
mdiCtrl.bits.regAdd = regAdd & 0x1f;
/* start the operation */
*MDI_CTL_REG(adapter[unit]) = mdiCtrl.word;
/* delay a bit */
delay_ms(1);
/* poll for completion */
mdiCtrl.word = *MDI_CTL_REG(adapter[unit]);
while ((mdiCtrl.bits.ready == MDI_NOT_READY) && (num_ms != 2000)) { /* wait max 2secs */
mdiCtrl.word = *MDI_CTL_REG(adapter[unit]);
delay_ms(1);
num_ms++;
}
if (num_ms >= 2000) {
printf ("readMDI Timeout!\n");
return (-1);
} else
return ((UINT16)mdiCtrl.bits.data);
}
static void writeMDI (int unit, UINT8 phyAdd, UINT8 regAdd, UINT16 data)
{
register MDI_CONTROL_U mdiCtrl;
int num_ms = 0;
/* prepare for the MDI operation */
mdiCtrl.bits.ready = MDI_NOT_READY;
mdiCtrl.bits.intEnab = MDI_POLLED; /* no interrupts */
mdiCtrl.bits.op = MDI_WRITE_OP;
mdiCtrl.bits.phyAdd = phyAdd & 0x1f;
mdiCtrl.bits.regAdd = regAdd & 0x1f;
mdiCtrl.bits.data = data & 0xffff;
/* start the operation */
*MDI_CTL_REG(adapter[unit]) = mdiCtrl.word;
/* delay a bit */
delay_ms(1);
/* poll for completion */
mdiCtrl.word = *MDI_CTL_REG(adapter[unit]);
while ((mdiCtrl.bits.ready == MDI_NOT_READY) && (num_ms != 2000)) {
mdiCtrl.word = *MDI_CTL_REG(adapter[unit]);
delay_ms(1);
num_ms++;
}
if (num_ms >= 2000)
printf ("writeMDI Timeout!\n");
return;
}
static int get_ether_addr (int unit,
UINT8 *buffer,
int print_flag) /* TRUE to print the information */
{
UINT16 temp_node_addr[3] = {0,0,0};
register int i;
/* Get the adapter's node address */
if (eeprom_read (adapter[unit],IA_OFFSET,temp_node_addr,3) != OK) {
printf ("Error reading the IA address from Serial EEPROM.\n");
return (ERROR);
}
buffer[0] = (UINT8)(temp_node_addr[0] & 0x00ff);
buffer[1] = (UINT8)((temp_node_addr[0] & 0xff00)>>8);
buffer[2] = (UINT8)(temp_node_addr[1] & 0x00ff);
buffer[3] = (UINT8)((temp_node_addr[1] & 0xff00)>>8);
buffer[4] = (UINT8)(temp_node_addr[2] & 0x00ff);
buffer[5] = (UINT8)((temp_node_addr[2] & 0xff00)>>8);
if (print_flag == TRUE) {
printf("Ethernet Address = [ ");
for (i=0; i<6; i++) {
printf("0x%02X ", buffer[i]);
}
printf("]\n\n");
}
return (OK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -