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 + -
显示快捷键?