Linux中编译mdio命令,linux网络设备—mdio总线

一.结构体

struct mii_bus {

const char *name;//总线名

char id[MII_BUS_ID_SIZE];//id

void *priv;//私有数据

int (*read)(struct mii_bus *bus, int phy_id, int regnum);//读方法

int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val);//写方法

int (*reset)(struct mii_bus *bus);//复位

struct mutex mdio_lock;

struct device *parent;//父设备

enum {

MDIOBUS_ALLOCATED = 1,

MDIOBUS_REGISTERED,

MDIOBUS_UNREGISTERED,

MDIOBUS_RELEASED,

} state;//总线状态

struct device dev;//设备文件

struct phy_device *phy_map[PHY_MAX_ADDR];//PHY设备数组

u32 phy_mask;

int *irq;//中断

};

二.初始化过程

在phy_init函数中调用了mdio_bus_init初始化mdio总线

int __init mdio_bus_init(void)

{

int ret;

ret = class_register(&mdio_bus_class);//注册设备类

if (!ret) {

ret = bus_register(&mdio_bus_type);//注册mdio总线

if (ret)

class_unregister(&mdio_bus_class);

}

return ret;

}

设备类"/sys/class/mdio_bus"

static struct class mdio_bus_class = {

.name= "mdio_bus",

.dev_release= mdiobus_release,

};

总线类型"/sys/bus/mdio"

struct bus_type mdio_bus_type = {

.name= "mdio_bus",

.match= mdio_bus_match,//匹配方法

.pm= MDIO_BUS_PM_OPS,

};

EXPORT_SYMBOL(mdio_bus_type);

三.mdio总线注册

1.调用mdiobus_alloc函数分配内存

struct mii_bus *mdiobus_alloc(void)

{

struct mii_bus *bus;

bus = kzalloc(sizeof(*bus), GFP_KERNEL);//分配内存

if (bus != NULL)

bus->state = MDIOBUS_ALLOCATED;

return bus;

}

EXPORT_SYMBOL(mdiobus_alloc);

2.填充mii_bus的结构体成员

mii_bus->name = ;

mii_bus->read = ;

mii_bus->write= ;

mii_bus->reset= ;

mii_bus->parent= ;

mii_bus->priv = ;

mii_bus->id= ;

3.注册mii_bus

int mdiobus_register(struct mii_bus *bus)

{

int i, err;

if (NULL == bus || NULL == bus->name || NULL == bus->read ||NULL == bus->write)

return -EINVAL;

BUG_ON(bus->state != MDIOBUS_ALLOCATED &&bus->state != MDIOBUS_UNREGISTERED);

bus->dev.parent = bus->parent;

bus->dev.class = &mdio_bus_class;//总线设备类"/sys/bus/mdio_bus"

bus->dev.groups = NULL;

dev_set_name(&bus->dev, "%s", bus->id);//设置总线设备名

err = device_register(&bus->dev);//注册设备文件

if (err) {

printk(KERN_ERR "mii_bus %s failed to register

", bus->id);

return -EINVAL;

}

mutex_init(&bus->mdio_lock);

if (bus->reset)

bus->reset(bus);//总线复位

for (i = 0; i < PHY_MAX_ADDR; i++) {

if ((bus->phy_mask & (1 << i)) == 0) {

struct phy_device *phydev;

phydev = mdiobus_scan(bus, i);//扫描phy设备

if (IS_ERR(phydev)) {

err = PTR_ERR(phydev);

goto error;

}

}

}

bus->state = MDIOBUS_REGISTERED;//状态设置为已注册

pr_info("%s: probed

", bus->name);

return 0;

error:

while (--i >= 0) {

if (bus->phy_map[i])

device_unregister(&bus->phy_map[i]->dev);

}

device_del(&bus->dev);

return err;

}

EXPORT_SYMBOL(mdiobus_register);

调用了mdiobus_scan函数

struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)

{

struct phy_device *phydev;

int err;

phydev = get_phy_device(bus, addr);//获取创建phy设备

if (IS_ERR(phydev) || phydev == NULL)

return phydev;

err = phy_device_register(phydev);//注册phy设备

if (err) {

phy_device_free(phydev);

return NULL;

}

return phydev;

}

EXPORT_SYMBOL(mdiobus_scan);

动态地创建了PHY设备

四.mii、mdio、phy、mac关系图

3f288ee285423cc6e29fa526842ca321.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值