慢慢欣赏linux 网络协议栈四 sk_buff以及数据收发
以3c359x.c的网卡为例,因为这是《深入理解Linux网络技术内幕》里面的例子

irqreturn_t vortex_interrupt(int irq, void *dev_id)

vortex_rx(dev);=>int vortex_rx(struct net_device *dev)    struct vortex_private *vp = netdev_priv(dev);    void __iomem *ioaddr = vp->ioaddr;    short rx_status;    while ((rx_status = ioread16(ioaddr + RxStatus)) > 0)        int pkt_len = rx_status & 0x1fff;        struct sk_buff *skb = dev_alloc_skb(pkt_len + 5);        skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */        if (vp->bus_master && ! (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000))             dma_addr_t dma = pci_map_single(VORTEX_PCI(vp), skb_put(skb, pkt_len), pkt_len, PCI_DMA_FROMDEVICE);            iowrite32(dma, ioaddr + Wn7_MasterAddr);            iowrite16((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);            iowrite16(StartDMAUp, ioaddr + EL3_CMD);            while (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)                ;            pci_unmap_single(VORTEX_PCI(vp), dma, pkt_len, PCI_DMA_FROMDEVICE);        else             ioread32_rep(ioaddr + RX_FIFO, skb_put(skb, pkt_len), (pkt_len + 3) >> 2);                    iowrite16(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */        skb->protocol = eth_type_trans(skb, dev);        netif_rx(skb)        =>int netif_rx(struct sk_buff *skb)            if (queue->input_pkt_queue.qlen <= netdev_max_backlog)                if (queue->input_pkt_queue.qlen)        enqueue:                    __skb_queue_tail(&queue->input_pkt_queue, skb);                    return NET_RX_SUCCESS;                                    napi_schedule(&queue->backlog);                =>inline void napi_schedule(struct napi_struct *n)                    if (napi_schedule_prep(n))                        __napi_schedule(n);                        =>void __napi_schedule(struct napi_struct *n)                            list_add_tail(&n->poll_list, &__get_cpu_var(softnet_data).poll_list);                            __raise_softirq_irqoff(NET_RX_SOFTIRQ);//唤醒软中断                goto enqueue;

收包软中断入口函数

void net_rx_action(struct softirq_action *h)

struct list_head *list = &__get_cpu_var(softnet_data).poll_list;while (!list_empty(list))    n = list_first_entry(list, struct napi_struct, poll_list);    have = netpoll_poll_lock(n);    weight = n->weight;        n = list_first_entry(list, struct napi_struct, poll_list);    have = netpoll_poll_lock(n);    weight = n->weight;        work = 0;    if (test_bit(NAPI_STATE_SCHED, &n->state))        work = n->poll(n, weight);        =>int process_backlog(struct napi_struct *napi, int quota)            budget -= work;

Linux 网络协议栈开发代码分析篇之数据收发(一) —— netif_receive_skb()函数
https://blog.csdn.net/zqixiao_09/article/details/79185800

Linux内核--网络栈实现分析(二)--数据包的传递过程(上)

https://blog.csdn.net/geekcome/article/details/7492423

作者:天麓
来源:CSDN
原文:https://blog.csdn.net/shipinsky/article/details/88923786
版权声明:本文为博主原创文章,转载请附上博文链接!

收藏 打印