本文共 11812 字,大约阅读时间需要 39 分钟。
the code behind is a some error ,the hwaddr must written to the relevant regesiters in the init function .this is important and essential. 最近手头刚好有个开发板,也还有点时间,就试着写了一下它上面的网卡驱动,当然也是参考了其现有的驱动再写的,程序如下:
#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>
static void *bwscon;
static void *gpfcon;
static void *extint0;
static void *intmsk;
#define BWSCON (0x48000000)
#define GPFCON (0x56000050)
#define EXTINT0 (0x56000088)
#define INTMSK (0x4A000008)
#define BWSCON (0x48000000)
#define GPFCON (0x56000050)
#define EXTINT0 (0x56000088)
#define INTMSK (0x4A000008)
#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_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"
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 struct net_device *xnet_dev = NULL;
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 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);
int xnet_probe(struct net_device *dev)
{
int i = 0;
u32 id_val;
u32 iobase;
struct dm9000x *dm9x;
unsigned char mac_add[6] = {0x00, 0x13, 0xf6, 0x6c, 0x87, 0x89};
bwscon = ioremap_nocache(BWSCON,0x0000004); //总线位宽和等待状态控制器
gpfcon = ioremap_nocache(GPFCON,0x0000004); //Port F 控制寄存器
extint0 = ioremap_nocache(EXTINT0,0x0000004); //外部中断控制
intmsk = ioremap_nocache(INTMSK,0x0000004); //中断控制
writel(readl(bwscon) | 0xc0000, bwscon); //允许等待,使用UB/LB
//设置GFP7为外部中断模式 EINT7
writel( (readl(gpfcon) & ~(0x3 << 14)) | (0x2 << 14), gpfcon);
//设置EINT7 为 falling edge triggered
writel( (readl(extint0) & ~(0xf << 28)) | (0x4 << 28), extint0);
//中断掩码设置1为屏蔽,这里设置开启EINT4~7
writel( (readl(intmsk)) & ~0x80, intmsk);
iobase = ioremap(DM9000_MIN_IO, 0x400); //进行地址隐射
outb(DM9000_VID_L, iobase);
id_val = inb(iobase + 4);