Skip to content

Commit 0228d37

Browse files
committed
Merge branch 'ftgmac100-fixes'
Heyi Guo says: ==================== drivers/net/ftgmac100: fix occasional DHCP failure This patch set is to fix the issues discussed in the mail thread: https://lore.kernel.org/netdev/51f5b7a7-330f-6b3c-253d-10e45cdb6805@linux.alibaba.com/ and follows the advice from Andrew Lunn. The first 2 patches refactors the code to enable adjust_link calling reset function directly. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents ecf4a24 + 1baf2e5 commit 0228d37

File tree

1 file changed

+129
-114
lines changed

1 file changed

+129
-114
lines changed

drivers/net/ethernet/faraday/ftgmac100.c

Lines changed: 129 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -989,117 +989,6 @@ static int ftgmac100_alloc_rx_buffers(struct ftgmac100 *priv)
989989
return 0;
990990
}
991991

992-
static void ftgmac100_adjust_link(struct net_device *netdev)
993-
{
994-
struct ftgmac100 *priv = netdev_priv(netdev);
995-
struct phy_device *phydev = netdev->phydev;
996-
bool tx_pause, rx_pause;
997-
int new_speed;
998-
999-
/* We store "no link" as speed 0 */
1000-
if (!phydev->link)
1001-
new_speed = 0;
1002-
else
1003-
new_speed = phydev->speed;
1004-
1005-
/* Grab pause settings from PHY if configured to do so */
1006-
if (priv->aneg_pause) {
1007-
rx_pause = tx_pause = phydev->pause;
1008-
if (phydev->asym_pause)
1009-
tx_pause = !rx_pause;
1010-
} else {
1011-
rx_pause = priv->rx_pause;
1012-
tx_pause = priv->tx_pause;
1013-
}
1014-
1015-
/* Link hasn't changed, do nothing */
1016-
if (phydev->speed == priv->cur_speed &&
1017-
phydev->duplex == priv->cur_duplex &&
1018-
rx_pause == priv->rx_pause &&
1019-
tx_pause == priv->tx_pause)
1020-
return;
1021-
1022-
/* Print status if we have a link or we had one and just lost it,
1023-
* don't print otherwise.
1024-
*/
1025-
if (new_speed || priv->cur_speed)
1026-
phy_print_status(phydev);
1027-
1028-
priv->cur_speed = new_speed;
1029-
priv->cur_duplex = phydev->duplex;
1030-
priv->rx_pause = rx_pause;
1031-
priv->tx_pause = tx_pause;
1032-
1033-
/* Link is down, do nothing else */
1034-
if (!new_speed)
1035-
return;
1036-
1037-
/* Disable all interrupts */
1038-
iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
1039-
1040-
/* Reset the adapter asynchronously */
1041-
schedule_work(&priv->reset_task);
1042-
}
1043-
1044-
static int ftgmac100_mii_probe(struct net_device *netdev)
1045-
{
1046-
struct ftgmac100 *priv = netdev_priv(netdev);
1047-
struct platform_device *pdev = to_platform_device(priv->dev);
1048-
struct device_node *np = pdev->dev.of_node;
1049-
struct phy_device *phydev;
1050-
phy_interface_t phy_intf;
1051-
int err;
1052-
1053-
/* Default to RGMII. It's a gigabit part after all */
1054-
err = of_get_phy_mode(np, &phy_intf);
1055-
if (err)
1056-
phy_intf = PHY_INTERFACE_MODE_RGMII;
1057-
1058-
/* Aspeed only supports these. I don't know about other IP
1059-
* block vendors so I'm going to just let them through for
1060-
* now. Note that this is only a warning if for some obscure
1061-
* reason the DT really means to lie about it or it's a newer
1062-
* part we don't know about.
1063-
*
1064-
* On the Aspeed SoC there are additionally straps and SCU
1065-
* control bits that could tell us what the interface is
1066-
* (or allow us to configure it while the IP block is held
1067-
* in reset). For now I chose to keep this driver away from
1068-
* those SoC specific bits and assume the device-tree is
1069-
* right and the SCU has been configured properly by pinmux
1070-
* or the firmware.
1071-
*/
1072-
if (priv->is_aspeed && !(phy_interface_mode_is_rgmii(phy_intf))) {
1073-
netdev_warn(netdev,
1074-
"Unsupported PHY mode %s !\n",
1075-
phy_modes(phy_intf));
1076-
}
1077-
1078-
phydev = phy_find_first(priv->mii_bus);
1079-
if (!phydev) {
1080-
netdev_info(netdev, "%s: no PHY found\n", netdev->name);
1081-
return -ENODEV;
1082-
}
1083-
1084-
phydev = phy_connect(netdev, phydev_name(phydev),
1085-
&ftgmac100_adjust_link, phy_intf);
1086-
1087-
if (IS_ERR(phydev)) {
1088-
netdev_err(netdev, "%s: Could not attach to PHY\n", netdev->name);
1089-
return PTR_ERR(phydev);
1090-
}
1091-
1092-
/* Indicate that we support PAUSE frames (see comment in
1093-
* Documentation/networking/phy.rst)
1094-
*/
1095-
phy_support_asym_pause(phydev);
1096-
1097-
/* Display what we found */
1098-
phy_attached_info(phydev);
1099-
1100-
return 0;
1101-
}
1102-
1103992
static int ftgmac100_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
1104993
{
1105994
struct net_device *netdev = bus->priv;
@@ -1410,10 +1299,8 @@ static int ftgmac100_init_all(struct ftgmac100 *priv, bool ignore_alloc_err)
14101299
return err;
14111300
}
14121301

1413-
static void ftgmac100_reset_task(struct work_struct *work)
1302+
static void ftgmac100_reset(struct ftgmac100 *priv)
14141303
{
1415-
struct ftgmac100 *priv = container_of(work, struct ftgmac100,
1416-
reset_task);
14171304
struct net_device *netdev = priv->netdev;
14181305
int err;
14191306

@@ -1459,6 +1346,134 @@ static void ftgmac100_reset_task(struct work_struct *work)
14591346
rtnl_unlock();
14601347
}
14611348

1349+
static void ftgmac100_reset_task(struct work_struct *work)
1350+
{
1351+
struct ftgmac100 *priv = container_of(work, struct ftgmac100,
1352+
reset_task);
1353+
1354+
ftgmac100_reset(priv);
1355+
}
1356+
1357+
static void ftgmac100_adjust_link(struct net_device *netdev)
1358+
{
1359+
struct ftgmac100 *priv = netdev_priv(netdev);
1360+
struct phy_device *phydev = netdev->phydev;
1361+
bool tx_pause, rx_pause;
1362+
int new_speed;
1363+
1364+
/* We store "no link" as speed 0 */
1365+
if (!phydev->link)
1366+
new_speed = 0;
1367+
else
1368+
new_speed = phydev->speed;
1369+
1370+
/* Grab pause settings from PHY if configured to do so */
1371+
if (priv->aneg_pause) {
1372+
rx_pause = tx_pause = phydev->pause;
1373+
if (phydev->asym_pause)
1374+
tx_pause = !rx_pause;
1375+
} else {
1376+
rx_pause = priv->rx_pause;
1377+
tx_pause = priv->tx_pause;
1378+
}
1379+
1380+
/* Link hasn't changed, do nothing */
1381+
if (phydev->speed == priv->cur_speed &&
1382+
phydev->duplex == priv->cur_duplex &&
1383+
rx_pause == priv->rx_pause &&
1384+
tx_pause == priv->tx_pause)
1385+
return;
1386+
1387+
/* Print status if we have a link or we had one and just lost it,
1388+
* don't print otherwise.
1389+
*/
1390+
if (new_speed || priv->cur_speed)
1391+
phy_print_status(phydev);
1392+
1393+
priv->cur_speed = new_speed;
1394+
priv->cur_duplex = phydev->duplex;
1395+
priv->rx_pause = rx_pause;
1396+
priv->tx_pause = tx_pause;
1397+
1398+
/* Link is down, do nothing else */
1399+
if (!new_speed)
1400+
return;
1401+
1402+
/* Disable all interrupts */
1403+
iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
1404+
1405+
/* Release phy lock to allow ftgmac100_reset to aquire it, keeping lock
1406+
* order consistent to prevent dead lock.
1407+
*/
1408+
if (netdev->phydev)
1409+
mutex_unlock(&netdev->phydev->lock);
1410+
1411+
ftgmac100_reset(priv);
1412+
1413+
if (netdev->phydev)
1414+
mutex_lock(&netdev->phydev->lock);
1415+
1416+
}
1417+
1418+
static int ftgmac100_mii_probe(struct net_device *netdev)
1419+
{
1420+
struct ftgmac100 *priv = netdev_priv(netdev);
1421+
struct platform_device *pdev = to_platform_device(priv->dev);
1422+
struct device_node *np = pdev->dev.of_node;
1423+
struct phy_device *phydev;
1424+
phy_interface_t phy_intf;
1425+
int err;
1426+
1427+
/* Default to RGMII. It's a gigabit part after all */
1428+
err = of_get_phy_mode(np, &phy_intf);
1429+
if (err)
1430+
phy_intf = PHY_INTERFACE_MODE_RGMII;
1431+
1432+
/* Aspeed only supports these. I don't know about other IP
1433+
* block vendors so I'm going to just let them through for
1434+
* now. Note that this is only a warning if for some obscure
1435+
* reason the DT really means to lie about it or it's a newer
1436+
* part we don't know about.
1437+
*
1438+
* On the Aspeed SoC there are additionally straps and SCU
1439+
* control bits that could tell us what the interface is
1440+
* (or allow us to configure it while the IP block is held
1441+
* in reset). For now I chose to keep this driver away from
1442+
* those SoC specific bits and assume the device-tree is
1443+
* right and the SCU has been configured properly by pinmux
1444+
* or the firmware.
1445+
*/
1446+
if (priv->is_aspeed && !(phy_interface_mode_is_rgmii(phy_intf))) {
1447+
netdev_warn(netdev,
1448+
"Unsupported PHY mode %s !\n",
1449+
phy_modes(phy_intf));
1450+
}
1451+
1452+
phydev = phy_find_first(priv->mii_bus);
1453+
if (!phydev) {
1454+
netdev_info(netdev, "%s: no PHY found\n", netdev->name);
1455+
return -ENODEV;
1456+
}
1457+
1458+
phydev = phy_connect(netdev, phydev_name(phydev),
1459+
&ftgmac100_adjust_link, phy_intf);
1460+
1461+
if (IS_ERR(phydev)) {
1462+
netdev_err(netdev, "%s: Could not attach to PHY\n", netdev->name);
1463+
return PTR_ERR(phydev);
1464+
}
1465+
1466+
/* Indicate that we support PAUSE frames (see comment in
1467+
* Documentation/networking/phy.rst)
1468+
*/
1469+
phy_support_asym_pause(phydev);
1470+
1471+
/* Display what we found */
1472+
phy_attached_info(phydev);
1473+
1474+
return 0;
1475+
}
1476+
14621477
static int ftgmac100_open(struct net_device *netdev)
14631478
{
14641479
struct ftgmac100 *priv = netdev_priv(netdev);

0 commit comments

Comments
 (0)