linux网卡的接收和发送,linux网卡数据流 发送与接收

通常网卡驱动代码量比较大,但是都离不开发送与接收,掌握好骨干也就好理解与调试了。

数据发送 :

发送函数:xxx_start_xmit()

上层封装好了sk_buff丢进kernel后,buf存储在skb->data中,通 过 xxx_start_xmit(),发送出去。

下面的实例是通过写入某个设备节点发送出去,当然这个设备肯定是串口或者sdio等传输设备,

也可以直接调用写入函数将buf送出去。

比如sdio的写入:

sdio_memcpy_toio(xxx->func, addr, buf, sizeof(buf));

net_device_ops结构题的填充,在里实现了open与发送等操作:

static const struct net_device_ops xxx_netdev_ops = {

.ndo_open = xxx_net_open,

.ndo_stop = xxx_net_stop,

.ndo_start_xmit = xxx_start_xmit,

.ndo_get_stats = xxx_get_stats,

.ndo_tx_timeout = xxx_tx_timeout,

};

static int xxx_start_xmit(struct sk_buff *skb, struct net_device *dev){

---------

nwrite = filep->f_op->write(filep, skb->data, skb->len, &filep->f_pos);

set_fs(old_fs);

if (nwrite == skb->len) {

priv->stats.tx_packets++;

priv->stats.tx_bytes +=skb->len;

priv->netdev->trans_start = jiffies;

}

-----------

}

数据接收:

目前我所看到的接收触发都是在中断(低速串口与sdio card)里面读取到buf后异步调用netif_rx()提交到网络栈,

对于sdio card的接收数据是host端接收到中断后调用到card里面的中断处理函数而读取buf的。另外一种就是软中断来接收,

比如usb与高速串口的数据接收。

netif_rx()是标准的网卡上交sk_buff数据流,通常网卡驱动代码量很大当你找不到接收函数时,搜netif_rx()是最 好的 选择。

下面接收处理函数:首先分配skb数据空间,再将读取的buf存入skb中,再调用netif_rx(),数据报入网络栈。

static int xxx_submit_skb(void *data)

{

--------

skb = netdev_alloc_skb(ndev, pkt_len + NET_IP_ALIGN); /* NET_IP_ALIGN is 2 */

if (!skb) {

printk(KERN_INFO "error: out of memory for rx'd frame\n");

priv->stats.rx_dropped++;

ret = -ENOMEM;

goto error;

}

skb_reserve(skb, NET_IP_ALIGN);

memcpy((skb_put(skb, pkt_len), pkt_len),buf,sizeof(buf);

skb->dev = priv->netdev;

skb->protocol = eth_type_trans(skb, priv->netdev);

priv->stats.rx_packets++;

priv->stats.rx_bytes += pkt_len;

ret = netif_rx(skb);

if (ret != 0)

printk(KERN_INFO "%s: netif_rx error\n", __func__);

--------

}

原文:http://blog.csdn.net/linux_devices_driver/article/details/39033351

你可能感兴趣的:(linux网卡的接收和发送)