]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
net: stmmac: Fix reception of Broadcom switches tags
authorFlorian Fainelli <f.fainelli@gmail.com>
Thu, 18 Jan 2018 23:12:21 +0000 (15:12 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 22 Jan 2018 21:12:11 +0000 (16:12 -0500)
Broadcom tags inserted by Broadcom switches put a 4 byte header after
the MAC SA and before the EtherType, which may look like some sort of 0
length LLC/SNAP packet (tcpdump and wireshark do think that way). With
ACS enabled in stmmac the packets were truncated to 8 bytes on
reception, whereas clearing this bit allowed normal reception to occur.

In order to make that possible, we need to pass a net_device argument to
the different core_init() functions and we are dependent on the Broadcom
tagger padding packets correctly (which it now does). To be as little
invasive as possible, this is only done for gmac1000 when the network
device is DSA-enabled (netdev_uses_dsa() returns true).

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

index ce2ea2d491acac195eefe3f01f8ec9df08d3e77c..2ffe76c0ff74256b78253287113e1a08d8c3d476 100644 (file)
@@ -474,7 +474,7 @@ struct mac_device_info;
 /* Helpers to program the MAC core */
 struct stmmac_ops {
        /* MAC core initialization */
-       void (*core_init)(struct mac_device_info *hw, int mtu);
+       void (*core_init)(struct mac_device_info *hw, struct net_device *dev);
        /* Enable the MAC RX/TX */
        void (*set_mac)(void __iomem *ioaddr, bool enable);
        /* Enable and verify that the IPC module is supported */
index 9eb7f65d8000d28190da780587dba562aed72152..a3fa65b1ca8e5f9c45416b3b114128ead5166ca3 100644 (file)
@@ -483,7 +483,8 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
        return 0;
 }
 
-static void sun8i_dwmac_core_init(struct mac_device_info *hw, int mtu)
+static void sun8i_dwmac_core_init(struct mac_device_info *hw,
+                                 struct net_device *dev)
 {
        void __iomem *ioaddr = hw->pcsr;
        u32 v;
index 8a86340ff2d348ebbaabe29f73b51a67060542fe..540d21786a43b885fc98f2d5282538bf20792bfe 100644 (file)
 #include <linux/crc32.h>
 #include <linux/slab.h>
 #include <linux/ethtool.h>
+#include <net/dsa.h>
 #include <asm/io.h>
 #include "stmmac_pcs.h"
 #include "dwmac1000.h"
 
-static void dwmac1000_core_init(struct mac_device_info *hw, int mtu)
+static void dwmac1000_core_init(struct mac_device_info *hw,
+                               struct net_device *dev)
 {
        void __iomem *ioaddr = hw->pcsr;
        u32 value = readl(ioaddr + GMAC_CONTROL);
+       int mtu = dev->mtu;
 
        /* Configure GMAC core */
        value |= GMAC_CORE_INIT;
 
+       /* Clear ACS bit because Ethernet switch tagging formats such as
+        * Broadcom tags can look like invalid LLC/SNAP packets and cause the
+        * hardware to truncate packets on reception.
+        */
+       if (netdev_uses_dsa(dev))
+               value &= ~GMAC_CONTROL_ACS;
+
        if (mtu > 1500)
                value |= GMAC_CONTROL_2K;
        if (mtu > 2000)
index 8ef5173563134235903350167ca9d16b366881af..91b23f9db31ade76c05a6a7a638d41506ed9c93d 100644 (file)
 *******************************************************************************/
 
 #include <linux/crc32.h>
+#include <net/dsa.h>
 #include <asm/io.h>
 #include "dwmac100.h"
 
-static void dwmac100_core_init(struct mac_device_info *hw, int mtu)
+static void dwmac100_core_init(struct mac_device_info *hw,
+                              struct net_device *dev)
 {
        void __iomem *ioaddr = hw->pcsr;
        u32 value = readl(ioaddr + MAC_CONTROL);
 
-       writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
+       value |= MAC_CORE_INIT;
+
+       /* Clear ASTP bit because Ethernet switch tagging formats such as
+        * Broadcom tags can look like invalid LLC/SNAP packets and cause the
+        * hardware to truncate packets on reception.
+        */
+       if (netdev_uses_dsa(dev))
+               value &= ~MAC_CONTROL_ASTP;
+
+       writel(value, ioaddr + MAC_CONTROL);
 
 #ifdef STMMAC_VLAN_TAG_USED
        writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
index f3ed8f7853eb4f0908718dd03eca2f9dc7dad350..ed222b20fcf19795ef8cdc1bc95cec8b8ed4f0f9 100644 (file)
 #include <linux/slab.h>
 #include <linux/ethtool.h>
 #include <linux/io.h>
+#include <net/dsa.h>
 #include "stmmac_pcs.h"
 #include "dwmac4.h"
 
-static void dwmac4_core_init(struct mac_device_info *hw, int mtu)
+static void dwmac4_core_init(struct mac_device_info *hw,
+                            struct net_device *dev)
 {
        void __iomem *ioaddr = hw->pcsr;
        u32 value = readl(ioaddr + GMAC_CONFIG);
+       int mtu = dev->mtu;
 
        value |= GMAC_CORE_INIT;
 
+       /* Clear ACS bit because Ethernet switch tagging formats such as
+        * Broadcom tags can look like invalid LLC/SNAP packets and cause the
+        * hardware to truncate packets on reception.
+        */
+       if (netdev_uses_dsa(dev))
+               value &= ~GMAC_CONFIG_ACS;
+
        if (mtu > 1500)
                value |= GMAC_CONFIG_2K;
        if (mtu > 2000)
index f99f14c35063d40cfd28ab11254d3042e1dd6c0c..7ad841434ec8d688d435d058d4cf259e911e3b55 100644 (file)
@@ -2527,7 +2527,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
        }
 
        /* Initialize the MAC Core */
-       priv->hw->mac->core_init(priv->hw, dev->mtu);
+       priv->hw->mac->core_init(priv->hw, dev);
 
        /* Initialize MTL*/
        if (priv->synopsys_id >= DWMAC_CORE_4_00)