summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/socionext/netsec.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
index 4289ccb26e4e..d9d0d03e4ce7 100644
--- a/drivers/net/ethernet/socionext/netsec.c
+++ b/drivers/net/ethernet/socionext/netsec.c
@@ -274,6 +274,7 @@ struct netsec_priv {
274 struct clk *clk; 274 struct clk *clk;
275 u32 msg_enable; 275 u32 msg_enable;
276 u32 freq; 276 u32 freq;
277 u32 phy_addr;
277 bool rx_cksum_offload_flag; 278 bool rx_cksum_offload_flag;
278}; 279};
279 280
@@ -431,9 +432,12 @@ static int netsec_mac_update_to_phy_state(struct netsec_priv *priv)
431 return 0; 432 return 0;
432} 433}
433 434
435static int netsec_phy_read(struct mii_bus *bus, int phy_addr, int reg_addr);
436
434static int netsec_phy_write(struct mii_bus *bus, 437static int netsec_phy_write(struct mii_bus *bus,
435 int phy_addr, int reg, u16 val) 438 int phy_addr, int reg, u16 val)
436{ 439{
440 int status;
437 struct netsec_priv *priv = bus->priv; 441 struct netsec_priv *priv = bus->priv;
438 442
439 if (netsec_mac_write(priv, GMAC_REG_GDR, val)) 443 if (netsec_mac_write(priv, GMAC_REG_GDR, val))
@@ -446,8 +450,19 @@ static int netsec_phy_write(struct mii_bus *bus,
446 GMAC_REG_SHIFT_CR_GAR))) 450 GMAC_REG_SHIFT_CR_GAR)))
447 return -ETIMEDOUT; 451 return -ETIMEDOUT;
448 452
449 return netsec_mac_wait_while_busy(priv, GMAC_REG_GAR, 453 status = netsec_mac_wait_while_busy(priv, GMAC_REG_GAR,
450 NETSEC_GMAC_GAR_REG_GB); 454 NETSEC_GMAC_GAR_REG_GB);
455
456 /* Developerbox implements RTL8211E PHY and there is
457 * a compatibility problem with F_GMAC4.
458 * RTL8211E expects MDC clock must be kept toggling for several
459 * clock cycle with MDIO high before entering the IDLE state.
460 * To meet this requirement, netsec driver needs to issue dummy
461 * read(e.g. read PHYID1(offset 0x2) register) right after write.
462 */
463 netsec_phy_read(bus, phy_addr, MII_PHYSID1);
464
465 return status;
451} 466}
452 467
453static int netsec_phy_read(struct mii_bus *bus, int phy_addr, int reg_addr) 468static int netsec_phy_read(struct mii_bus *bus, int phy_addr, int reg_addr)
@@ -940,6 +955,9 @@ static void netsec_uninit_pkt_dring(struct netsec_priv *priv, int id)
940 dring->head = 0; 955 dring->head = 0;
941 dring->tail = 0; 956 dring->tail = 0;
942 dring->pkt_cnt = 0; 957 dring->pkt_cnt = 0;
958
959 if (id == NETSEC_RING_TX)
960 netdev_reset_queue(priv->ndev);
943} 961}
944 962
945static void netsec_free_dring(struct netsec_priv *priv, int id) 963static void netsec_free_dring(struct netsec_priv *priv, int id)
@@ -1343,11 +1361,11 @@ static int netsec_netdev_stop(struct net_device *ndev)
1343 netsec_uninit_pkt_dring(priv, NETSEC_RING_TX); 1361 netsec_uninit_pkt_dring(priv, NETSEC_RING_TX);
1344 netsec_uninit_pkt_dring(priv, NETSEC_RING_RX); 1362 netsec_uninit_pkt_dring(priv, NETSEC_RING_RX);
1345 1363
1346 ret = netsec_reset_hardware(priv, false);
1347
1348 phy_stop(ndev->phydev); 1364 phy_stop(ndev->phydev);
1349 phy_disconnect(ndev->phydev); 1365 phy_disconnect(ndev->phydev);
1350 1366
1367 ret = netsec_reset_hardware(priv, false);
1368
1351 pm_runtime_put_sync(priv->dev); 1369 pm_runtime_put_sync(priv->dev);
1352 1370
1353 return ret; 1371 return ret;
@@ -1357,6 +1375,7 @@ static int netsec_netdev_init(struct net_device *ndev)
1357{ 1375{
1358 struct netsec_priv *priv = netdev_priv(ndev); 1376 struct netsec_priv *priv = netdev_priv(ndev);
1359 int ret; 1377 int ret;
1378 u16 data;
1360 1379
1361 ret = netsec_alloc_dring(priv, NETSEC_RING_TX); 1380 ret = netsec_alloc_dring(priv, NETSEC_RING_TX);
1362 if (ret) 1381 if (ret)
@@ -1366,6 +1385,11 @@ static int netsec_netdev_init(struct net_device *ndev)
1366 if (ret) 1385 if (ret)
1367 goto err1; 1386 goto err1;
1368 1387
1388 /* set phy power down */
1389 data = netsec_phy_read(priv->mii_bus, priv->phy_addr, MII_BMCR) |
1390 BMCR_PDOWN;
1391 netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, data);
1392
1369 ret = netsec_reset_hardware(priv, true); 1393 ret = netsec_reset_hardware(priv, true);
1370 if (ret) 1394 if (ret)
1371 goto err2; 1395 goto err2;
@@ -1415,7 +1439,7 @@ static const struct net_device_ops netsec_netdev_ops = {
1415}; 1439};
1416 1440
1417static int netsec_of_probe(struct platform_device *pdev, 1441static int netsec_of_probe(struct platform_device *pdev,
1418 struct netsec_priv *priv) 1442 struct netsec_priv *priv, u32 *phy_addr)
1419{ 1443{
1420 priv->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); 1444 priv->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
1421 if (!priv->phy_np) { 1445 if (!priv->phy_np) {
@@ -1423,6 +1447,8 @@ static int netsec_of_probe(struct platform_device *pdev,
1423 return -EINVAL; 1447 return -EINVAL;
1424 } 1448 }
1425 1449
1450 *phy_addr = of_mdio_parse_addr(&pdev->dev, priv->phy_np);
1451
1426 priv->clk = devm_clk_get(&pdev->dev, NULL); /* get by 'phy_ref_clk' */ 1452 priv->clk = devm_clk_get(&pdev->dev, NULL); /* get by 'phy_ref_clk' */
1427 if (IS_ERR(priv->clk)) { 1453 if (IS_ERR(priv->clk)) {
1428 dev_err(&pdev->dev, "phy_ref_clk not found\n"); 1454 dev_err(&pdev->dev, "phy_ref_clk not found\n");
@@ -1623,12 +1649,14 @@ static int netsec_probe(struct platform_device *pdev)
1623 } 1649 }
1624 1650
1625 if (dev_of_node(&pdev->dev)) 1651 if (dev_of_node(&pdev->dev))
1626 ret = netsec_of_probe(pdev, priv); 1652 ret = netsec_of_probe(pdev, priv, &phy_addr);
1627 else 1653 else
1628 ret = netsec_acpi_probe(pdev, priv, &phy_addr); 1654 ret = netsec_acpi_probe(pdev, priv, &phy_addr);
1629 if (ret) 1655 if (ret)
1630 goto free_ndev; 1656 goto free_ndev;
1631 1657
1658 priv->phy_addr = phy_addr;
1659
1632 if (!priv->freq) { 1660 if (!priv->freq) {
1633 dev_err(&pdev->dev, "missing PHY reference clock frequency\n"); 1661 dev_err(&pdev->dev, "missing PHY reference clock frequency\n");
1634 ret = -ENODEV; 1662 ret = -ENODEV;