ksz9031 mmd读取不了_Ambarella 平台KSZ9031网卡直连不识别问题

博客讲述了在Ambarella peanut板子之间使用KSZ9031网卡直连无法协商成功的问题。通过分析驱动代码发现,问题出在MII Write: reg[0x09], val[0x1300],其中09H的第12位被设置为1,不应如此。解决方案是注释掉kernel中设置该位的代码,重新编译内核或模块,从而解决网卡自动协商失败的问题。" 107601173,7989742,Vue 3精选:新特性与实战指南,"['Vue', '前端开发', 'Web开发', '编程语言', '框架']
摘要由CSDN通过智能技术生成

问题描述:

两个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定义看此篇博客:MDC/MDIO接口定义

static int ambhw_mdio_write(struct mii_bus *bus,int mii_id, intregnum, u16 value)

{int ret_val = 0;struct ambeth_info *lp;intval;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;gotoambhw_mdio_write_exit;

}

val=value;

writel_relaxed(val, lp->regbase +ETH_MAC_GMII_DATA_OFFSET); //把要写到网卡芯片寄存器的值写到ambarella SoC芯片的 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); //给lp->regbase+ETH_MAC_GMII_ADDR_OFFSET写入一些flag(包括要写入的网卡芯片寄存器的地址)触发 lp->regbase+ETH_MAC_GMII_DATA_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;gotoambhw_mdio_write_exit;

}

ambhw_mdio_write_exit:returnret_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 ,Microchip提供到kernel里的网卡驱动让ambarella修改了,注释掉val |= 0x1000; 这一行,重新编译进内核或者编译成模块,问题解决。

拓展

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

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

虽然这个问题解决了,但还是不知道ambarella原厂为啥做这样的修改,在其他ambarella SoC平台里用的Realtek网卡芯片ambarella没有做类似的修改,是为了修复什么bug? 在咨询过microchip FAE后,得到的回复是千兆自动协商有时会遇到兼容性问题,例如某些千兆设备的连接,发现要在slave模式,或者必须工作在master模式,不然工作不稳定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值