Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'netsec-fixes'

Masahisa Kojima says:

====================
Bugfix for the netsec driver

This patch series include bugfix for the netsec ethernet
controller driver, fix the problem in interface down/up.

changes in v2:
- change the place to perform the PHY power down
- use the MACROs defiend in include/uapi/linux/mii.h
- update commit comment
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+34 -6
+34 -6
drivers/net/ethernet/socionext/netsec.c
··· 274 274 struct clk *clk; 275 275 u32 msg_enable; 276 276 u32 freq; 277 + u32 phy_addr; 277 278 bool rx_cksum_offload_flag; 278 279 }; 279 280 ··· 432 431 return 0; 433 432 } 434 433 434 + static int netsec_phy_read(struct mii_bus *bus, int phy_addr, int reg_addr); 435 + 435 436 static int netsec_phy_write(struct mii_bus *bus, 436 437 int phy_addr, int reg, u16 val) 437 438 { 439 + int status; 438 440 struct netsec_priv *priv = bus->priv; 439 441 440 442 if (netsec_mac_write(priv, GMAC_REG_GDR, val)) ··· 450 446 GMAC_REG_SHIFT_CR_GAR))) 451 447 return -ETIMEDOUT; 452 448 453 - return netsec_mac_wait_while_busy(priv, GMAC_REG_GAR, 454 - NETSEC_GMAC_GAR_REG_GB); 449 + status = netsec_mac_wait_while_busy(priv, GMAC_REG_GAR, 450 + NETSEC_GMAC_GAR_REG_GB); 451 + 452 + /* Developerbox implements RTL8211E PHY and there is 453 + * a compatibility problem with F_GMAC4. 454 + * RTL8211E expects MDC clock must be kept toggling for several 455 + * clock cycle with MDIO high before entering the IDLE state. 456 + * To meet this requirement, netsec driver needs to issue dummy 457 + * read(e.g. read PHYID1(offset 0x2) register) right after write. 458 + */ 459 + netsec_phy_read(bus, phy_addr, MII_PHYSID1); 460 + 461 + return status; 455 462 } 456 463 457 464 static int netsec_phy_read(struct mii_bus *bus, int phy_addr, int reg_addr) ··· 955 940 dring->head = 0; 956 941 dring->tail = 0; 957 942 dring->pkt_cnt = 0; 943 + 944 + if (id == NETSEC_RING_TX) 945 + netdev_reset_queue(priv->ndev); 958 946 } 959 947 960 948 static void netsec_free_dring(struct netsec_priv *priv, int id) ··· 1361 1343 netsec_uninit_pkt_dring(priv, NETSEC_RING_TX); 1362 1344 netsec_uninit_pkt_dring(priv, NETSEC_RING_RX); 1363 1345 1364 - ret = netsec_reset_hardware(priv, false); 1365 - 1366 1346 phy_stop(ndev->phydev); 1367 1347 phy_disconnect(ndev->phydev); 1348 + 1349 + ret = netsec_reset_hardware(priv, false); 1368 1350 1369 1351 pm_runtime_put_sync(priv->dev); 1370 1352 ··· 1375 1357 { 1376 1358 struct netsec_priv *priv = netdev_priv(ndev); 1377 1359 int ret; 1360 + u16 data; 1378 1361 1379 1362 ret = netsec_alloc_dring(priv, NETSEC_RING_TX); 1380 1363 if (ret) ··· 1384 1365 ret = netsec_alloc_dring(priv, NETSEC_RING_RX); 1385 1366 if (ret) 1386 1367 goto err1; 1368 + 1369 + /* set phy power down */ 1370 + data = netsec_phy_read(priv->mii_bus, priv->phy_addr, MII_BMCR) | 1371 + BMCR_PDOWN; 1372 + netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, data); 1387 1373 1388 1374 ret = netsec_reset_hardware(priv, true); 1389 1375 if (ret) ··· 1439 1415 }; 1440 1416 1441 1417 static int netsec_of_probe(struct platform_device *pdev, 1442 - struct netsec_priv *priv) 1418 + struct netsec_priv *priv, u32 *phy_addr) 1443 1419 { 1444 1420 priv->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); 1445 1421 if (!priv->phy_np) { 1446 1422 dev_err(&pdev->dev, "missing required property 'phy-handle'\n"); 1447 1423 return -EINVAL; 1448 1424 } 1425 + 1426 + *phy_addr = of_mdio_parse_addr(&pdev->dev, priv->phy_np); 1449 1427 1450 1428 priv->clk = devm_clk_get(&pdev->dev, NULL); /* get by 'phy_ref_clk' */ 1451 1429 if (IS_ERR(priv->clk)) { ··· 1649 1623 } 1650 1624 1651 1625 if (dev_of_node(&pdev->dev)) 1652 - ret = netsec_of_probe(pdev, priv); 1626 + ret = netsec_of_probe(pdev, priv, &phy_addr); 1653 1627 else 1654 1628 ret = netsec_acpi_probe(pdev, priv, &phy_addr); 1655 1629 if (ret) 1656 1630 goto free_ndev; 1631 + 1632 + priv->phy_addr = phy_addr; 1657 1633 1658 1634 if (!priv->freq) { 1659 1635 dev_err(&pdev->dev, "missing PHY reference clock frequency\n");