/drivers/net/phy/phy.c的状态机phy_state_machine分析
来源:互联网 发布:用波士顿矩阵分析海尔 编辑:程序博客网 时间:2024/05/29 15:29
本文分析基于PHY不采用中断方式,而且是固定速率模式,不采用自适应。
在mii总线初始化过程中,mdio总线会通过mdiobus_scan()扫描挂载在该总线上的所有phy设备,并且通过phy_device_create()函数创建phy_device结构体。同时绑定marvell.c文件中对应的驱动。
新创建的phy_device结构体成员初始化为:
dev->speed = 0;dev->duplex = -1;dev->pause = dev->asym_pause = 0;dev->link = 1;dev->interface = PHY_INTERFACE_MODE_GMII;dev->autoneg = AUTONEG_ENABLE;dev->state = PHY_DOWN;
在struct net_device_ops的ndo_open()函数会在网口被打开时调用。ndo_open()函数绑定PHY对应的驱动,并修改PHY的状态
phydev->drv->config_init //调用config_init驱动函数.......................... phydev->state = PHY_READY; phy_prepare_link(phydev, handler); phy_start_machine(phydev);
phy_prepare_link()绑定phy_device结构体的adjust_link回调函数。然后启动PHY状态机。
phydev->supported &= (PHY_GBIT_FEATURES | SUPPORTED_Pause |SUPPORTED_Asym_Pause);phydev->advertising = phydev->supported;lp->link = 0;lp->speed = 0;lp->duplex = -1;lp->phy_dev = phydev;phy_start(lp->phy_dev);
void phy_start(struct phy_device *phydev){mutex_lock(&phydev->lock);switch (phydev->state) {case PHY_STARTING:phydev->state = PHY_PENDING;break;case PHY_READY:phydev->state = PHY_UP;break;case PHY_HALTED:phydev->state = PHY_RESUMING;default:break;}mutex_unlock(&phydev->lock);}在PHY状态机中
case PHY_UP:needs_aneg = true;phydev->link_timeout = PHY_AN_TIMEOUT;break;。。。。 if (needs_aneg) err = phy_start_aneg(phydev);
标记1:phy_start_anegphy_start_aneg会修改
phydev->speed = settings[idx].speed;phydev->duplex = settings[idx].duplex;然后调用驱动函数config_aneg()
如果PHY不支持自适应,phy_start_aneg首先将PHY状态置为PHY_FORCING,否则置为PHY_AN
/** * phy_start_aneg - start auto-negotiation for this PHY device * @phydev: the phy_device struct * * Description: Sanitizes the settings (if we're not autonegotiating * them), and then calls the driver's config_aneg function. * If the PHYCONTROL Layer is operating, we change the state to * reflect the beginning of Auto-negotiation or forcing. */int phy_start_aneg(struct phy_device *phydev){int err;mutex_lock(&phydev->lock);if (AUTONEG_DISABLE == phydev->autoneg)phy_sanitize_settings(phydev);err = phydev->drv->config_aneg(phydev);if (err < 0)goto out_unlock;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;}}out_unlock:mutex_unlock(&phydev->lock);return err;}
PHY状态机对PHY_FORCING状态的处理如下:
case PHY_FORCING:err = genphy_update_link(phydev);if (err)break;if (phydev->link) {phydev->state = PHY_RUNNING;netif_carrier_on(phydev->attached_dev);} else {if (0 == phydev->link_timeout--)needs_aneg = true;}phydev->adjust_link(phydev->attached_dev);break;1、genphy_update_link读取PHy的状态寄存器,更新phy_device->link;
2、如果link的话,phydev->state = PHY_RUNNING;调用adjust_link回调函数
case PHY_FORCING:err = genphy_update_link(phydev);if (err)break;if (phydev->link) {phydev->state = PHY_RUNNING;netif_carrier_on(phydev->attached_dev);} else {if (0 == phydev->link_timeout--)needs_aneg = true;}phydev->adjust_link(phydev->attached_dev);break;
3、没有link的话,继续调用phy_start_aneg,重复标记1开始的流程
PHY状态机对PHY_RUNNING状态的处理如下
case PHY_RUNNING:/* Only register a CHANGE if we are * polling or ignoring interrupts */if (!phy_interrupt_is_valid(phydev))phydev->state = PHY_CHANGELINK;break;
case PHY_CHANGELINK:err = phy_read_status(phydev);if (err)break;if (phydev->link) {phydev->state = PHY_RUNNING;netif_carrier_on(phydev->attached_dev);} else {phydev->state = PHY_NOLINK;netif_carrier_off(phydev->attached_dev);}phydev->adjust_link(phydev->attached_dev);if (phy_interrupt_is_valid(phydev))err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);break;case PHY_HALTED:if (phydev->link) {phydev->link = 0;netif_carrier_off(phydev->attached_dev);phydev->adjust_link(phydev->attached_dev);do_suspend = true;}break;
PHY_CHANGELINK状态处理分支:
读取PHY状态,如果link,置为PHY_RUNNING,调用adjust_link
否则置为PHY_NOLINK,调用adjust_link
0 0
- /drivers/net/phy/phy.c的状态机phy_state_machine分析
- < NET > PHY
- D-PHY、M-PHY、C-PHY
- PHY
- PHY
- PHY
- phy
- 以太网的phy寄存器分析
- 以太网的phy寄存器分析
- phy子系统分析
- PHY的基本知识
- phy device的注册
- PHY的基本知识
- Mac与Phy组成原理的简单分析
- Mac与Phy组成原理的简单分析
- Mac与Phy组成原理的简单分析
- Mac与Phy组成原理的简单分析
- Mac与Phy组成原理的简单分析
- 初识Spring+SpringMVC+MyBatis框架(一)---web.xml
- [美文欣赏] 春风沉醉的晚上
- TeeChart在VC中实时曲线绘制的应用(工控),附实时曲线代码
- unicode编码相关资料
- automake编写完整的项目---动态库+可执行文件
- /drivers/net/phy/phy.c的状态机phy_state_machine分析
- 黑马程序员--------java基础知识 函数、数组
- 算法导论--学习笔记01
- 中国用人做事模式
- SQL exists 与 in
- JDBC 与JAVA 数据库编程
- idle in transaction
- HBASE之RowKey排序解析
- POJ1068 Parencodings(模拟)