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

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

时间:11-20 来源:互联网 点击:
硬件平台:FL2440 (S3C2440)

内核版本:2.6.35

主机平台:Ubuntu 11.04

内核版本:2.6.39

交叉编译器:arm-linux-gcc 4.3.2

原创作品,转载请标明出处

本文接上文

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

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

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

1、接下来接着分析DM9000网卡驱动的数据接收函数

view plainprint?

static void

dm9000_rx(struct net_device *dev)

{

board_info_t *db = netdev_priv(dev);

struct dm9000_rxhdr rxhdr;

struct sk_buff *skb;

u8 rxbyte, *rdptr;

bool GoodPacket;

int RxLen;

do {

ior(db, DM9000_MRCMDX);

rxbyte = readb(db->io_data);

if (rxbyte & DM9000_PKT_ERR) {

dev_warn(db->dev, "status check fail: %d\n", rxbyte);

iow(db, DM9000_RCR, 0x00);

iow(db, DM9000_ISR, IMR_PAR);

return;

}

if (!(rxbyte & DM9000_PKT_RDY))

return;

GoodPacket = true;

writeb(DM9000_MRCMD, db->io_addr);

(db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));

RxLen = le16_to_cpu(rxhdr.RxLen);

if (netif_msg_rx_status(db))

dev_dbg(db->dev, "RX: status x, length x\n",

rxhdr.RxStatus, RxLen);

if (RxLen < 0x40) {

GoodPacket = false;

if (netif_msg_rx_err(db))

dev_dbg(db->dev, "RX: Bad Packet (runt)\n");

}

if (RxLen > DM9000_PKT_MAX) {

dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen);

}

if (rxhdr.RxStatus & (RSR_FOE | RSR_CE | RSR_AE |

RSR_PLE | RSR_RWTO |

RSR_LCS | RSR_RF)) {

GoodPacket = false;

if (rxhdr.RxStatus & RSR_FOE) {

if (netif_msg_rx_err(db))

dev_dbg(db->dev, "fifo error\n");

dev->stats.rx_fifo_errors++;

}

if (rxhdr.RxStatus & RSR_CE) {

if (netif_msg_rx_err(db))

dev_dbg(db->dev, "crc error\n");

dev->stats.rx_crc_errors++;

}

if (rxhdr.RxStatus & RSR_RF) {

if (netif_msg_rx_err(db))

dev_dbg(db->dev, "length error\n");

dev->stats.rx_length_errors++;

}

}

if (GoodPacket &&

((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {

skb_reserve(skb, 2);

rdptr = (u8 *) skb_put(skb, RxLen - 4);

(db->inblk)(db->io_data, rdptr, RxLen);

dev->stats.rx_bytes += RxLen;

skb->protocol = eth_type_trans(skb, dev);

if (db->rx_csum) {

if ((((rxbyte & 0x1c) < 3) & rxbyte) == 0)

skb->ip_summed = CHECKSUM_UNNECESSARY;

else

skb->ip_summed = CHECKSUM_NONE;

}

netif_rx(skb);

dev->stats.rx_packets++;

} else {

(db->dumpblk)(db->io_data, RxLen);

}

} while (rxbyte & DM9000_PKT_RDY);

}

2、下面是完整的DM9000驱动代码,可以完整的查看

view plainprint?

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "dm9000.h"

#include

#include

#include

#define DM9000_PHY 0x40

#define CARDNAME "dm9000"

#define DRV_VERSION "1.31"

static int watchdog = 5000;

module_param(watchdog, int, 0400);

MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");

enum dm9000_type {

TYPE_DM9000E,

TYPE_DM9000A,

TYPE_DM9000B

};

typedef struct board_info {

void __iomem *io_addr;

void __iomem *io_data;

u16 irq;

u16 tx_pkt_cnt;

u16 queue_pkt_len;

u16 queue_start_addr;

u16 queue_ip_summed;

u16 dbug_cnt;

u8 io_mode;

u8 phy_addr;

u8 imr_all;

unsigned int flags;

unsigned int in_suspend :1;

unsigned int wake_supported :1;

int debug_level;

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

网站地图

Top