--- a/drivers/net/hieth-sf/net.c +++ b/drivers/net/hieth-sf/net.c @@ -674,7 +674,7 @@ .ndo_get_stats = hieth_net_get_stats, }; -static int hieth_platdev_probe_port(struct platform_device *pdev, int port) +static int hieth_platdev_probe_port(struct platform_device *pdev, int port, int hieth_mdio_if_u, int hieth_mdio_if_d, int hieth_phyaddr_u, int hieth_phyaddr_d) { int ret = -1; struct net_device *netdev = NULL; @@ -685,6 +685,11 @@ ret = -ENODEV; goto _error_exit; } + + printk(KERN_INFO "PHY probing %s hieth_mdio_if_u=%d, hieth_mdio_if_d=%d," + " hieth_phyaddr_u=%d, hieth_phyaddr_d=%d\n", + UP_PORT ? "UP_PORT" : "DOWN_PORT", hieth_mdio_if_u, + hieth_mdio_if_d, hieth_phyaddr_u, hieth_phyaddr_d); netdev = alloc_etherdev(sizeof(*ld)); if (netdev == NULL) { @@ -816,7 +821,7 @@ return 0; } -static void phy_quirk(struct hieth_mdio_local *mdio, int phyaddr) +static void phy_quirk(struct hieth_mdio_local *mdio, int phyaddr, int hieth_mdio_if_u) { unsigned long phy_id; unsigned short id1, id2; @@ -860,6 +865,28 @@ } } +static struct { + int up; + int down; +} trial_table[] = { + { 1, 0 }, + { 1, 2 }, + { 0, 2 }, +}; + +static void bruteforce_hieth(struct platform_device *pdev) { + int i; + + for (i = 0; i < sizeof(trial_table) / sizeof(trial_table[0]); i++) { + if (!hieth_platdev_probe_port(pdev, UP_PORT, hieth_mdio_if_u, + hieth_mdio_if_d, trial_table[i].up, trial_table[i].down)) { + printk(KERN_INFO "PHY auto probing success, using u/d %d/%d\n", + trial_table[i].up, trial_table[i].down); + break; + } + } +} + static int hieth_plat_driver_probe(struct platform_device *pdev) { int ret = -1; @@ -877,13 +904,12 @@ hieth_verify_flow_ctrl_args(); - hieth_platdev_probe_port(pdev, UP_PORT); -#ifdef CONFIG_HIETH_DOWNPORT_EN - hieth_platdev_probe_port(pdev, DOWN_PORT); -#endif - - phy_quirk(&hieth_mdio_local_device, hieth_phyaddr_u); - phy_quirk(&hieth_mdio_local_device, hieth_phyaddr_d); + if (hieth_platdev_probe_port(pdev, UP_PORT, hieth_mdio_if_u, hieth_mdio_if_d, hieth_phyaddr_u, hieth_phyaddr_d)) + if (hieth_platdev_probe_port(pdev, DOWN_PORT, hieth_mdio_if_u, hieth_mdio_if_d, hieth_phyaddr_u, hieth_phyaddr_d)) + bruteforce_hieth(pdev); + + phy_quirk(&hieth_mdio_local_device, hieth_phyaddr_u, hieth_mdio_if_u); + phy_quirk(&hieth_mdio_local_device, hieth_phyaddr_d, hieth_mdio_if_u); if (hieth_devs_save[UP_PORT]) ndev = hieth_devs_save[UP_PORT];