PHY驱动注册部分

news2024/11/16 13:36:41

SOC可以对PHY 进行配置或者读取PHY 相关状态,这个就需要 PHY 内部寄存器去实现了。PHY 芯片寄存器地址空间为 5位(支持访问32个寄存器).IEEE 定义了0~15这 16个寄存器的功能。而 16~31这16 个寄存器由厂商自行实现。

就是说不管你用的哪个厂家的 PHY 芯片,其中 0~15 这 16 个寄存器是一模一样的。仅靠这16个寄存器是完全可以驱动起 PHY 芯片的,至少能保证基本的网络数据通信,因此 Linux 内核有通用 PHY 驱动。所以 一般情况下,如果不需要使用PHY厂家提供的自定义的寄存器配置实现一些个性化的功能,那么PHY驱动就基本不需要修改。

如 寄存器0是PHY控制寄存器,通过Control Register可以对PHY的主要工作状态进行设置。 寄存器1是PHY状态寄存器,主要包含PHY的状态信息。等等 具体可以去找具体的寄存器信息,这里不做详细叙述。

如:

MAC控制器通过MDIO总线来管理phy设备,mdio总线与i2c总线类似,可以一个主机对应多个从设备,每个从设备都有地址。mdio最多接32个phy设备。

对应的目录是/sys/mdio,在/sys/mdio/devices目录中会有挂载在mdio的phy设备,在/sys/mdio/drivers中会有phy设备的驱动。

如:
 /sys/bus/mdio_bus/devices/stmmac-0:00 
其中 stmmac-0:00 表示 PHY 地址是 0。


该命令会读取 0~31 的所有寄存器,所以可以查看对应的寄存器值
cat /sys/bus/mdio_bus/devices/stmmac-0:00/phy_registers
root@OpenSDT:/sys/devices/platform/fe300000.ethernet/mdio_bus/stmmac-0/stmmac-0:00# cat phy_registers
 0: 0x1140
 1: 0x7989
 2: 0x1c
 3: 0xc982
 4: 0x1e1
 5: 0x0
 6: 0x64
 7: 0x2001
 8: 0x0
 9: 0xe00
10: 0x0
11: 0x0
12: 0x0
13: 0x0
14: 0x0
15: 0x2000
16: 0x23
17: 0x0
18: 0xffff
19: 0x0
20: 0x0
21: 0x0
22: 0xf00
23: 0xf00
24: 0x19c
25: 0x40
26: 0x5000
27: 0x802a
28: 0x0
29: 0x220
30: 0x0
31: 0x0
root@OpenSDT:/sys/devices/platform/fe300000.ethernet/mdio_bus/stmmac-0/stmmac-0:00# 

drivers\net\phy\phy_device.c

static struct phy_driver genphy_driver = {
	.phy_id		= 0xffffffff,
	.phy_id_mask	= 0xffffffff,
	.name		= "Generic PHY",
	.soft_reset	= genphy_no_soft_reset,
	.config_init	= genphy_config_init,
	.features	= PHY_GBIT_FEATURES | SUPPORTED_MII |
			  SUPPORTED_AUI | SUPPORTED_FIBRE |
			  SUPPORTED_BNC,
	.aneg_done	= genphy_aneg_done,
	.suspend	= genphy_suspend,
	.resume		= genphy_resume,
	.set_loopback   = genphy_loopback,
};

static int __init phy_init(void)
{
	int rc;

	//mdio 总线初始化注册:
	/*
		注册:
		/sys/class/mdio_bus
		/sys/bus/mdio_bus
	*/
	rc = mdio_bus_init();
	if (rc)
		return rc;

	//注册 名为    "Generic 10G PHY" phy驱动 到 mdio 总线
	rc = phy_driver_register(&genphy_10g_driver, THIS_MODULE);
	if (rc)
		goto err_10g;

	//注册 名为   "Generic PHY" phy驱动 到 mdio 总线
	rc = phy_driver_register(&genphy_driver, THIS_MODULE);
	if (rc) {
		phy_driver_unregister(&genphy_10g_driver);
err_10g:
		mdio_bus_exit();
	}

	return rc;
}

static void __exit phy_exit(void)
{
	phy_driver_unregister(&genphy_10g_driver);
	phy_driver_unregister(&genphy_driver);
	mdio_bus_exit();
}

subsys_initcall(phy_init);
module_exit(phy_exit);

\drivers\net\phy\mdio_bus.c

// sys/class/mdio_bus
static struct class mdio_bus_class = {
	.name		= "mdio_bus",
	.dev_release	= mdiobus_release,
};


// /sys/bus/mdio_bus
struct bus_type mdio_bus_type = {
	.name		= "mdio_bus",
	.match		= mdio_bus_match,
	.uevent		= mdio_uevent,
};
EXPORT_SYMBOL(mdio_bus_type);

int __init mdio_bus_init(void)
{
	int ret;

	// 即 /sys/class/mdio_bus
	ret = class_register(&mdio_bus_class);
	if (!ret) {
		
		//即 /sys/bus/mdio_bus
		ret = bus_register(&mdio_bus_type);
		if (ret)
			class_unregister(&mdio_bus_class);
	}

	return ret;
}
EXPORT_SYMBOL_GPL(mdio_bus_init);


int phy_driver_register(struct phy_driver *new_driver, struct module *owner)
{
	int retval;

/*
//phy 驱动
struct phy_driver
	.name		= "Generic PHY",
	 //MDIO 驱动通用部分
	 struct mdio_driver_common mdiodrv;-----+
											|
											|
											+---struct mdio_driver_common mdiodrv;
													int flags  |= MDIO_DEVICE_IS_PHY
													struct device_driver driver;
														.name		= "Generic PHY",
														//总线													//mdio 总线
														struct bus_type		*bus;-------------------------------struct bus_type mdio_bus_type = {
														int (*probe) (struct device *dev); = phy_probe              .name		= "mdio_bus",
														...                                                       	.match		= mdio_bus_match,
                                                                                                                  	.uevent		= mdio_uevent,
																													struct subsys_private *p;
																														//相关的驱动程序列表
																														struct kset *drivers_kset;

*/
	new_driver->mdiodrv.flags |= MDIO_DEVICE_IS_PHY;
	new_driver->mdiodrv.driver.name = new_driver->name;
	new_driver->mdiodrv.driver.bus = &mdio_bus_type;
	new_driver->mdiodrv.driver.probe = phy_probe;
	new_driver->mdiodrv.driver.remove = phy_remove;
	new_driver->mdiodrv.driver.owner = owner;


	new_driver->mdiodrv.driver.probe_type = PROBE_FORCE_SYNCHRONOUS;

	retval = driver_register(&new_driver->mdiodrv.driver);
	if (retval) {
		pr_err("%s: Error %d in registering driver\n",
		       new_driver->name, retval);

		return retval;
	}

	pr_debug("%s: Registered new driver\n", new_driver->name);

	return 0;
}
EXPORT_SYMBOL(phy_driver_register);

所以 phy 驱动注册部分主要做了如下工作:

1 创建 初始化 struct phy_driver
2 设置struct phy_driver ,
如所在的名为“mdio_bus” 的mdio_bus_type 总线
如 匹配成功后的 probe()函数

3 注册 phy_driver

在这里插入图片描述

至此
phy_driver注册成功了,那就差phy_device的注册。看代码就知道 phy_device的注册不依靠设备树,而是在GMAC控制器注册时候 在其中的mdiobus_register中会注册phy_device 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/125990.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SAP ABAP——SAP简介(三)【S/4 HANA开发环境】

💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后…

linux常用命令(三)-目录操作

目录创建 - mkdir 我们可以使用mkdir(make directory)来创建目录。 示例 目录删除 - rm 可以使用rm(remove)来删除一个目录 语法 rm [-irf] name ...i:删除前逐一询问确认r:将目录及以下之档案亦逐一删…

转转AB平台的设计与实现

导读 在数据驱动时代,不管是在产品功能迭代还是策略决策时都需要数据的支撑。那么,当我们准备上线一个新功能或者策略时,如何评估新老版本优劣,即数据的可量化就成了问题。这个时候就需要引入 A/B Test 了。 一、A/B Test 是什么…

Tomcat基本用法

Tomcat基本用法一、Tomcat 是什么二、下载安装三、目录结构四、启动服务器五、部署静态页面一、Tomcat 是什么 汤姆猫? 事实上,Java 世界中的 “汤姆猫” 完全不是一回事,但是同样大名鼎鼎 ~ Tomcat 是一个 HTTP 服务器。 前面我们已经学…

公司如何做好舆情监控,舆情监控解决方案有哪些?

随着互联网快速发展,企业网络舆情动态成为决策发展的重要依据,所以做好网络舆情监控至关重要,接下来TOOM舆情监测小编带您简单了解公司如何做好舆情监控,舆情监控解决方案有哪些? 一、公司如何做好舆情监控 舆情监控是指通过不…

Spring Boot 使用 SpringDoc 库的 Swagger3.0

Swagger 定义 Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步…

房产管理系统平台安全性分析?

房产管理系统是数图互通公司自主研发的FMCenterV5.0平台,是针对中国高校房产的管理特点和管理要求,研发的一套标准产品;通过在中国100多所高校的成功实施和迭代,形成了一套成熟、完善、全生命周期的房屋资源管理解决方案。 以下是…

FL Studio21电脑版免费音乐编曲宿主软件下载

编曲主要考验电脑的处理器(CPU)性能、声卡。所以配置电脑的时候有条件的伙伴可以着重考虑这两方面。现在市面上惠普、戴尔、华为、苹果等品牌的电脑,在四五千这个范围的商务本,就可以胜任编曲工作。但是在一些较为庞大的工程中可能…

SolarMesh(微服务监管平台)安装教程

SolarMesh简介 SolarMesh是基于服务网格构建的微服务监管平台。SolarMesh基于 Istio 及容器技术,提供微服务流量监控和管理,提供完善的非侵入式服务治理解决方案,在提供Istio流量管理等基础能力外,还提供多集群纳管、监控告警、W…

为什么全球科技巨头都在布局超高清?

我们能明显地感受到,进入21世纪以来,影像视频所占用人类生活的时间、空间已达到人类诞生以来的最大值。根据《2022全球互联网现象报告》,2021年流媒体视频占互联网带宽流量的53.7%,比2020年提升了4.8%。衣食住行,休闲娱…

十亿人都在用的健康码,运维体系是怎么设计的?

导读|随着疫情防控模式的迭代,健康码访问DAU逐渐趋于下跌,意味着健康码将逐步完成历史使命,见证着疫情的结束。本文特邀腾讯研发工程师李雄政将从技术架构、可观测体系、运营保障体系等运维体系多方面,总结回顾健康码业…

骨传导耳机到底怎么样,五款好用的骨传导耳机推荐

还有很多人不知道骨传导耳机使用感受到底如何,骨传导耳机是开放式的听音方式,在使用骨传导耳机时,会更加安全、耳机的声音相对于入耳式的声音会更加具有空间立体感,具体使用感感受到底如何,看下文大家就有一定的了解了…

服务器ssl证书升级

最近服务器扫描出ssl证书是使用弱哈希算法签名的SSL证书(CVE-2004-2761)【原理扫描】,要求联系证书颁发机构重新颁发证书。使用弱哈希算法签名SSL证书的端口有1433,3389。所有要对这俩端口配置一个新的证书。算法且满足sha256。 下面是我我服务器证书升…

国际原子时(TAI),GPS时间,协调世界时(UTC)以及rinex文件起止时间

最近学习使用PRIDE-PPPAR处理GNSS原始数据,判断rinex文件是不是单天的问题实在让人费解。必应搜索了一下,结合手头上的软件,问题大致弄清楚了。 比如现在有1个rinex文件:GPSR0190.19O,如果用PRIDE-PPPAR 的命令pdp3处…

零售行业R公司对接亚马逊Amazon Device EDI项目案例

为了满足平台货物的多样性,亚马逊Amazon邀请了来自全球各地的优秀供应商加入其供应链体系。要管理如此庞大的供应商群体,需要完成大量的数据处理工作,位列世界500强的Amazon是如何传输这些数据的呢? 答案是:通过EDI&a…

基于Amlogic 安卓9.0, 驱动简说(三):使用misc框架,让驱动更简单

文章目录一、前文总结二、系列文章三、MISC框架驱动四、解析:完整源码4.1 helloworld_misc_amlogic_driver.c4.2 Makefile五、编译执行(1)编译及部署(2)运行六、应用层调用6.1 APP源码6.2 命令及运行效果七、源码下载八…

思考札记1

2022年12月26日 今天看了荣耀新出的80GT,主处理器是第一代骁龙8,以及一个辅助处理器,性能怎么样不知道,但是12256价格来到了 3299,主摄5400万像素,感觉偏贵,我是不会买的 可能这机子就是主打性能…

【杂谈】一个项目获得10倍学费收入,我在有三AI学以致用的故事

各位有三AI的读者朋友们大家好,作为一名在职AI算法工程师和有三AI的读者,今天和大家分享一下我和有三AI几年来结识和学习的经历,希望对大家有所帮助。结识有三AI2019年我刚工作时对AI理论基础和实践经验还非常不足,因此工作之余我…

质数距离 acwing

196. 质数距离 - AcWing题库 题意是给你一个区间[l,r],相当于让你把这个区间里面所有的质数提出来,然后找到相邻质数距离最近和最远的第一个点在什么地方 看一下数据范围,不同的数据范围决定了用什么方法去做: 两个数据范围&…

Linux多路转接or多路复用模型

目录 一、功能 二、应用场景 三、多路转接模型的实现 1.select模型 1.1操作流程 1.2相关接口 1.3示例 1.4常见使用方式 1.5优缺点 2.poll模型 2.1操作流程 2.2相关接口 2.3示例 2.4优缺点 3.epoll模型 3.1操作流程 3.2相关接口 3.3常见使用方式 3.4epoll的事…