From e98233a6192d75d695b0972dc955d6561e46964f Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 18 Apr 2017 08:36:58 +1000 Subject: [PATCH 1/9] ftgmac100: Add ethtool n-way reset call A non-wired up implementation accidentally made its way in a previous patch (Make ring sizes configurable via ethtool). This removes it and wires up the generic phy_ethtool_nway_reset instead. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: David S. Miller --- drivers/net/ethernet/faraday/ftgmac100.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 2153c5bbdd12..4cdd25a5742d 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -1045,13 +1045,6 @@ static void ftgmac100_get_drvinfo(struct net_device *netdev, strlcpy(info->bus_info, dev_name(&netdev->dev), sizeof(info->bus_info)); } -static int ftgmac100_nway_reset(struct net_device *ndev) -{ - if (!ndev->phydev) - return -ENXIO; - return phy_start_aneg(ndev->phydev); -} - static void ftgmac100_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ering) { @@ -1090,6 +1083,7 @@ static const struct ethtool_ops ftgmac100_ethtool_ops = { .get_link = ethtool_op_get_link, .get_link_ksettings = phy_ethtool_get_link_ksettings, .set_link_ksettings = phy_ethtool_set_link_ksettings, + .nway_reset = phy_ethtool_nway_reset, .get_ringparam = ftgmac100_get_ringparam, .set_ringparam = ftgmac100_set_ringparam, }; From 7c8e5141ca633ae6dc7489dc85cabcfed2144a2d Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 18 Apr 2017 08:36:59 +1000 Subject: [PATCH 2/9] ftgmac100: Add pause frames configuration and support Hopefully my understanding of how the hardware works is correct, as the documentation isn't completely clear. So far I have seen no obvious issue. Pause seem to also work with NC-SI. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: David S. Miller --- drivers/net/ethernet/faraday/ftgmac100.c | 96 +++++++++++++++++++++++- drivers/net/ethernet/faraday/ftgmac100.h | 7 ++ 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 4cdd25a5742d..949b48c0eae6 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -99,6 +99,11 @@ struct ftgmac100 { int cur_duplex; bool use_ncsi; + /* Flow control settings */ + bool tx_pause; + bool rx_pause; + bool aneg_pause; + /* Misc */ bool need_mac_restart; bool is_aspeed; @@ -219,6 +224,23 @@ static int ftgmac100_set_mac_addr(struct net_device *dev, void *p) return 0; } +static void ftgmac100_config_pause(struct ftgmac100 *priv) +{ + u32 fcr = FTGMAC100_FCR_PAUSE_TIME(16); + + /* Throttle tx queue when receiving pause frames */ + if (priv->rx_pause) + fcr |= FTGMAC100_FCR_FC_EN; + + /* Enables sending pause frames when the RX queue is past a + * certain threshold. + */ + if (priv->tx_pause) + fcr |= FTGMAC100_FCR_FCTHR_EN; + + iowrite32(fcr, priv->base + FTGMAC100_OFFSET_FCR); +} + static void ftgmac100_init_hw(struct ftgmac100 *priv) { u32 reg, rfifo_sz, tfifo_sz; @@ -912,6 +934,7 @@ static void ftgmac100_adjust_link(struct net_device *netdev) { struct ftgmac100 *priv = netdev_priv(netdev); struct phy_device *phydev = netdev->phydev; + bool tx_pause, rx_pause; int new_speed; /* We store "no link" as speed 0 */ @@ -920,8 +943,21 @@ static void ftgmac100_adjust_link(struct net_device *netdev) else new_speed = phydev->speed; + /* Grab pause settings from PHY if configured to do so */ + if (priv->aneg_pause) { + rx_pause = tx_pause = phydev->pause; + if (phydev->asym_pause) + tx_pause = !rx_pause; + } else { + rx_pause = priv->rx_pause; + tx_pause = priv->tx_pause; + } + + /* Link hasn't changed, do nothing */ if (phydev->speed == priv->cur_speed && - phydev->duplex == priv->cur_duplex) + phydev->duplex == priv->cur_duplex && + rx_pause == priv->rx_pause && + tx_pause == priv->tx_pause) return; /* Print status if we have a link or we had one and just lost it, @@ -932,6 +968,8 @@ static void ftgmac100_adjust_link(struct net_device *netdev) priv->cur_speed = new_speed; priv->cur_duplex = phydev->duplex; + priv->rx_pause = rx_pause; + priv->tx_pause = tx_pause; /* Link is down, do nothing else */ if (!new_speed) @@ -963,6 +1001,12 @@ static int ftgmac100_mii_probe(struct ftgmac100 *priv) return PTR_ERR(phydev); } + /* Indicate that we support PAUSE frames (see comment in + * Documentation/networking/phy.txt) + */ + phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; + phydev->advertising = phydev->supported; + return 0; } @@ -1078,6 +1122,48 @@ static int ftgmac100_set_ringparam(struct net_device *netdev, return 0; } +static void ftgmac100_get_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct ftgmac100 *priv = netdev_priv(netdev); + + pause->autoneg = priv->aneg_pause; + pause->tx_pause = priv->tx_pause; + pause->rx_pause = priv->rx_pause; +} + +static int ftgmac100_set_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct ftgmac100 *priv = netdev_priv(netdev); + struct phy_device *phydev = netdev->phydev; + + priv->aneg_pause = pause->autoneg; + priv->tx_pause = pause->tx_pause; + priv->rx_pause = pause->rx_pause; + + if (phydev) { + phydev->advertising &= ~ADVERTISED_Pause; + phydev->advertising &= ~ADVERTISED_Asym_Pause; + + if (pause->rx_pause) { + phydev->advertising |= ADVERTISED_Pause; + phydev->advertising |= ADVERTISED_Asym_Pause; + } + + if (pause->tx_pause) + phydev->advertising ^= ADVERTISED_Asym_Pause; + } + if (netif_running(netdev)) { + if (phydev && priv->aneg_pause) + phy_start_aneg(phydev); + else + ftgmac100_config_pause(priv); + } + + return 0; +} + static const struct ethtool_ops ftgmac100_ethtool_ops = { .get_drvinfo = ftgmac100_get_drvinfo, .get_link = ethtool_op_get_link, @@ -1086,6 +1172,8 @@ static const struct ethtool_ops ftgmac100_ethtool_ops = { .nway_reset = phy_ethtool_nway_reset, .get_ringparam = ftgmac100_get_ringparam, .set_ringparam = ftgmac100_set_ringparam, + .get_pauseparam = ftgmac100_get_pauseparam, + .set_pauseparam = ftgmac100_set_pauseparam, }; static irqreturn_t ftgmac100_interrupt(int irq, void *dev_id) @@ -1217,6 +1305,7 @@ static int ftgmac100_init_all(struct ftgmac100 *priv, bool ignore_alloc_err) /* Reinit and restart HW */ ftgmac100_init_hw(priv); + ftgmac100_config_pause(priv); ftgmac100_start_hw(priv); /* Re-enable the device */ @@ -1546,6 +1635,11 @@ static int ftgmac100_probe(struct platform_device *pdev) netdev->irq = irq; + /* Enable pause */ + priv->tx_pause = true; + priv->rx_pause = true; + priv->aneg_pause = true; + /* MAC address from chip or random one */ ftgmac100_initial_mac(priv); diff --git a/drivers/net/ethernet/faraday/ftgmac100.h b/drivers/net/ethernet/faraday/ftgmac100.h index 97912c456e80..0653d8176e6a 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.h +++ b/drivers/net/ethernet/faraday/ftgmac100.h @@ -198,6 +198,13 @@ #define FTGMAC100_PHYDATA_MIIWDATA(x) ((x) & 0xffff) #define FTGMAC100_PHYDATA_MIIRDATA(phydata) (((phydata) >> 16) & 0xffff) +/* + * Flow control register + */ +#define FTGMAC100_FCR_FC_EN (1 << 0) +#define FTGMAC100_FCR_FCTHR_EN (1 << 2) +#define FTGMAC100_FCR_PAUSE_TIME(x) (((x) & 0xffff) << 16) + /* * Transmit descriptor, aligned to 16 bytes */ From f48b3c0d5b6ab4d88db75e45e1ea38074e2765c9 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 18 Apr 2017 08:37:00 +1000 Subject: [PATCH 3/9] ftgmac100: Add ndo_set_rx_mode() and support for multicast & promisc This adds the ndo_set_rx_mode() callback to configure the multicast filters, promisc and allmulti options. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: David S. Miller --- drivers/net/ethernet/faraday/ftgmac100.c | 52 ++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 949b48c0eae6..f4db6e21f5df 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -99,6 +100,10 @@ struct ftgmac100 { int cur_duplex; bool use_ncsi; + /* Multicast filter settings */ + u32 maht0; + u32 maht1; + /* Flow control settings */ bool tx_pause; bool rx_pause; @@ -266,6 +271,10 @@ static void ftgmac100_init_hw(struct ftgmac100 *priv) /* Write MAC address */ ftgmac100_write_mac_addr(priv, priv->netdev->dev_addr); + /* Write multicast filter */ + iowrite32(priv->maht0, priv->base + FTGMAC100_OFFSET_MAHT0); + iowrite32(priv->maht1, priv->base + FTGMAC100_OFFSET_MAHT1); + /* Configure descriptor sizes and increase burst sizes according * to values in Aspeed SDK. The FIFO arbitration is enabled and * the thresholds set based on the recommended values in the @@ -319,6 +328,12 @@ static void ftgmac100_start_hw(struct ftgmac100 *priv) /* Add other bits as needed */ if (priv->cur_duplex == DUPLEX_FULL) maccr |= FTGMAC100_MACCR_FULLDUP; + if (priv->netdev->flags & IFF_PROMISC) + maccr |= FTGMAC100_MACCR_RX_ALL; + if (priv->netdev->flags & IFF_ALLMULTI) + maccr |= FTGMAC100_MACCR_RX_MULTIPKT; + else if (netdev_mc_count(priv->netdev)) + maccr |= FTGMAC100_MACCR_HT_MULTI_EN; /* Hit the HW */ iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); @@ -329,6 +344,42 @@ static void ftgmac100_stop_hw(struct ftgmac100 *priv) iowrite32(0, priv->base + FTGMAC100_OFFSET_MACCR); } +static void ftgmac100_calc_mc_hash(struct ftgmac100 *priv) +{ + struct netdev_hw_addr *ha; + + priv->maht1 = 0; + priv->maht0 = 0; + netdev_for_each_mc_addr(ha, priv->netdev) { + u32 crc_val = ether_crc_le(ETH_ALEN, ha->addr); + + crc_val = (~(crc_val >> 2)) & 0x3f; + if (crc_val >= 32) + priv->maht1 |= 1ul << (crc_val - 32); + else + priv->maht0 |= 1ul << (crc_val); + } +} + +static void ftgmac100_set_rx_mode(struct net_device *netdev) +{ + struct ftgmac100 *priv = netdev_priv(netdev); + + /* Setup the hash filter */ + ftgmac100_calc_mc_hash(priv); + + /* Interface down ? that's all there is to do */ + if (!netif_running(netdev)) + return; + + /* Update the HW */ + iowrite32(priv->maht0, priv->base + FTGMAC100_OFFSET_MAHT0); + iowrite32(priv->maht1, priv->base + FTGMAC100_OFFSET_MAHT1); + + /* Reconfigure MACCR */ + ftgmac100_start_hw(priv); +} + static int ftgmac100_alloc_rx_buf(struct ftgmac100 *priv, unsigned int entry, struct ftgmac100_rxdes *rxdes, gfp_t gfp) { @@ -1503,6 +1554,7 @@ static const struct net_device_ops ftgmac100_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = ftgmac100_do_ioctl, .ndo_tx_timeout = ftgmac100_tx_timeout, + .ndo_set_rx_mode = ftgmac100_set_rx_mode, }; static int ftgmac100_setup_mdio(struct net_device *netdev) From 0fb9968876c386697170bc468633f4a9e2041a91 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 18 Apr 2017 08:37:01 +1000 Subject: [PATCH 4/9] ftgmac100: Add vlan HW offload The chip supports HW vlan tag insertion and extraction. Add support for it. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: David S. Miller --- drivers/net/ethernet/faraday/ftgmac100.c | 46 +++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index f4db6e21f5df..40a03d53432c 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -335,6 +336,10 @@ static void ftgmac100_start_hw(struct ftgmac100 *priv) else if (netdev_mc_count(priv->netdev)) maccr |= FTGMAC100_MACCR_HT_MULTI_EN; + /* Vlan filtering enabled */ + if (priv->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) + maccr |= FTGMAC100_MACCR_RM_VLAN; + /* Hit the HW */ iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); } @@ -530,6 +535,12 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed) /* Transfer received size to skb */ skb_put(skb, size); + /* Extract vlan tag */ + if ((netdev->features & NETIF_F_HW_VLAN_CTAG_RX) && + (csum_vlan & FTGMAC100_RXDES1_VLANTAG_AVAIL)) + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), + csum_vlan & 0xffff); + /* Tear down DMA mapping, do necessary cache management */ map = le32_to_cpu(rxdes->rxdes3); @@ -754,6 +765,13 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb, 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 */ @@ -1546,6 +1564,30 @@ static void ftgmac100_tx_timeout(struct net_device *netdev) schedule_work(&priv->reset_task); } +static int ftgmac100_set_features(struct net_device *netdev, + netdev_features_t features) +{ + struct ftgmac100 *priv = netdev_priv(netdev); + netdev_features_t changed = netdev->features ^ features; + + if (!netif_running(netdev)) + return 0; + + /* Update the vlan filtering bit */ + if (changed & NETIF_F_HW_VLAN_CTAG_RX) { + u32 maccr; + + maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR); + if (priv->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) + maccr |= FTGMAC100_MACCR_RM_VLAN; + else + maccr &= ~FTGMAC100_MACCR_RM_VLAN; + iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); + } + + return 0; +} + static const struct net_device_ops ftgmac100_netdev_ops = { .ndo_open = ftgmac100_open, .ndo_stop = ftgmac100_stop, @@ -1555,6 +1597,7 @@ static const struct net_device_ops ftgmac100_netdev_ops = { .ndo_do_ioctl = ftgmac100_do_ioctl, .ndo_tx_timeout = ftgmac100_tx_timeout, .ndo_set_rx_mode = ftgmac100_set_rx_mode, + .ndo_set_features = ftgmac100_set_features, }; static int ftgmac100_setup_mdio(struct net_device *netdev) @@ -1730,7 +1773,8 @@ static int ftgmac100_probe(struct platform_device *pdev) /* Base feature set */ netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM | - NETIF_F_GRO | NETIF_F_SG; + NETIF_F_GRO | NETIF_F_SG | NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_CTAG_TX; /* AST2400 doesn't have working HW checksum generation */ if (np && (of_device_is_compatible(np, "aspeed,ast2400-mac"))) From 030d9828703ec7ecc09d09d39fb68b72f45b05e7 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 18 Apr 2017 08:37:02 +1000 Subject: [PATCH 5/9] ftgmac100: Add netpoll support Just call the interrupt handler with interrupts locally disabled Signed-off-by: Benjamin Herrenschmidt Signed-off-by: David S. Miller --- drivers/net/ethernet/faraday/ftgmac100.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 40a03d53432c..f76765e0b243 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -1588,6 +1588,17 @@ static int ftgmac100_set_features(struct net_device *netdev, return 0; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void ftgmac100_poll_controller(struct net_device *netdev) +{ + unsigned long flags; + + local_irq_save(flags); + ftgmac100_interrupt(netdev->irq, netdev); + local_irq_restore(flags); +} +#endif + static const struct net_device_ops ftgmac100_netdev_ops = { .ndo_open = ftgmac100_open, .ndo_stop = ftgmac100_stop, @@ -1598,6 +1609,9 @@ static const struct net_device_ops ftgmac100_netdev_ops = { .ndo_tx_timeout = ftgmac100_tx_timeout, .ndo_set_rx_mode = ftgmac100_set_rx_mode, .ndo_set_features = ftgmac100_set_features, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = ftgmac100_poll_controller, +#endif }; static int ftgmac100_setup_mdio(struct net_device *netdev) From abcc3eb00e10af3a0c5df90ce515ebde5fc12319 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 18 Apr 2017 08:37:03 +1000 Subject: [PATCH 6/9] ftgmac100: Allow configuration of phy interface via device-tree This uses the standard phy-mode property Signed-off-by: Benjamin Herrenschmidt Signed-off-by: David S. Miller --- drivers/net/ethernet/faraday/ftgmac100.c | 42 ++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index f76765e0b243..7721c2ab24ef 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -1051,7 +1052,7 @@ static void ftgmac100_adjust_link(struct net_device *netdev) schedule_work(&priv->reset_task); } -static int ftgmac100_mii_probe(struct ftgmac100 *priv) +static int ftgmac100_mii_probe(struct ftgmac100 *priv, phy_interface_t intf) { struct net_device *netdev = priv->netdev; struct phy_device *phydev; @@ -1063,7 +1064,7 @@ static int ftgmac100_mii_probe(struct ftgmac100 *priv) } phydev = phy_connect(netdev, phydev_name(phydev), - &ftgmac100_adjust_link, PHY_INTERFACE_MODE_GMII); + &ftgmac100_adjust_link, intf); if (IS_ERR(phydev)) { netdev_err(netdev, "%s: Could not attach to PHY\n", netdev->name); @@ -1618,6 +1619,8 @@ 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; + struct device_node *np = pdev->dev.of_node; int i, err = 0; u32 reg; @@ -1633,6 +1636,39 @@ static int ftgmac100_setup_mdio(struct net_device *netdev) iowrite32(reg, priv->base + FTGMAC100_OFFSET_REVR); }; + /* 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) + phy_intf = PHY_INTERFACE_MODE_RGMII; + + /* Aspeed only supports these. I don't know about other IP + * block vendors so I'm going to just let them through for + * now. Note that this is only a warning if for some obscure + * reason the DT really means to lie about it or it's a newer + * part we don't know about. + * + * On the Aspeed SoC there are additionally straps and SCU + * control bits that could tell us what the interface is + * (or allow us to configure it while the IP block is held + * in reset). For now I chose to keep this driver away from + * those SoC specific bits and assume the device-tree is + * right and the SCU has been configured properly by pinmux + * or the firmware. + */ + if (priv->is_aspeed && + phy_intf != PHY_INTERFACE_MODE_RMII && + phy_intf != PHY_INTERFACE_MODE_RGMII && + phy_intf != PHY_INTERFACE_MODE_RGMII_ID && + phy_intf != PHY_INTERFACE_MODE_RGMII_RXID && + phy_intf != PHY_INTERFACE_MODE_RGMII_TXID) { + netdev_warn(netdev, + "Unsupported PHY mode %s !\n", + phy_modes(phy_intf)); + } + } + priv->mii_bus->name = "ftgmac100_mdio"; snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%d", pdev->name, pdev->id); @@ -1649,7 +1685,7 @@ static int ftgmac100_setup_mdio(struct net_device *netdev) goto err_register_mdiobus; } - err = ftgmac100_mii_probe(priv); + err = ftgmac100_mii_probe(priv, phy_intf); if (err) { dev_err(priv->dev, "MII Probe failed!\n"); goto err_mii_probe; From 33de693248b45640c0d894c2454a9909f2e81ffd Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 18 Apr 2017 08:37:04 +1000 Subject: [PATCH 7/9] ftgmac100: Display the discovered PHY device info Signed-off-by: Benjamin Herrenschmidt Signed-off-by: David S. Miller --- drivers/net/ethernet/faraday/ftgmac100.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 7721c2ab24ef..45b8267b81b7 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -1077,6 +1077,9 @@ static int ftgmac100_mii_probe(struct ftgmac100 *priv, phy_interface_t intf) phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; phydev->advertising = phydev->supported; + /* Display what we found */ + phy_attached_info(phydev); + return 0; } From ccaf725a1fd7904ed3e771ed178c2aa1ccb21509 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 18 Apr 2017 08:37:05 +1000 Subject: [PATCH 8/9] ftgmac100: Fix potential ordering issue in NAPI poll We need to ensure the loads from the descriptor are done after the MMIO store clearing the interrupts has completed, otherwise we might still miss work. A read back from the MMIO register will "push" the posted store and ioread32 has a barrier on weakly aordered architectures that will order subsequent accesses. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: David S. Miller --- drivers/net/ethernet/faraday/ftgmac100.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 45b8267b81b7..95bf5e89cfd1 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -1349,6 +1349,13 @@ static int ftgmac100_poll(struct napi_struct *napi, int budget) */ iowrite32(FTGMAC100_INT_RXTX, priv->base + FTGMAC100_OFFSET_ISR); + + /* Push the above (and provides a barrier vs. subsequent + * reads of the descriptor). + */ + ioread32(priv->base + FTGMAC100_OFFSET_ISR); + + /* Check RX and TX descriptors for more work to do */ if (ftgmac100_check_rx(priv) || ftgmac100_tx_buf_cleanable(priv)) return budget; From 88a286f7e9df643e211debe55a7aa206d2332763 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 18 Apr 2017 08:37:06 +1000 Subject: [PATCH 9/9] ftgmac100: Document device-tree binding Signed-off-by: Benjamin Herrenschmidt Signed-off-by: David S. Miller --- .../devicetree/bindings/net/ftgmac100.txt | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/ftgmac100.txt diff --git a/Documentation/devicetree/bindings/net/ftgmac100.txt b/Documentation/devicetree/bindings/net/ftgmac100.txt new file mode 100644 index 000000000000..c1ce1680246f --- /dev/null +++ b/Documentation/devicetree/bindings/net/ftgmac100.txt @@ -0,0 +1,35 @@ +* Faraday Technology FTGMAC100 gigabit ethernet controller + +Required properties: +- compatible: "faraday,ftgmac100" + + Must also contain one of these if used as part of an Aspeed AST2400 + or 2500 family SoC as they have some subtle tweaks to the + implementation: + + - "aspeed,ast2400-mac" + - "aspeed,ast2500-mac" + +- reg: Address and length of the register set for the device +- interrupts: Should contain ethernet controller interrupt + +Optional properties: +- phy-mode: See ethernet.txt file in the same directory. If the property is + absent, "rgmii" is assumed. Supported values are "rgmii*" and "rmii" for + aspeed parts. Other (unknown) parts will accept any value. +- use-ncsi: Use the NC-SI stack instead of an MDIO PHY. Currently assumes + rmii (100bT) but kept as a separate property in case NC-SI grows support + for a gigabit link. +- no-hw-checksum: Used to disable HW checksum support. Here for backward + compatibility as the driver now should have correct defaults based on + the SoC. + +Example: + + mac0: ethernet@1e660000 { + compatible = "aspeed,ast2500-mac", "faraday,ftgmac100"; + reg = <0x1e660000 0x180>; + interrupts = <2>; + status = "okay"; + use-ncsi; + };