BCM89XXX系列PHY驱动代码适配

文章讲述了如何修改Linux内核驱动以适应BCM89881PHY的C45协议,通过修改`get_phy_id`函数来读取PHYID。同时提供了千兆和百兆模式的配置脚本,以及Mac驱动程序的修改以支持BCM89881在100Mbps速率下的工作。
摘要由CSDN通过智能技术生成

BCM89XXX系列PHY使用的MDIO配置默认通信协议是C45,Linux内核驱动默认使用C22协议对PHY进行相关配置,所以Linux内核驱动需要使用C22协议模仿C45协议对PHY进行相关配置。

  1. 识别BCM89881
    修改/linux_zvs/drivers/net/phy/phy_device.c中读取Phy id函数内容,具体修改内容如下:

static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,
bool is_c45, struct phy_c45_device_ids *c45_ids)
{
int phy_reg;

if (is_c45)
    return get_phy_c45_ids(bus, addr, phy_id, c45_ids);

    /* Grab the bits from PHYIR1, and put them in the upper half */
    mdiobus_write(bus, addr, 0x0d, 0x01);        
    mdiobus_write(bus, addr, 0x0e, MII_PHYSID1);
    mdiobus_write(bus, addr, 0x0d, 0x4001);
    phy_reg = mdiobus_read(bus, addr, 0x0e);
    if (phy_reg < 0) {
            /* if there is no device, return without an error so scanning
             * the bus works properly
             */
            if (phy_reg == -EIO || phy_reg == -ENODEV) {
                    *phy_id = 0xffffffff;
                    return 0;
            }

            return -EIO;
    }

    *phy_id = (phy_reg & 0xffff) << 16;

    /* Grab the bits from PHYIR2, and put them in the lower half */
    mdiobus_write(bus, addr, 0x0d, 0x01);        
    mdiobus_write(bus, addr, 0x0e, MII_PHYSID2);
    mdiobus_write(bus, addr, 0x0d, 0x4001);
    phy_reg = mdiobus_read(bus, addr, 0x0e);
    if (phy_reg < 0)
            return -EIO;

    *phy_id |= (phy_reg & 0xffff);

return 0;

}

  1. 千兆模式配置
    板卡启动后通过如下脚本配置BCM89881工作在1000Mbps slave模式:

#!/bin/sh

./mdio eth0 0x0 0xA000 #power down the phy
usleep 2000
./mdio eth0 0x0 0xA000 #power down the phy

usleep 5000

./mdio eth0 0 0x2000 #power on the phy
./mdio eth0 0 0x2000 #power on the phy

slave 1000M

./mdio eth0 0x0d 0x01
./mdio eth0 0x0e 0x0834
./mdio eth0 0x0d 0x4001
./mdio eth0 0x0e 0x8001

./mdio eth0 0x0d 0x01
./mdio eth0 0x0e 0xa010
./mdio eth0 0x0d 0x4001
./mdio eth0 0x0e 0x101

  1. 百兆模式配置
    3.1. Mac驱动程序修改
    若使BCM89881工作在100Mbps速率,需要对Linux内核的mac配置进行修改,对/linux_zvs/drivers/net/ethernet/cadence/macb_main.c

进行如下修改:

static void macb_handle_link_change(struct net_device *dev)
{
struct macb *bp = netdev_priv(dev);
struct phy_device *phydev = dev->phydev;
unsigned long flags;
int status_change = 0;

spin_lock_irqsave(&bp->lock, flags);

if (phydev->link) {
    if ((bp->speed != phydev->speed) ||
        (bp->duplex != phydev->duplex)) {
        u32 reg;

        reg = macb_readl(bp, NCFGR);
        reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
        if (macb_is_gem(bp))
            reg &= ~GEM_BIT(GBE);

        if (phydev->duplex)
            reg |= MACB_BIT(FD);
        if (phydev->speed == SPEED_100)
            reg |= MACB_BIT(SPD);
        if (phydev->speed == SPEED_1000 &&
            bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE)
            reg |= GEM_BIT(GBE);
                    /* 2023 02 08 */
        phydev->speed = SPEED_100;    
        reg |= MACB_BIT(SPD);
        reg &= ~GEM_BIT(GBE);
        phydev->duplex = DUPLEX_FULL;

        macb_or_gem_writel(bp, NCFGR, reg);

        bp->speed = phydev->speed;
        bp->duplex = phydev->duplex;
        status_change = 1;
    }
}

if (phydev->link != bp->link) {
    if (!phydev->link) {
        bp->speed = 0;
        bp->duplex = -1;
    }
    bp->link = phydev->link;

    status_change = 1;
}

spin_unlock_irqrestore(&bp->lock, flags);

if (status_change) {
    if (phydev->link) {
        /* Update the TX clock rate if and only if the link is
         * up and there has been a link change.
         */
        macb_set_tx_clk(bp->tx_clk, phydev->speed, dev);

        netif_carrier_on(dev);
        netdev_info(dev, "link up (%d/%s)\n",
                phydev->speed,
                phydev->duplex == DUPLEX_FULL ?
                "Full" : "Half");
    } else {
        netif_carrier_off(dev);
        netdev_info(dev, "link down\n");
    }
}

}

3.2. Slave模式配置脚本
#!/bin/sh

slave 100M

#C22

./mdio eth0 0x0 0xA000 #power down the phy
usleep 2000
./mdio eth0 0x0 0xA000 #power down the phy

usleep 5000

./mdio eth0 0 0x2000 #power on the phy
./mdio eth0 0 0x2000 #power on the phy

./mdio eth0 0x0d 0x01
./mdio eth0 0x0e 0x0834
./mdio eth0 0x0d 0x4001
./mdio eth0 0x0e 0x8000

./mdio eth0 0x0d 0x01
./mdio eth0 0x0e 0xa010
./mdio eth0 0x0d 0x4001
./mdio eth0 0x0e 0x101

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值