理解系统内核linux phy驱动

PHY设备驱动是基于device、driver、bus的连接方式,驱动涉及如下几个重要部分: 总线 - sturct mii_bus (mii stand for media independent interface) 设备 - struct phy_device 驱动 - struct phy_driver。PHY驱动函数驱动功能:

函数名称 功能描述

soft_reset 执行 phy 的软件复位

config_init 在 phy 复位后将 phy 配置为一个既定的状态

probe 创建 phy->priv 并执行类似驱动绑定的过程

suspend/resume 电源管理挂起与恢复功能

config_aneq 修改速率双工模式自协商等配置

aneq_done 驱动自协商的结果

read_status 获取当前的速率双工与自协商配置状态

ack_interrupt 清楚挂起的中断

did_interrupt 检查是否 phy 触发了一个中断信号

config_intr 开启、关闭中断

remove 当驱动被移除时调用的接口

ts_info 请求查询 HW 时间戳状态

hwtstap 设置 phy 的 HW时间戳配置

rxtstamp 在 phy 这一层为 skb 请求一个接收时间戳

txtsamp 在 phy 这一层为 skd 请求一个发送时间戳

set_wol 使能 Wake-on-Lan

get_wol 获取 Wake-on-Lan 状态

read_mmd_indirect 读取 phy MMD 间接寄存器

write_mmd_indirect 写入 phy MMD 间接寄存器

个驱动都有独立的操作函数来对 phy 进行操作,也就是说网卡会直接调用类似 phy_ops 中的虚函数来使用 phy 的功能。而对于这种 phy 驱动而言,它与网卡驱动是独立的,将网卡驱动与 phy 驱动关联起来步骤:

PHY驱动的注册:在phy_init函数中不仅注册了mdio_bus总线,还注册了一个通用的PHY驱动作为缺省的内核PHY驱动,但是如果PHY芯片的内部寄存器和802.3定义的并不一样或者需要特殊的功能配置以实现更强的功能,这就需要专有的驱动。

*phy_start_aneg_priv-启动此phy设备的自动协商

*@phydev:phy_device结构

*@sync:表示是否等待工作队列取消

描述:对设置进行Sanitize(如果我们没有自动协商它们),然后调用驱动程序的config_aeg函数。如果PHYCONTROL层正在运行,我们会更改状态以反映自动协商或强制的开始

复制代码
static int phy_start_aneg_priv(struct phy_device *phydev, bool sync)
{
	bool trigger = 0;
	int err;

	if (!phydev->drv)
		return -EIO;

	mutex_lock(&phydev->lock);
      printk("111111111111\n");
	if (AUTONEG_DISABLE == phydev->autoneg)
		phy_sanitize_settings(phydev);
    printk("~~phydev->autoneg~~~~~~~~~~\n",phydev->autoneg);
	/* Invalidate LP advertising flags */
	phydev->lp_advertising = 0;
    printk("222222222\n");
	
	err = phydev->drv->config_aneg(phydev);
	printk("err=%d\n",err );
	if (err < 0)
		goto out_unlock;

     printk("333333333\n");
	if (phydev->state != PHY_HALTED) {
		if (AUTONEG_ENABLE == phydev->autoneg) {
			phydev->state = PHY_AN;
			phydev->link_timeout = PHY_AN_TIMEOUT;
		} else {
			phydev->state = PHY_FORCING;
			phydev->link_timeout = PHY_FORCE_TIMEOUT;
		}
	}

	/* Re-schedule a PHY state machine to check PHY status because
	 * negotiation may already be done and aneg interrupt may not be
	 * generated.
	 */
	if (phy_interrupt_is_valid(phydev) && (phydev->state == PHY_AN)) {
		err = phy_aneg_done(phydev);
		if (err > 0) {
			trigger = true;
			err = 0;
		}
	}

out_unlock:
	mutex_unlock(&phydev->lock);

	if (trigger)
		phy_trigger_machine(phydev, sync);

	return err;
}
相关推荐
铁锚7 分钟前
一个WordPress连续登录失败的问题排查
java·linux·服务器·nginx·tomcat
华颉科技11 分钟前
机架式服务器是什么?机架式/塔式/刀片式三大服务器类型区别与选型全解析
服务器·科技·服务器类型·刀片服务器·机架服务器·塔式服务器
DavieLau14 分钟前
Python开发后端InfluxDB数据库测试接口
服务器·数据库·python·时序数据库
生命不息战斗不止(王子晗)37 分钟前
mybatis中${}和#{}的区别
java·服务器·tomcat
Ha-gd1 小时前
Linux基础开发工具一(yum/apt ,vim)
linux·服务器
水水沝淼㵘3 小时前
嵌入式开发学习日志(数据结构--顺序结构单链表)Day19
linux·服务器·c语言·数据结构·学习·算法·排序算法
愚润求学3 小时前
【Linux】基础 IO(一)
linux·运维·服务器·开发语言·c++·笔记
monstercl4 小时前
游戏资源传输服务器
运维·服务器·游戏
网硕互联的小客服4 小时前
服务器配置错误导致SSL/TLS出现安全漏洞,如何进行排查?
运维·服务器
GreatNXY5 小时前
【阿里云】阿里云 Ubuntu 服务器无法更新 systemd(Operation not permitted)的解决方法
服务器·阿里云·云计算