#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <mach/hardware.h>
#include <mach/regs-gpio.h>
#include <linux/crc32.h>
static volatile unsigned long *bwscon;
static volatile unsigned long *bankcon4;
#define BWSCON (0x48000000) #define BANKCON4 (0x48000014)
#define DM9000_MIN_IO
0x20000300 //-- #define DM9000_MAX_IO 0x20000370 //-- #define DM9000_VID_L 0x28 #define DM9000_VID_H 0x29 #define DM9000_PID_L 0x2A #define DM9000_PID_H 0x2B #define DM9000_NCR 0x00 #define DM9000_PKT_MAX 1536 //Received packet max size #define DM9000_PKT_RDY 0x01 //Packet ready to receive
#define DMFE_TIMER_WUT jiffies+(HZ*2) //timer wakeup time : 2 second #define DMFE_TX_TIMEOUT (HZ*2) //tx packet time-out time 1.5 s" #define DBG(msg...) do{ \ if(debug)\ printk(KERN_INFO msg);\ }while(0)
struct dm9000x{
u32 ioaddr; // Register I/O base address u32 iodata; // Data I/O address u16 irq; // IRQ u8 iomode; // 0:16bits 1:word 2:byte u8 opmode; u16 Preg0, Preg4; u16 tx_pkt_cnt; u16 sent_pkt_len, queue_pkt_len; u8 device_wait_reset; //device state u8 nic_type; // NIC type spinlock_t lock; }; static int debug=0; static struct net_device *xnet_dev = NULL;
static void dm9000_hash_table(struct net_device *dev);
int xnet_probe(struct net_device *dev); static int xnet_open(struct net_device *dev); static int xnet_stop(struct net_device *dev); static int xnet_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t xnet_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void do_init_dm9000x(struct net_device *dev); static void do_xnet_tx(void); static void do_xnet_rx(void); static void do_xnet_reset(struct dm9000x *dm9x); static void iowt(struct dm9000x *dm9x, int reg, u8 value); static u8 iord(struct dm9000x *dm9x, int reg); //static u16 phy_read(struct dm9000x *dm9x, int reg); //static void phy_write(struct dm9000x *dm9x, int reg, u16 value); static void xnet_timeout(struct net_device *dev); static void xnet_timeout(struct net_device *dev) { struct dm9000x *dm9x=netdev_priv(dev); u8 reg_save; reg_save=readb(dm9x->ioaddr); netif_stop_queue(dev); do_xnet_reset(dm9x); dev->trans_start=jiffies; netif_wake_queue(dev); writeb(reg_save,dm9x->ioaddr); } int xnet_probe(struct net_device *dev)
{ int i = 0; u32 id_val; unsigned long iobase; struct dm9000x *dm9x=netdev_priv(dev); unsigned char mac_add[6] = {0x00, 0x13, 0xf6, 0x6c, 0x87, 0x89}; memset(dm9x,0,sizeof(struct dm9000x)); bwscon = ioremap_nocache(BWSCON,0x0000004); //总线位宽和等待状态控制器 bankcon4= ioremap_nocache(BANKCON4,0x0000004); iobase =(unsigned long)ioremap(DM9000_MIN_IO, 0x400); //进行地址隐射 writel((readl(bwscon) &(~(0xf<<16)))|(0xD<<16), bwscon); //enable UB/LB enable WAIT 16-bit writel(0x1f7c,bankcon4); s3c2410_gpio_cfgpin(S3C2410_GPF7,S3C2410_GPF7_EINT7); spin_lock_init(&dm9x->lock); outb(DM9000_VID_L, iobase); id_val = inb(iobase + 4); outb(DM9000_VID_H, iobase); id_val |= inb(iobase + 4) << 8; outb(DM9000_PID_L, iobase); id_val |= inb(iobase + 4) << 16; outb(DM9000_PID_H, iobase); id_val |= inb(iobase + 4) << 24; if (id_val == 0x90000a46) { DBG("id_val: %x, iobase: %p \n", id_val, (void *)iobase); dm9x->ioaddr = iobase; dm9x->iodata = iobase + 4; ether_setup(dev); dev->base_addr = iobase; dev->irq = IRQ_EINT7; dev->open