1. 发送中断

1.1. DMA发送完数据后产生中断,调用 stmmac_interrupt服务程序

1.2. stmmac_interrupt 通过调用 stmmac_dma_interrupt 处理DMA相关中断(包括发送和接收)。在stmmac_dma_interrupt中,通过NAPI机制触发软中断,调用stmmac_poll处理相关事件。

1.3. stmmac_poll调用stmmac_tx_clean回收资源,以及queue操作

1)通过dma_unmap_single解除dma映射

dma_unmap_single(priv->device, tx_q->tx_skbuff_dma[entry].buf, tx_q->tx_skbuff_dma[entry].len, DMA_TO_DEVICE);

2)释放skb

dev_consume_skb_any(skb);

3)清空descriptor:des2和des3, 将其赋值0

release_tx_desc()

4)设置queue的状态 ,如果queue是停止状态(__QUEUE_STATE_STACK_XOFF 或 __QUEUE_STATE_DRV_XOFF被置位),但是现在已经满足开启条件,则唤醒queue。

在stmmac_xmit发送时如果停止了queue,现在如果条件满足,会重新恢复queue。

    netdev_tx_completed_queue(netdev_get_tx_queue(priv->dev, queue),pkts_compl, bytes_compl);if (unlikely(netif_tx_queue_stopped(netdev_get_tx_queue(priv->dev,queue))) &&stmmac_tx_avail(priv, queue) > STMMAC_TX_THRESH) {netif_dbg(priv, tx_done, priv->dev,"%s: restart transmit\n", __func__);netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, queue));}

在netdev_tx_completed_queue中,test_and_clear_bit(__QUEUE_STATE_STACK_XOFF, &dev_queue->state),如果test_and_clear_bit返回真,调用 netif_schedule_queue(q)重新开始调度queue

在netif_tx_wake_queue中,test_and_clear_bit(__QUEUE_STATE_DRV_XOFF, &dev_queue->state),如果test_and_clear_bit返回真,调用 __netif_schedule(q)重新开始调度queue

2. 接收中断

2.1. DMA产生中断,调用 stmmac_interrupt服务程序

2.2. stmmac_interrupt 通过调用 stmmac_dma_interrupt 处理DMA相关中断(包括发送和接收)。在stmmac_dma_interrupt中,通过NAPI机制触发软中断,调用stmmac_poll接收数据包。

2.3. 在stmmac_poll中调用如下代码收数据包

    work_done = stmmac_rx(priv, budget, rx_q->queue_index);if (work_done < budget) {napi_complete_done(napi, work_done);stmmac_enable_dma_irq(priv, chan);}return work_done;

1)调用stmmac_rx接收,budget为循环读取dma descriptor(通过处理descriptor来获取数据包,每个descriptor对应一个数据包)的最大次数,work_done为实际循环的次数。

2)if (work_done < budget) 代表实际循环读取dma descriptor的次数小于最大次数budget,代表已经处理完所有需要被处理的descriptor,取完所有的数据包。这时,调用stmmac_enable_dma_irq()开启中断,再次接收数据。如果work_done = budget,代表可能还有数据包需要处理,那么这些数据包留到net_rx_action再次调用stmmac_poll时处理。

3)return work_done; 该返回值会被net_rx_action使用。

2.4. 在stmmac_rx中,循环收包,循环次数while (count < limit)。每次循环以DMA descriptor为处理单位,即每次循环时从一个descriptor指定的buffer读取一个数据包,再通过 napi_gro_receive 送给协议层,处理完后count++。这里limit = budget。

2.5. 调用 stmmac_rx_refill重新填充descriptor。

在触发DMA中断前,DMA已经将网卡收到的数据包搬到descriptor指定的buffer,而这个buffer又采用了zero-copy机制,所以直接将该buffer的地址copy给一个skb,再将此skb送到协议层处理,最后再调用 stmmac_rx_refill重新填充descriptor并设置buffer。之前descriptor指定的buffer地址已经被赋值给skb,由协议层负责该skb(buffer)的管理(释放内存等)。

2.6. 总结:

这里有三种“一次获取多个数据包”的情况

1)一次软中断可能会多次调用net_rx_action

2)net_rx_action可能会多次调用stmmac_poll

3)stmmac_poll处理多个descriptor

stmmac 中断处理相关推荐

  1. 网卡驱动(hisi3536网卡驱动,以及stmmac层)

    一:基本概念 应用程序最终以套接字的形式完成网络设备的接口.,对网络设备定义四个层次:网络协议接口层(数据包的发送接收,向网络层协议提供统一的数据包收发接口,舍得上层协议独立于具体的设备,(ip,ar ...

  2. Linux内核设计第五周学习总结 分析system_call中断处理过程

    陈巧然原创作品 转载请注明出处   <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 使用gdb跟踪分析一 ...

  3. Linux中断处理驱动程序编写【转】

    转自:http://blog.163.com/baosongliang@126/blog/static/1949357020132585316912/ 本章节我们一起来探讨一下Linux中的中断 中断 ...

  4. 《Linux内核设计与实现》读书笔记(七)- 中断处理【转】

    转自:http://www.cnblogs.com/wang_yb/archive/2013/04/19/3030345.html 中断处理一般不是纯软件来实现的,需要硬件的支持.通过对中断的学习有助 ...

  5. linux中断系统那些事之----中断处理过程【转】

    转自:http://blog.csdn.net/xiaojsj111/article/details/14129661 以外部中断irq为例来说明,当外部硬件产生中断时,linux的处理过程.首先先说 ...

  6. 【linux kernel】 中断处理-中断下半部【转】

    转自:http://www.cnblogs.com/embedded-tzp/p/4453987.html 欢迎转载,转载时需保留作者信息,谢谢. 邮箱:tangzhongp@163.com 博客园地 ...

  7. Linux中的中断处理

    与Linux设备驱动中中断处理相关的首先是申请与释放IRQ的API request_irq()和free_irq(), request_irq()的原型为: int request_irq(unsig ...

  8. QEMU和KVM 中断处理过程

    本文讲述一个网络数据包从到达物理网卡,一直到中断注入给VM的整个过程. 为了讲述清晰,假设宿主物理机有两个物理CPU,分别为CPU0和CPU1.假设GuestOS运行在CPU1上,物理网卡接到数据包后 ...

  9. 把数据转换为在内存中Tree(树形结构)。_Linux的中断处理机制 [二] - 数据结构(2)...

    Linux的中断处理机制 [一] - 数据结构(1) 上文提到,每个IRQ同时有"irq"和"hwirq"两个编号.这里"hwirq"是硬件 ...

最新文章

  1. 2021年大数据ELK(二十四):安装Kibana
  2. java unsafe获取指针_【实战Java高并发程序设计 1】Java中的指针:Unsafe类
  3. accesskey 提交
  4. Xen与KVM虚拟化技术调研报告
  5. python 文本框内容变化_jquery文本框内容改变事件
  6. 《啊哈!算法》笔记_Day02
  7. python基础语法-对目录(文件夹)的操作
  8. 网络安全课程学习内容
  9. matlab 马丢函数,振幅调制产生马丢光束的方法与流程
  10. 汉斯·乌尔里希·鲁德尔-唯一一个钻石金双剑金橡叶骑士勋章获得者
  11. 原生JavaScript开发高级课程 |智能S
  12. 龙蜥开发者说:我眼里的龙蜥社区:一个包容的大家庭 | 第 10 期
  13. 如何使用阿里云搭建个人网站 1
  14. 一道2016年美国高中数学竞赛题
  15. 苹果6性能测试软件,5款iPhone升级iOS13.6性能测试:运行速度有所提升?
  16. C语言—求数组的对角线和副对角线之和
  17. [机缘参悟-33]:眼见不一定为实,大多数时候“眼见为虚”
  18. linux io apic,linux-kernel – IO-APIC级别与PCI-MSI-X之间的差异
  19. 详解 input accept属性
  20. 解决Watchdogs 、kthrotlds 挖矿蠕虫

热门文章

  1. 精品软件 推荐 360 安全卫士
  2. SSAS系列——【08】多维数据(程序展现Cube)
  3. 海量数据拆分到nosql系统的一种方案
  4. 用Java编写模仿的太阳系(九星行旋转)--原创
  5. 一起谈.NET技术,NHibernate3.0剖析:Query篇之NHibernate.Linq标准查询
  6. matlab mobilenet v2,MobileNetV2-SSDLite代码分析-6 VOC Dataset
  7. ustc linux 网络通,USTC 网络通脚本
  8. 双11技术分享 | “喵糖”背后的商业化流量投放算法
  9. TensorFlow2快速模型构建及tensorboard初体验
  10. python基础教程--代码集合(下)