📄 dm9000x.c
字号:
do { Uart_SendString("resetting the DM9000, 2nd reset\n"); udelay(25); /* Wait at least 20 us */ } while (DM9000_ior(DM9000_NCR) & 1); /* Check whether the ethernet controller is present */ if ((DM9000_ior(DM9000_PIDL) != 0x0) || (DM9000_ior(DM9000_PIDH) != 0x90)) { Uart_SendString("ERROR: resetting DM9000 -> not responding\n"); }}/* * Search DM9000 device,check the DM9000 identifier. */static int dm9000_probe(void){ u32 id_val; id_val = DM9000_ior(DM9000_VIDL); id_val |= DM9000_ior(DM9000_VIDH) << 8; id_val |= DM9000_ior(DM9000_PIDL) << 16; id_val |= DM9000_ior(DM9000_PIDH) << 24; if (id_val == DM9000_ID) { Uart_Printf("dm9000 i/o: 0x%x, id: 0x%x\n", CONFIG_DM9000_BASE, id_val); return 0; } else { //OSPrintf("dm9000 not found at 0x%08x id: 0x%08x\n", CONFIG_DM9000_BASE, id_val); return -1; }// return (id_val == DM9000_ID)? 0:-1;}/* * Initialize dm9000 device */int dm9000_init(/*struct eth_device *dev, bd_t *bd*/){ extern HANDLER hEthernetInput; int i, oft, lnk; u8 io_mode; #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr = 0;#endif //hEthernetInput = OSAPISemNew(0); //OSPrintf("Init event=0x%x and intr for DM9k\n", hEthernetInput); //config intr for DM9000 //OS_ENTER_CRITICAL() //{ // rGPGCON = (rGPGCON & (~(0x03<<2))) | (0x02<<2); // rEXTINT1 = (rEXTINT1 & (~(0x07<<4))) | (0x01<<4); // rEINTMASK = rEINTMASK & (~(0x01<<9)); //EINIT9 // rEINTPEND |= (1<<9); // ClearPending(BIT_EINT8_23); //rSRCPND|=0x1<<5;rINTPND|=0x1<<5 ; // pISR_EINT8_23 = (U32)irqEMACISR; // rINTMSK = rINTMSK & (~(BIT_EINT8_23)); //} //OS_EXIT_CRITICAL() /* RESET device */ dm9000_reset(); buffer_pool_init(); if (dm9000_probe() < 0) { return -1; } /* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */ #if 1 io_mode = DM9000_ior(DM9000_ISR)>>6; switch (io_mode) { case 0x0: /* 16-bit mode */ Uart_SendString("DM9000: running in 16 bit mode\n"); //db->outblk = dm9000_outblk_16bit; //db->inblk = dm9000_inblk_16bit; //db->rx_status = dm9000_rx_status_16bit; break; case 0x01: /* 32-bit mode */ Uart_SendString("DM9000: running in 32 bit mode\n"); //db->outblk = dm9000_outblk_32bit; //db->inblk = dm9000_inblk_32bit; //db->rx_status = dm9000_rx_status_32bit; break; case 0x02: /* 8 bit mode */ Uart_SendString("DM9000: running in 8 bit mode\n"); //db->outblk = dm9000_outblk_8bit; //db->inblk = dm9000_inblk_8bit; //db->rx_status = dm9000_rx_status_8bit; break; default: /* Assume 8 bit mode, will probably not work anyway */ //OSPrintf("DM9000: Undefined IO-mode:0x%x\n", io_mode); //db->outblk = dm9000_outblk_8bit; //db->inblk = dm9000_inblk_8bit; //db->rx_status = dm9000_rx_status_8bit; break; } #endif //初始化设置步骤:1 //DM9000_iow(DM9000_GPCR, 0x01); //设置 GPCR(1EH) bit[0]=1,使DM9000的GPIO3为输出 //DM9000_iow(DM9000_GPR, 0x00); //GPR bit[0]=0 使DM9000的GPIO3输出为低以激活内部PHY //udelay(2000); //延时2ms以上等待PHY上电 //初始化设置步骤:2 //DM9000_iow(DM9000_NCR, 0x03); //软件复位 //udelay(25); //延时20us以上等待软件复位完成 //DM9000_iow(DM9000_NCR, 0x00); //复位完成,设置正常工作模式 //DM9000_iow(DM9000_NCR, 0x03); //第二次软件复位,为了确保软件复位完全成功。此步骤是必要的 //udelay(25); /* Program operating register, only internal phy supported */ //DM9000_iow(DM9000_NCR, 0x00); //DM9000_iow(DM9000_IMR, 0x80); //中断禁止 //DM9000_iow(DM9000_TCR, 0x00); //发送控制 //DM9000_iow(DM9000_BPTR, 0x3f); //DM9000_iow(DM9000_FCTR, 0x38); //接收FIFO门限3k 8k //DM9000_iow(DM9000_FCR, 0xff); //DM9000_iow(DM9000_SMCR, 0x00); /* TX Polling clear */ DM9000_iow(DM9000_TCR, 0); /* Less 3Kb, 200us */ DM9000_iow(DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_600US); /* Flow Control : High/Low Water */ DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); /* SH FIXME: This looks strange! Flow Control */ DM9000_iow(DM9000_FCR, 0x0); /* Special Mode */ DM9000_iow(DM9000_SMCR, 0); /* clear TX status */ DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* Clear interrupt status */ DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS); //OSPrintf("MAC: %pM\n", dev->enetaddr); /* fill device MAC address registers */ for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) DM9000_iow(oft, MACAddr[i]); for (i = 0, oft = 0x16; i < 8; i++, oft++) DM9000_iow(oft, 0xff); /* read back mac, just to be sure for (i = 0, oft = 0x10; i < 6; i++, oft++) { OSPrintf("%02x:", DM9000_ior(oft)); }*/ //OSPrintf("\nEnter to intr for DM9000, EVENT is 0x%x\n", hEthernetInput); /* Activate DM9000 */ /* RX enable */ //DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); /* Enable TX/RX interrupt mask */ //DM9000_iow(DM9000_IMR, IMR_PAR); SetDM9000Intr(); DM9000_iow(DM9000_NSR, 0x2c); //清除各种状态标志位 DM9000_iow(DM9000_ISR, 0x3f); //清除所有中断标志位 DM9000_iow(DM9000_RCR, 0x39); //接收控制 DM9000_iow(DM9000_IMR, 0x81); //中断使能 Uart_SendString("DM9000 config OK!\n"); return 1;}volatile u8 * NetTxPacket; /* Transmit packet */volatile u8 * NetRxPackets[PKTBUFSRX];/* Receive packets *//* * Hardware start transmission. * Send a packet to media from the upper layer. *///int dm9000_send(struct eth_device *netdev,volatile void *packet,int length)int dm9000_send(volatile void *packet, int length){ int tmo; //struct board_info *db = &dm9000_info; //DM9000_DMP_PACKET(__func__ , packet, length); /* step 1: Clear Tx bit in ISR */ DM9000_iow(DM9000_ISR, IMR_PTM); /* step 2: Move data to DM9000 TX RAM to Prepare for TX-data */ DM9000_outb(DM9000_MWCMD, DM9000_IO); /* push the data to the TX-fifo */ //(db->outblk)(packet, length); dm9000_outblk_16bit(packet, length);// 16 bit mode /* step3: Set TX length to DM9000 */ DM9000_iow(DM9000_TXPLL, length & 0xff); DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff); /* step4 Issue TX polling command */ DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ /* wait for end of transmission */ tmo = get_timer(0) + 5 * CONFIG_SYS_HZ; while ( !(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) || !(DM9000_ior(DM9000_ISR) & IMR_PTM) ) { if (get_timer(0) >= tmo) { Uart_SendString("transmission timeout\n"); break; } } DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ Uart_SendString("transmit done\n\n"); return 0;}/* * Received a packet and pass to upper layer */int dm9000_rx(){ extern void NetReceiveProcess (volatile u8_t *, int); u8 rxbyte, *rdptr = (u8 *)NetRxPackets[0]; u16 RxStatus, RxLen = 0; DM9000_ior(0xF4); DM9000_ior(0xF5); /* Check packet ready or not, we must check the ISR status first for DM9000A */ #if 1 //if (!(DM9000_ior(DM9000_ISR) & 0x01)) { if (!(LastIsrState & 0x01)) { /* Rx-ISR bit must be set. */ Uart_SendString("packet is not received, check the ISR status first for DM9000A\n"); return 0; } #endif DM9000_iow(DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */ /* There is _at least_ 1 package in the fifo, read them all */ for (;;) { DM9000_ior(DM9000_MRCMDX); /* Dummy read */ /* Get most updated data, only look at bits 0:1 */ rxbyte = DM9000_inb(DM9000_DATA) & 0x03; /* Status check: this byte must be 0 or 1 */ if (rxbyte > DM9000_PKT_RDY) { DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */ DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */ OSPrintf("DM9000 error: status check fail: 0x%x\n", rxbyte); return 0; } if (rxbyte != DM9000_PKT_RDY) { /* No packet received, ignore */ //OSPrintf("No packet received\n"); return 0; } //OSPrintf("receiving packet\n"); /* A packet ready now & Get status/length */ //(db->rx_status)(&RxStatus, &RxLen); dm9000_rx_status_16bit(&RxStatus, &RxLen); //OSPrintf("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen); /* Move data from DM9000, Read received packet from RX SRAM */ //(db->inblk)(rdptr, RxLen); dm9000_inblk_16bit(rdptr, RxLen); if ((RxStatus & 0xbf00) || (RxLen < 0x40) || (RxLen > DM9000_PKT_MAX)) { if (RxStatus & 0x100) { Uart_SendString("rx fifo error\n"); } if (RxStatus & 0x200) { Uart_SendString("rx crc error\n"); } if (RxStatus & 0x8000) { Uart_SendString("rx length error\n"); } if (RxLen > DM9000_PKT_MAX) { Uart_SendString("rx length too big\n"); dm9000_reset(); } } else { //DM9000_DMP_PACKET(__func__ , rdptr, RxLen); //OSPrintf("passing packet to upper layer\n"); /* * process the receive frame. */ NetReceiveProcess (NetRxPackets[0], RxLen); } } return 0;}//*------------------------------------------------------------------------------------------------//* 函数名称 : GetInputPacketLen//* 功能描述 : 获取到达的信息包的长度//* 入口参数 : 无//* 出口参数 : 无//*------------------------------------------------------------------------------------------------struct buffer_pool * GetInputPacketLen( void){ struct buffer_pool * pp; if(head_used==NULL) return NULL; else { OSSchedLock(); pp=head_used; head_used=head_used->next; pp->next=NULL; OSSchedUnlock(); return pp; } return pp;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -