📄 dm9000 network driver - linux_kernel google 网上论坛.htm
字号:
target=_parent>...</A>@simtec.co.uk> <BR>+ *
Cleanup of code to
remove ifdefs <BR>+ *
Allowed platform device data to
influence access width <BR>+ *
Reformatting areas of code <BR>+
* <BR>+ * 17-Mar-2005 Sascha Hauer
<s.ha<A
href="http://groups.google.com/groups/unlock?msg=997a80484234d5ce&_done=/group/linux.kernel/msg/997a80484234d5ce"
target=_parent>...</A>@pengutronix.de> <BR>+ *
*
removed 2.4 style module parameters <BR>+ *
* removed
removed unused stat counter and fixed <BR>+ *
net_device_stats <BR>+ *
* introduced tx_timeout
function <BR>+ *
* reworked locking <BR>+ */ <BR>+
<BR>+#include <linux/module.h> <BR>+#include
<linux/ioport.h> <BR>+#include <linux/netdevice.h>
<BR>+#include <linux/etherdevice.h> <BR>+#include
<linux/init.h> <BR>+#include <linux/skbuff.h>
<BR>+#include <linux/version.h> <BR>+#include
<linux/spinlock.h> <BR>+#include <linux/crc32.h>
<BR>+#include <linux/mii.h> <BR>+#include
<linux/dm9000.h> <BR>+#include <linux/delay.h> <BR>+
<BR>+#include <asm/delay.h> <BR>+#include <asm/irq.h>
<BR>+#include <asm/io.h> <BR>+ <BR>+#include "dm9000.h" <BR>+
<BR>+/* Board/System/Debug information/definition ----------------
*/ <BR>+ <BR>+#define DM9000_PHY
0x40 /* PHY address 0x01 */ <BR>+ <BR>+#define
TRUE
1 <BR>+#define FALSE
0 <BR>+ <BR>+#define CARDNAME "dm9000"
<BR>+#define PFX CARDNAME ": " <BR>+ <BR>+#define DM9000_TIMER_WUT
jiffies+(HZ*2) /* timer wakeup time : 2
second */ <BR>+ <BR>+#define DM9000_DEBUG 0 <BR>+ <BR>+#if
DM9000_DEBUG > 2 <BR>+#define PRINTK3(args...)
printk(CARDNAME ": " args) <BR>+#else <BR>+#define
PRINTK3(args...) do { } while(0) <BR>+#endif <BR>+ <BR>+#if
DM9000_DEBUG > 1 <BR>+#define PRINTK2(args...)
printk(CARDNAME ": " args) <BR>+#else <BR>+#define
PRINTK2(args...) do { } while(0) <BR>+#endif <BR>+ <BR>+#if
DM9000_DEBUG > 0 <BR>+#define PRINTK1(args...)
printk(CARDNAME ": " args) <BR>+#define PRINTK(args...)
printk(CARDNAME ": " args) <BR>+#else <BR>+#define PRINTK1(args...)
do { } while(0) <BR>+#define PRINTK(args...)
printk(KERN_DEBUG args) <BR>+#endif <BR>+ <BR>+/* <BR>+ * Transmit
timeout, default 5 seconds. <BR>+ */ <BR>+static int watchdog =
5000; <BR>+module_param(watchdog, int, 0400);
<BR>+MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
<BR>+ <BR>+/* Structure/enum declaration
------------------------------- */ <BR>+typedef struct board_info {
<BR>+ <BR>+ void __iomem *io_addr; /*
Register I/O base address */ <BR>+ void __iomem
*io_data; /* Data I/O address */ <BR>+
u16 irq; /*
IRQ */ <BR>+ <BR>+ u16 tx_pkt_cnt; <BR>+
u16 queue_pkt_len; <BR>+ u16
queue_start_addr; <BR>+ u16 dbug_cnt; <BR>+
u8 io_mode;
/* 0:word, 2:byte */ <BR>+ u8 phy_addr;
<BR>+ <BR>+ void (*inblk)(void __iomem *port,
void *data, int length); <BR>+ void
(*outblk)(void __iomem *port, void *data, int length); <BR>+
void (*dumpblk)(void __iomem *port, int length); <BR>+
<BR>+ struct resource *addr_res; /*
resources found */ <BR>+ struct resource
*data_res; <BR>+ struct resource *addr_req;
/* resources requested */ <BR>+ struct
resource *data_req; <BR>+ struct resource
*irq_res; <BR>+ <BR>+ struct timer_list timer;
<BR>+ struct net_device_stats stats; <BR>+
unsigned char srom[128]; <BR>+
spinlock_t lock; <BR>+ <BR>+ struct
mii_if_info mii; <BR>+ u32 msg_enable; <BR>+}
board_info_t; <BR>+ <BR>+/* function declaration
------------------------------------- */ <BR>+static int
dm9000_probe(struct device *); <BR>+static int dm9000_open(struct
net_device *); <BR>+static int dm9000_start_xmit(struct sk_buff *,
struct net_device *); <BR>+static int dm9000_stop(struct net_device
*); <BR>+static int dm9000_do_ioctl(struct net_device *, struct
ifreq *, int); <BR>+ <BR>+ <BR>+static void dm9000_timer(unsigned
long); <BR>+static void dm9000_init_dm9000(struct net_device *);
<BR>+ <BR>+static struct net_device_stats *dm9000_get_stats(struct
net_device *); <BR>+ <BR>+static irqreturn_t dm9000_interrupt(int,
void *, struct pt_regs *); <BR>+ <BR>+static int
dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int
reg); <BR>+static void dm9000_phy_write(struct net_device *dev, int
phyaddr_unused, int reg, <BR>+
int value);
<BR>+static u16 read_srom_word(board_info_t *, int); <BR>+static
void dm9000_rx(struct net_device *); <BR>+static void
dm9000_hash_table(struct net_device *); <BR>+ <BR>+//#define
DM9000_PROGRAM_EEPROM <BR>+#ifdef DM9000_PROGRAM_EEPROM <BR>+static
void program_eeprom(board_info_t * db); <BR>+#endif <BR>+/* DM9000
network board routine ---------------------------- */ <BR>+
<BR>+static void <BR>+dm9000_reset(board_info_t * db) <BR>+{ <BR>+
PRINTK1("dm9000x: resetting\n"); <BR>+
/* RESET device */ <BR>+
writeb(DM9000_NCR, db->io_addr); <BR>+
udelay(200); <BR>+ writeb(NCR_RST,
db->io_data); <BR>+ udelay(200); <BR>+}
<BR>+ <BR>+/* <BR>+ * Read a byte from I/O port <BR>+ */
<BR>+static u8 <BR>+ior(board_info_t * db, int reg) <BR>+{ <BR>+
writeb(reg, db->io_addr); <BR>+
return readb(db->io_data); <BR>+} <BR>+ <BR>+/*
<BR>+ * Write a byte to I/O port <BR>+ */ <BR>+ <BR>+static
void <BR>+iow(board_info_t * db, int reg, int value) <BR>+{ <BR>+
writeb(reg, db->io_addr); <BR>+
writeb(value, db->io_data); <BR>+} <BR>+ <BR>+/*
routines for sending block to chip */ <BR>+ <BR>+static void
dm9000_outblk_8bit(void __iomem *reg, void *data, int count) <BR>+{
<BR>+ writesb(reg, data, count); <BR>+} <BR>+
<BR>+static void dm9000_outblk_16bit(void __iomem *reg, void *data,
int count) <BR>+{ <BR>+ writesw(reg, data,
(count+1) >> 1); <BR>+} <BR>+ <BR>+static void
dm9000_outblk_32bit(void __iomem *reg, void *data, int count) <BR>+{
<BR>+ writesl(reg, data, (count+3) >> 2);
<BR>+} <BR>+ <BR>+/* input block from chip to memory */ <BR>+
<BR>+static void dm9000_inblk_8bit(void __iomem *reg, void *data,
int count) <BR>+{ <BR>+ readsb(reg, data,
count+1); <BR>+} <BR>+ <BR>+ <BR>+static void
dm9000_inblk_16bit(void __iomem *reg, void *data, int count) <BR>+{
<BR>+ readsw(reg, data, (count+1) >> 1);
<BR>+} <BR>+ <BR>+static void dm9000_inblk_32bit(void __iomem *reg,
void *data, int count) <BR>+{ <BR>+ readsl(reg,
data, (count+3) >> 2); <BR>+} <BR>+ <BR>+/* dump block from
chip to null */ <BR>+ <BR>+static void dm9000_dumpblk_8bit(void
__iomem *reg, int count) <BR>+{ <BR>+ int i;
<BR>+ int tmp; <BR>+ <BR>+
for (i = 0; i < count; i++) <BR>+
tmp = readb(reg); <BR>+} <BR>+ <BR>+static void
dm9000_dumpblk_16bit(void __iomem *reg, int count) <BR>+{ <BR>+
int i; <BR>+ int tmp;
<BR>+ <BR>+ count = (count + 1) >> 1;
<BR>+ <BR>+ for (i = 0; i < count; i++)
<BR>+ tmp =
readw(reg); <BR>+} <BR>+ <BR>+static void dm9000_dumpblk_32bit(void
__iomem *reg, int count) <BR>+{ <BR>+ int i;
<BR>+ int tmp; <BR>+ <BR>+
count = (count + 3) >> 2; <BR>+ <BR>+ for
(i = 0; i < count; i++) <BR>+
tmp = readl(reg); <BR>+} <BR>+ <BR>+/* dm9000_set_io
<BR>+ * <BR>+ * select the specified set of io routines to use with
the <BR>+ * device <BR>+ */ <BR>+ <BR>+static void
dm9000_set_io(struct board_info *db, int byte_width) <BR>+{ <BR>+
/* use the size of the data resource to work
out what IO <BR>+ * routines we want to
use <BR>+ */ <BR>+ <BR>+
switch (byte_width) { <BR>+ case 1:
<BR>+
db->dumpblk = dm9000_dumpblk_8bit; <BR>+
db->outblk =
dm9000_outblk_8bit; <BR>+
db->inblk = dm9000_inblk_8bit; <BR>+
break; <BR>+ <BR>+
case 2: <BR>+
db->dumpblk = dm9000_dumpblk_16bit; <BR>+
db->outblk =
dm9000_outblk_16bit; <BR>+
db->inblk = dm9000_inblk_16bit; <BR>+
break; <BR>+
<BR>+
case 3: <BR>+
printk(KERN_ERR PFX ": 3 byte IO, falling back to
16bit\n"); <BR>+
db->dumpblk = dm9000_dumpblk_16bit; <BR>+
db->outblk =
dm9000_outblk_16bit; <BR>+
db->inblk = dm9000_inblk_16bit; <BR>+
break;
<BR>+ <BR>+
case 4: <BR>+ default: <BR>+
db->dumpblk =
dm9000_dumpblk_32bit; <BR>+
db->outblk = dm9000_outblk_32bit; <BR>+
db->inblk
= dm9000_inblk_32bit; <BR>+
break; <BR>+ } <BR>+} <BR>+ <BR>+
<BR>+/* Our watchdog timed out. Called by the networking layer */
<BR>+static void dm9000_timeout(struct net_device *dev) <BR>+{ <BR>+
board_info_t *db = (board_info_t *)
dev->priv; <BR>+ u8 reg_save; <BR>+
unsigned long flags; <BR>+ <BR>+
/* Save previous register address */ <BR>+
reg_save = readb(db->io_addr); <BR>+
spin_lock_irqsave(db->lock,flags); <BR>+ <BR>+
netif_stop_queue(dev); <BR>+
dm9000_reset(db); <BR>+
dm9000_init_dm9000(dev); <BR>+ /* We can accept
TX packets again */ <BR>+ dev->trans_start =
jiffies; <BR>+ netif_wake_queue(dev); <BR>+
<BR>+ /* Restore previous register address */
<BR>+ writeb(reg_save, db->io_addr); <BR>+
spin_unlock_irqrestore(db->lock,flags);
<BR>+} <BR>+ <BR>+ <BR>+/* dm9000_release_board <BR>+ * <BR>+ *
release a board, and any mapped resources <BR>+ */ <BR>+ <BR>+static
void <BR>+dm9000_release_board(struct platform_device *pdev, struct
board_info *db) <BR>+{ <BR>+ if
(db->data_res == NULL) { <BR>+
if (db->addr_res != NULL) <BR>+
release_mem_region((unsigned long)db->io_addr, 4); <BR>+
return; <BR>+
} <BR>+ <BR>+ /* unmap our
resources */ <BR>+ <BR>+
iounmap(db->io_addr); <BR>+
iounmap(db->io_data); <BR>+ <BR>+ /* release
the resources */ <BR>+ <BR>+ if
(db->data_req != NULL) { <BR>+
release_resource(db->data_req); <BR>+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -