ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ambarella peanut平台KSZ9031网卡直连不识别问题

2020-10-30 19:33:04  阅读:634  来源: 互联网

标签:直连 Write KSZ9031 val 网卡 MII 0x0d 0x0e reg


问题描述:

  两个ambarella peanut板子的网口之间用网线直连,会发现不能自动协商成功(网口灯不亮),但是ambarella peanut板子的网口和其他X86 Linux机器网口直连可以协商成功(网口灯亮)。

  对于想使用peanut板子网口作LAN口,给其他peanut 板子DHCP分配IP地址会失败。

 

问题分析

  1. 查看ambarella peanut平台驱动kernel/linux-4.4/drivers/net/ethernet/ambarella/ambarella_eth.c 对网卡芯片 KSZ9031 做了哪些 MDIO 读写,关于MDIO定义看此篇博客:https://www.cnblogs.com/rykang/p/11905593.html

static int ambhw_mdio_write(struct mii_bus *bus,
        int mii_id, int regnum, u16 value)
{
        int ret_val = 0;
        struct ambeth_info *lp;
        int val;
        int cnt = 0;

        lp = (struct ambeth_info *)bus->priv;

        printk("MII Write: reg[0x%.2x], val[0x%.4x].\n",
                        regnum, value); //添加的打印MDIO写了哪些寄存器,写了哪些值
        if (netif_msg_hw(lp))
                dev_info(&lp->ndev->dev,
                        "MII Write: id[0x%02x], add[0x%02x], val[0x%04x].\n",
                        mii_id, regnum, value);

        for (cnt = AMBETH_MII_RETRY_CNT; cnt > 0; cnt--) {
                val = readl_relaxed(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET);
                if (!(val & ETH_MAC_GMII_ADDR_GB))
                        break;
                udelay(10);
        }
        if ((cnt <= 0) && netif_msg_hw(lp)) {
                dev_err(&lp->ndev->dev, "MII Error: Prewrite tmo!\n");
                ret_val = -EIO;
                goto ambhw_mdio_write_exit;
        }

        val = value;
        writel_relaxed(val, lp->regbase + ETH_MAC_GMII_DATA_OFFSET);
        val = ETH_MAC_GMII_ADDR_PA(mii_id) | ETH_MAC_GMII_ADDR_GR(regnum);
        val |= ETH_MAC_GMII_ADDR_CR_250_300MHZ | ETH_MAC_GMII_ADDR_GW |
                ETH_MAC_GMII_ADDR_GB;
        writel_relaxed(val, lp->regbase + ETH_MAC_GMII_ADDR_OFFSET);

        for (cnt = AMBETH_MII_RETRY_CNT; cnt > 0; cnt--) {
                val = readl_relaxed(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET);
                if (!(val & ETH_MAC_GMII_ADDR_GB))
                        break;
                udelay(10);
        }
        if ((cnt <= 0) && netif_msg_hw(lp)) {
                dev_err(&lp->ndev->dev, "MII Error: Postwrite tmo!\n");
                ret_val = -EIO;
                goto ambhw_mdio_write_exit;
        }

ambhw_mdio_write_exit:
        return ret_val;
}

修改后发现打印信息如下:

MII Write: reg[0x00], val[0x8000].
MII Write: reg[0x0d], val[0x0002].
MII Write: reg[0x0e], val[0x0008].
MII Write: reg[0x0d], val[0x4002].
MII Write: reg[0x0d], val[0x0002].
MII Write: reg[0x0e], val[0x0008].
MII Write: reg[0x0d], val[0x4002].
MII Write: reg[0x0e], val[0x3df6].
MII Write: reg[0x0d], val[0x0002].
MII Write: reg[0x0e], val[0x0004].
MII Write: reg[0x0d], val[0x4002].
MII Write: reg[0x0d], val[0x0002].
MII Write: reg[0x0e], val[0x0004].
MII Write: reg[0x0d], val[0x4002].
MII Write: reg[0x0e], val[0x0027].
MII Write: reg[0x0d], val[0x0002].
MII Write: reg[0x0e], val[0x0005].
MII Write: reg[0x0d], val[0x4002].
MII Write: reg[0x0e], val[0x2222].
MII Write: reg[0x0d], val[0x0000].
MII Write: reg[0x0e], val[0x0004].
MII Write: reg[0x0d], val[0x4000].
MII Write: reg[0x0e], val[0x0006].
MII Write: reg[0x0d], val[0x0000].
MII Write: reg[0x0e], val[0x0003].
MII Write: reg[0x0d], val[0x4000].
MII Write: reg[0x0e], val[0x1a80].
MII Write: reg[0x00], val[0x1340].
MII Write: reg[0x00], val[0x1140].
MII Write: reg[0x09], val[0x0300].
MII Write: reg[0x09], val[0x1300].

  对照KSZ9031 datasheet比较下来,导致问题的可疑之处定位在MII Write: reg[0x09], val[0x1300]上面。

 

   本来09H的第12位网卡默认值为0的,但被设置为1了,从哪个位置设置的呢?

  2. 为了找到在哪个地方把09H的第12位设置为1的,我找到了kernel source code里的kernel/linux-4.4/drivers/net/phy/micrel.c,这个驱动是microchip系列网卡芯片相关寄存器配置的地方,找到如下函数:

static int ksz9031_config_aneg(struct phy_device *phydev)
{
        u32 val;

        genphy_config_aneg(phydev);

        /* Set auto Master/Slave resolution process */
        val = phy_read(phydev, MII_CTRL1000);
        val |= 0x1000; // MII_CTRL1000宏的值就是0x9
        val &= ~(0x0800);
        phy_write(phydev, MII_CTRL1000, val);

        return 0;
}

原来是在这里设置的Enable master-slave manual configuration,注释掉 “val |= 0x1000;” 这一行,重新编译进内核或者编译成模块,问题解决。

拓展

这个问题的根本原因就是两个peanut板子都设置成了 使能手动主从控制,导致用网线直连两个网卡不能自动协商,其中有一个peanut板子Disable master-slave manual configuration都不会有这个问题;

在问题发生后,给其中一个peanut板子的网口接到交换机上,正常识别后再拔掉网线会导致网卡 MDIO 配置的复位(9H寄存器的第12位恢复默认值0),这时候再用网线直连两个peanut板子,是可以正常协商成功的。

标签:直连,Write,KSZ9031,val,网卡,MII,0x0d,0x0e,reg
来源: https://www.cnblogs.com/wanglouxiaozi/p/13903840.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有