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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-ftgmac100-various-probe-cleanups'

Jacky Chou says:

====================
net: ftgmac100: Various probe cleanups

The probe function of the ftgmac100 is rather complex, due to the way
it has evolved over time, dealing with poor DT descriptions, and new
variants of the MAC.

Make use of DT match data to identify the MAC variant, rather than
looking at the compatible string all the time.

Make use of devm_ calls to simplify cleanup. This indirectly fixes
inconsistent goto label names.

Always probe the MDIO bus, when it exists. This simplifies the logic a
bit.

Move code into helpers to simply probe.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Jacky Chou <jacky_chou@aspeedtech.com>
====================

Link: https://patch.msgid.link/20260206-ftgmac-cleanup-v5-0-ad28a9067ea7@aspeedtech.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+195 -163
+195 -163
drivers/net/ethernet/faraday/ftgmac100.c
··· 33 33 34 34 #define DRV_NAME "ftgmac100" 35 35 36 + enum ftgmac100_mac_id { 37 + FTGMAC100_FARADAY = 1, 38 + FTGMAC100_AST2400, 39 + FTGMAC100_AST2500, 40 + FTGMAC100_AST2600 41 + }; 42 + 43 + struct ftgmac100_match_data { 44 + enum ftgmac100_mac_id mac_id; 45 + }; 46 + 36 47 /* Arbitrary values, I am not sure the HW has limits */ 37 48 #define MAX_RX_QUEUE_ENTRIES 1024 38 49 #define MAX_TX_QUEUE_ENTRIES 1024 ··· 76 65 /* Registers */ 77 66 struct resource *res; 78 67 void __iomem *base; 68 + 69 + enum ftgmac100_mac_id mac_id; 79 70 80 71 /* Rx ring */ 81 72 unsigned int rx_q_entries; ··· 1483 1470 phy_interface_t phy_intf; 1484 1471 int err; 1485 1472 1473 + if (!priv->mii_bus) { 1474 + dev_err(priv->dev, "No MDIO bus available\n"); 1475 + return -ENODEV; 1476 + } 1477 + 1486 1478 /* Default to RGMII. It's a gigabit part after all */ 1487 1479 err = of_get_phy_mode(np, &phy_intf); 1488 1480 if (err) ··· 1717 1699 struct platform_device *pdev = to_platform_device(priv->dev); 1718 1700 struct device_node *np = pdev->dev.of_node; 1719 1701 struct device_node *mdio_np; 1720 - int i, err = 0; 1702 + int err = 0; 1721 1703 u32 reg; 1722 1704 1723 1705 /* initialize mdio bus */ 1724 - priv->mii_bus = mdiobus_alloc(); 1706 + priv->mii_bus = devm_mdiobus_alloc(priv->dev); 1725 1707 if (!priv->mii_bus) 1726 1708 return -EIO; 1727 1709 1728 - if (of_device_is_compatible(np, "aspeed,ast2400-mac") || 1729 - of_device_is_compatible(np, "aspeed,ast2500-mac")) { 1710 + if (priv->mac_id == FTGMAC100_AST2400 || 1711 + priv->mac_id == FTGMAC100_AST2500) { 1730 1712 /* The AST2600 has a separate MDIO controller */ 1731 1713 1732 1714 /* For the AST2400 and AST2500 this driver only supports the ··· 1745 1727 priv->mii_bus->read = ftgmac100_mdiobus_read; 1746 1728 priv->mii_bus->write = ftgmac100_mdiobus_write; 1747 1729 1748 - for (i = 0; i < PHY_MAX_ADDR; i++) 1749 - priv->mii_bus->irq[i] = PHY_POLL; 1750 - 1751 1730 mdio_np = of_get_child_by_name(np, "mdio"); 1752 1731 1753 - err = of_mdiobus_register(priv->mii_bus, mdio_np); 1732 + err = devm_of_mdiobus_register(priv->dev, priv->mii_bus, mdio_np); 1733 + of_node_put(mdio_np); 1754 1734 if (err) { 1755 1735 dev_err(priv->dev, "Cannot register MDIO bus!\n"); 1756 - goto err_register_mdiobus; 1736 + return err; 1757 1737 } 1758 1738 1759 - of_node_put(mdio_np); 1760 - 1761 1739 return 0; 1762 - 1763 - err_register_mdiobus: 1764 - mdiobus_free(priv->mii_bus); 1765 - return err; 1766 1740 } 1767 1741 1768 1742 static void ftgmac100_phy_disconnect(struct net_device *netdev) ··· 1773 1763 fixed_phy_unregister(phydev); 1774 1764 } 1775 1765 1776 - static void ftgmac100_destroy_mdio(struct net_device *netdev) 1777 - { 1778 - struct ftgmac100 *priv = netdev_priv(netdev); 1779 - 1780 - if (!priv->mii_bus) 1781 - return; 1782 - 1783 - mdiobus_unregister(priv->mii_bus); 1784 - mdiobus_free(priv->mii_bus); 1785 - } 1786 - 1787 1766 static void ftgmac100_ncsi_handler(struct ncsi_dev *nd) 1788 1767 { 1789 1768 if (unlikely(nd->state != ncsi_dev_state_functional)) ··· 1787 1788 struct clk *clk; 1788 1789 int rc; 1789 1790 1790 - clk = devm_clk_get(priv->dev, NULL /* MACCLK */); 1791 + clk = devm_clk_get_enabled(priv->dev, NULL /* MACCLK */); 1791 1792 if (IS_ERR(clk)) 1792 1793 return PTR_ERR(clk); 1793 1794 priv->clk = clk; 1794 - rc = clk_prepare_enable(priv->clk); 1795 - if (rc) 1796 - return rc; 1797 1795 1798 1796 /* Aspeed specifies a 100MHz clock is required for up to 1799 1797 * 1000Mbit link speeds. As NCSI is limited to 100Mbit, 25MHz ··· 1799 1803 rc = clk_set_rate(priv->clk, priv->use_ncsi ? FTGMAC_25MHZ : 1800 1804 FTGMAC_100MHZ); 1801 1805 if (rc) 1802 - goto cleanup_clk; 1806 + return rc; 1803 1807 1804 1808 /* RCLK is for RMII, typically used for NCSI. Optional because it's not 1805 1809 * necessary if it's the AST2400 MAC, or the MAC is configured for 1806 1810 * RGMII, or the controller is not an ASPEED-based controller. 1807 1811 */ 1808 - priv->rclk = devm_clk_get_optional(priv->dev, "RCLK"); 1809 - rc = clk_prepare_enable(priv->rclk); 1810 - if (!rc) 1811 - return 0; 1812 + priv->rclk = devm_clk_get_optional_enabled(priv->dev, "RCLK"); 1813 + if (IS_ERR(priv->rclk)) 1814 + return PTR_ERR(priv->rclk); 1812 1815 1813 - cleanup_clk: 1814 - clk_disable_unprepare(priv->clk); 1815 - 1816 - return rc; 1816 + return 0; 1817 1817 } 1818 1818 1819 1819 static bool ftgmac100_has_child_node(struct device_node *np, const char *name) ··· 1825 1833 return ret; 1826 1834 } 1827 1835 1836 + static int ftgmac100_probe_ncsi(struct net_device *netdev, 1837 + struct ftgmac100 *priv, 1838 + struct platform_device *pdev) 1839 + { 1840 + struct device_node *np = pdev->dev.of_node; 1841 + struct phy_device *phydev; 1842 + int err; 1843 + 1844 + if (!IS_ENABLED(CONFIG_NET_NCSI)) { 1845 + dev_err(&pdev->dev, "NCSI stack not enabled\n"); 1846 + return -EINVAL; 1847 + } 1848 + 1849 + dev_info(&pdev->dev, "Using NCSI interface\n"); 1850 + priv->use_ncsi = true; 1851 + priv->ndev = ncsi_register_dev(netdev, ftgmac100_ncsi_handler); 1852 + if (!priv->ndev) 1853 + return -EINVAL; 1854 + 1855 + phydev = fixed_phy_register(&ncsi_phy_status, np); 1856 + if (IS_ERR(phydev)) { 1857 + dev_err(&pdev->dev, "failed to register fixed PHY device\n"); 1858 + err = PTR_ERR(phydev); 1859 + goto err_register_ndev; 1860 + } 1861 + err = phy_connect_direct(netdev, phydev, ftgmac100_adjust_link, 1862 + PHY_INTERFACE_MODE_RMII); 1863 + if (err) { 1864 + dev_err(&pdev->dev, "Connecting PHY failed\n"); 1865 + goto err_register_phy; 1866 + } 1867 + 1868 + return 0; 1869 + err_register_phy: 1870 + fixed_phy_unregister(phydev); 1871 + err_register_ndev: 1872 + if (priv->ndev) 1873 + ncsi_unregister_dev(priv->ndev); 1874 + priv->ndev = NULL; 1875 + return err; 1876 + } 1877 + 1878 + static int ftgmac100_probe_dt(struct net_device *netdev, 1879 + struct platform_device *pdev, 1880 + struct ftgmac100 *priv, 1881 + struct device_node *np) 1882 + { 1883 + struct phy_device *phy; 1884 + int err; 1885 + 1886 + if (of_get_property(np, "use-ncsi", NULL)) 1887 + return ftgmac100_probe_ncsi(netdev, priv, pdev); 1888 + 1889 + if (of_phy_is_fixed_link(np) || 1890 + of_get_property(np, "phy-handle", NULL)) { 1891 + /* Support "mdio"/"phy" child nodes for ast2400/2500 1892 + * with an embedded MDIO controller. Automatically 1893 + * scan the DTS for available PHYs and register 1894 + * them. 2600 has an independent MDIO controller, not 1895 + * part of the MAC. 1896 + */ 1897 + phy = of_phy_get_and_connect(priv->netdev, np, 1898 + &ftgmac100_adjust_link); 1899 + if (!phy) { 1900 + dev_err(&pdev->dev, "Failed to connect to phy\n"); 1901 + return -EINVAL; 1902 + } 1903 + 1904 + /* Indicate that we support PAUSE frames (see comment in 1905 + * Documentation/networking/phy.rst) 1906 + */ 1907 + phy_support_asym_pause(phy); 1908 + 1909 + /* Display what we found */ 1910 + phy_attached_info(phy); 1911 + return 0; 1912 + } 1913 + 1914 + if (!ftgmac100_has_child_node(np, "mdio")) { 1915 + /* Support legacy ASPEED devicetree descriptions that 1916 + * decribe a MAC with an embedded MDIO controller but 1917 + * have no "mdio" child node. Automatically scan the 1918 + * MDIO bus for available PHYs. 1919 + */ 1920 + err = ftgmac100_mii_probe(netdev); 1921 + if (err) { 1922 + dev_err(priv->dev, "MII probe failed!\n"); 1923 + return err; 1924 + } 1925 + } 1926 + 1927 + return 0; 1928 + } 1929 + 1828 1930 static int ftgmac100_probe(struct platform_device *pdev) 1829 1931 { 1932 + const struct ftgmac100_match_data *match_data; 1933 + enum ftgmac100_mac_id mac_id; 1830 1934 struct resource *res; 1831 1935 int irq; 1832 1936 struct net_device *netdev; 1833 - struct phy_device *phydev; 1834 1937 struct ftgmac100 *priv; 1835 1938 struct device_node *np; 1836 1939 int err = 0; 1940 + 1941 + np = pdev->dev.of_node; 1942 + if (np) { 1943 + match_data = of_device_get_match_data(&pdev->dev); 1944 + if (!match_data) 1945 + return -EINVAL; 1946 + mac_id = match_data->mac_id; 1947 + } else { 1948 + mac_id = FTGMAC100_FARADAY; 1949 + } 1837 1950 1838 1951 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1839 1952 if (!res) ··· 1949 1852 return irq; 1950 1853 1951 1854 /* setup net_device */ 1952 - netdev = alloc_etherdev(sizeof(*priv)); 1953 - if (!netdev) { 1954 - err = -ENOMEM; 1955 - goto err_alloc_etherdev; 1956 - } 1855 + netdev = devm_alloc_etherdev(&pdev->dev, sizeof(*priv)); 1856 + if (!netdev) 1857 + return -ENOMEM; 1957 1858 1958 1859 SET_NETDEV_DEV(netdev, &pdev->dev); 1959 1860 ··· 1965 1870 priv = netdev_priv(netdev); 1966 1871 priv->netdev = netdev; 1967 1872 priv->dev = &pdev->dev; 1873 + priv->mac_id = mac_id; 1968 1874 INIT_WORK(&priv->reset_task, ftgmac100_reset_task); 1969 1875 1970 1876 /* map io memory */ 1971 - priv->res = request_mem_region(res->start, resource_size(res), 1972 - dev_name(&pdev->dev)); 1877 + priv->res = devm_request_mem_region(&pdev->dev, 1878 + res->start, resource_size(res), 1879 + dev_name(&pdev->dev)); 1973 1880 if (!priv->res) { 1974 1881 dev_err(&pdev->dev, "Could not reserve memory region\n"); 1975 - err = -ENOMEM; 1976 - goto err_req_mem; 1882 + return -ENOMEM; 1977 1883 } 1978 1884 1979 - priv->base = ioremap(res->start, resource_size(res)); 1885 + priv->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); 1980 1886 if (!priv->base) { 1981 1887 dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n"); 1982 - err = -EIO; 1983 - goto err_ioremap; 1888 + return -EIO; 1984 1889 } 1985 1890 1986 1891 netdev->irq = irq; ··· 1993 1898 /* MAC address from chip or random one */ 1994 1899 err = ftgmac100_initial_mac(priv); 1995 1900 if (err) 1996 - goto err_phy_connect; 1901 + return err; 1997 1902 1998 - np = pdev->dev.of_node; 1999 - if (np && (of_device_is_compatible(np, "aspeed,ast2400-mac") || 2000 - of_device_is_compatible(np, "aspeed,ast2500-mac") || 2001 - of_device_is_compatible(np, "aspeed,ast2600-mac"))) { 1903 + if (priv->mac_id == FTGMAC100_AST2400 || 1904 + priv->mac_id == FTGMAC100_AST2500 || 1905 + priv->mac_id == FTGMAC100_AST2600) { 2002 1906 priv->rxdes0_edorr_mask = BIT(30); 2003 1907 priv->txdes0_edotr_mask = BIT(30); 2004 1908 priv->is_aspeed = true; ··· 2006 1912 priv->txdes0_edotr_mask = BIT(15); 2007 1913 } 2008 1914 2009 - if (np && of_get_property(np, "use-ncsi", NULL)) { 2010 - if (!IS_ENABLED(CONFIG_NET_NCSI)) { 2011 - dev_err(&pdev->dev, "NCSI stack not enabled\n"); 2012 - err = -EINVAL; 2013 - goto err_phy_connect; 2014 - } 2015 - 2016 - dev_info(&pdev->dev, "Using NCSI interface\n"); 2017 - priv->use_ncsi = true; 2018 - priv->ndev = ncsi_register_dev(netdev, ftgmac100_ncsi_handler); 2019 - if (!priv->ndev) { 2020 - err = -EINVAL; 2021 - goto err_phy_connect; 2022 - } 2023 - 2024 - phydev = fixed_phy_register(&ncsi_phy_status, np); 2025 - if (IS_ERR(phydev)) { 2026 - dev_err(&pdev->dev, "failed to register fixed PHY device\n"); 2027 - err = PTR_ERR(phydev); 2028 - goto err_phy_connect; 2029 - } 2030 - err = phy_connect_direct(netdev, phydev, ftgmac100_adjust_link, 2031 - PHY_INTERFACE_MODE_RMII); 2032 - if (err) { 2033 - dev_err(&pdev->dev, "Connecting PHY failed\n"); 2034 - goto err_phy_connect; 2035 - } 2036 - } else if (np && (of_phy_is_fixed_link(np) || 2037 - of_get_property(np, "phy-handle", NULL))) { 2038 - struct phy_device *phy; 2039 - 2040 - /* Support "mdio"/"phy" child nodes for ast2400/2500 with 2041 - * an embedded MDIO controller. Automatically scan the DTS for 2042 - * available PHYs and register them. 2043 - */ 2044 - if (of_get_property(np, "phy-handle", NULL) && 2045 - (of_device_is_compatible(np, "aspeed,ast2400-mac") || 2046 - of_device_is_compatible(np, "aspeed,ast2500-mac"))) { 2047 - err = ftgmac100_setup_mdio(netdev); 2048 - if (err) 2049 - goto err_setup_mdio; 2050 - } 2051 - 2052 - phy = of_phy_get_and_connect(priv->netdev, np, 2053 - &ftgmac100_adjust_link); 2054 - if (!phy) { 2055 - dev_err(&pdev->dev, "Failed to connect to phy\n"); 2056 - err = -EINVAL; 2057 - goto err_phy_connect; 2058 - } 2059 - 2060 - /* Indicate that we support PAUSE frames (see comment in 2061 - * Documentation/networking/phy.rst) 2062 - */ 2063 - phy_support_asym_pause(phy); 2064 - 2065 - /* Display what we found */ 2066 - phy_attached_info(phy); 2067 - } else if (np && !ftgmac100_has_child_node(np, "mdio")) { 2068 - /* Support legacy ASPEED devicetree descriptions that decribe a 2069 - * MAC with an embedded MDIO controller but have no "mdio" 2070 - * child node. Automatically scan the MDIO bus for available 2071 - * PHYs. 2072 - */ 2073 - priv->use_ncsi = false; 1915 + if (priv->mac_id == FTGMAC100_FARADAY || 1916 + priv->mac_id == FTGMAC100_AST2400 || 1917 + priv->mac_id == FTGMAC100_AST2500) { 2074 1918 err = ftgmac100_setup_mdio(netdev); 2075 1919 if (err) 2076 - goto err_setup_mdio; 1920 + return err; 1921 + } 2077 1922 2078 - err = ftgmac100_mii_probe(netdev); 2079 - if (err) { 2080 - dev_err(priv->dev, "MII probe failed!\n"); 2081 - goto err_ncsi_dev; 2082 - } 2083 - 1923 + if (np) { 1924 + err = ftgmac100_probe_dt(netdev, pdev, priv, np); 1925 + if (err) 1926 + goto err; 2084 1927 } 2085 1928 2086 1929 priv->rst = devm_reset_control_get_optional_exclusive(priv->dev, NULL); 2087 1930 if (IS_ERR(priv->rst)) { 2088 1931 err = PTR_ERR(priv->rst); 2089 - goto err_phy_connect; 1932 + goto err; 2090 1933 } 2091 1934 2092 1935 if (priv->is_aspeed) { 2093 1936 err = ftgmac100_setup_clk(priv); 2094 1937 if (err) 2095 - goto err_phy_connect; 2096 - 2097 - /* Disable ast2600 problematic HW arbitration */ 2098 - if (of_device_is_compatible(np, "aspeed,ast2600-mac")) 2099 - iowrite32(FTGMAC100_TM_DEFAULT, 2100 - priv->base + FTGMAC100_OFFSET_TM); 1938 + goto err; 2101 1939 } 1940 + 1941 + /* Disable ast2600 problematic HW arbitration */ 1942 + if (priv->mac_id == FTGMAC100_AST2600) 1943 + iowrite32(FTGMAC100_TM_DEFAULT, 1944 + priv->base + FTGMAC100_OFFSET_TM); 2102 1945 2103 1946 /* Default ring sizes */ 2104 1947 priv->rx_q_entries = priv->new_rx_q_entries = DEF_RX_QUEUE_ENTRIES; ··· 2050 2019 netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; 2051 2020 2052 2021 /* AST2400 doesn't have working HW checksum generation */ 2053 - if (np && (of_device_is_compatible(np, "aspeed,ast2400-mac"))) 2022 + if (priv->mac_id == FTGMAC100_AST2400) 2054 2023 netdev->hw_features &= ~NETIF_F_HW_CSUM; 2055 2024 2056 2025 /* AST2600 tx checksum with NCSI is broken */ 2057 - if (priv->use_ncsi && of_device_is_compatible(np, "aspeed,ast2600-mac")) 2026 + if (priv->use_ncsi && priv->mac_id == FTGMAC100_AST2600) 2058 2027 netdev->hw_features &= ~NETIF_F_HW_CSUM; 2059 2028 2060 2029 if (np && of_get_property(np, "no-hw-checksum", NULL)) ··· 2065 2034 err = register_netdev(netdev); 2066 2035 if (err) { 2067 2036 dev_err(&pdev->dev, "Failed to register netdev\n"); 2068 - goto err_register_netdev; 2037 + goto err; 2069 2038 } 2070 2039 2071 2040 netdev_info(netdev, "irq %d, mapped at %p\n", netdev->irq, priv->base); 2072 2041 2073 2042 return 0; 2074 2043 2075 - err_register_netdev: 2076 - clk_disable_unprepare(priv->rclk); 2077 - clk_disable_unprepare(priv->clk); 2078 - err_phy_connect: 2044 + err: 2079 2045 ftgmac100_phy_disconnect(netdev); 2080 - err_ncsi_dev: 2081 2046 if (priv->ndev) 2082 2047 ncsi_unregister_dev(priv->ndev); 2083 - ftgmac100_destroy_mdio(netdev); 2084 - err_setup_mdio: 2085 - iounmap(priv->base); 2086 - err_ioremap: 2087 - release_resource(priv->res); 2088 - err_req_mem: 2089 - free_netdev(netdev); 2090 - err_alloc_etherdev: 2091 2048 return err; 2092 2049 } 2093 2050 ··· 2091 2072 ncsi_unregister_dev(priv->ndev); 2092 2073 unregister_netdev(netdev); 2093 2074 2094 - clk_disable_unprepare(priv->rclk); 2095 - clk_disable_unprepare(priv->clk); 2096 - 2097 2075 /* There's a small chance the reset task will have been re-queued, 2098 2076 * during stop, make sure it's gone before we free the structure. 2099 2077 */ 2100 2078 cancel_work_sync(&priv->reset_task); 2101 2079 2102 2080 ftgmac100_phy_disconnect(netdev); 2103 - ftgmac100_destroy_mdio(netdev); 2104 - 2105 - iounmap(priv->base); 2106 - release_resource(priv->res); 2107 - 2108 - netif_napi_del(&priv->napi); 2109 - free_netdev(netdev); 2110 2081 } 2111 2082 2083 + static const struct ftgmac100_match_data ftgmac100_match_data_ast2400 = { 2084 + .mac_id = FTGMAC100_AST2400 2085 + }; 2086 + 2087 + static const struct ftgmac100_match_data ftgmac100_match_data_ast2500 = { 2088 + .mac_id = FTGMAC100_AST2500 2089 + }; 2090 + 2091 + static const struct ftgmac100_match_data ftgmac100_match_data_ast2600 = { 2092 + .mac_id = FTGMAC100_AST2600 2093 + }; 2094 + 2095 + static const struct ftgmac100_match_data ftgmac100_match_data_faraday = { 2096 + .mac_id = FTGMAC100_FARADAY 2097 + }; 2098 + 2112 2099 static const struct of_device_id ftgmac100_of_match[] = { 2113 - { .compatible = "faraday,ftgmac100" }, 2100 + { .compatible = "aspeed,ast2400-mac", 2101 + .data = &ftgmac100_match_data_ast2400}, 2102 + { .compatible = "aspeed,ast2500-mac", 2103 + .data = &ftgmac100_match_data_ast2500 }, 2104 + { .compatible = "aspeed,ast2600-mac", 2105 + .data = &ftgmac100_match_data_ast2600 }, 2106 + { .compatible = "faraday,ftgmac100", 2107 + .data = &ftgmac100_match_data_faraday }, 2114 2108 { } 2115 2109 }; 2116 2110 MODULE_DEVICE_TABLE(of, ftgmac100_of_match);