void cs8900_recv(struct net_device *dev) { volatile u16 status, length; struct sk_buff *skb; status = cs8900_read(dev, PP_RxStatus); length = cs8900_read(dev, PP_RxLength); if(!(status & RxOK)) { return; } skb = dev_alloc_skb(length + 2); if(!skb) { //printk("alloc skb error!\n"); return; } skb_reserve(skb, 2); skb->dev = dev; cs8900_frame_read(dev, skb, length); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); return; }
irqreturn_t cs8900_interrupt(int irq, void *dev_id) { volatile u16 status; struct net_device *dev = (struct net_device *)dev_id; while((status = cs8900_read(dev, PP_ISQ)) != 0) { switch(RegNum(status)) { case RxEvent: cs8900_recv(dev); //接收数据 break; case TxEvent: netif_wake_queue(dev); break; case BufEvent: //既有接收中断事件,又有发送中断事件 if(((RegContent(status)) & TxUnderrun)) { netif_wake_queue(dev); } break; } } return IRQ_HANDLED; }
int cs8900_xmit(struct sk_buff *skb, struct net_device *dev) { volatile u16 status; spin_lock_irq(&mylock); netif_stop_queue(dev); cs8900_write(dev, PP_TxCMD, TxStart(After5)); cs8900_write(dev, PP_TxLength, skb->len); status = cs8900_read(dev, PP_BusST); if((status & TxBidErr)) { spin_unlock_irq(&mylock); printk("invalid data length!\n"); return 0; } if(!(status & Rdy4TxNOW)) { spin_unlock_irq(&mylock); printk("tx buffer is not free!\n"); return 0; } cs8900_frame_write(dev, skb); spin_unlock_irq(&mylock); dev_kfree_skb(skb); return 0; }
/* ----- read byte from I/O range in VICE ----- */ BYTE cs8900io_read(WORD io_address) { if (!cs8900io_cannot_use) { return cs8900_read(io_address); } return 0; }
/* ----- read byte from I/O range in VICE ----- */ static BYTE tfe_read(WORD io_address) { if (tfe_as_rr_net) { /* rr status register is handled by rr cartidge */ if (io_address < 0x02) { return 0; } io_address ^= 0x08; } tfe_current_device->io_source_valid = 1; return cs8900_read(io_address); }
int cs8900_init(struct net_device *dev) { int i; dev->open = cs8900_open; dev->stop = cs8900_stop; dev->hard_start_xmit = cs8900_xmit; ether_setup(dev); //协议栈用的MAC地址 dev->dev_addr[0] = 0x08; dev->dev_addr[1] = 0x00; dev->dev_addr[2] = 0x3e; dev->dev_addr[3] = 0x26; dev->dev_addr[4] = 0x0a; dev->dev_addr[5] = 0x5b; dev->if_port = IF_PORT_10BASET; //RJ45 dev->irq = IRQ_EINT9; dev->base_addr = (unsigned long)ioremap(0x19000000, 16); //检测是否是cs8900a网卡芯片 if(cs8900_read(dev, PP_ProductID) != 0x630E) { printk("this is not a CS8900A chip!\n"); return -1; } //cs8900网卡芯片端使用的是INTRQ0管脚连接了s3c2440芯片的EINT9中断管脚 cs8900_write(dev, PP_IntNum, 0); for(i = 0; i < 6; i += 2) { cs8900_write(dev, PP_IA + i, (dev->dev_addr[i+1]<<8) | dev->dev_addr[i]); } return 0; }
static inline void cs8900_set(struct net_device *dev, u16 regno, u16 value) { cs8900_write(dev, regno, cs8900_read(dev, regno) | value); }