微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM-Linux驱动--DM9000网卡驱动分析(四)

ARM-Linux驱动--DM9000网卡驱动分析(四)

时间:11-20 来源:互联网 点击:

enum dm9000_type type;

void (*inblk)(void __iomem *port, void *data, int length);

void (*outblk)(void __iomem *port, void *data, int length);

void (*dumpblk)(void __iomem *port, int length);

struct device *dev;

struct resource *addr_res;

struct resource *data_res;

struct resource *addr_req;

struct resource *data_req;

struct resource *irq_res;

int irq_wake;

struct mutex addr_lock;

struct delayed_work phy_poll;

struct net_device *ndev;

spinlock_t lock;

struct mii_if_info mii;

u32 msg_enable;

u32 wake_state;

int rx_csum;

int can_csum;

int ip_summed;

} board_info_t;

#define dm9000_dbg(db, lev, msg...) do { \

if ((lev) < CONFIG_DM9000_DEBUGLEVEL && \

(lev) < db->debug_level) { \

dev_dbg(db->dev, msg); \

} \

} while (0)

static inline board_info_t *to_dm9000_board(struct net_device *dev)

{

return netdev_priv(dev);

}

static void

dm9000_reset(board_info_t * db)

{

dev_dbg(db->dev, "resetting device\n");

writeb(DM9000_NCR, db->io_addr);

udelay(200);

writeb(NCR_RST, db->io_data);

udelay(200);

}

static u8

ior(board_info_t * db, int reg)

{

writeb(reg, db->io_addr);

return readb(db->io_data);

}

static void

iow(board_info_t * db, int reg, int value)

{

writeb(reg, db->io_addr);

writeb(value, db->io_data);

}

static void dm9000_outblk_8bit(void __iomem *reg, void *data, int count)

{

writesb(reg, data, count);

}

static void dm9000_outblk_16bit(void __iomem *reg, void *data, int count)

{

writesw(reg, data, (count+1) >> 1);

}

static void dm9000_outblk_32bit(void __iomem *reg, void *data, int count)

{

writesl(reg, data, (count+3) >> 2);

}

static void dm9000_inblk_8bit(void __iomem *reg, void *data, int count)

{

readsb(reg, data, count);

}

static void dm9000_inblk_16bit(void __iomem *reg, void *data, int count)

{

readsw(reg, data, (count+1) >> 1);

}

static void dm9000_inblk_32bit(void __iomem *reg, void *data, int count)

{

readsl(reg, data, (count+3) >> 2);

}

static void dm9000_dumpblk_8bit(void __iomem *reg, int count)

{

int i;

int tmp;

for (i = 0; i < count; i++)

tmp = readb(reg);

}

static void dm9000_dumpblk_16bit(void __iomem *reg, int count)

{

int i;

int tmp;

count = (count + 1) >> 1;

for (i = 0; i < count; i++)

tmp = readw(reg);

}

static void dm9000_dumpblk_32bit(void __iomem *reg, int count)

{

int i;

int tmp;

count = (count + 3) >> 2;

for (i = 0; i < count; i++)

tmp = readl(reg);

}

static void dm9000_set_io(struct board_info *db, int byte_width)

{

switch (byte_width) {

case 1:

db->dumpblk = dm9000_dumpblk_8bit;

db->outblk = dm9000_outblk_8bit;

db->inblk = dm9000_inblk_8bit;

break;

case 3:

dev_dbg(db->dev, ": 3 byte IO, falling back to 16bit\n");

case 2:

db->dumpblk = dm9000_dumpblk_16bit;

db->outblk = dm9000_outblk_16bit;

db->inblk = dm9000_inblk_16bit;

break;

case 4:

default:

db->dumpblk = dm9000_dumpblk_32bit;

db->outblk = dm9000_outblk_32bit;

db->inblk = dm9000_inblk_32bit;

break;

}

}

static void dm9000_schedule_poll(board_info_t *db)

{

if (db->type == TYPE_DM9000E)

schedule_delayed_work(&db->phy_poll, HZ * 2);

}

static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd)

{

board_info_t *dm = to_dm9000_board(dev);

if (!netif_running(dev))

return -EINVAL;

return generic_mii_ioctl(&dm->mii, if_mii(req), cmd, NULL);

}

static unsigned int

dm9000_read_locked(board_info_t *db, int reg)

{

unsigned long flags;

unsigned int ret;

spin_lock_irqsave(&db->lock, flags);

ret = ior(db, reg);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top