diff options
Diffstat (limited to 'drivers/net/ethernet/faraday/ftgmac100.c')
-rw-r--r-- | drivers/net/ethernet/faraday/ftgmac100.c | 81 |
1 files changed, 55 insertions, 26 deletions
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 9b7af94a40bb..a6f2063f1475 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -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, |