文章目录
写在前面
移植瑞芯微px30 网卡RTL8363的时候,不能识别到网卡 日志打印No found PHY, 前面的硬件确认无误之后,调试代码 ,最后发现源码有一点小问题,结论为
int __mdiobus_register(struct mii_bus *bus, struct module *owner) struct phy_device *phydev;
phydev <span class="token operator">=</span> <span class="token function">mdiobus_scan</span><span class="token punctuation">(</span>bus<span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
- if (IS_ERR(phydev)) {
+ // fix BUG
+ if (IS_ERR(phydev) && (PTR_ERR(phydev) != -ENODEV)) {
err = PTR_ERR(phydev);
goto error;
}
按以前的源码会报错直接走goto err了,我看新的kernel版本判断条件变了,更改之后,解决,相应源码分析如下
一、源码分析
当设备中匹配到相应的gmac之后,调用rk_gmac_probe函数
static const struct of_device_id rk_gmac_dwmac_match[] = { { .compatible = "rockchip,px30-gmac", .data = &px30_ops }, { .compatible = "rockchip,rk1808-gmac", .data = &rk1808_ops }, { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops }, { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, { .compatible = "rockchip,rk3308-mac", .data = &rk3308_ops }, { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops }, { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops }, { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops }, { } }; MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match); static int rk_gmac_probe(struct platform_device *pdev) { struct plat_stmmacenet_data *plat_dat; struct stmmac_resources stmmac_res; const struct rk_gmac_ops *data; int ret;
data <span class="token operator">=</span> <span class="token function">of_device_get_match_data</span><span class="token punctuation">(</span><span class="token operator">&</span>pdev<span class="token operator">-></span>dev<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>data<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token function">dev_err</span><span class="token punctuation">(</span><span class="token operator">&</span>pdev<span class="token operator">-></span>dev<span class="token punctuation">,</span> <span class="token string">"no of match data provided\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token operator">-</span>EINVAL<span class="token punctuation">;</span> <span class="token punctuation">}</span> ret <span class="token operator">=</span> <span class="token function">stmmac_get_platform_resources</span><span class="token punctuation">(</span>pdev<span class="token punctuation">,</span> <span class="token operator">&</span>stmmac_res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>ret<span class="token punctuation">)</span> <span class="token keyword">return</span> ret<span class="token punctuation">;</span> plat_dat <span class="token operator">=</span> <span class="token function">stmmac_probe_config_dt</span><span class="token punctuation">(</span>pdev<span class="token punctuation">,</span> <span class="token operator">&</span>stmmac_res<span class="token punctuation">.</span>mac<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">IS_ERR</span><span class="token punctuation">(</span>plat_dat<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token function">PTR_ERR</span><span class="token punctuation">(</span>plat_dat<span class="token punctuation">)</span><span class="token punctuation">;</span> plat_dat<span class="token operator">-></span>has_gmac <span class="token operator">=</span> true<span class="token punctuation">;</span> plat_dat<span class="token operator">-></span>fix_mac_speed <span class="token operator">=</span> rk_fix_speed<span class="token punctuation">;</span> plat_dat<span class="token operator">-></span>get_eth_addr <span class="token operator">=</span> rk_get_eth_addr<span class="token punctuation">;</span> plat_dat<span class="token operator">-></span>bsp_priv <span class="token operator">=</span> <span class="token function">rk_gmac_setup</span><span class="token punctuation">(</span>pdev<span class="token punctuation">,</span> plat_dat<span class="token punctuation">,</span> data<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">IS_ERR</span><span class="token punctuation">(</span>plat_dat<span class="token operator">-></span>bsp_priv<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token function">PTR_ERR</span><span class="token punctuation">(</span>plat_dat<span class="token operator">-></span>bsp_priv<span class="token punctuation">)</span><span class="token punctuation">;</span> ret <span class="token operator">=</span> <span class="token function">rk_gmac_clk_init</span><span class="token punctuation">(</span>plat_dat<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>ret<span class="token punctuation">)</span> <span class="token keyword">return</span> ret<span class="token punctuation">;</span> ret <span class="token operator">=</span> <span class="token function">rk_gmac_powerup</span><span class="token punctuation">(</span>plat_dat<span class="token operator">-></span>bsp_priv<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>ret<span class="token punctuation">)</span> <span class="token keyword">return</span> ret<span class="token punctuation">;</span> <span class="token comment">//探测函数</span> ret <span class="token operator">=</span> <span class="token function">stmmac_dvr_probe</span><span class="token punctuation">(</span><span class="token operator">&</span>pdev<span class="token operator">-></span>dev<span class="token punctuation">,</span> plat_dat<span class="token punctuation">,</span> <span class="token operator">&</span>stmmac_res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>ret<span class="token punctuation">)</span> <span class="token keyword">goto</span> err_gmac_powerdown<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
err_gmac_powerdown:
rk_gmac_powerdown(plat_dat->bsp_priv);
<span class="token keyword">return</span> ret<span class="token punctuation">;</span>
}
#ifdef STMMAC_VLAN_TAG_USED
/* Both mac100 and gmac support receive VLAN tag detection */
ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;
#endif
priv->msg_enable = netif_msg_init(debug, default_msg_level);
<span class="token keyword">if</span> <span class="token punctuation">(</span>flow_ctrl<span class="token punctuation">)</span>
priv<span class="token operator">-></span>flow_ctrl <span class="token operator">=</span> FLOW_AUTO<span class="token punctuation">;</span> <span class="token comment">/* RX/TX pause on */</span>
<span class="token comment">/* Rx Watchdog is available in the COREs newer than the 3.40.
* In some case, for example on bugged HW this feature
* has to be disable and this can be done by passing the
* riwt_off field from the platform.
*/</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>priv<span class="token operator">-></span>synopsys_id <span class="token operator">>=</span> DWMAC_CORE_3_50<span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token punctuation">(</span><span class="token operator">!</span>priv<span class="token operator">-></span>plat<span class="token operator">-></span>riwt_off<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
priv<span class="token operator">-></span>use_riwt <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">" Enable RX Mitigation via HW Watchdog Timer\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">netif_napi_add</span><span class="token punctuation">(</span>ndev<span class="token punctuation">,</span> <span class="token operator">&</span>priv<span class="token operator">-></span>napi<span class="token punctuation">,</span> stmmac_poll<span class="token punctuation">,</span> <span class="token number">64</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mutex_init</span><span class="token punctuation">(</span><span class="token operator">&</span>priv<span class="token operator">-></span>lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">spin_lock_init</span><span class="token punctuation">(</span><span class="token operator">&</span>priv<span class="token operator">-></span>tx_lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">/* If a specific clk_csr value is passed from the platform
* this means that the CSR Clock Range selection cannot be
* changed at run-time and it is fixed. Viceversa the driver'll try to
* set the MDC clock dynamically according to the csr actual
* clock input.
*/</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>priv<span class="token operator">-></span>plat<span class="token operator">-></span>clk_csr<span class="token punctuation">)</span>
<span class="token function">stmmac_clk_csr_set</span><span class="token punctuation">(</span>priv<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">else</span>
priv<span class="token operator">-></span>clk_csr <span class="token operator">=</span> priv<span class="token operator">-></span>plat<span class="token operator">-></span>clk_csr<span class="token punctuation">;</span>
<span class="token function">stmmac_check_pcs_mode</span><span class="token punctuation">(</span>priv<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>priv<span class="token operator">-></span>pcs <span class="token operator">!=</span> STMMAC_PCS_RGMII <span class="token operator">&&</span> priv<span class="token operator">-></span>pcs <span class="token operator">!=</span> STMMAC_PCS_TBI <span class="token operator">&&</span>
priv<span class="token operator">-></span>pcs <span class="token operator">!=</span> STMMAC_PCS_RTBI<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token comment">/* MDIO bus Registration */</span>
<span class="token comment">//注册mdio总线</span>
ret <span class="token operator">=</span> <span class="token function">stmmac_mdio_register</span><span class="token punctuation">(</span>ndev<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//rtk_switch_reg1b03();</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token function">pr_debug</span><span class="token punctuation">(</span><span class="token string">"%s: MDIO bus (id: %d) registration failed"</span><span class="token punctuation">,</span>
<span class="token constant">__func__</span><span class="token punctuation">,</span> priv<span class="token operator">-></span>plat<span class="token operator">-></span>bus_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">goto</span> error_mdio_register<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
ret <span class="token operator">=</span> <span class="token function">register_netdev</span><span class="token punctuation">(</span>ndev<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>ret<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token function">netdev_err</span><span class="token punctuation">(</span>priv<span class="token operator">-></span>dev<span class="token punctuation">,</span> <span class="token string">"%s: ERROR %i registering the device\n"</span><span class="token punctuation">,</span>
<span class="token constant">__func__</span><span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">goto</span> error_netdev_register<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> ret<span class="token punctuation">;</span>
error_netdev_register:
if (priv->pcs != STMMAC_PCS_RGMII &&
priv->pcs != STMMAC_PCS_TBI &&
priv->pcs != STMMAC_PCS_RTBI)
stmmac_mdio_unregister(ndev);
error_mdio_register:
netif_napi_del(&priv->napi);
error_hw_init:
clk_disable_unprepare(priv->pclk);
error_pclk_get:
clk_disable_unprepare(priv->stmmac_clk);
error_clk_get:
free_netdev(ndev);
<span class="token keyword">return</span> ret<span class="token punctuation">;</span>
}
EXPORT_SYMBOL_GPL(stmmac_dvr_probe);
#ifdef CONFIG_OF
if (priv->device->of_node)
mdio_bus_data->reset_gpio = -1;
#endif
new_bus<span class="token operator">-></span>name <span class="token operator">=</span> <span class="token string">"stmmac"</span><span class="token punctuation">;</span>
<span class="token comment">//mdio的读写函数</span>
new_bus<span class="token operator">-></span>read <span class="token operator">=</span> <span class="token operator">&</span>stmmac_mdio_read<span class="token punctuation">;</span>
new_bus<span class="token operator">-></span>write <span class="token operator">=</span> <span class="token operator">&</span>stmmac_mdio_write<span class="token punctuation">;</span>
new_bus<span class="token operator">-></span>reset <span class="token operator">=</span> <span class="token operator">&</span>stmmac_mdio_reset<span class="token punctuation">;</span>
<span class="token function">snprintf</span><span class="token punctuation">(</span>new_bus<span class="token operator">-></span>id<span class="token punctuation">,</span> MII_BUS_ID_SIZE<span class="token punctuation">,</span> <span class="token string">"%s-%x"</span><span class="token punctuation">,</span>
new_bus<span class="token operator">-></span>name<span class="token punctuation">,</span> priv<span class="token operator">-></span>plat<span class="token operator">-></span>bus_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
new_bus<span class="token operator">-></span>priv <span class="token operator">=</span> ndev<span class="token punctuation">;</span>
new_bus<span class="token operator">-></span>irq <span class="token operator">=</span> irqlist<span class="token punctuation">;</span>
new_bus<span class="token operator">-></span>phy_mask <span class="token operator">=</span> mdio_bus_data<span class="token operator">-></span>phy_mask<span class="token punctuation">;</span>
new_bus<span class="token operator">-></span>parent <span class="token operator">=</span> priv<span class="token operator">-></span>device<span class="token punctuation">;</span>
<span class="token comment">//注册mdio总线</span>
err <span class="token operator">=</span> <span class="token function">mdiobus_register</span><span class="token punctuation">(</span>new_bus<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>err <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token function">pr_err</span><span class="token punctuation">(</span><span class="token string">"%s: Cannot register as MDIO bus\n"</span><span class="token punctuation">,</span> new_bus<span class="token operator">-></span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">goto</span> bus_register_fail<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
found <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span>addr <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> addr <span class="token operator"><</span> PHY_MAX_ADDR<span class="token punctuation">;</span> addr<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token keyword">struct</span> <span class="token class-name">phy_device</span> <span class="token operator">*</span>phydev <span class="token operator">=</span> new_bus<span class="token operator">-></span>phy_map<span class="token punctuation">[</span>addr<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>phydev<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token keyword">int</span> act <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">char</span> irq_num<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">char</span> <span class="token operator">*</span>irq_str<span class="token punctuation">;</span>
<span class="token comment">/*
* If an IRQ was provided to be assigned after
* the bus probe, do it here.
*/</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>mdio_bus_data<span class="token operator">-></span>irqs <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token operator">&&</span>
<span class="token punctuation">(</span>mdio_bus_data<span class="token operator">-></span>probed_phy_irq <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
irqlist<span class="token punctuation">[</span>addr<span class="token punctuation">]</span> <span class="token operator">=</span> mdio_bus_data<span class="token operator">-></span>probed_phy_irq<span class="token punctuation">;</span>
phydev<span class="token operator">-></span>irq <span class="token operator">=</span> mdio_bus_data<span class="token operator">-></span>probed_phy_irq<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">/*
* If we're going to bind the MAC to this PHY bus,
* and no PHY number was provided to the MAC,
* use the one probed here.
*/</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>priv<span class="token operator">-></span>plat<span class="token operator">-></span>phy_addr <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span>
priv<span class="token operator">-></span>plat<span class="token operator">-></span>phy_addr <span class="token operator">=</span> addr<span class="token punctuation">;</span>
act <span class="token operator">=</span> <span class="token punctuation">(</span>priv<span class="token operator">-></span>plat<span class="token operator">-></span>phy_addr <span class="token operator">==</span> addr<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">switch</span> <span class="token punctuation">(</span>phydev<span class="token operator">-></span>irq<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token keyword">case</span> PHY_POLL<span class="token operator">:</span>
irq_str <span class="token operator">=</span> <span class="token string">"POLL"</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">case</span> PHY_IGNORE_INTERRUPT<span class="token operator">:</span>
irq_str <span class="token operator">=</span> <span class="token string">"IGNORE"</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">default</span><span class="token operator">:</span>
<span class="token function">sprintf</span><span class="token punctuation">(</span>irq_num<span class="token punctuation">,</span> <span class="token string">"%d"</span><span class="token punctuation">,</span> phydev<span class="token operator">-></span>irq<span class="token punctuation">)</span><span class="token punctuation">;</span>
irq_str <span class="token operator">=</span> irq_num<span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"%s: PHY ID %08x at %d IRQ %s (%s)%s\n"</span><span class="token punctuation">,</span>
ndev<span class="token operator">-></span>name<span class="token punctuation">,</span> phydev<span class="token operator">-></span>phy_id<span class="token punctuation">,</span> addr<span class="token punctuation">,</span>
irq_str<span class="token punctuation">,</span> <span class="token function">dev_name</span><span class="token punctuation">(</span><span class="token operator">&</span>phydev<span class="token operator">-></span>dev<span class="token punctuation">)</span><span class="token punctuation">,</span>
act <span class="token operator">?</span> <span class="token string">" active"</span> <span class="token operator">:</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
found <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>found<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token function">pr_warn</span><span class="token punctuation">(</span><span class="token string">"%s: No PHY found\n"</span><span class="token punctuation">,</span> ndev<span class="token operator">-></span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mdiobus_unregister</span><span class="token punctuation">(</span>new_bus<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mdiobus_free</span><span class="token punctuation">(</span>new_bus<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span>ENODEV<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
priv<span class="token operator">-></span>mii <span class="token operator">=</span> new_bus<span class="token punctuation">;</span>
rtl8761_bus<span class="token operator">=</span>new_bus<span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
bus_register_fail:
mdiobus_free(new_bus);
return err;
}
error:
while (–i >= 0) {
struct phy_device *phydev = bus->phy_map[i];
if (phydev) {
phy_device_remove(phydev);
phy_device_free(phydev);
}
}
device_del(&bus->dev);
return err;
}
}
EXPORT_SYMBOL(get_phy_device);
*phy_id = (phy_reg & 0xffff) << 16;
<span class="token comment">/* Grab the bits from PHYIR2, and put them in the lower half */</span>
// 通过mdio总线读取设备id
phy_reg = mdiobus_read(bus, addr, MII_PHYSID2);
if (phy_reg < 0)
return -EIO;
<span class="token operator">*</span>phy_id <span class="token operator">|=</span> <span class="token punctuation">(</span>phy_reg <span class="token operator">&</span> <span class="token number">0xffff</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
}
return retval;
}
EXPORT_SYMBOL(mdiobus_read);
</div><div data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://blog.csdn.net/weixin_34799243/article/details/123953920","extend1":"pc","ab":"new"}"><div></div></div>
<link href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/markdown_views-22a2fefd3b.css" rel="stylesheet">
<link href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/style-4f8fbf9108.css" rel="stylesheet">
</div>