基于335X的linux网口驱动分析

一、 系统构成

1、  硬件平台 AM335X

2、  LINUX内核版本 4.4.12

二、 网口驱动构架(mdio部分)

mdio网口驱动部分 使用 总线、设备、驱动模型,总结如下:

若设备和驱动匹配,则执行

davinci_mdio_probe

--> mdiobus_register

--> device_register

--> mdiobus_scan

--> get_phy_device

--> get_phy_id // 读寄存器

-->  phy_device_create // 创建phy设备

--> INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); // !!!!!!初始化状态机函数

--> phy_device_register

经过以上步骤,由davinci_mdio_driver又创建出一个mdio_bus_type类型的bus.并扫描并创建了连接在bus上的phydev.

若设备和驱动匹配,这时,也进行了phydev和phy_driver的匹配和绑定。则执行phy_probe

以上总线下的设备和驱动的匹配过程如下,以platform_bus为例,其它总线也是这个流程

platform_device跟platform_driver的匹配

drivers/base/platform.c

a. 注册 platform_driver 的过程:

platform_driver_register

__platform_driver_register

drv->driver.probe = platform_drv_probe;

driver_register

bus_add_driver

klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);    // 把 platform_driver 放入 platform_bus_type 的driver链表中

driver_attach

bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);  // 对于plarform_bus_type下的每一个设备, 调用__driver_attach

__driver_attach

ret = driver_match_device(drv, dev);  // 判断dev和drv是否匹配成功

return drv->bus->match ? drv->bus->match(dev, drv) : 1;  // 调用 platform_bus_type.match

driver_probe_device(drv, dev);

really_probe

drv->probe  // platform_drv_probe

platform_drv_probe

struct platform_driver *drv = to_platform_driver(_dev->driver);

drv->probe

b. 注册 platform_device 的过程:

platform_device_register

platform_device_add

device_add

bus_add_device

klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices); // 把 platform_device 放入 platform_bus_type的device链表中

bus_probe_device(dev);

device_initial_probe

__device_attach

ret = bus_for_each_drv(dev->bus, NULL, &data, __device_attach_driver); // // 对于plarform_bus_type下的每一个driver, 调用 __device_attach_driver

__device_attach_driver

ret = driver_match_device(drv, dev);

return drv->bus->match ? drv->bus->match(dev, drv) : 1;  // 调用platform_bus_type.match

driver_probe_device

匹配函数是platform_bus_type.match, 即platform_match,

匹配过程按优先顺序罗列如下:

a. 比较 platform_dev.driver_override 和 platform_driver.drv->name

b. 比较 platform_dev.dev.of_node的compatible属性 和 platform_driver.drv->of_match_table

c. 比较 platform_dev.name 和 platform_driver.id_table

d. 比较 platform_dev.name 和 platform_driver.drv->name

有一个成功, 即匹配成功

CPSW也是一个内部设备,也遵循总线、设备、驱动模型。CPSW设备从设备树中获得,DRV则是系统注册,匹配后进行probe,其主要执行过程如下:

cpsw_probe

--> CPSW平台数据、资源、DMA初始化、赋值netdev_ops、ethtool_ops

--> 注册网络设备:register_netdev

--> cpsw_ndo_open (此处根据实际经验得到,目前还没有从源代码级别解答出调用过程)

--> cpsw_slave_open

--> phy_connect (传递cpsw_adjust_link)

--> bus_find_device_by_name (从mdio总线上查找device)

--> to_phy_device (从device结构体中找到phy_device)

--> phy_connect_direct (传递handler,初始化 ***)

--> phy_attach_direct ()

--> d->driver = &genphy_driver[GENPHY_DRV_1G].driver;(通用驱动赋值,3.17支持1G和10G)

--> d->driver->probe (这里就调用到Generic PHY的检测函数phy_probe)

--> device_bind_driver (绑定驱动到设备)

--> phydev->attached_dev = dev; (有函数使用到attached_dev指针)

--> phydev->state = PHY_READY; (将PHY状态标记为PHY_READY)

--> phy_init_hw (硬件级的初始化,最后会调用genphy_config_init)

--> phy_prepare_link (赋值cpsw_adjust_link为adjust_link)

--> phy_start_machine (启动PHY状态机 ***)

--> phy_start_interrupts (经测了,但好像没调用到这里)

--> phy_start(PHY_READY变成PHY_UP)

--> 其它的CPSW的初始化

基于335X的Linux网口驱动分析的更多相关文章

  1. 基于335X的UBOOT网口驱动分析

    基于335X的UBOOT网口驱动分析 一.软硬件平台资料 1.  开发板:创龙AM3359核心板,网口采用RMII形式 2.  UBOOT版本:U-Boot-2016.05,采用FDT和DM. 参考链 ...

  2. 基于335X平台Linux交换芯片驱动开发

    基于335X平台Linux交换芯片驱动开发   一.软硬件平台资料 1.开发板:创龙AM3359核心板,网口采用RMII形式. 2.Kernel版本:4.4.12,采用FDT 3.交换芯片MARVEL ...

  3. linux串口驱动分析

    linux串口驱动分析 硬件资源及描写叙述 s3c2440A 通用异步接收器和发送器(UART)提供了三个独立的异步串行 I/O(SIO)port,每一个port都能够在中断模式或 DMA 模式下操作 ...

  4. 基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(一)之miscdevice和ioctl

    基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(一)之miscdevice和ioctl 0. 导语 在嵌入式的道路上寻寻觅觅很久,进入嵌入式这个行业也有几年的时间了,从2011年后 ...

  5. 基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(二)之cdev与read、write

    基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(二)之cdev与read.write 0. 导语 在上一篇博客里面,基于OMAPL138的字符驱动_GPIO驱动AD9833(一)之 ...

  6. Linux spi驱动分析(二)----SPI核心(bus、device_driver和device)

    一.spi总线注册 这里所说的SPI核心,就是指/drivers/spi/目录下spi.c文件中提供给其他文件的函数,首先看下spi核心的初始化函数spi_init(void).程序如下: 点击(此处 ...

  7. Linux I2C驱动分析(三)----i2c_dev驱动和应用层分析 【转】

    本文转载自:http://blog.chinaunix.net/uid-21558711-id-3959287.html 分类: LINUX 原文地址:Linux I2C驱动分析(三)----i2c_ ...

  8. linux驱动基础系列--Linux I2c驱动分析

    前言 主要是想对Linux I2c驱动框架有一个整体的把控,因此会忽略协议上的某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.设备模型.sysfs等也不进行详细说明原理,涉及到i2c协议部分也只 ...

  9. Linux gadget驱动分析1------驱动加载过程

    为了解决一个问题,简单看了一遍linux gadget驱动的加载流程.做一下记录. 使用的内核为linux 2.6.35 硬件为芯唐NUC950. gadget是在UDC驱动上面的一层,如果要编写ga ...

随机推荐

  1. 运维笔记--ubuntu安装指定版本的RabbitMQ

    场景描述: 日常开发or生产环境经常会需要安装指定版本的软件,出于和其他软件的配合兼容性,以及稳定性的考虑. 现在我们的需求是安装指定版本的RabbitMQ,版本号: 操作步骤: 注意事项: 异常处理 ...

  2. Sublime用正则表达式进行逗号分隔实现列的替换

    eg: ([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*).* 这是取前面10列,后面的不管 ...

  3. svg复用方式<g>, <defs>, <symbol>, <use>

    svg复用元素的方式主要有 <g>, <defs>, <symbol>, <use> 1. <g> group, 分组,定义一组元素,初始不 ...

  4. laravel composer 使用阿里云镜像

    使用composer安装错误提示: 即: [Composer\Downloader\TransportException] The "https://packagist.laravel-ch ...

  5. OpenShift 4.1 基本问题探索

    因为在OpenShift 4.1环境中不建议直接登录集群主机操作,因此很多操作可能需要在外部的Client VM上完成.当然用rhel的worker node的同事也可以和原来习惯保持一致. 这里记录 ...

  6. stylelint那些事儿

    一.参考文档 -   http://stylelint.cn/ -   https://stylelint.io/ -   https://stylelint.io/user-guide/exampl ...

  7. [LeetCode] 203. Remove Linked List Elements 移除链表元素

    Remove all elements from a linked list of integers that have value val. ExampleGiven: 1 --> 2 --& ...

  8. tp5之服务器不显示验证码

    今天在使用tp框架的时候遇到的一个bug,前辈们早已有解决方法,遇到了做个笔记 TP5框架,自带的验证码在本地localhost运行是没问题的,可以正常显示,如图: 然后,把框架拿到服务器是去运行,验 ...

  9. tween算法

    tween算法 https://www.cnblogs.com/cloudgamer/archive/2009/01/06/Tween.html 参数说明: t: current time:当前时间: ...

  10. 用ArcMap在PostgreSQL中创建要素类需要执行”create enterprise geodatabase”吗

    问:用Acmap在PostgreSQL中创建要素类需要执行"create enterprise geodatabase"吗? 关于这个问题,是在为新员工做postgresql培训后 ...