Davicom公司DM9000A和DM9010 ISA NIC 以太网驱动分析
e: %s %xn, msg, vaule)
#endif
#ifndef CONFIG_ARCH_MAINSTONE
#pragma pack(push, 1)
#endif
typedef struct _RX_DESC
{
u8 rxbyte;
u8 status;
u16 length;
}RX_DESC;
typedef union{
u8 buf[4];
RX_DESC desc;
} rx_t;
#ifndef CONFIG_ARCH_MAINSTONE
#pragma pack(pop)
#endif
enum DM9KS_PHY_mode {
DM9KS_10MHD = 0,
DM9KS_100MHD = 1,
DM9KS_10MFD = 4,
DM9KS_100MFD = 5,
DM9KS_AUTO = 8,
};
/* Structure/enum declaration ------------------------------- */
typedef struct board_info {
u32 reset_counter; /* counter: RESET */
u32 reset_tx_timeout; /* RESET caused by TX Timeout */
u32 io_addr; /* Register I/O base address */
u32 io_data; /* Data I/O address */
int tx_pkt_cnt;
u8 op_mode; /* PHY operation mode */
u8 io_mode; /* 0:word, 2:byte */
u8 device_wait_reset; /* device state */
u8 Speed; /* current speed */
int cont_rx_pkt_cnt;/* current number of continuos rx packets */
struct timer_list timer;
struct net_device_stats stats;
unsigned char srom[128];
spinlock_t lock;
} board_info_t;
/* Global variable declaration ----------------------------- */
/*static int dmfe_debug = 0;*/
static struct net_device * dmfe_dev = NULL;
/* For module input parameter */
static int mode = DM9KS_AUTO;
static int media_mode = DM9KS_AUTO;
static u8 irq = DM9K_IRQ;
static u32 iobase = DM9KS_MIN_IO;
/* function declaration ------------------------------------- */
int dmfe_probe(struct net_device *);
static int dmfe_open(struct net_device *);
static int dmfe_start_xmit(struct sk_buff *, struct net_device *);
static void dmfe_tx_done(unsigned long);
static void dmfe_packet_receive(struct net_device *);
static int dmfe_stop(struct net_device *);
static struct net_device_stats * dmfe_get_stats(struct net_device *);
static int dmfe_do_ioctl(struct net_device *, struct ifreq *, int);
#if LINUX_VERSION_CODE KERNEL_VERSION(2,5,0)
static void dmfe_interrupt(int , void *, struct pt_regs *);
#else
static irqreturn_t dmfe_interrupt(int , void *, struct pt_regs *);
#endif
static void dmfe_timer(unsigned long);
static void dmfe_init_dm9000(struct net_device *);
static unsigned long cal_CRC(unsigned char *, unsigned int, u8);
static u8 ior(board_info_t *, int);
static void iow(board_info_t *, int, u8);
static u16 phy_read(board_info_t *, int);
static void phy_write(board_info_t *, int, u16);
static u16 read_srom_word(board_info_t *, int);
static void dm9000_hash_table(struct net_device *);
static void dmfe_timeout(struct net_device *);
static void dmfe_reset(struct net_device *);
#if defined(CHECKSUM)
static u8 check_rx_ready(u8);
#endif
//DECLARE_TASKLET(dmfe_tx_tasklet,dmfe_tx_done,0);
/* DM9000 network baord routine ---------------------------- */
/*
Search DM9000 board, allocate space and register it
*/
struct net_device * __init dmfe_probe1(void)
{
struct net_device *dev;
int err;
#if LINUX_VERSION_CODE KERNEL_VERSION(2,5,0)
dev = init_etherdev(NULL, sizeof(struct board_info));
ether_setup(dev);
#else
dev= alloc_etherdev(sizeof(struct board_info));
#endif
if(!dev)
return ERR_PTR(-ENOMEM);
SET_MODULE_OWNER(dev);
err = dmfe_probe(dev);
if (err)
goto out;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
err = register_netdev(dev);
if (err)
goto out1;
#endif
return dev;
out1:
release_region(dev->base_addr,2);
out:
#if LINUX_VERSION_CODE KERNEL_VERSION(2,5,0)
kfree(dev);
#else
free_netdev(dev);
#endif
return ERR_PTR(err);
}
int __init dmfe_probe(struct net_device *dev)
{
struct board_info *db; /* Point a board information structure */
u32 id_val;
u16 i, dm9000_found = FALSE;
DMFE_DBUG(0, dmfe_probe(),0);
/* Search All DM9000 serial NIC */
do {
outb(DM9KS_VID_L, iobase);
id_val = inb(iobase + 4);
outb(DM9KS_VID_H, iobase);
id_val |= inb(iobase + 4) 8;
outb(DM9KS_PID_L, iobase);
id_val |= inb(iobase + 4) 16;
out
以太网 驱动 分析 NIC ISA 公司 DM9000A DM9010 Davicom 相关文章:
- 基于S3C44B0X+μcLinux的嵌入式以太网设计(07-08)
- TM1300 DSP系统以太网接口的设计(03-07)
- 工业级特性在嵌入式处理中至关重要(05-08)
- 基于VxWorks的双端口网卡智能双冗余驱动(07-01)
- 基于μC/OS-II和TCP/IP协议的多串口服务器(08-23)
- 基于DSP/FPGA的以太网控制器的运动控制器设计(02-06)