千兆网口 Freescale ETSEC + Marvell 88E1111 uboot Linux 驱动分析 五

千兆网口 Freescale ETSEC + Marvell 88E1111 uboot Linux 驱动分析 五       

        分类:            Linux 内核和文件系统 PowerPC体系结构 Linux驱动2010-11-15 20:18 1701人阅读 评论(1) 收藏 举报

8 of_platform总线上gianfar设备驱动添加,并绑定设备e0024000.ethernete0025000.ethernet

/driver/net/gianfar.c

module_init(gfar_init);

gfar_init à of_register_platform_driver(&gfar_driver) à of_register_driver à driver_register à bus_add_driver à driver_attach

遍历整个of_platform总线,寻找与之相匹配的设备

driver_attach à __driver_attach à driver_match_device

drivermatch_table里的信息和dev_nod中的做比较,若符合就进入driverprobe,也就是gfar_probe

现在设备e0024000.ethernete0025000.ethernet都有了他们自己的驱动。

到这步,of_platform上的gianfar设备和mdio设备都有其各自的驱动,mdio总线上的phy设备和tbi-phy设备都有了其驱动程序,但是phy设备和gianfar设备之间还没有任何联系,phygianfar都没有初始化。现在要调用相应的驱动去初始化各个设备,连接gianfarphy

9 gianfar_probe 初始化gianfar设备,填充devpriv结构体。其中gfar_of_init 会从of结构中读出priv->phy_node

10 phy的初始化,phy gianfar的连接

/net/ipv4/ipconfig.c

late_initcall(ip_auto_config)

ip_auto_config à ic_open_devs à dev_change_flags à __dev_change_flags à __dev_open à ops->ndo_open à gfar_enet_open

gfar设备的打开函数中会去初始化phy,并connect to gianfar

u       gfar_enet_open à init_phy

static int init_phy(struct net_device *dev)

{

interface = gfar_get_interface(dev);

/*PHY连接和初始化*/

priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, 0,

/*配置TBI-PHY*/

if (interface == PHY_INTERFACE_MODE_SGMII)

gfar_configure_serdes(dev);

. . . . .

return 0;

}

u       of_phy_connect函数

priv->phy_node是从of结构中读出的phy的信息,还不是真正的phy,所以这里要在mdio_bus_type总线上再找一次匹配的phy。若找到phy_device *phy指针就不为空。

struct phy_device *of_phy_connect(struct net_device *dev,

  struct device_node *phy_np,

  void (*hndlr)(struct net_device *), u32 flags,

  phy_interface_t iface)

{

/*mdio总线上找到和of tree上读出的phy_node相匹配的phy设备*/

struct phy_device *phy = of_phy_find_device(phy_np);

if (!phy)

return NULL;

/*phy的初始化和phy的某些操作*/

return phy_connect_direct(dev, phy, hndlr, flags, iface) ? NULL : phy;

}

u       phy_connect_direct函数

int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,

       void (*handler)(struct net_device *), u32 flags,

       phy_interface_t interface)

{

int rc;

/*phy 连接和初始化*/

rc = phy_attach_direct(dev, phydev, flags, interface);

if (rc)

return rc;

/*挂载PHY状态改变后修改gianfar驱动寄存器的回调函数*/

phy_prepare_link(phydev, handler);

/*PHY的状态机开启*/

phy_start_machine(phydev, NULL);

if (phydev->irq > 0)

{

/*PHY中断的开启*/

phy_start_interrupts(phydev);

}

return 0;

}

u       phy_attach_direct函数

int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,

      u32 flags, phy_interface_t interface)

{

struct device *d = &phydev->dev;

/* 如何该phy没有驱动,就使用genphy的驱动 */

if (NULL == d->driver) {

int err;

d->driver = &genphy_driver.driver;

err = d->driver->probe(d);

if (err >= 0)

err = device_bind_driver(d);

if (err)

return err;

}

/*如果phy已经和gianfar连接返回*/

if (phydev->attached_dev) {

dev_err(&dev->dev, "PHY already attached/n");

return -EBUSY;

}

/*连接phygianfar*/

phydev->attached_dev = dev;

phydev->dev_flags = flags;

phydev->interface = interface;

/*使用phy的驱动中的初始化函数去初始化phy设备。*/

return phy_init_hw(phydev);

}

到这里,所有的gianfarphytbi-phy设备都已经注册,驱动已经加载,gianfarphy已经连接,并初始化完成。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值