ether_test.c

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

C
1,146
字号
	    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 + =
减小字号Ctrl + -
显示快捷键?