Merge tag 'docs-5.5a' of git://git.lwn.net/linux
[sfrench/cifs-2.6.git] / drivers / net / ethernet / faraday / ftgmac100.c
index 8abe5e90d268341ddb5b70a4aaf3512698f7445d..8ed85037f0217c516de2910af3a98b0b475f4c1b 100644 (file)
@@ -90,6 +90,9 @@ struct ftgmac100 {
        struct mii_bus *mii_bus;
        struct clk *clk;
 
+       /* AST2500/AST2600 RMII ref clock gate */
+       struct clk *rclk;
+
        /* Link management */
        int cur_speed;
        int cur_duplex;
@@ -727,6 +730,18 @@ static netdev_tx_t ftgmac100_hard_start_xmit(struct sk_buff *skb,
         */
        nfrags = skb_shinfo(skb)->nr_frags;
 
+       /* Setup HW checksumming */
+       csum_vlan = 0;
+       if (skb->ip_summed == CHECKSUM_PARTIAL &&
+           !ftgmac100_prep_tx_csum(skb, &csum_vlan))
+               goto drop;
+
+       /* Add VLAN tag */
+       if (skb_vlan_tag_present(skb)) {
+               csum_vlan |= FTGMAC100_TXDES1_INS_VLANTAG;
+               csum_vlan |= skb_vlan_tag_get(skb) & 0xffff;
+       }
+
        /* Get header len */
        len = skb_headlen(skb);
 
@@ -753,19 +768,6 @@ static netdev_tx_t ftgmac100_hard_start_xmit(struct sk_buff *skb,
        if (nfrags == 0)
                f_ctl_stat |= FTGMAC100_TXDES0_LTS;
        txdes->txdes3 = cpu_to_le32(map);
-
-       /* Setup HW checksumming */
-       csum_vlan = 0;
-       if (skb->ip_summed == CHECKSUM_PARTIAL &&
-           !ftgmac100_prep_tx_csum(skb, &csum_vlan))
-               goto drop;
-
-       /* Add VLAN tag */
-       if (skb_vlan_tag_present(skb)) {
-               csum_vlan |= FTGMAC100_TXDES1_INS_VLANTAG;
-               csum_vlan |= skb_vlan_tag_get(skb) & 0xffff;
-       }
-
        txdes->txdes1 = cpu_to_le32(csum_vlan);
 
        /* Next descriptor */
@@ -1610,7 +1612,7 @@ static int ftgmac100_setup_mdio(struct net_device *netdev)
 {
        struct ftgmac100 *priv = netdev_priv(netdev);
        struct platform_device *pdev = to_platform_device(priv->dev);
-       int phy_intf = PHY_INTERFACE_MODE_RGMII;
+       phy_interface_t phy_intf = PHY_INTERFACE_MODE_RGMII;
        struct device_node *np = pdev->dev.of_node;
        int i, err = 0;
        u32 reg;
@@ -1635,8 +1637,8 @@ static int ftgmac100_setup_mdio(struct net_device *netdev)
        /* Get PHY mode from device-tree */
        if (np) {
                /* Default to RGMII. It's a gigabit part after all */
-               phy_intf = of_get_phy_mode(np);
-               if (phy_intf < 0)
+               err = of_get_phy_mode(np, &phy_intf);
+               if (err)
                        phy_intf = PHY_INTERFACE_MODE_RGMII;
 
                /* Aspeed only supports these. I don't know about other IP
@@ -1718,20 +1720,41 @@ static void ftgmac100_ncsi_handler(struct ncsi_dev *nd)
                   nd->link_up ? "up" : "down");
 }
 
-static void ftgmac100_setup_clk(struct ftgmac100 *priv)
+static int ftgmac100_setup_clk(struct ftgmac100 *priv)
 {
-       priv->clk = devm_clk_get(priv->dev, NULL);
-       if (IS_ERR(priv->clk))
-               return;
+       struct clk *clk;
+       int rc;
 
-       clk_prepare_enable(priv->clk);
+       clk = devm_clk_get(priv->dev, NULL /* MACCLK */);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+       priv->clk = clk;
+       rc = clk_prepare_enable(priv->clk);
+       if (rc)
+               return rc;
 
        /* Aspeed specifies a 100MHz clock is required for up to
         * 1000Mbit link speeds. As NCSI is limited to 100Mbit, 25MHz
         * is sufficient
         */
-       clk_set_rate(priv->clk, priv->use_ncsi ? FTGMAC_25MHZ :
-                       FTGMAC_100MHZ);
+       rc = clk_set_rate(priv->clk, priv->use_ncsi ? FTGMAC_25MHZ :
+                         FTGMAC_100MHZ);
+       if (rc)
+               goto cleanup_clk;
+
+       /* RCLK is for RMII, typically used for NCSI. Optional because its not
+        * necessary if it's the AST2400 MAC, or the MAC is configured for
+        * RGMII, or the controller is not an ASPEED-based controller.
+        */
+       priv->rclk = devm_clk_get_optional(priv->dev, "RCLK");
+       rc = clk_prepare_enable(priv->rclk);
+       if (!rc)
+               return 0;
+
+cleanup_clk:
+       clk_disable_unprepare(priv->clk);
+
+       return rc;
 }
 
 static int ftgmac100_probe(struct platform_device *pdev)
@@ -1853,8 +1876,11 @@ static int ftgmac100_probe(struct platform_device *pdev)
                        goto err_setup_mdio;
        }
 
-       if (priv->is_aspeed)
-               ftgmac100_setup_clk(priv);
+       if (priv->is_aspeed) {
+               err = ftgmac100_setup_clk(priv);
+               if (err)
+                       goto err_ncsi_dev;
+       }
 
        /* Default ring sizes */
        priv->rx_q_entries = priv->new_rx_q_entries = DEF_RX_QUEUE_ENTRIES;
@@ -1886,8 +1912,10 @@ static int ftgmac100_probe(struct platform_device *pdev)
 
        return 0;
 
-err_ncsi_dev:
 err_register_netdev:
+       clk_disable_unprepare(priv->rclk);
+       clk_disable_unprepare(priv->clk);
+err_ncsi_dev:
        ftgmac100_destroy_mdio(netdev);
 err_setup_mdio:
        iounmap(priv->base);
@@ -1909,6 +1937,7 @@ static int ftgmac100_remove(struct platform_device *pdev)
 
        unregister_netdev(netdev);
 
+       clk_disable_unprepare(priv->rclk);
        clk_disable_unprepare(priv->clk);
 
        /* There's a small chance the reset task will have been re-queued,