您的位置:首页 > 其它

A20 网卡驱动分析

2014-06-02 17:09 155 查看
网卡芯片为realteak 8201

1. net_device结构体的分配和注册

1) "/drivers/net/ethernet/sun7i/sun7i_wemac.c"

wemac_probe()

ndev = alloc_etherdev(sizeof(struct wemac_board_info)); 分配

ret = register_netdev(ndev); 注册

2) alloc_etherdev定义在 "/include/linux/etherdevice.h"

#define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1)

#define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count)

3) alloc_etherdev_mqs定义在
"/net/ethernet/eth.c"

struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs,

unsigned int rxqs)

{

return alloc_netdev_mqs(sizeof_priv, "eth%d", ether_setup, txqs, rxqs);

}

2. 发包函数

"/drivers/net/ethernet/sun7i/sun7i_wemac.c"

/*

* Hardware start transmission.

* Send a packet to media from the upper layer.

*/

static int wemac_start_xmit(struct sk_buff *skb, struct net_device *dev)

1) dev->stats.tx_bytes += skb->len; 发包统计信息

2)将skb数据写入网卡

/* set TX len */

writel(skb->len, db->emac_vbase + EMAC_TX_PL0_REG);

/* start translate from fifo to phy */

writel(readl(db->emac_vbase + EMAC_TX_CTL0_REG)

| 1, db->emac_vbase + EMAC_TX_CTL0_REG);

dev->trans_start = jiffies; /* save the time stamp */

3) 释放skb

dev_kfree_skb(skb);
释放skb

4) netif_stop_queue(dev); 停止队列,数据发送完后由中断处理程序来唤醒队列

3. 中断处理程序

static irqreturn_t wemac_interrupt(int irq, void *dev_id)

1) wemac_tx_done(dev, db, int_status)

当数据发送完后,产生中断,此函数调用,然后调用netif_wake_queue(dev)来唤醒队列

2) wemac_rx(dev)

接收数据包,最终调用netif_rx接收skb

4. MAC地址设置

"/drivers/net/ethernet/sun7i/sun7i_wemac.c"

static int wemac_set_mac_address(struct net_device *dev, void *p)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: