一、源文件

源码路径:\drivers\net\ethernet\rockchip\gmac

源码阅读顺序:

二、重要探针函数stmmac_dvr_probe

1. alloc_etherdev

申请网卡设备和私有数据。

struct net_device *ndev = NULL;

struct stmmac_priv *priv;

ndev = alloc_etherdev(sizeof(struct stmmac_priv));

priv = netdev_priv(ndev);

网卡设备和私有数据紧紧的挨在一起:网卡设备+私用数据结构,通过netdev_priv获取私有数据。网卡设备是通用数据结构,私有数据则为各个MAC控制器的数据结构。

2. stmmac_hw_init

初始化MAC设备。检测要添加的设备(GMAC/MAC10-100),检查HW能力并设置驱动程序的特性。

3. netif_napi_add

初始化一个NAPI上下文,轮询接收数据包接口。

netif_napi_add(ndev, &priv->napi, stmmac_poll, 64);

stmmac_poll是轮询接口

该接口完成两个事情:

1)当数据发送完成时产生中断,进入该函数进行资源回收。

2)收到数据产生中断,进入该函数进行数据接收和处理。

static int stmmac_poll(struct napi_struct *napi, int budget)
{
  ......
  stmmac_tx_clean(priv);  //传输完成后回收资源work_done = stmmac_rx(priv, budget); //数据包接收处理stmmac_enable_dma_irq(priv); //使能dma终端
  ......
}

stmmac_rx函数解析

作用:再次填充并使用skb预先分配的缓存,由NAPI轮询方法调用,可以获得环内所有帧。

函数:static int stmmac_rx(struct stmmac_priv *priv, int limit)

函数内定义:

1)priv->hw->desc->get_rx_owner(p)

判断当前描述子的归属:描述子数据结构中OWN位,

  0: 当前描述子应该由CPU操作,

  1: 前描述子应该由GMAC操作。

对于接收,初始化dma描述子队列时设置为1。

GMAC根据寄存器配置,获取可用接收描述子,然后从RxFIFO中读取从PHY接收的Ethernet报文,如果报文符合接收条件,将该报文写入接收描述子指向的数据缓冲区,并回写接收描述子。这个回写就会将OWN位设置为0。

2)next_entry = (++priv->cur_rx) % rxsize;

获取下一帧描述符,

p_next =priv->dma_rx + next_entry;

priv->cur_rx:已经传递给协议层的index。

3)status =(priv->hw->desc->rx_status(&priv->dev->stats, &priv->xstats,p));

获取收到帧状态,如果是丢弃帧,则什么都不处理;否则上传到上层网络。

4)frame_len = priv->hw->desc->get_rx_frame_len(p, coe); 获取帧长度

5)skb = priv->rx_skbuff[entry];

priv->rx_skbuff[entry] = NULL;

注意:skb将有上层网络处理完后进行释放。

6)skb_put(skb, frame_len);

dma_unmap_single(priv->device,priv->rx_skbuff_dma[entry],priv->dma_buf_sz, DMA_FROM_DEVICE);  设置skb数据长度和解除流式DMA映射

7)获取skb的协议类型

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

skb->dev = priv->dev;

8)napi_gro_receive(&priv->napi,skb);

将skb通过NAPI接口上传上层网络协议处理。

9)stmmac_rx_refill(priv); 重新填充接收队列

三、打开网卡设备接口stmmac_open

网卡刚起来时是关闭的,要用命令去打开,ifconfig eth0 up 时调用net_device_ops的.ndo_open,这里为stmmac_open。

  1. netdev_priv 获得网络设备私有数据
  2. stmmac_check_ether_addr 检测MAC地址是否有效,若无效,随机产生一个
  3. stmmac_mdio_register注册MII总线

mdiobus_register()

a.注册总线设备device_register(&bus->dev);

b.复位总线bus->reset(bus);

c.扫描总线上的PHY设备,最大支持32个

4. stmmac_init_phy初始化PHY设备,并将PHY和MAC绑定

5. request_irq 申请中断

ret = request_irq(dev->irq, stmmac_interrupt,

IRQF_SHARED, dev->name, dev);

注册中断请求线IRQ,中断处理函数stmmac_interrupt用于接收DMA数据,配合NAPI处理。

static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
{....../* To handle DMA interrupts */stmmac_dma_interrupt(priv);  
}static void stmmac_dma_interrupt(struct stmmac_priv *priv)
{......status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);if (likely((status & handle_rx)) || (status & handle_tx)) {if (likely(napi_schedule_prep(&priv->napi))) {stmmac_disable_dma_irq(priv);__napi_schedule(&priv->napi); //加入poll流程}}......
}

四、发送数据接口stmmac_xmit

该接口实现了Scatter/Gather I/O功能,通过skb_shinfo宏来判断数据包是由一个数据片段组成,还是由大量数据片段组成。

1、entry= priv->cur_tx % txsize;

desc= priv->dma_tx + entry; 获取可用发送描述子

first= desc; 保存第一个数据片段

2、priv->tx_skbuff[entry]= skb;

priv->tx_page[entry]= NULL; 将skb放到发送队列

3、unsignedint nopaged_len = skb_headlen(skb);

desc->des2=dma_map_single(priv->device,skb->data,nopaged_len, DMA_TO_DEVICE);

priv->hw->desc->prepare_tx_desc(desc,1, nopaged_len, csum_insertion);

发送单个或第一个数据包,当只有一个数据片段时,skb->data将发送所有数据;当有多个数据片段时,skb->data则指向第一个数据片段,数据长度skb->len –skb->data_len,其他数据存放在共享数据结构frags数组中。(skb->len:数据包中全部数据的长度,skb->data_len分隔存储数据片段长度)

4、

for (i = 0; i < nfrags; i++) {const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];int len = skb_frag_size(frag);entry = (++priv->cur_tx) % txsize;if (priv->extend_desc)desc = (struct dma_desc *)(priv->dma_etx + entry);elsedesc = priv->dma_tx + entry;TX_DBG("\t[entry %d] segment len: %d\n", entry, len);desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len, DMA_TO_DEVICE);priv->tx_skbuff_dma[entry] = desc->des2;priv->tx_skbuff[entry] = NULL;priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion,priv->mode);wmb();priv->hw->desc->set_tx_owner(desc);wmb();
}

发送剩余数据片段。

对于多个数据片段时,还要进行数据片段的发送,采用页处理。直接处理页结构,而不是内核虚拟地址。

5、priv->hw->desc->set_tx_owner(first);

priv->cur_tx ++;

将第一个数据片段描述子交给GMAC,记录当前发送index

6、priv->hw->dma->enable_dma_transmission(priv->dma_ioaddr,

priv->dma_channel);

写任何值唤醒处于挂起的RxDMA

转载于:https://www.cnblogs.com/debruyne/p/9133439.html

RK3288 GMAC整理相关推荐

  1. android dts配置_rk3288 — i2s dts配置

    关键词:rockchip,rk3066-i2s:rockchip,px30-i2s:rockchip,rk3036-i2s:rockchip,rk3128-i2s:rockchip,rk3188-i2 ...

  2. Rk3288运行linux,查看“Firefly-rk3288 build linux”的源代码

    因为以下原因,您没有权限编辑本页: 您所请求的操作仅限于该用户组的用户使用:用户 该页面已被保护以防止编辑和其他操作. 您可以查看与复制此页面的源代码.=编译firefly linux-SDK系统= ...

  3. vxworks下gmac调试的总结

    1:3280芯片手册详解过程: MAC 控制器支持 DMA 接收和发送,内部在接收和发送方向各有一个 2048 字节的 FIFO作为缓存.由于 FIFO 深度所限,MAC 控制器不支持硬件自动流控机制 ...

  4. rk3288 linux 编译,RK3288系统编译及环境搭建

    准备工作 编译 Android 对机器的配置要求较高: 64 位 cpu 16GB 物理内存+交换内存 30GB 空闲的磁盘空间用于构建,源码树另外占用大约 8GB 官方推荐 Ubuntu 12.04 ...

  5. rk3288 Android 8,RK3288W Android8.1开发日志(一)

    1.板子是参考官方公版设计,SDK版本是RK3288_ANDROID8.1_SDK_20180512: 2.解压SDK,直接执行source build.sh,再执行./mkimage.sh,烧录进板 ...

  6. Linux驱动学习--linux以太网驱动及硬件结构介绍(结合gmac项目分析)

    目录 1.引言 2.以太网硬件结构 3.以太网驱动分析(结合gmac项目) 3.1 dts节点分析 3.2 gmac驱动源码分析(open 收发包机制简要分析) 一.引言 最近在Android项目中, ...

  7. 【重磅最新】163篇ICML-2021强化学习领域论文整理汇总(2021.06.07)

    深度强化学习实验室 官网:http://www.neurondance.com/ 论坛:http://deeprl.neurondance.com/ 作者:深度强化学习实验室 来源:整理自https: ...

  8. Map再整理,从底层源码探究HashMap

    前言 本文为对Map集合的再一次整理.内容包括:Map HashMap LinkedHashMap TreeHashMap HashTable ConcurrentHashMap Map Map< ...

  9. List再整理,从代码底层全面解析List(看完后保证收获满满)

    前言 本文为对List集合的再一次整理,从父集接口Collection到顶级接口Iterable再到线程不安全实现类:ArrayList.LinkedList,再到线程安全实现类:Vector(被弃用 ...

最新文章

  1. 1、tomcat目录及端口规划实践
  2. LeetCode Range Addition II
  3. Codeforces 1215
  4. 讲解web服务所涉及到的重要知识点
  5. 2021福建计算机会考操作题,2021年福建省信息技术会考笔试试题答案.doc
  6. textarea回车不换行 小程序_微信小程序商城到底值得不值得开通?
  7. iOS UIButton文字和图片间距随意调整
  8. docunment对象
  9. LinAlgError: SVD did not converge
  10. c#退出应用程序办法
  11. 机械制造技术基础【3】
  12. 图像相似度比较之哈希算法
  13. python运算符用来计算集合并集的_Python 运算符中用来计算集合并集的是 _______ 。_学小易找答案...
  14. 关于AD与KiCad绘制PCB的一点看法
  15. hⅰgh怎么读音发音英语_gh和ph的发音
  16. android 系统 优化设置,优化设置 让你的Android手机快人一步
  17. 双极性正弦脉冲宽度调制
  18. proteus中继电器怎么找_proteus中这个开关在哪
  19. BMR(基础代谢率)计算器
  20. 多序列比对要多久时间_多序列比对算法探讨

热门文章

  1. hibernate重要知识点总结
  2. hadoop大数据分析与挖掘实战(读书笔记3)
  3. ubuntu16.04服务器配置mysql,并开启远程连接
  4. jpa单向多对一关联映射
  5. 文件流下载到本地 - 待完成
  6. 颜色字符串转换(正则)
  7. es6总结(一) ——开发环境
  8. 36)PHP,搜寻数据库信息在html中显示(晋级1)
  9. 织梦channel标签currentstyle样式无效不起作用
  10. (原创)基于ZedBoard的Webcam设计(二):USB摄像头图片采集+QT显示