cs8900.c
来自「ADS下的bios工程」· C语言 代码 · 共 669 行 · 第 1/2 页
C
669 行
int cs8900_probe (struct netdev *dev);static int cs8900_open (struct netdev *dev);static int cs8900_close (struct netdev *dev);static int cs8900_init (struct netdev *dev);static int cs8900_send (struct netdev *dev, void *buf, int size);static int cs8900_recv (struct netdev *dev, void *buf);/* extern functions */extern int eth_setup (struct netdev *dev);static unsigned short ins( unsigned short offset ){ CSRH_WRITE(CS8900_IO_BASE + DEFAULTIOBASE + ADD_PORT, offset); return CSRH_READ(CS8900_IO_BASE + DEFAULTIOBASE + DATA_PORT);}static void outs(unsigned short offset, unsigned short value ){ CSRH_WRITE(CS8900_IO_BASE+ DEFAULTIOBASE + ADD_PORT, offset); CSRH_WRITE(CS8900_IO_BASE + DEFAULTIOBASE + DATA_PORT, value);}static unsigned short readreg( unsigned short offset ){ return CSRH_READ(CS8900_MEM_BASE + offset);}static void writereg(unsigned short offset, unsigned short value ){ CSRH_WRITE(CS8900_MEM_BASE + offset, value);}static void readpkt(int from, short *to, int len){ int i; volatile unsigned short *sptr; sptr = (unsigned short *)(CS8900_MEM_BASE + PP_RxFrame); for(i=0; i<len; i++) *to++ = *sptr++;}static void writepkt(int to, unsigned short *from, int len){ int i; volatile unsigned short *dptr; dptr = (unsigned short *)(CS8900_MEM_BASE + PP_TxFrame); for(i=0; i<len; i++) *dptr = *from++;}#ifdef DEBUG_CS8900static void cs8900_register(unsigned int ioaddr){ if((ins(PP_BusCTL) & MEMORY_ON)) { printf("\nRead on memory mode\n"); printf("PP_ChipID [%x: %x]\n", PP_ChipID, readreg(PP_ChipID)); printf("PP_RxCFG [%x: %x]\n", PP_RxCFG, readreg(PP_RxCFG)); printf("PP_RxCTL [%x: %x]\n", PP_RxCTL, readreg(PP_RxCTL)); printf("PP_TxCFG [%x: %x]\n", PP_TxCFG, readreg(PP_TxCFG)); printf("PP_TxCMD [%x: %x]\n", PP_TxCMD, readreg(PP_TxCMD)); printf("PP_BufCFG [%x: %x]\n", PP_BufCFG, readreg(PP_BufCFG)); printf("PP_LineCTL [%x: %x]\n", PP_LineCTL, readreg(PP_LineCTL)); printf("PP_SelfCTL [%x: %x]\n", PP_SelfCTL, readreg(PP_SelfCTL)); printf("PP_BusCTL [%x: %x]\n", PP_BusCTL, readreg(PP_BusCTL)); printf("PP_TestCTL [%x: %x]\n", PP_TestCTL, readreg(PP_TestCTL)); } else { printf("\nRead on i/o mode\n"); printf("PP_ChipID [%x: %x]\n", PP_ChipID, ins(PP_ChipID)); printf("PP_RxCFG [%x: %x]\n", PP_RxCFG, ins(PP_RxCFG)); printf("PP_RxCTL [%x: %x]\n", PP_RxCTL, ins(PP_RxCTL)); printf("PP_TxCFG [%x: %x]\n", PP_TxCFG, ins(PP_TxCFG)); printf("PP_TxCMD [%x: %x]\n", PP_TxCMD, ins(PP_TxCMD)); printf("PP_BufCFG [%x: %x]\n", PP_BufCFG, ins(PP_BufCFG)); printf("PP_LineCTL [%x: %x]\n", PP_LineCTL, ins(PP_LineCTL)); printf("PP_SelfCTL [%x: %x]\n", PP_SelfCTL, ins(PP_SelfCTL)); printf("PP_BusCTL [%x: %x]\n", PP_BusCTL, ins(PP_BusCTL)); printf("PP_TestCTL [%x: %x]\n", PP_TestCTL, ins(PP_TestCTL)); }}#endifstatic int cs8900_send (struct netdev *dev, void *buf, int size){ volatile struct ei_device *ei = &ei_local; int count ; /* Transmit packet size */ static char tx_buff[ETH_FRAME_LEN]; unsigned long flags; save_flags(flags); cli(); count = (size <= ETH_ZLEN) ? ETH_ZLEN : size; memcpy (tx_buff, (char *)buf, size); if ( count != size) memset (tx_buff+size, 0, count - size); /* initiate a transmit sequence */ writereg(PP_TxCommand, TX_AFTER_ALL); writereg(PP_TxLength, count); /* Test to see if the chip has allocated memory for the packet */ if ((readreg(PP_BusST) & READY_FOR_TX_NOW) == 0) { /* Gasp! It hasn't. But that shouldn't happen since we're waiting for TxOk, so return 1 and requeue this packet. */ restore_flags(flags); return 1; } /* Write the contents of the packet */ writepkt(PP_TxFrame, (unsigned short *)tx_buff, count>>1); ei->stats.tx_packets++; //cs8900_tx_intr(); /* Transmitter, no error */ restore_flags(flags); return 0;}static int cs8900_receive(void *buf){ volatile struct ei_device *ei = &ei_local; int status, length; /* Received Packet status, length */ unsigned char *frame_buff; length = 0; frame_buff = (unsigned char *)buf; status = readreg(PP_RxStatus); length = readreg(PP_RxLength); if(!length) return 0; length -= 4; if((status & RX_OK) == 0) { ei->stats.rx_errors++; if (status & RX_RUNT) ei->stats.rx_length_errors++; if (status & RX_EXTRA_DATA) ei->stats.rx_length_errors++; if (status & RX_CRC_ERROR) if (!(status & (RX_EXTRA_DATA|RX_RUNT))) ei->stats.rx_crc_errors++; if (status & RX_DRIBBLE) ei->stats.rx_frame_errors++; return 0; } readpkt(PP_RxFrame, (unsigned short *)frame_buff, length>>1); if(length & 1) frame_buff[length-1] = readreg(PP_RxFrame); DEBUG_MAC("RECV_OK: pkt size(%d)\n", length); ei->stats.rx_packets++; ei->stats.rx_bytes += length; return length;}static int cs8900_recv(struct netdev *dev, void *buf){ volatile struct ei_device *ei = &ei_local; int status, length; length = 0; status = readreg(PP_ISQ); if((status & ISQ_EVENT_MASK) == 0) { return 0; } if((status & ISQ_EVENT_MASK) == ISQ_RX_MISS_EVENT) { ei->stats.rx_missed_errors++; return 0; } if((status & ISQ_EVENT_MASK) == ISQ_RECEIVER_EVENT) { DEBUG_MAC("<<RECV GOOD(PKT NO = %d)\n",ei->no++); length = cs8900_receive(buf); /* Recv. good packets */ } return length;}static int cs8900_init (struct netdev *dev){ /* Fill the dev fields */ dev->name = "ETH_CS8900"; dev->open = &cs8900_open; dev->close = &cs8900_close; dev->send = &cs8900_send; dev->recv = &cs8900_recv; eth_setup (dev); return 0;}static int cs8900_open (struct netdev *dev){ volatile struct ei_device *ei = &ei_local; int i; /* Assign interrupt number */ outs(PP_INTNUM, CS8900_IRQ_NUM); /* Change io mode to memory mode */ outs(PP_MEMBASE, 0x1000); outs(PP_BusCTL, MEMORY_ON); /* set the Ethernet address */ for (i=0; i < ETH_ALEN/2; i++) writereg(PP_IA+i*2, dev->hw_addr[i*2] | (dev->hw_addr[i*2+1] << 8)); /* Turn on both receive and transmit operations */ writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON); /* Receive only error free packets addressed to this card */ ei->rx_mode = 0; writereg(PP_RxCTL, DEF_RX_ACCEPT); ei->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL; writereg(PP_RxCFG, ei->curr_rx_cfg | BUFFER_CRC); DEBUG_MAC("PP_RxCFG [%x: %x]\n", PP_RxCFG, readreg(PP_RxCFG)); writereg(PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL | TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL); DEBUG_MAC("PP_TxCFG [%x: %x]\n", PP_TxCFG, readreg(PP_TxCFG)); writereg(PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL | TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL); DEBUG_MAC("PP_BufCFG[%x: %x]\n", PP_BufCFG, readreg(PP_BufCFG)); /* now that we've got our act together, enable everything */ DEBUG_MAC("PP_BusCTL[%x: %x]\n", PP_BusCTL, readreg(PP_BusCTL)); return 0;}static int check_dev_valid(int ioaddr){ /* check device valid, if not return 0 */ /* device is valid, them return io address */ DEBUG_MAC("CS8900_IO_BASE+DEFAULTIOBASE+ADD_PORT = [%x]\n",CS8900_IO_BASE+DEFAULTIOBASE+ADD_PORT); if(CSRH_READ(CS8900_IO_BASE+DEFAULTIOBASE+ADD_PORT) == ADD_SIG) { if(ins(PP_ChipID) == EISA_ID_SIG) { return ioaddr; } else { printf("EISA_ID_SIG(%x)\n", ins(PP_ChipID)); return 0; } } else { printf("ADD_SIG(%x)\n", CSRH_READ(CS8900_IO_BASE+DEFAULTIOBASE+ADD_PORT)); return 0; }}void reset_chip(void){ int i; /* Issue a reset command to the chip */ outs(PP_SelfCTL, ins(PP_SelfCTL) | POWER_ON_RESET); /* Delay for 125 micro-seconds */ for(i=0; i<50*125; i++); /* Transition SBHE to switch chip from 8-bit to 16-bit */ CSRB_READ(CS8900_IO_BASE + DEFAULTIOBASE + ADD_PORT); CSRB_READ(CS8900_IO_BASE + DEFAULTIOBASE + ADD_PORT + 1); CSRB_READ(CS8900_IO_BASE + DEFAULTIOBASE + ADD_PORT); CSRB_READ(CS8900_IO_BASE + DEFAULTIOBASE + ADD_PORT + 1); /* Wait until the chip is reset */ for(i=0; i<50*1000*20; i++); /* 20ms(at least 10ms) */}int cs8900_probe(struct netdev *dev){ volatile struct ei_device *ei = &ei_local; int ioaddr; /* Define non-cachable region */ /* Initialize the device structure */ memset((void *)ei, 0, sizeof(struct ei_device)); /* Check device valid */ ioaddr = check_dev_valid(DEFAULTIOBASE); DEBUG_MAC("ioaddr value is [%d][%x]\n", ioaddr, ioaddr); if(!ioaddr) { printf("Check device error\n"); return 1; } dev->base_addr = ioaddr; DEBUG_MAC("Ether probed (0x%3x)\n",dev->base_addr); /* Reset cs8900 device */ reset_chip(); #ifdef DEBUG_CS8900 cs8900_register(dev->base_addr); /* read CS8900 all register value for test */#endif /* Setup Interrupt vector for ZDMA0 */ //set_IrqAction(INT_CS8900, cs8900_interrupt); //INT_ENABLE(INT_CS8900) ; DEBUG_MAC("INTMSK(%x)\n", CSR_READ(INTMSK)); cs8900_init(dev); /* CS8900 device will be initialized */ return 0;}static int cs8900_close (struct netdev *dev){ writereg(PP_SelfCTL, POWER_ON_RESET); INT_DISABLE(INT_CS8900); DEBUG_MAC("Shutdown Ethernet...INTMSK(%x)\n", CSR_READ(INTMSK)); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?