📄 ether_test.c
字号:
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;
bzero (rtnPtr, numBytes);
return ((char *) rtnPtr);
}
/* "Poor Man's bzero" - zero's a block of memory. */
static void bzero (volatile char *ptr, long num_bytes)
{
volatile long i; /* loop counter */
/* zero out space */
for (i = 0; i < num_bytes; *ptr++ = 0, i++)
;
}
/*
* 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 ()
{
portWrite (PORT_RESET); /* bits 4-31 not used for reset */
/* wait 5 msec for device to stabilize */
Wait(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 (pTxBuffer, pRxBuffer, length)
UINT8 *pTxBuffer; /* Pointer data that was transmitted */
UINT8 *pRxBuffer; /* Pointer data that was received */
int length; /* How many bytes to check */
{
int byteNum; /* Current byte number */
#if 0
printf ("\n");
printf ("Transmit Buffer at 0x%08X\n", pTxBuffer);
printf ("Receive Buffer at 0x%08X\n", pRxBuffer);
#endif
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 0
printf ("i557IntHandler: i557Status = 0x%04x\n", i557Status);
#endif
/* 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)
;
#if 0
/* DEBUG */
printf ("give waitSem\n");
#endif
/* 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()
{
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()
{
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 */
Wait (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 */
Wait (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 void Wait (int msecs)
{
delay_ms(msecs);
}
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);
}
void bcopy(UINT32* src, UINT32* dst, int num_bytes)
{
int i;
for (i = 0; i < num_bytes; i++)
*dst++ = *src++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -