Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next v2 08/10] Documentation/bindings: net: marvell-pp2: add the system controller
From: Antoine Tenart @ 2017-08-22 17:08 UTC (permalink / raw)
  To: davem, jason, andrew, gregory.clement, sebastian.hesselbarth
  Cc: Antoine Tenart, thomas.petazzoni, nadavh, linux, mw, stefanc,
	netdev, linux-arm-kernel
In-Reply-To: <20170822170830.32413-1-antoine.tenart@free-electrons.com>

This patch documents the new marvell,system-controller property used by
the Marvell ppv2 network driver.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Tested-by: Marcin Wojtas <mw@semihalf.com>
---
 Documentation/devicetree/bindings/net/marvell-pp2.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/net/marvell-pp2.txt b/Documentation/devicetree/bindings/net/marvell-pp2.txt
index 8918ad3ccf14..49484db81583 100644
--- a/Documentation/devicetree/bindings/net/marvell-pp2.txt
+++ b/Documentation/devicetree/bindings/net/marvell-pp2.txt
@@ -45,6 +45,7 @@ Optional properties (port):
                    be the name associated to the interrupts listed. Valid
                    names are: "tx-cpu0", "tx-cpu1", "tx-cpu2", "tx-cpu3",
 		   "rx-shared".
+- marvell,system-controller: a phandle to the system controller.
 
 Example for marvell,armada-375-pp2:
 
-- 
2.13.5

^ permalink raw reply related

* [PATCH net-next v2 10/10] arm64: dts: marvell: mcbin: enable more networking ports
From: Antoine Tenart @ 2017-08-22 17:08 UTC (permalink / raw)
  To: davem, jason, andrew, gregory.clement, sebastian.hesselbarth
  Cc: Antoine Tenart, thomas.petazzoni, nadavh, linux, mw, stefanc,
	netdev, linux-arm-kernel
In-Reply-To: <20170822170830.32413-1-antoine.tenart@free-electrons.com>

This patch enables the two GE/SFP ports. They are configured in 10GKR
mode by default. To do this the cpm_xdmio is enabled as well, and two
phy descriptions are added.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Tested-by: Marcin Wojtas <mw@semihalf.com>
---
 arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts | 30 +++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
index abd39d1c1739..6cb4b000e1ac 100644
--- a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
+++ b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
@@ -127,6 +127,30 @@
 	};
 };
 
+&cpm_xmdio {
+	status = "okay";
+
+	phy0: ethernet-phy@0 {
+		compatible = "ethernet-phy-ieee802.3-c45";
+		reg = <0>;
+	};
+
+	phy1: ethernet-phy@1 {
+		compatible = "ethernet-phy-ieee802.3-c45";
+		reg = <8>;
+	};
+};
+
+&cpm_ethernet {
+	status = "okay";
+};
+
+&cpm_eth0 {
+	status = "okay";
+	phy = <&phy0>;
+	phy-mode = "10gbase-kr";
+};
+
 &cpm_sata0 {
 	/* CPM Lane 0 - U29 */
 	status = "okay";
@@ -154,6 +178,12 @@
 	status = "okay";
 };
 
+&cps_eth0 {
+	status = "okay";
+	phy = <&phy1>;
+	phy-mode = "10gbase-kr";
+};
+
 &cps_eth1 {
 	/* CPS Lane 0 - J5 (Gigabit RJ45) */
 	status = "okay";
-- 
2.13.5

^ permalink raw reply related

* [PATCH net-next v2 09/10] arm64: dts: marvell: add a reference to the sysctrl syscon in the ppv2 node
From: Antoine Tenart @ 2017-08-22 17:08 UTC (permalink / raw)
  To: davem, jason, andrew, gregory.clement, sebastian.hesselbarth
  Cc: Antoine Tenart, thomas.petazzoni, nadavh, linux, mw, stefanc,
	netdev, linux-arm-kernel
In-Reply-To: <20170822170830.32413-1-antoine.tenart@free-electrons.com>

The network driver on Marvell SoC (7k/8k) needs to access some registers
in the system controller to configure its ports at runtime. This patch
adds a phandle reference to the syscon system controller node in the
ppv2 node.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Tested-by: Marcin Wojtas <mw@semihalf.com>
---
 arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi | 1 +
 arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
index 4c68605675a8..18299e164cb7 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
@@ -65,6 +65,7 @@
 				reg = <0x0 0x100000>, <0x129000 0xb000>;
 				clocks = <&cpm_clk 1 3>, <&cpm_clk 1 9>, <&cpm_clk 1 5>;
 				clock-names = "pp_clk", "gop_clk", "mg_clk";
+				marvell,system-controller = <&cpm_syscon0>;
 				status = "disabled";
 				dma-coherent;
 
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
index 923f354b02f0..5ae8fa575859 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
@@ -72,6 +72,7 @@
 				reg = <0x0 0x100000>, <0x129000 0xb000>;
 				clocks = <&cps_clk 1 3>, <&cps_clk 1 9>, <&cps_clk 1 5>;
 				clock-names = "pp_clk", "gop_clk", "mg_clk";
+				marvell,system-controller = <&cps_syscon0>;
 				status = "disabled";
 				dma-coherent;
 
-- 
2.13.5

^ permalink raw reply related

* [PATCH net-next v2 07/10] net: mvpp2: initialize the GoP
From: Antoine Tenart @ 2017-08-22 17:08 UTC (permalink / raw)
  To: davem, jason, andrew, gregory.clement, sebastian.hesselbarth
  Cc: Antoine Tenart, thomas.petazzoni, nadavh, linux, mw, stefanc,
	netdev, linux-arm-kernel
In-Reply-To: <20170822170830.32413-1-antoine.tenart@free-electrons.com>

The patch adds GoP (group of ports) initialization functions. The mvpp2
driver was relying on the firmware/bootloader initialization; this patch
moves this setup to the mvpp2 driver.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Tested-by: Marcin Wojtas <mw@semihalf.com>
---
 drivers/net/ethernet/marvell/mvpp2.c | 170 +++++++++++++++++++++++++++++++++++
 1 file changed, 170 insertions(+)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index b2d2b4c9d5af..02c62cbbfe51 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -18,6 +18,7 @@
 #include <linux/inetdevice.h>
 #include <linux/mbus.h>
 #include <linux/module.h>
+#include <linux/mfd/syscon.h>
 #include <linux/interrupt.h>
 #include <linux/cpumask.h>
 #include <linux/of.h>
@@ -30,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/hrtimer.h>
 #include <linux/ktime.h>
+#include <linux/regmap.h>
 #include <uapi/linux/ppp_defs.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
@@ -388,6 +390,38 @@
 #define MVPP2_QUEUE_NEXT_DESC(q, index) \
 	(((index) < (q)->last_desc) ? ((index) + 1) : 0)
 
+/* XPCS registers. PPv2.2 only */
+#define MVPP22_MPCS_BASE(port)			(0x7000 + (port) * 0x1000)
+#define MVPP22_MPCS_CTRL			0x14
+#define     MVPP22_MPCS_CTRL_FWD_ERR_CONN	BIT(10)
+#define MVPP22_MPCS_CLK_RESET			0x14c
+#define     MAC_CLK_RESET_SD_TX			BIT(0)
+#define     MAC_CLK_RESET_SD_RX			BIT(1)
+#define     MAC_CLK_RESET_MAC			BIT(2)
+#define     MVPP22_MPCS_CLK_RESET_DIV_RATIO(n)	((n) << 4)
+#define     MVPP22_MPCS_CLK_RESET_DIV_SET	BIT(11)
+
+/* XPCS registers. PPv2.2 only */
+#define MVPP22_XPCS_BASE(port)			(0x7400 + (port) * 0x1000)
+#define MVPP22_XPCS_CFG0			0x0
+#define     MVPP22_XPCS_CFG0_PCS_MODE(n)	((n) << 3)
+#define     MVPP22_XPCS_CFG0_ACTIVE_LANE(n)	((n) << 5)
+
+/* System controller registers. Accessed through a regmap. */
+#define GENCONF_SOFT_RESET1				0x1108
+#define     GENCONF_SOFT_RESET1_GOP			BIT(6)
+#define GENCONF_PORT_CTRL0				0x1110
+#define     GENCONF_PORT_CTRL0_BUS_WIDTH_SELECT		BIT(1)
+#define     GENCONF_PORT_CTRL0_RX_DATA_SAMPLE		BIT(29)
+#define     GENCONF_PORT_CTRL0_CLK_DIV_PHASE_CLR	BIT(31)
+#define GENCONF_PORT_CTRL1				0x1114
+#define     GENCONF_PORT_CTRL1_EN(p)			BIT(p)
+#define     GENCONF_PORT_CTRL1_RESET(p)			(BIT(p) << 28)
+#define GENCONF_CTRL0					0x1120
+#define     GENCONF_CTRL0_PORT0_RGMII			BIT(0)
+#define     GENCONF_CTRL0_PORT1_RGMII_MII		BIT(1)
+#define     GENCONF_CTRL0_PORT1_RGMII			BIT(2)
+
 /* Various constants */
 
 /* Coalescing */
@@ -731,6 +765,11 @@ struct mvpp2 {
 	 */
 	void __iomem *swth_base[MVPP2_MAX_THREADS];
 
+	/* On PPv2.2, some port control registers are located into the system
+	 * controller space. These registers are accessible through a regmap.
+	 */
+	struct regmap *sysctrl_base;
+
 	/* Common clocks */
 	struct clk *pp_clk;
 	struct clk *gop_clk;
@@ -4259,6 +4298,123 @@ mvpp2_shared_interrupt_mask_unmask(struct mvpp2_port *port, bool mask)
 
 /* Port configuration routines */
 
+static void mvpp22_gop_init_rgmii(struct mvpp2_port *port)
+{
+	struct mvpp2 *priv = port->priv;
+	u32 val;
+
+	regmap_read(priv->sysctrl_base, GENCONF_PORT_CTRL0, &val);
+	val |= GENCONF_PORT_CTRL0_BUS_WIDTH_SELECT;
+	regmap_write(priv->sysctrl_base, GENCONF_PORT_CTRL0, val);
+
+	regmap_read(priv->sysctrl_base, GENCONF_CTRL0, &val);
+	if (port->gop_id == 2)
+		val |= GENCONF_CTRL0_PORT0_RGMII | GENCONF_CTRL0_PORT1_RGMII;
+	else if (port->gop_id == 3)
+		val |= GENCONF_CTRL0_PORT1_RGMII_MII;
+	regmap_write(priv->sysctrl_base, GENCONF_CTRL0, val);
+}
+
+static void mvpp22_gop_init_sgmii(struct mvpp2_port *port)
+{
+	struct mvpp2 *priv = port->priv;
+	u32 val;
+
+	regmap_read(priv->sysctrl_base, GENCONF_PORT_CTRL0, &val);
+	val |= GENCONF_PORT_CTRL0_BUS_WIDTH_SELECT |
+	       GENCONF_PORT_CTRL0_RX_DATA_SAMPLE;
+	regmap_write(priv->sysctrl_base, GENCONF_PORT_CTRL0, val);
+
+	if (port->gop_id > 1) {
+		regmap_read(priv->sysctrl_base, GENCONF_CTRL0, &val);
+		if (port->gop_id == 2)
+			val &= ~GENCONF_CTRL0_PORT0_RGMII;
+		else if (port->gop_id == 3)
+			val &= ~GENCONF_CTRL0_PORT1_RGMII_MII;
+		regmap_write(priv->sysctrl_base, GENCONF_CTRL0, val);
+	}
+}
+
+static void mvpp22_gop_init_10gkr(struct mvpp2_port *port)
+{
+	struct mvpp2 *priv = port->priv;
+	void __iomem *mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
+	void __iomem *xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
+	u32 val;
+
+	/* XPCS */
+	val = readl(xpcs + MVPP22_XPCS_CFG0);
+	val &= ~(MVPP22_XPCS_CFG0_PCS_MODE(0x3) |
+		 MVPP22_XPCS_CFG0_ACTIVE_LANE(0x3));
+	val |= MVPP22_XPCS_CFG0_ACTIVE_LANE(2);
+	writel(val, xpcs + MVPP22_XPCS_CFG0);
+
+	/* MPCS */
+	val = readl(mpcs + MVPP22_MPCS_CTRL);
+	val &= ~MVPP22_MPCS_CTRL_FWD_ERR_CONN;
+	writel(val, mpcs + MVPP22_MPCS_CTRL);
+
+	val = readl(mpcs + MVPP22_MPCS_CLK_RESET);
+	val &= ~(MVPP22_MPCS_CLK_RESET_DIV_RATIO(0x7) | MAC_CLK_RESET_MAC |
+		 MAC_CLK_RESET_SD_RX | MAC_CLK_RESET_SD_TX);
+	val |= MVPP22_MPCS_CLK_RESET_DIV_RATIO(1);
+	writel(val, mpcs + MVPP22_MPCS_CLK_RESET);
+
+	val &= ~MVPP22_MPCS_CLK_RESET_DIV_SET;
+	val |= MAC_CLK_RESET_MAC | MAC_CLK_RESET_SD_RX | MAC_CLK_RESET_SD_TX;
+	writel(val, mpcs + MVPP22_MPCS_CLK_RESET);
+}
+
+static int mvpp22_gop_init(struct mvpp2_port *port)
+{
+	struct mvpp2 *priv = port->priv;
+	u32 val;
+
+	if (!priv->sysctrl_base)
+		return 0;
+
+	switch (port->phy_interface) {
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		if (port->gop_id == 0)
+			goto invalid_conf;
+		mvpp22_gop_init_rgmii(port);
+		break;
+	case PHY_INTERFACE_MODE_SGMII:
+		mvpp22_gop_init_sgmii(port);
+		break;
+	case PHY_INTERFACE_MODE_10GKR:
+		if (port->gop_id != 0)
+			goto invalid_conf;
+		mvpp22_gop_init_10gkr(port);
+		break;
+	default:
+		goto unsupported_conf;
+	}
+
+	regmap_read(priv->sysctrl_base, GENCONF_PORT_CTRL1, &val);
+	val |= GENCONF_PORT_CTRL1_RESET(port->gop_id) |
+	       GENCONF_PORT_CTRL1_EN(port->gop_id);
+	regmap_write(priv->sysctrl_base, GENCONF_PORT_CTRL1, val);
+
+	regmap_read(priv->sysctrl_base, GENCONF_PORT_CTRL0, &val);
+	val |= GENCONF_PORT_CTRL0_CLK_DIV_PHASE_CLR;
+	regmap_write(priv->sysctrl_base, GENCONF_PORT_CTRL0, val);
+
+	regmap_read(priv->sysctrl_base, GENCONF_SOFT_RESET1, &val);
+	val |= GENCONF_SOFT_RESET1_GOP;
+	regmap_write(priv->sysctrl_base, GENCONF_SOFT_RESET1, val);
+
+unsupported_conf:
+	return 0;
+
+invalid_conf:
+	netdev_err(port->dev, "Invalid port configuration\n");
+	return -EINVAL;
+}
+
 static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port)
 {
 	u32 val;
@@ -6105,6 +6261,9 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
 	/* Enable interrupts on all CPUs */
 	mvpp2_interrupts_enable(port);
 
+	if (port->priv->hw_version == MVPP22)
+		mvpp22_gop_init(port);
+
 	mvpp2_port_mii_set(port);
 	mvpp2_port_enable(port);
 	phy_start(ndev->phydev);
@@ -7350,6 +7509,17 @@ static int mvpp2_probe(struct platform_device *pdev)
 		priv->iface_base = devm_ioremap_resource(&pdev->dev, res);
 		if (IS_ERR(priv->iface_base))
 			return PTR_ERR(priv->iface_base);
+
+		priv->sysctrl_base =
+			syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+							"marvell,system-controller");
+		if (IS_ERR(priv->sysctrl_base))
+			/* The system controller regmap is optional for dt
+			 * compatibility reasons. When not provided, the
+			 * configuration of the GoP relies on the
+			 * firmware/bootloader.
+			 */
+			priv->sysctrl_base = NULL;
 	}
 
 	for (i = 0; i < MVPP2_MAX_THREADS; i++) {
-- 
2.13.5

^ permalink raw reply related

* [PATCH net-next v2 05/10] net: mvpp2: initialize the XLG MAC when using a port
From: Antoine Tenart @ 2017-08-22 17:08 UTC (permalink / raw)
  To: davem, jason, andrew, gregory.clement, sebastian.hesselbarth
  Cc: Antoine Tenart, thomas.petazzoni, nadavh, linux, mw, stefanc,
	netdev, linux-arm-kernel
In-Reply-To: <20170822170830.32413-1-antoine.tenart@free-electrons.com>

This adds a routine to initialize the XLG MAC at the port level when
using a port and the XAUI/10GKR interface mode. This wasn't done until
this commit, and the mvpp2 driver was relying on the bootloader/firmware
initialization. This doesn't mean everything is configured in the mvpp2
driver now, but it helps reducing the gap.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Tested-by: Marcin Wojtas <mw@semihalf.com>
---
 drivers/net/ethernet/marvell/mvpp2.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 2ab7366ac90f..64e0a1bae7d0 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -361,6 +361,7 @@
 #define MVPP22_XLG_CTRL0_REG			0x100
 #define     MVPP22_XLG_CTRL0_PORT_EN		BIT(0)
 #define     MVPP22_XLG_CTRL0_MAC_RESET_DIS	BIT(1)
+#define     MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN	BIT(7)
 #define     MVPP22_XLG_CTRL0_MIB_CNT_DIS	BIT(14)
 
 #define MVPP22_XLG_CTRL3_REG			0x11c
@@ -368,6 +369,11 @@
 #define     MVPP22_XLG_CTRL3_MACMODESELECT_GMAC	(0 << 13)
 #define     MVPP22_XLG_CTRL3_MACMODESELECT_10G	(1 << 13)
 
+#define MVPP22_XLG_CTRL4_REG			0x184
+#define     MVPP22_XLG_CTRL4_FWD_FC		BIT(5)
+#define     MVPP22_XLG_CTRL4_FWD_PFC		BIT(6)
+#define     MVPP22_XLG_CTRL4_MACMODSELECT_GMAC	BIT(12)
+
 /* SMI registers. PPv2.2 only, relative to priv->iface_base. */
 #define MVPP22_SMI_MISC_CFG_REG			0x1204
 #define     MVPP22_SMI_POLLING_EN		BIT(10)
@@ -4337,6 +4343,23 @@ static void mvpp2_port_mii_gmac_configure(struct mvpp2_port *port)
 	writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
 }
 
+static void mvpp2_port_mii_xlg_configure(struct mvpp2_port *port)
+{
+	u32 val;
+
+	if (port->gop_id != 0)
+		return;
+
+	val = readl(port->base + MVPP22_XLG_CTRL0_REG);
+	val |= MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN;
+	writel(val, port->base + MVPP22_XLG_CTRL0_REG);
+
+	val = readl(port->base + MVPP22_XLG_CTRL4_REG);
+	val &= ~MVPP22_XLG_CTRL4_MACMODSELECT_GMAC;
+	val |= MVPP22_XLG_CTRL4_FWD_FC | MVPP22_XLG_CTRL4_FWD_PFC;
+	writel(val, port->base + MVPP22_XLG_CTRL4_REG);
+}
+
 static void mvpp22_port_mii_set(struct mvpp2_port *port)
 {
 	u32 val;
@@ -4367,6 +4390,8 @@ static void mvpp2_port_mii_set(struct mvpp2_port *port)
 	    port->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID ||
 	    port->phy_interface == PHY_INTERFACE_MODE_SGMII)
 		mvpp2_port_mii_gmac_configure(port);
+	else if (port->phy_interface == PHY_INTERFACE_MODE_10GKR)
+		mvpp2_port_mii_xlg_configure(port);
 }
 
 static void mvpp2_port_fc_adv_enable(struct mvpp2_port *port)
-- 
2.13.5

^ permalink raw reply related

* [PATCH net-next v2 06/10] net: mvpp2: set maximum packet size for 10G ports
From: Antoine Tenart @ 2017-08-22 17:08 UTC (permalink / raw)
  To: davem, jason, andrew, gregory.clement, sebastian.hesselbarth
  Cc: Stefan Chulski, thomas.petazzoni, nadavh, linux, mw, netdev,
	linux-arm-kernel, Antoine Tenart
In-Reply-To: <20170822170830.32413-1-antoine.tenart@free-electrons.com>

From: Stefan Chulski <stefanc@marvell.com>

Set maximum packet size for XLG 10G ports. Missing maximum packet size
for XLG configuration will cause kernel panic if oversized packet is
received by port.

Signed-off-by: Stefan Chulski <stefanc@marvell.com>
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 drivers/net/ethernet/marvell/mvpp2.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 64e0a1bae7d0..b2d2b4c9d5af 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -363,7 +363,9 @@
 #define     MVPP22_XLG_CTRL0_MAC_RESET_DIS	BIT(1)
 #define     MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN	BIT(7)
 #define     MVPP22_XLG_CTRL0_MIB_CNT_DIS	BIT(14)
-
+#define MVPP22_XLG_CTRL1_REG			0x104
+#define     MVPP22_XLG_CTRL1_FRAMESIZELIMIT	BIT(0)
+#define     MVPP22_XLG_CTRL1_FRAMESIZELIMIT_MASK	0x1fff
 #define MVPP22_XLG_CTRL3_REG			0x11c
 #define     MVPP22_XLG_CTRL3_MACMODESELECT_MASK	(7 << 13)
 #define     MVPP22_XLG_CTRL3_MACMODESELECT_GMAC	(0 << 13)
@@ -4498,6 +4500,18 @@ static inline void mvpp2_gmac_max_rx_size_set(struct mvpp2_port *port)
 	writel(val, port->base + MVPP2_GMAC_CTRL_0_REG);
 }
 
+/* Change maximum receive size of the port */
+static inline void mvpp2_xlg_max_rx_size_set(struct mvpp2_port *port)
+{
+	u32 val;
+
+	val =  readl(port->base + MVPP22_XLG_CTRL1_REG);
+	val &= ~MVPP22_XLG_CTRL1_FRAMESIZELIMIT_MASK;
+	val |= ((port->pkt_size - MVPP2_MH_SIZE) / 2) <<
+	       MVPP22_XLG_CTRL1_FRAMESIZELIMIT;
+	writel(val, port->base + MVPP22_XLG_CTRL1_REG);
+}
+
 /* Set defaults to the MVPP2 port */
 static void mvpp2_defaults_set(struct mvpp2_port *port)
 {
@@ -6076,7 +6090,13 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
 	struct net_device *ndev = port->dev;
 	int i;
 
-	mvpp2_gmac_max_rx_size_set(port);
+	if (port->gop_id == 0 &&
+	    (port->phy_interface == PHY_INTERFACE_MODE_XAUI ||
+	     port->phy_interface == PHY_INTERFACE_MODE_10GKR))
+		mvpp2_xlg_max_rx_size_set(port);
+	else
+		mvpp2_gmac_max_rx_size_set(port);
+
 	mvpp2_txp_max_tx_size_set(port);
 
 	for (i = 0; i < port->nqvecs; i++)
-- 
2.13.5

^ permalink raw reply related

* [PATCH net-next v2 04/10] net: mvpp2: initialize the GMAC when using a port
From: Antoine Tenart @ 2017-08-22 17:08 UTC (permalink / raw)
  To: davem, jason, andrew, gregory.clement, sebastian.hesselbarth
  Cc: Antoine Tenart, thomas.petazzoni, nadavh, linux, mw, stefanc,
	netdev, linux-arm-kernel
In-Reply-To: <20170822170830.32413-1-antoine.tenart@free-electrons.com>

This adds a routine to initialize the GMAC at the port level when using
a port. This wasn't done until this commit, and the mvpp2 driver was
relying on the bootloader/firmware initialization. This doesn't mean
everything is configured in the mvpp2 driver now, but it helps reducing
the gap.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Tested-by: Marcin Wojtas <mw@semihalf.com>
---
 drivers/net/ethernet/marvell/mvpp2.c | 123 ++++++++++++++++++++++++++++-------
 1 file changed, 98 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 087eb793ab4d..2ab7366ac90f 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -315,6 +315,7 @@
 /* Per-port registers */
 #define MVPP2_GMAC_CTRL_0_REG			0x0
 #define     MVPP2_GMAC_PORT_EN_MASK		BIT(0)
+#define     MVPP2_GMAC_PORT_TYPE_MASK		BIT(1)
 #define     MVPP2_GMAC_MAX_RX_SIZE_OFFS		2
 #define     MVPP2_GMAC_MAX_RX_SIZE_MASK		0x7ffc
 #define     MVPP2_GMAC_MIB_CNTR_EN_MASK		BIT(15)
@@ -326,16 +327,21 @@
 #define     MVPP2_GMAC_SA_LOW_OFFS		7
 #define MVPP2_GMAC_CTRL_2_REG			0x8
 #define     MVPP2_GMAC_INBAND_AN_MASK		BIT(0)
+#define     MVPP2_GMAC_FLOW_CTRL_MASK		GENMASK(2, 1)
 #define     MVPP2_GMAC_PCS_ENABLE_MASK		BIT(3)
 #define     MVPP2_GMAC_PORT_RGMII_MASK		BIT(4)
+#define     MVPP2_GMAC_DISABLE_PADDING		BIT(5)
 #define     MVPP2_GMAC_PORT_RESET_MASK		BIT(6)
 #define MVPP2_GMAC_AUTONEG_CONFIG		0xc
 #define     MVPP2_GMAC_FORCE_LINK_DOWN		BIT(0)
 #define     MVPP2_GMAC_FORCE_LINK_PASS		BIT(1)
+#define     MVPP2_GMAC_IN_BAND_AUTONEG		BIT(2)
+#define     MVPP2_GMAC_IN_BAND_AUTONEG_BYPASS	BIT(3)
 #define     MVPP2_GMAC_CONFIG_MII_SPEED	BIT(5)
 #define     MVPP2_GMAC_CONFIG_GMII_SPEED	BIT(6)
 #define     MVPP2_GMAC_AN_SPEED_EN		BIT(7)
 #define     MVPP2_GMAC_FC_ADV_EN		BIT(9)
+#define     MVPP2_GMAC_FLOW_CTRL_AUTONEG	BIT(11)
 #define     MVPP2_GMAC_CONFIG_FULL_DUPLEX	BIT(12)
 #define     MVPP2_GMAC_AN_DUPLEX_EN		BIT(13)
 #define MVPP2_GMAC_PORT_FIFO_CFG_1_REG		0x1c
@@ -4245,6 +4251,92 @@ mvpp2_shared_interrupt_mask_unmask(struct mvpp2_port *port, bool mask)
 
 /* Port configuration routines */
 
+static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port)
+{
+	u32 val;
+
+	if (port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+		val = readl(port->base + MVPP22_GMAC_CTRL_4_REG);
+		val |= MVPP22_CTRL4_SYNC_BYPASS_DIS | MVPP22_CTRL4_DP_CLK_SEL |
+		       MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE;
+		val &= ~MVPP22_CTRL4_EXT_PIN_GMII_SEL;
+		writel(val, port->base + MVPP22_GMAC_CTRL_4_REG);
+
+		val = readl(port->base + MVPP2_GMAC_CTRL_2_REG);
+		val |= MVPP2_GMAC_DISABLE_PADDING;
+		val &= ~MVPP2_GMAC_FLOW_CTRL_MASK;
+		writel(val, port->base + MVPP2_GMAC_CTRL_2_REG);
+	} else if (port->phy_interface == PHY_INTERFACE_MODE_RGMII ||
+		   port->phy_interface == PHY_INTERFACE_MODE_RGMII_ID ||
+		   port->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID ||
+		   port->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) {
+		val = readl(port->base + MVPP22_GMAC_CTRL_4_REG);
+		val |= MVPP22_CTRL4_EXT_PIN_GMII_SEL |
+		       MVPP22_CTRL4_SYNC_BYPASS_DIS |
+		       MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE;
+		val &= ~MVPP22_CTRL4_DP_CLK_SEL;
+		writel(val, port->base + MVPP22_GMAC_CTRL_4_REG);
+
+		val = readl(port->base + MVPP2_GMAC_CTRL_2_REG);
+		val &= ~MVPP2_GMAC_DISABLE_PADDING;
+		writel(val, port->base + MVPP2_GMAC_CTRL_2_REG);
+	}
+
+	/* The port is connected to a copper PHY */
+	val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
+	val &= ~MVPP2_GMAC_PORT_TYPE_MASK;
+	writel(val, port->base + MVPP2_GMAC_CTRL_0_REG);
+
+	val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+	val |= MVPP2_GMAC_IN_BAND_AUTONEG_BYPASS |
+	       MVPP2_GMAC_AN_SPEED_EN | MVPP2_GMAC_FLOW_CTRL_AUTONEG |
+	       MVPP2_GMAC_AN_DUPLEX_EN;
+	if (port->phy_interface == PHY_INTERFACE_MODE_SGMII)
+		val |= MVPP2_GMAC_IN_BAND_AUTONEG;
+	writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+}
+
+static void mvpp2_port_mii_gmac_configure(struct mvpp2_port *port)
+{
+	u32 val;
+
+	/* Force link down */
+	val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+	val &= ~MVPP2_GMAC_FORCE_LINK_PASS;
+	val |= MVPP2_GMAC_FORCE_LINK_DOWN;
+	writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+
+	/* Set the GMAC in a reset state */
+	val = readl(port->base + MVPP2_GMAC_CTRL_2_REG);
+	val |= MVPP2_GMAC_PORT_RESET_MASK;
+	writel(val, port->base + MVPP2_GMAC_CTRL_2_REG);
+
+	/* Configure the PCS and in-band AN */
+	val = readl(port->base + MVPP2_GMAC_CTRL_2_REG);
+	if (port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+	        val |= MVPP2_GMAC_INBAND_AN_MASK | MVPP2_GMAC_PCS_ENABLE_MASK;
+	} else if (port->phy_interface == PHY_INTERFACE_MODE_RGMII ||
+		   port->phy_interface == PHY_INTERFACE_MODE_RGMII_ID ||
+		   port->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID ||
+		   port->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) {
+		val &= ~MVPP2_GMAC_PCS_ENABLE_MASK;
+		val |= MVPP2_GMAC_PORT_RGMII_MASK;
+	}
+	writel(val, port->base + MVPP2_GMAC_CTRL_2_REG);
+
+	mvpp2_port_mii_gmac_configure_mode(port);
+
+	/* Unset the GMAC reset state */
+	val = readl(port->base + MVPP2_GMAC_CTRL_2_REG);
+	val &= ~MVPP2_GMAC_PORT_RESET_MASK;
+	writel(val, port->base + MVPP2_GMAC_CTRL_2_REG);
+
+	/* Stop forcing link down */
+	val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+	val &= ~MVPP2_GMAC_FORCE_LINK_DOWN;
+	writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+}
+
 static void mvpp22_port_mii_set(struct mvpp2_port *port)
 {
 	u32 val;
@@ -4262,38 +4354,19 @@ static void mvpp22_port_mii_set(struct mvpp2_port *port)
 
 		writel(val, port->base + MVPP22_XLG_CTRL3_REG);
 	}
-
-	val = readl(port->base + MVPP22_GMAC_CTRL_4_REG);
-	if (port->phy_interface == PHY_INTERFACE_MODE_RGMII)
-		val |= MVPP22_CTRL4_EXT_PIN_GMII_SEL;
-	else
-		val &= ~MVPP22_CTRL4_EXT_PIN_GMII_SEL;
-	val &= ~MVPP22_CTRL4_DP_CLK_SEL;
-	val |= MVPP22_CTRL4_SYNC_BYPASS_DIS;
-	val |= MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE;
-	writel(val, port->base + MVPP22_GMAC_CTRL_4_REG);
 }
 
 static void mvpp2_port_mii_set(struct mvpp2_port *port)
 {
-	u32 val;
-
 	if (port->priv->hw_version == MVPP22)
 		mvpp22_port_mii_set(port);
 
-	val = readl(port->base + MVPP2_GMAC_CTRL_2_REG);
-
-	switch (port->phy_interface) {
-	case PHY_INTERFACE_MODE_SGMII:
-		val |= MVPP2_GMAC_INBAND_AN_MASK;
-		break;
-	case PHY_INTERFACE_MODE_RGMII:
-		val |= MVPP2_GMAC_PORT_RGMII_MASK;
-	default:
-		val &= ~MVPP2_GMAC_PCS_ENABLE_MASK;
-	}
-
-	writel(val, port->base + MVPP2_GMAC_CTRL_2_REG);
+	if (port->phy_interface == PHY_INTERFACE_MODE_RGMII ||
+	    port->phy_interface == PHY_INTERFACE_MODE_RGMII_ID ||
+	    port->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID ||
+	    port->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID ||
+	    port->phy_interface == PHY_INTERFACE_MODE_SGMII)
+		mvpp2_port_mii_gmac_configure(port);
 }
 
 static void mvpp2_port_fc_adv_enable(struct mvpp2_port *port)
-- 
2.13.5

^ permalink raw reply related

* [PATCH net-next v2 01/10] net: mvpp2: unify register definitions coding style
From: Antoine Tenart @ 2017-08-22 17:08 UTC (permalink / raw)
  To: davem, jason, andrew, gregory.clement, sebastian.hesselbarth
  Cc: Antoine Tenart, thomas.petazzoni, nadavh, linux, mw, stefanc,
	netdev, linux-arm-kernel
In-Reply-To: <20170822170830.32413-1-antoine.tenart@free-electrons.com>

Cosmetic patch to use the same formatting rules on all register
definitions.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Tested-by: Marcin Wojtas <mw@semihalf.com>
---
 drivers/net/ethernet/marvell/mvpp2.c | 88 ++++++++++++++++++------------------
 1 file changed, 44 insertions(+), 44 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 39bc8fbbdd65..34c679f25fec 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -193,18 +193,18 @@
 #define     MVPP2_MAX_ISR_RX_THRESHOLD		0xfffff0
 #define MVPP21_ISR_RXQ_GROUP_REG(port)		(0x5400 + 4 * (port))
 
-#define MVPP22_ISR_RXQ_GROUP_INDEX_REG          0x5400
+#define MVPP22_ISR_RXQ_GROUP_INDEX_REG		0x5400
 #define MVPP22_ISR_RXQ_GROUP_INDEX_SUBGROUP_MASK 0xf
-#define MVPP22_ISR_RXQ_GROUP_INDEX_GROUP_MASK   0x380
-#define MVPP22_ISR_RXQ_GROUP_INDEX_GROUP_OFFSET 7
+#define MVPP22_ISR_RXQ_GROUP_INDEX_GROUP_MASK	0x380
+#define MVPP22_ISR_RXQ_GROUP_INDEX_GROUP_OFFSET	7
 
 #define MVPP22_ISR_RXQ_GROUP_INDEX_SUBGROUP_MASK 0xf
-#define MVPP22_ISR_RXQ_GROUP_INDEX_GROUP_MASK   0x380
+#define MVPP22_ISR_RXQ_GROUP_INDEX_GROUP_MASK	0x380
 
-#define MVPP22_ISR_RXQ_SUB_GROUP_CONFIG_REG     0x5404
-#define MVPP22_ISR_RXQ_SUB_GROUP_STARTQ_MASK    0x1f
-#define MVPP22_ISR_RXQ_SUB_GROUP_SIZE_MASK      0xf00
-#define MVPP22_ISR_RXQ_SUB_GROUP_SIZE_OFFSET    8
+#define MVPP22_ISR_RXQ_SUB_GROUP_CONFIG_REG	0x5404
+#define MVPP22_ISR_RXQ_SUB_GROUP_STARTQ_MASK	0x1f
+#define MVPP22_ISR_RXQ_SUB_GROUP_SIZE_MASK	0xf00
+#define MVPP22_ISR_RXQ_SUB_GROUP_SIZE_OFFSET	8
 
 #define MVPP2_ISR_ENABLE_REG(port)		(0x5420 + 4 * (port))
 #define     MVPP2_ISR_ENABLE_INTERRUPT(mask)	((mask) & 0xffff)
@@ -272,7 +272,7 @@
 #define MVPP2_BM_VIRT_RLS_REG			0x64c0
 #define MVPP22_BM_ADDR_HIGH_RLS_REG		0x64c4
 #define     MVPP22_BM_ADDR_HIGH_PHYS_RLS_MASK	0xff
-#define	    MVPP22_BM_ADDR_HIGH_VIRT_RLS_MASK	0xff00
+#define     MVPP22_BM_ADDR_HIGH_VIRT_RLS_MASK	0xff00
 #define     MVPP22_BM_ADDR_HIGH_VIRT_RLS_SHIFT	8
 
 /* TX Scheduler registers */
@@ -314,57 +314,57 @@
 
 /* Per-port registers */
 #define MVPP2_GMAC_CTRL_0_REG			0x0
-#define      MVPP2_GMAC_PORT_EN_MASK		BIT(0)
-#define      MVPP2_GMAC_MAX_RX_SIZE_OFFS	2
-#define      MVPP2_GMAC_MAX_RX_SIZE_MASK	0x7ffc
-#define      MVPP2_GMAC_MIB_CNTR_EN_MASK	BIT(15)
+#define     MVPP2_GMAC_PORT_EN_MASK		BIT(0)
+#define     MVPP2_GMAC_MAX_RX_SIZE_OFFS		2
+#define     MVPP2_GMAC_MAX_RX_SIZE_MASK		0x7ffc
+#define     MVPP2_GMAC_MIB_CNTR_EN_MASK		BIT(15)
 #define MVPP2_GMAC_CTRL_1_REG			0x4
-#define      MVPP2_GMAC_PERIODIC_XON_EN_MASK	BIT(1)
-#define      MVPP2_GMAC_GMII_LB_EN_MASK		BIT(5)
-#define      MVPP2_GMAC_PCS_LB_EN_BIT		6
-#define      MVPP2_GMAC_PCS_LB_EN_MASK		BIT(6)
-#define      MVPP2_GMAC_SA_LOW_OFFS		7
+#define     MVPP2_GMAC_PERIODIC_XON_EN_MASK	BIT(1)
+#define     MVPP2_GMAC_GMII_LB_EN_MASK		BIT(5)
+#define     MVPP2_GMAC_PCS_LB_EN_BIT		6
+#define     MVPP2_GMAC_PCS_LB_EN_MASK		BIT(6)
+#define     MVPP2_GMAC_SA_LOW_OFFS		7
 #define MVPP2_GMAC_CTRL_2_REG			0x8
-#define      MVPP2_GMAC_INBAND_AN_MASK		BIT(0)
-#define      MVPP2_GMAC_PCS_ENABLE_MASK		BIT(3)
-#define      MVPP2_GMAC_PORT_RGMII_MASK		BIT(4)
-#define      MVPP2_GMAC_PORT_RESET_MASK		BIT(6)
+#define     MVPP2_GMAC_INBAND_AN_MASK		BIT(0)
+#define     MVPP2_GMAC_PCS_ENABLE_MASK		BIT(3)
+#define     MVPP2_GMAC_PORT_RGMII_MASK		BIT(4)
+#define     MVPP2_GMAC_PORT_RESET_MASK		BIT(6)
 #define MVPP2_GMAC_AUTONEG_CONFIG		0xc
-#define      MVPP2_GMAC_FORCE_LINK_DOWN		BIT(0)
-#define      MVPP2_GMAC_FORCE_LINK_PASS		BIT(1)
-#define      MVPP2_GMAC_CONFIG_MII_SPEED	BIT(5)
-#define      MVPP2_GMAC_CONFIG_GMII_SPEED	BIT(6)
-#define      MVPP2_GMAC_AN_SPEED_EN		BIT(7)
-#define      MVPP2_GMAC_FC_ADV_EN		BIT(9)
-#define      MVPP2_GMAC_CONFIG_FULL_DUPLEX	BIT(12)
-#define      MVPP2_GMAC_AN_DUPLEX_EN		BIT(13)
+#define     MVPP2_GMAC_FORCE_LINK_DOWN		BIT(0)
+#define     MVPP2_GMAC_FORCE_LINK_PASS		BIT(1)
+#define     MVPP2_GMAC_CONFIG_MII_SPEED	BIT(5)
+#define     MVPP2_GMAC_CONFIG_GMII_SPEED	BIT(6)
+#define     MVPP2_GMAC_AN_SPEED_EN		BIT(7)
+#define     MVPP2_GMAC_FC_ADV_EN		BIT(9)
+#define     MVPP2_GMAC_CONFIG_FULL_DUPLEX	BIT(12)
+#define     MVPP2_GMAC_AN_DUPLEX_EN		BIT(13)
 #define MVPP2_GMAC_PORT_FIFO_CFG_1_REG		0x1c
-#define      MVPP2_GMAC_TX_FIFO_MIN_TH_OFFS	6
-#define      MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK	0x1fc0
-#define      MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(v)	(((v) << 6) & \
+#define     MVPP2_GMAC_TX_FIFO_MIN_TH_OFFS	6
+#define     MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK	0x1fc0
+#define     MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(v)	(((v) << 6) & \
 					MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK)
 #define MVPP22_GMAC_CTRL_4_REG			0x90
-#define      MVPP22_CTRL4_EXT_PIN_GMII_SEL	BIT(0)
-#define      MVPP22_CTRL4_DP_CLK_SEL		BIT(5)
-#define      MVPP22_CTRL4_SYNC_BYPASS		BIT(6)
-#define      MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE	BIT(7)
+#define     MVPP22_CTRL4_EXT_PIN_GMII_SEL	BIT(0)
+#define     MVPP22_CTRL4_DP_CLK_SEL		BIT(5)
+#define     MVPP22_CTRL4_SYNC_BYPASS		BIT(6)
+#define     MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE	BIT(7)
 
 /* Per-port XGMAC registers. PPv2.2 only, only for GOP port 0,
  * relative to port->base.
  */
 #define MVPP22_XLG_CTRL0_REG			0x100
-#define      MVPP22_XLG_CTRL0_PORT_EN		BIT(0)
-#define      MVPP22_XLG_CTRL0_MAC_RESET_DIS	BIT(1)
-#define      MVPP22_XLG_CTRL0_MIB_CNT_DIS	BIT(14)
+#define     MVPP22_XLG_CTRL0_PORT_EN		BIT(0)
+#define     MVPP22_XLG_CTRL0_MAC_RESET_DIS	BIT(1)
+#define     MVPP22_XLG_CTRL0_MIB_CNT_DIS	BIT(14)
 
 #define MVPP22_XLG_CTRL3_REG			0x11c
-#define      MVPP22_XLG_CTRL3_MACMODESELECT_MASK	(7 << 13)
-#define      MVPP22_XLG_CTRL3_MACMODESELECT_GMAC	(0 << 13)
-#define      MVPP22_XLG_CTRL3_MACMODESELECT_10G		(1 << 13)
+#define     MVPP22_XLG_CTRL3_MACMODESELECT_MASK	(7 << 13)
+#define     MVPP22_XLG_CTRL3_MACMODESELECT_GMAC	(0 << 13)
+#define     MVPP22_XLG_CTRL3_MACMODESELECT_10G	(1 << 13)
 
 /* SMI registers. PPv2.2 only, relative to priv->iface_base. */
 #define MVPP22_SMI_MISC_CFG_REG			0x1204
-#define      MVPP22_SMI_POLLING_EN		BIT(10)
+#define     MVPP22_SMI_POLLING_EN		BIT(10)
 
 #define MVPP22_GMAC_BASE(port)		(0x7000 + (port) * 0x1000 + 0xe00)
 
-- 
2.13.5

^ permalink raw reply related

* [PATCH net-next v2 00/10] net: mvpp2: MAC/GoP configuration
From: Antoine Tenart @ 2017-08-22 17:08 UTC (permalink / raw)
  To: davem, jason, andrew, gregory.clement, sebastian.hesselbarth
  Cc: Antoine Tenart, thomas.petazzoni, nadavh, linux, mw, stefanc,
	netdev, linux-arm-kernel

Hi all,

This is based on net-next (e2a7c34fb285).

I removed the GoP interrupt and PHY optional parts in this v2 to ease
the review process as the MAC/GoP initialization seemed to start less
discussions :)

This series now only aims at making the PPv2 driver less depending on
the firmware/bootloader initialization. Some patches cleanup some parts
as well, and add new interface descriptions in the dt.

The current implementation of the PPv2 driver relies on the
firmware/bootloader initialization to configure some parts, as the Group
of Ports (GoP) and the MACs (GMAC and/or XLG MAC --for 10G--).  The
drawback is the kernel must be configured to match exactly what the
bootloader configures which is not convenient and is an issue when using
boards having an Ethernet port and an SFP port wired to the same GoP
port, as no dynamic configuration can be done.

This series adds the GoP and GMAC/XLG MAC initializations so that the
PPV2 does not have to rely on a previous initialization. One part is
still missing from this series, and that would be the 'comphy' which
provides shared serdes PHYs and which must be configured as well for a
full kernel initialization to work. This comphy support will be part of
a following up series. (This series was also tested with this 'comphy'
support, as it's nearly ready).

@Dave: patches 9 and 10 should go through the mvebu tree. Thanks!

Since v1:
  - Split the previous series.
  - Rebased on net-next and reworked the series accordingly.
  - Added support for all RGMII variants.
  - Added a patch from Stefan Chulski improving / fixing 10G support.
  - Various small fixes.

Antoine Tenart (9):
  net: mvpp2: unify register definitions coding style
  net: mvpp2: fix the synchronization module bypass macro name
  net: mvpp2: move the mii configuration in the ndo_open path
  net: mvpp2: initialize the GMAC when using a port
  net: mvpp2: initialize the XLG MAC when using a port
  net: mvpp2: initialize the GoP
  Documentation/bindings: net: marvell-pp2: add the system controller
  arm64: dts: marvell: add a reference to the sysctrl syscon in the ppv2
    node
  arm64: dts: marvell: mcbin: enable more networking ports

Stefan Chulski (1):
  net: mvpp2: set maximum packet size for 10G ports

 .../devicetree/bindings/net/marvell-pp2.txt        |   1 +
 arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts  |  30 ++
 .../boot/dts/marvell/armada-cp110-master.dtsi      |   1 +
 .../arm64/boot/dts/marvell/armada-cp110-slave.dtsi |   1 +
 drivers/net/ethernet/marvell/mvpp2.c               | 432 +++++++++++++++++----
 5 files changed, 393 insertions(+), 72 deletions(-)

-- 
2.13.5

^ permalink raw reply

* [PATCH net-next v2 03/10] net: mvpp2: move the mii configuration in the ndo_open path
From: Antoine Tenart @ 2017-08-22 17:08 UTC (permalink / raw)
  To: davem, jason, andrew, gregory.clement, sebastian.hesselbarth
  Cc: thomas.petazzoni, netdev, Antoine Tenart, linux, nadavh, stefanc,
	mw, linux-arm-kernel
In-Reply-To: <20170822170830.32413-1-antoine.tenart@free-electrons.com>

This moves the mii configuration in the ndo_open path, to allow handling
different mii configurations later and to switch between these
configurations at runtime.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Tested-by: Marcin Wojtas <mw@semihalf.com>
---
 drivers/net/ethernet/marvell/mvpp2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 03b7ced1082f..087eb793ab4d 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -5987,6 +5987,7 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
 	/* Enable interrupts on all CPUs */
 	mvpp2_interrupts_enable(port);
 
+	mvpp2_port_mii_set(port);
 	mvpp2_port_enable(port);
 	phy_start(ndev->phydev);
 	netif_tx_start_all_queues(port->dev);
@@ -6949,7 +6950,6 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 		goto err_free_stats;
 	}
 
-	mvpp2_port_mii_set(port);
 	mvpp2_port_periodic_xon_disable(port);
 
 	if (priv->hw_version == MVPP21)
-- 
2.13.5

^ permalink raw reply related

* Re: [PATCH] net: ftgmac100: Fix oops in probe on failure to find associated PHY
From: Benjamin Herrenschmidt @ 2017-08-22 16:59 UTC (permalink / raw)
  To: Andrew Jeffery, netdev
  Cc: davem, joel, linux-kernel, openbmc, linux-aspeed, ryan_chen
In-Reply-To: <20170822063622.21550-1-andrew@aj.id.au>

On Tue, 2017-08-22 at 16:06 +0930, Andrew Jeffery wrote:
> netif_napi_del() should be paired with netif_napi_add(), however no
> such call takes place in ftgmac100_probe(). This triggers a NULL
> pointer dereference if e.g. no PHY is found by the MDIO probe:
> 
> 	 [ 2.770000] libphy: Fixed MDIO Bus: probed
> 	 [ 2.770000] ftgmac100 1e660000.ethernet: Generated random MAC address 66:58:c0:5a:50:b8
> 	 [ 2.790000] libphy: ftgmac100_mdio: probed
> 	 [ 2.790000] ftgmac100 1e660000.ethernet (unnamed net_device) (uninitialized): eth%d: no PHY found
> 	 [ 2.790000] ftgmac100 1e660000.ethernet: MII Probe failed!
> 	 [ 2.810000] Unable to handle kernel NULL pointer dereference at virtual address 00000004
> 	 [ 2.810000] pgd = 80004000
> 	 [ 2.810000] [00000004] *pgd=00000000
> 	 [ 2.810000] Internal error: Oops: 805 [#1] ARM
> 	 [ 2.810000] CPU: 0 PID: 1 Comm: swapper Not tainted 4.10.17-1a4df30c39cf5ee0e3d2528c409787ccbb4a672a #1
> 	 [ 2.810000] Hardware name: ASpeed SoC
> 	 [ 2.810000] task: 9e421b60 task.stack: 9e4a0000
> 	 [ 2.810000] PC is at netif_napi_del+0x74/0xa4
> 	 [ 2.810000] LR is at ftgmac100_probe+0x290/0x674
> 	 [ 2.810000] pc : [<80331004>] lr : [<80292b30>] psr: 60000013
> 	 [ 2.810000] sp : 9e4a1d70 ip : 9e4a1d88 fp : 9e4a1d84
> 	 [ 2.810000] r10: 9e565000 r9 : ffffffed r8 : 00000007
> 	 [ 2.810000] r7 : 9e565480 r6 : 9ec072c0 r5 : 00000000 r4 : 9e5654d8
> 	 [ 2.810000] r3 : 9e565530 r2 : 00000000 r1 : 00000000 r0 : 9e5654d8
> 	 [ 2.810000] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
> 	 [ 2.810000] Control: 00c5387d Table: 80004008 DAC: 00000055
> 	 [ 2.810000] Process swapper (pid: 1, stack limit = 0x9e4a0188)
> 	 [ 2.810000] Stack: (0x9e4a1d70 to 0x9e4a2000)
> 	 [ 2.810000] 1d60: 9e565000 9e549e10 9e4a1dcc 9e4a1d88
> 	 [ 2.810000] 1d80: 80292b30 80330f9c ffffffff 9e4a1d98 80146058 9ec072c0 00009e10 00000000
> 	 [ 2.810000] 1da0: 9e549e18 9e549e10 ffffffed 805f81f4 fffffdfb 00000000 00000000 00000000
> 	 [ 2.810000] 1dc0: 9e4a1dec 9e4a1dd0 80243df8 802928ac 9e549e10 8062cbd8 8062cbe0 805f81f4
> 	 [ 2.810000] 1de0: 9e4a1e24 9e4a1df0 80242178 80243da4 803001d0 802ffa60 9e4a1e24 9e549e10
> 	 [ 2.810000] 1e00: 9e549e44 805f81f4 00000000 00000000 805b8840 8058a6b0 9e4a1e44 9e4a1e28
> 	 [ 2.810000] 1e20: 80242434 80241f04 00000000 805f81f4 80242344 00000000 9e4a1e6c 9e4a1e48
> 	 [ 2.810000] 1e40: 80240148 80242350 9e425bac 9e4fdc90 9e790e94 805f81f4 9e790e60 805f5640
> 	 [ 2.810000] 1e60: 9e4a1e7c 9e4a1e70 802425dc 802400d8 9e4a1ea4 9e4a1e80 80240ba8 802425c0
> 	 [ 2.810000] 1e80: 8050b6ac 9e4a1e90 805f81f4 ffffe000 805b8838 80616720 9e4a1ebc 9e4a1ea8
> 	 [ 2.810000] 1ea0: 80243068 80240a68 805ab24c ffffe000 9e4a1ecc 9e4a1ec0 80244a38 80242fec
> 	 [ 2.810000] 1ec0: 9e4a1edc 9e4a1ed0 805ab264 80244a04 9e4a1f4c 9e4a1ee0 8058ae70 805ab258
> 	 [ 2.810000] 1ee0: 80032c68 801e3fd8 8052f800 8041af2c 9e4a1f4c 9e4a1f00 80032f90 8058a6bc
> 	 [ 2.810000] 1f00: 9e4a1f2c 9e4a1f10 00000006 00000006 00000000 8052f220 805112f0 00000000
> 	 [ 2.810000] 1f20: 9e4a1f4c 00000006 80616720 805cf400 80616720 805b8838 80616720 00000057
> 	 [ 2.810000] 1f40: 9e4a1f94 9e4a1f50 8058b040 8058add0 00000006 00000006 00000000 8058a6b0
> 	 [ 2.810000] 1f60: 3940bf3d 00000007 f115c2e8 00000000 803fd158 00000000 00000000 00000000
> 	 [ 2.810000] 1f80: 00000000 00000000 9e4a1fac 9e4a1f98 803fd170 8058af38 00000000 803fd158
> 	 [ 2.810000] 1fa0: 00000000 9e4a1fb0 8000a5e8 803fd164 00000000 00000000 00000000 00000000
> 	 [ 2.810000] 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 	 [ 2.810000] 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 d11dcae8 af8ddec5
> 	 [ 2.810000] [<80331004>] (netif_napi_del) from [<80292b30>] (ftgmac100_probe+0x290/0x674)
> 	 [ 2.810000] [<80292b30>] (ftgmac100_probe) from [<80243df8>] (platform_drv_probe+0x60/0xc0)
> 	 [ 2.810000] [<80243df8>] (platform_drv_probe) from [<80242178>] (driver_probe_device+0x280/0x44c)
> 	 [ 2.810000] [<80242178>] (driver_probe_device) from [<80242434>] (__driver_attach+0xf0/0x104)
> 	 [ 2.810000] [<80242434>] (__driver_attach) from [<80240148>] (bus_for_each_dev+0x7c/0xb0)
> 	 [ 2.810000] [<80240148>] (bus_for_each_dev) from [<802425dc>] (driver_attach+0x28/0x30)
> 	 [ 2.810000] [<802425dc>] (driver_attach) from [<80240ba8>] (bus_add_driver+0x14c/0x268)
> 	 [ 2.810000] [<80240ba8>] (bus_add_driver) from [<80243068>] (driver_register+0x88/0x104)
> 	 [ 2.810000] [<80243068>] (driver_register) from [<80244a38>] (__platform_driver_register+0x40/0x54)
> 	 [ 2.810000] [<80244a38>] (__platform_driver_register) from [<805ab264>] (ftgmac100_driver_init+0x18/0x20)
> 	 [ 2.810000] [<805ab264>] (ftgmac100_driver_init) from [<8058ae70>] (do_one_initcall+0xac/0x168)
> 	 [ 2.810000] [<8058ae70>] (do_one_initcall) from [<8058b040>] (kernel_init_freeable+0x114/0x1cc)
> 	 [ 2.810000] [<8058b040>] (kernel_init_freeable) from [<803fd170>] (kernel_init+0x18/0x104)
> 	 [ 2.810000] [<803fd170>] (kernel_init) from [<8000a5e8>] (ret_from_fork+0x14/0x2c)
> 	 [ 2.810000] Code: e594205c e5941058 e2843058 e3a05000 (e5812004)
> 	 [ 3.210000] ---[ end trace f32811052fd3860c ]---
> 
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

Good catch, thanks. Ack below.

I think there is one more instance of that bug in ftgmac100_remove()
that should probably go away too. (travelling, can't really do/test
a patch this week).

Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

> ---
>  drivers/net/ethernet/faraday/ftgmac100.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
> index 34dae51effd4..59da7ac3c108 100644
> --- a/drivers/net/ethernet/faraday/ftgmac100.c
> +++ b/drivers/net/ethernet/faraday/ftgmac100.c
> @@ -1863,7 +1863,6 @@ static int ftgmac100_probe(struct platform_device *pdev)
>  err_ioremap:
>  	release_resource(priv->res);
>  err_req_mem:
> -	netif_napi_del(&priv->napi);
>  	free_netdev(netdev);
>  err_alloc_etherdev:
>  	return err;

^ permalink raw reply

* Re: [PATCH v3 3/4] net: stmmac: register parent MDIO node for sun8i-h3-emac
From: Maxime Ripard @ 2017-08-22 16:50 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Andrew Lunn, Corentin Labbe, Rob Herring, Mark Rutland,
	Russell King, Giuseppe Cavallaro, Alexandre Torgue, devicetree,
	linux-arm-kernel, linux-kernel, netdev
In-Reply-To: <CAGb2v64E4T=1ff3POGuXZA=MvjGAnKQ6OF6A3sT_cU-=jh6zNw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 567 bytes --]

On Tue, Aug 22, 2017 at 11:39:22PM +0800, Chen-Yu Tsai wrote:
> Now can we please decide on something? We're a week and a half from
> the 4.13 release. If mdio-mux is wrong, then we could have two mdio
> nodes (internal-mdio & external-mdio).

I can only emphasize this. I'm afraid that if we don't have an
agreement and a patch implementing it with the proper acks by the end
of the week, we'll have to revert all the DT bits and the bindings.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: [PATCH v2 net] udp: on peeking bad csum, drop packets even if not at head
From: Paolo Abeni @ 2017-08-22 16:47 UTC (permalink / raw)
  To: Eric Dumazet, David Miller; +Cc: Willem de Bruijn, netdev
In-Reply-To: <1503419968.2499.33.camel@edumazet-glaptop3.roam.corp.google.com>

On Tue, 2017-08-22 at 09:39 -0700, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
> 
> When peeking, if a bad csum is discovered, the skb is unlinked from
> the queue with __sk_queue_drop_skb and the peek operation restarted.
> 
> __sk_queue_drop_skb only drops packets that match the queue head.
> 
> This fails if the skb was found after the head, using SO_PEEK_OFF
> socket option. This causes an infinite loop.
> 
> We MUST drop this problematic skb, and we can simply check if skb was
> already removed by another thread, by looking at skb->next :
> 
> This pointer is set to NULL by the  __skb_unlink() operation, that might
> have happened only under the spinlock protection.
> 
> Many thanks to syzkaller team (and particularly Dmitry Vyukov who
> provided us nice C reproducers exhibiting the lockup) and Willem de
> Bruijn who provided first version for this patch and a test program.
> 
> Fixes: 627d2d6b5500 ("udp: enable MSG_PEEK at non-zero offset")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Cc: Willem de Bruijn <willemb@google.com>
> ---
>  net/core/datagram.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/core/datagram.c b/net/core/datagram.c
> index a21ca8dee5ea..8c2f4489ff8f 100644
> --- a/net/core/datagram.c
> +++ b/net/core/datagram.c
> @@ -362,7 +362,7 @@ int __sk_queue_drop_skb(struct sock *sk, struct sk_buff_head *sk_queue,
>  	if (flags & MSG_PEEK) {
>  		err = -ENOENT;
>  		spin_lock_bh(&sk_queue->lock);
> -		if (skb == skb_peek(sk_queue)) {
> +		if (skb->next) {
>  			__skb_unlink(skb, sk_queue);
>  			refcount_dec(&skb->users);
>  			if (destructor)
> 

This version is really nice!

Acked-by: Paolo Abeni <pabeni@redhat.com>

^ permalink raw reply

* Re: Something hitting my total number of connections to the server
From: David Ahern @ 2017-08-22 16:43 UTC (permalink / raw)
  To: Eric Dumazet, Akshat Kakkar; +Cc: David Laight, netdev
In-Reply-To: <1503406926.2499.20.camel@edumazet-glaptop3.roam.corp.google.com>

On 8/22/17 6:02 AM, Eric Dumazet wrote:
>>
>> net.core.netdev_max_backlog=10000
> This is an insane backlog.
> 

https://www.kernel.org/doc/Documentation/networking/scaling.txt

"== Suggested Configuration

Flow limit is useful on systems with many concurrent connections,
where a single connection taking up 50% of a CPU indicates a problem.
In such environments, enable the feature on all CPUs that handle
network rx interrupts (as set in /proc/irq/N/smp_affinity).

The feature depends on the input packet queue length to exceed
the flow limit threshold (50%) + the flow history length (256).
Setting net.core.netdev_max_backlog to either 1000 or 10000
performed well in experiments."

^ permalink raw reply

* [PATCHv4 net-next] gre: introduce native tunnel support for ERSPAN
From: William Tu @ 2017-08-22 16:40 UTC (permalink / raw)
  To: netdev; +Cc: Meenakshi Vohra, Alexey Kuznetsov, Hideaki YOSHIFUJI

The patch adds ERSPAN type II tunnel support.  The implementation
is based on the draft at [1].  One of the purposes is for Linux
box to be able to receive ERSPAN monitoring traffic sent from
the Cisco switch, by creating a ERSPAN tunnel device.
In addition, the patch also adds ERSPAN TX, so Linux virtual
switch can redirect monitored traffic to the ERSPAN tunnel device.
The traffic will be encapsulated into ERSPAN and sent out.

The implementation reuses tunnel key as ERSPAN session ID, and
field 'erspan' as ERSPAN Index fields:
./ip link add dev ers11 type erspan seq key 100 erspan 123 \
			local 172.16.1.200 remote 172.16.1.100

To use the above device as ERSPAN receiver, configure
Nexus 5000 switch as below:

monitor session 100 type erspan-source
  erspan-id 123
  vrf default
  destination ip 172.16.1.200
  source interface Ethernet1/11 both
  source interface Ethernet1/12 both
  no shut
monitor erspan origin ip-address 172.16.1.100 global

[1] https://tools.ietf.org/html/draft-foschiano-erspan-01
[2] iproute2 patch: http://marc.info/?l=linux-netdev&m=150306086924951&w=2
[3] test script: http://marc.info/?l=linux-netdev&m=150231021807304&w=2

Signed-off-by: William Tu <u9012063@gmail.com>
Signed-off-by: Meenakshi Vohra <mvohra@vmware.com>
Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
---
v3->v4:
  fix skb_may_pull len
  fix local variable ordering
  fix commit message Nexus set-up
v2->v3:
  add skb_may_pull check at erspan_rcv
  a couple of minor fixes and checks for index value
v1->v2:
  Add missing erspan.h header
---
 include/net/erspan.h           |  61 ++++++++++
 include/net/ip_tunnels.h       |   3 +
 include/uapi/linux/if_ether.h  |   1 +
 include/uapi/linux/if_tunnel.h |   1 +
 net/ipv4/ip_gre.c              | 269 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 335 insertions(+)
 create mode 100644 include/net/erspan.h

diff --git a/include/net/erspan.h b/include/net/erspan.h
new file mode 100644
index 000000000000..ca94fc86865e
--- /dev/null
+++ b/include/net/erspan.h
@@ -0,0 +1,61 @@
+#ifndef __LINUX_ERSPAN_H
+#define __LINUX_ERSPAN_H
+
+/*
+ * GRE header for ERSPAN encapsulation (8 octets [34:41]) -- 8 bytes
+ *       0                   1                   2                   3
+ *      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *     |0|0|0|1|0|00000|000000000|00000|    Protocol Type for ERSPAN   |
+ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *     |      Sequence Number (increments per packet per session)      |
+ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *  Note that in the above GRE header [RFC1701] out of the C, R, K, S,
+ *  s, Recur, Flags, Version fields only S (bit 03) is set to 1. The
+ *  other fields are set to zero, so only a sequence number follows.
+ *
+ *  ERSPAN Type II header (8 octets [42:49])
+ *  0                   1                   2                   3
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  Ver  |          VLAN         | COS | En|T|    Session ID     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      Reserved         |                  Index                |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * GRE proto ERSPAN type II = 0x88BE, type III = 0x22EB
+ */
+
+#define ERSPAN_VERSION	0x1
+
+#define VER_MASK	0xf000
+#define VLAN_MASK	0x0fff
+#define COS_MASK	0xe000
+#define EN_MASK		0x1800
+#define T_MASK		0x0400
+#define ID_MASK		0x03ff
+#define INDEX_MASK	0xfffff
+
+enum erspan_encap_type {
+	ERSPAN_ENCAP_NOVLAN = 0x0,	/* originally without VLAN tag */
+	ERSPAN_ENCAP_ISL = 0x1,		/* originally ISL encapsulated */
+	ERSPAN_ENCAP_8021Q = 0x2,	/* originally 802.1Q encapsulated */
+	ERSPAN_ENCAP_INFRAME = 0x3,	/* VLAN tag perserved in frame */
+};
+
+struct erspan_metadata {
+	__be32 index;   /* type II */
+};
+
+struct erspanhdr {
+	__be16 ver_vlan;
+#define VER_OFFSET  12
+	__be16 session_id;
+#define COS_OFFSET  13
+#define EN_OFFSET   11
+#define T_OFFSET    10
+	struct erspan_metadata md;
+};
+
+#endif
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 520809912f03..625c29329372 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -115,6 +115,9 @@ struct ip_tunnel {
 	u32		o_seqno;	/* The last output seqno */
 	int		tun_hlen;	/* Precalculated header length */
 
+	/* This field used only by ERSPAN */
+	u32		index;		/* ERSPAN type II index */
+
 	struct dst_cache dst_cache;
 
 	struct ip_tunnel_parm parms;
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
index 5bc9bfd816b7..efeb1190c2ca 100644
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@ -66,6 +66,7 @@
 #define ETH_P_ATALK	0x809B		/* Appletalk DDP		*/
 #define ETH_P_AARP	0x80F3		/* Appletalk AARP		*/
 #define ETH_P_8021Q	0x8100          /* 802.1Q VLAN Extended Header  */
+#define ETH_P_ERSPAN	0x88BE		/* ERSPAN type II		*/
 #define ETH_P_IPX	0x8137		/* IPX over DIX			*/
 #define ETH_P_IPV6	0x86DD		/* IPv6 over bluebook		*/
 #define ETH_P_PAUSE	0x8808		/* IEEE Pause frames. See 802.3 31B */
diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h
index 6792d1967d31..2e520883c054 100644
--- a/include/uapi/linux/if_tunnel.h
+++ b/include/uapi/linux/if_tunnel.h
@@ -134,6 +134,7 @@ enum {
 	IFLA_GRE_COLLECT_METADATA,
 	IFLA_GRE_IGNORE_DF,
 	IFLA_GRE_FWMARK,
+	IFLA_GRE_ERSPAN_INDEX,
 	__IFLA_GRE_MAX,
 };
 
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 7a7829e839c2..6e8a62289e03 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -48,6 +48,7 @@
 #include <net/rtnetlink.h>
 #include <net/gre.h>
 #include <net/dst_metadata.h>
+#include <net/erspan.h>
 
 /*
    Problems & solutions
@@ -115,6 +116,7 @@ static int ipgre_tunnel_init(struct net_device *dev);
 
 static unsigned int ipgre_net_id __read_mostly;
 static unsigned int gre_tap_net_id __read_mostly;
+static unsigned int erspan_net_id __read_mostly;
 
 static void ipgre_err(struct sk_buff *skb, u32 info,
 		      const struct tnl_ptk_info *tpi)
@@ -246,6 +248,56 @@ static void gre_err(struct sk_buff *skb, u32 info)
 	ipgre_err(skb, info, &tpi);
 }
 
+static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
+		      int gre_hdr_len)
+{
+	struct net *net = dev_net(skb->dev);
+	struct metadata_dst *tun_dst = NULL;
+	struct ip_tunnel_net *itn;
+	struct ip_tunnel *tunnel;
+	struct erspanhdr *ershdr;
+	const struct iphdr *iph;
+	__be32 session_id;
+	__be32 index;
+	int len;
+
+	itn = net_generic(net, erspan_net_id);
+	iph = ip_hdr(skb);
+	len = gre_hdr_len + sizeof(*ershdr);
+
+	if (unlikely(!pskb_may_pull(skb, len)))
+		return -ENOMEM;
+
+	iph = ip_hdr(skb);
+	ershdr = (struct erspanhdr *)(skb->data + gre_hdr_len);
+
+	/* The original GRE header does not have key field,
+	 * Use ERSPAN 10-bit session ID as key.
+	 */
+	session_id = cpu_to_be32(ntohs(ershdr->session_id));
+	tpi->key = session_id;
+	index = ershdr->md.index;
+	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,
+				  tpi->flags | TUNNEL_KEY,
+				  iph->saddr, iph->daddr, tpi->key);
+
+	if (tunnel) {
+		if (__iptunnel_pull_header(skb,
+					   gre_hdr_len + sizeof(*ershdr),
+					   htons(ETH_P_TEB),
+					   false, false) < 0)
+			goto drop;
+
+		tunnel->index = ntohl(index);
+		skb_reset_mac_header(skb);
+		ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
+		return PACKET_RCVD;
+	}
+drop:
+	kfree_skb(skb);
+	return PACKET_RCVD;
+}
+
 static int __ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
 		       struct ip_tunnel_net *itn, int hdr_len, bool raw_proto)
 {
@@ -328,6 +380,11 @@ static int gre_rcv(struct sk_buff *skb)
 	if (hdr_len < 0)
 		goto drop;
 
+	if (unlikely(tpi.proto == htons(ETH_P_ERSPAN))) {
+		if (erspan_rcv(skb, &tpi, hdr_len) == PACKET_RCVD)
+			return 0;
+	}
+
 	if (ipgre_rcv(skb, &tpi, hdr_len) == PACKET_RCVD)
 		return 0;
 
@@ -503,6 +560,81 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
 	return NETDEV_TX_OK;
 }
 
+static inline u8 tos_to_cos(u8 tos)
+{
+	u8 dscp, cos;
+
+	dscp = tos >> 2;
+	cos = dscp >> 3;
+	return cos;
+}
+
+static void erspan_build_header(struct sk_buff *skb,
+				__be32 id, u32 index, bool truncate)
+{
+	struct iphdr *iphdr = ip_hdr(skb);
+	struct ethhdr *eth = eth_hdr(skb);
+	enum erspan_encap_type enc_type;
+	struct erspanhdr *ershdr;
+	struct qtag_prefix {
+		__be16 eth_type;
+		__be16 tci;
+	} *qp;
+	u16 vlan_tci = 0;
+
+	enc_type = ERSPAN_ENCAP_NOVLAN;
+
+	/* If mirrored packet has vlan tag, extract tci and
+	 *  perserve vlan header in the mirrored frame.
+	 */
+	if (eth->h_proto == htons(ETH_P_8021Q)) {
+		qp = (struct qtag_prefix *)(skb->data + 2 * ETH_ALEN);
+		vlan_tci = ntohs(qp->tci);
+		enc_type = ERSPAN_ENCAP_INFRAME;
+	}
+
+	skb_push(skb, sizeof(*ershdr));
+	ershdr = (struct erspanhdr *)skb->data;
+	memset(ershdr, 0, sizeof(*ershdr));
+
+	ershdr->ver_vlan = htons((vlan_tci & VLAN_MASK) |
+				 (ERSPAN_VERSION << VER_OFFSET));
+	ershdr->session_id = htons((u16)(ntohl(id) & ID_MASK) |
+			   ((tos_to_cos(iphdr->tos) << COS_OFFSET) & COS_MASK) |
+			   (enc_type << EN_OFFSET & EN_MASK) |
+			   ((truncate << T_OFFSET) & T_MASK));
+	ershdr->md.index = htonl(index & INDEX_MASK);
+}
+
+static netdev_tx_t erspan_xmit(struct sk_buff *skb,
+			       struct net_device *dev)
+{
+	struct ip_tunnel *tunnel = netdev_priv(dev);
+	bool truncate = false;
+
+	if (gre_handle_offloads(skb, false))
+		goto free_skb;
+
+	if (skb_cow_head(skb, dev->needed_headroom))
+		goto free_skb;
+
+	if (skb->len > dev->mtu) {
+		pskb_trim(skb, dev->mtu);
+		truncate = true;
+	}
+
+	/* Push ERSPAN header */
+	erspan_build_header(skb, tunnel->parms.o_key, tunnel->index, truncate);
+	tunnel->parms.o_flags &= ~TUNNEL_KEY;
+	__gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_ERSPAN));
+	return NETDEV_TX_OK;
+
+free_skb:
+	kfree_skb(skb);
+	dev->stats.tx_dropped++;
+	return NETDEV_TX_OK;
+}
+
 static netdev_tx_t gre_tap_xmit(struct sk_buff *skb,
 				struct net_device *dev)
 {
@@ -828,6 +960,39 @@ static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[],
 	return ipgre_tunnel_validate(tb, data, extack);
 }
 
+static int erspan_validate(struct nlattr *tb[], struct nlattr *data[],
+			   struct netlink_ext_ack *extack)
+{
+	__be16 flags = 0;
+	int ret;
+
+	if (!data)
+		return 0;
+
+	ret = ipgre_tap_validate(tb, data, extack);
+	if (ret)
+		return ret;
+
+	/* ERSPAN should only have GRE sequence and key flag */
+	flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
+	flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
+	if (flags != (GRE_SEQ | GRE_KEY))
+		return -EINVAL;
+
+	/* ERSPAN Session ID only has 10-bit. Since we reuse
+	 * 32-bit key field as ID, check it's range.
+	 */
+	if (data[IFLA_GRE_IKEY] &&
+	    (ntohl(nla_get_be32(data[IFLA_GRE_IKEY])) & ~ID_MASK))
+		return -EINVAL;
+
+	if (data[IFLA_GRE_OKEY] &&
+	    (ntohl(nla_get_be32(data[IFLA_GRE_OKEY])) & ~ID_MASK))
+		return -EINVAL;
+
+	return 0;
+}
+
 static int ipgre_netlink_parms(struct net_device *dev,
 				struct nlattr *data[],
 				struct nlattr *tb[],
@@ -892,6 +1057,13 @@ static int ipgre_netlink_parms(struct net_device *dev,
 	if (data[IFLA_GRE_FWMARK])
 		*fwmark = nla_get_u32(data[IFLA_GRE_FWMARK]);
 
+	if (data[IFLA_GRE_ERSPAN_INDEX]) {
+		t->index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]);
+
+		if (t->index & ~INDEX_MASK)
+			return -EINVAL;
+	}
+
 	return 0;
 }
 
@@ -949,6 +1121,36 @@ static const struct net_device_ops gre_tap_netdev_ops = {
 	.ndo_fill_metadata_dst	= gre_fill_metadata_dst,
 };
 
+static int erspan_tunnel_init(struct net_device *dev)
+{
+	struct ip_tunnel *tunnel = netdev_priv(dev);
+	int t_hlen;
+
+	tunnel->tun_hlen = 8;
+	tunnel->parms.iph.protocol = IPPROTO_GRE;
+	t_hlen = tunnel->hlen + sizeof(struct iphdr) + sizeof(struct erspanhdr);
+
+	dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4;
+	dev->mtu = ETH_DATA_LEN - t_hlen - 4;
+	dev->features		|= GRE_FEATURES;
+	dev->hw_features	|= GRE_FEATURES;
+	dev->priv_flags		|= IFF_LIVE_ADDR_CHANGE;
+
+	return ip_tunnel_init(dev);
+}
+
+static const struct net_device_ops erspan_netdev_ops = {
+	.ndo_init		= erspan_tunnel_init,
+	.ndo_uninit		= ip_tunnel_uninit,
+	.ndo_start_xmit		= erspan_xmit,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= ip_tunnel_change_mtu,
+	.ndo_get_stats64	= ip_tunnel_get_stats64,
+	.ndo_get_iflink		= ip_tunnel_get_iflink,
+	.ndo_fill_metadata_dst	= gre_fill_metadata_dst,
+};
+
 static void ipgre_tap_setup(struct net_device *dev)
 {
 	ether_setup(dev);
@@ -1041,6 +1243,8 @@ static size_t ipgre_get_size(const struct net_device *dev)
 		nla_total_size(1) +
 		/* IFLA_GRE_FWMARK */
 		nla_total_size(4) +
+		/* IFLA_GRE_ERSPAN_INDEX */
+		nla_total_size(4) +
 		0;
 }
 
@@ -1083,12 +1287,25 @@ static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
 			goto nla_put_failure;
 	}
 
+	if (t->index)
+		if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index))
+			goto nla_put_failure;
+
 	return 0;
 
 nla_put_failure:
 	return -EMSGSIZE;
 }
 
+static void erspan_setup(struct net_device *dev)
+{
+	ether_setup(dev);
+	dev->netdev_ops = &erspan_netdev_ops;
+	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+	ip_tunnel_setup(dev, erspan_net_id);
+}
+
 static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
 	[IFLA_GRE_LINK]		= { .type = NLA_U32 },
 	[IFLA_GRE_IFLAGS]	= { .type = NLA_U16 },
@@ -1107,6 +1324,7 @@ static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
 	[IFLA_GRE_COLLECT_METADATA]	= { .type = NLA_FLAG },
 	[IFLA_GRE_IGNORE_DF]	= { .type = NLA_U8 },
 	[IFLA_GRE_FWMARK]	= { .type = NLA_U32 },
+	[IFLA_GRE_ERSPAN_INDEX]	= { .type = NLA_U32 },
 };
 
 static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
@@ -1139,6 +1357,21 @@ static struct rtnl_link_ops ipgre_tap_ops __read_mostly = {
 	.get_link_net	= ip_tunnel_get_link_net,
 };
 
+static struct rtnl_link_ops erspan_link_ops __read_mostly = {
+	.kind		= "erspan",
+	.maxtype	= IFLA_GRE_MAX,
+	.policy		= ipgre_policy,
+	.priv_size	= sizeof(struct ip_tunnel),
+	.setup		= erspan_setup,
+	.validate	= erspan_validate,
+	.newlink	= ipgre_newlink,
+	.changelink	= ipgre_changelink,
+	.dellink	= ip_tunnel_dellink,
+	.get_size	= ipgre_get_size,
+	.fill_info	= ipgre_fill_info,
+	.get_link_net	= ip_tunnel_get_link_net,
+};
+
 struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
 					u8 name_assign_type)
 {
@@ -1202,6 +1435,26 @@ static struct pernet_operations ipgre_tap_net_ops = {
 	.size = sizeof(struct ip_tunnel_net),
 };
 
+static int __net_init erspan_init_net(struct net *net)
+{
+	return ip_tunnel_init_net(net, erspan_net_id,
+				  &erspan_link_ops, "erspan0");
+}
+
+static void __net_exit erspan_exit_net(struct net *net)
+{
+	struct ip_tunnel_net *itn = net_generic(net, erspan_net_id);
+
+	ip_tunnel_delete_net(itn, &erspan_link_ops);
+}
+
+static struct pernet_operations erspan_net_ops = {
+	.init = erspan_init_net,
+	.exit = erspan_exit_net,
+	.id   = &erspan_net_id,
+	.size = sizeof(struct ip_tunnel_net),
+};
+
 static int __init ipgre_init(void)
 {
 	int err;
@@ -1216,6 +1469,10 @@ static int __init ipgre_init(void)
 	if (err < 0)
 		goto pnet_tap_faied;
 
+	err = register_pernet_device(&erspan_net_ops);
+	if (err < 0)
+		goto pnet_erspan_failed;
+
 	err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
 	if (err < 0) {
 		pr_info("%s: can't add protocol\n", __func__);
@@ -1230,13 +1487,21 @@ static int __init ipgre_init(void)
 	if (err < 0)
 		goto tap_ops_failed;
 
+	err = rtnl_link_register(&erspan_link_ops);
+	if (err < 0)
+		goto erspan_link_failed;
+
 	return 0;
 
+erspan_link_failed:
+	rtnl_link_unregister(&ipgre_tap_ops);
 tap_ops_failed:
 	rtnl_link_unregister(&ipgre_link_ops);
 rtnl_link_failed:
 	gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
 add_proto_failed:
+	unregister_pernet_device(&erspan_net_ops);
+pnet_erspan_failed:
 	unregister_pernet_device(&ipgre_tap_net_ops);
 pnet_tap_faied:
 	unregister_pernet_device(&ipgre_net_ops);
@@ -1247,9 +1512,11 @@ static void __exit ipgre_fini(void)
 {
 	rtnl_link_unregister(&ipgre_tap_ops);
 	rtnl_link_unregister(&ipgre_link_ops);
+	rtnl_link_unregister(&erspan_link_ops);
 	gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
 	unregister_pernet_device(&ipgre_tap_net_ops);
 	unregister_pernet_device(&ipgre_net_ops);
+	unregister_pernet_device(&erspan_net_ops);
 }
 
 module_init(ipgre_init);
@@ -1257,5 +1524,7 @@ module_exit(ipgre_fini);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_RTNL_LINK("gre");
 MODULE_ALIAS_RTNL_LINK("gretap");
+MODULE_ALIAS_RTNL_LINK("erspan");
 MODULE_ALIAS_NETDEV("gre0");
 MODULE_ALIAS_NETDEV("gretap0");
+MODULE_ALIAS_NETDEV("erspan0");
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH v3 2/4] net: stmmac: dwmac-sun8i: choose internal PHY via phy-is-integrated
From: Florian Fainelli @ 2017-08-22 16:40 UTC (permalink / raw)
  To: Corentin Labbe, robh+dt, mark.rutland, linux, maxime.ripard, wens,
	peppe.cavallaro, alexandre.torgue
  Cc: devicetree, linux-kernel, linux-arm-kernel, netdev
In-Reply-To: <20170818122118.4925-3-clabbe.montjoie@gmail.com>

On 08/18/2017 05:21 AM, Corentin Labbe wrote:
> The current way to find if the phy is internal is to compare DT phy-mode
> and emac_variant/internal_phy.
> But it will negate a possible future SoC where an external PHY use the
> same phy mode than the internal one.
> 
> This patch adds a new way to find if the PHY is internal, via
> the phy-is-integrated property.
> 
> Since the internal_phy variable does not need anymore to contain the xMII mode
> used by the internal PHY, it is still used for knowing the presence of an
> internal PHY, so it is modified to a boolean soc_has_internal_phy.
> 
> Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [PATCH v3 3/4] net: stmmac: register parent MDIO node for sun8i-h3-emac
From: Florian Fainelli @ 2017-08-22 16:40 UTC (permalink / raw)
  To: Chen-Yu Tsai, Andrew Lunn
  Cc: Maxime Ripard, Corentin Labbe, Rob Herring, Mark Rutland,
	Russell King, Giuseppe Cavallaro, Alexandre Torgue, devicetree,
	linux-arm-kernel, linux-kernel, netdev
In-Reply-To: <CAGb2v64E4T=1ff3POGuXZA=MvjGAnKQ6OF6A3sT_cU-=jh6zNw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On 08/22/2017 08:39 AM, Chen-Yu Tsai wrote:
> On Mon, Aug 21, 2017 at 10:23 PM, Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org> wrote:
>>> All muxes are mostly always represented the same way afaik, or do you
>>> want to simply introduce a new compatible / property?
>>
>> +         mdio-mux {
>> +               compatible = "allwinner,sun8i-h3-mdio-switch";
>> +               mdio-parent-bus = <&mdio_parent>;
>> +               #address-cells = <1>;
>> +               #size-cells = <0>;
>> +
>> +               internal_mdio: mdio@1 {
>>                         reg = <1>;
>> -                       clocks = <&ccu CLK_BUS_EPHY>;
>> -                       resets = <&ccu RST_BUS_EPHY>;
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +                       int_mii_phy: ethernet-phy@1 {
>> +                               compatible = "ethernet-phy-ieee802.3-c22";
>> +                               reg = <1>;
>> +                               clocks = <&ccu CLK_BUS_EPHY>;
>> +                               resets = <&ccu RST_BUS_EPHY>;
>> +                               phy-is-integrated;
>> +                       };
>> +               };
>> +               mdio: mdio@0 {
>> +                       reg = <0>;
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>>                 };
>>
>> Hi Maxim
>>
>> Anybody who knows the MDIO-mux code/binding, knows that it is a run
>> time mux. You swap the mux per MDIO transaction. You can access all
>> the PHY and switches on the mux'ed MDIO bus.
>>
>> However here, it is effectively a boot-time MUX. You cannot change it
>> on the fly. What happens when somebody has a phandle to a PHY on the
>> internal and a phandle to a phy on the external? Does the driver at
>> least return -EINVAL, or -EBUSY? Is there a representation which
>> eliminates this possibility?
> 
> There is only one controller. Either you use the internal PHY, which
> is then directly coupled (no magnetics needed) to the RJ45 port, or
> you use an external PHY over MII/RMII/RGMII. You could supposedly
> have both on a board, and let the user choose one. But why bother
> with the extra complexity and cost? Either you use the internal PHY
> at 100M, or an external RGMII PHY for gigabit speeds.

I agree, there is no point in over-engineering any of this. I don't
think there is actually any MDIO mux per-se in that the MDIO clock and
data lines are muxed, however there has to be some kind of built-in port
multiplexer that lets you chose between connecting to the internal PHY
and any external PHY/MAC, but that is not what a "mdio-mux" node represents.

> 
> So I think what you are saying is either impossible or engineering-wise
> a very stupid design, like using an external MAC with a discrete PHY
> connected to the internal MAC's MDIO bus, while using the internal MAC
> with the internal PHY.
> 
> Now can we please decide on something? We're a week and a half from
> the 4.13 release. If mdio-mux is wrong, then we could have two mdio
> nodes (internal-mdio & external-mdio).

I really don't see a need for a mdio-mux in the first place, just have
one MDIO controller (current state) sub-node which describes the
built-in STMMAC MDIO controller and declare the internal PHY as a child
node (along with 'phy-is-integrated'). If a different configuration is
used, then just put the external PHY as a child node there.

If fixed-link is required, the mdio node becomes unused anyway.

Works for everyone?
-- 
Florian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v2 net] udp: on peeking bad csum, drop packets even if not at head
From: Eric Dumazet @ 2017-08-22 16:39 UTC (permalink / raw)
  To: David Miller; +Cc: pabeni, Willem de Bruijn, netdev
In-Reply-To: <1503355232.2499.15.camel@edumazet-glaptop3.roam.corp.google.com>

From: Eric Dumazet <edumazet@google.com>

When peeking, if a bad csum is discovered, the skb is unlinked from
the queue with __sk_queue_drop_skb and the peek operation restarted.

__sk_queue_drop_skb only drops packets that match the queue head.

This fails if the skb was found after the head, using SO_PEEK_OFF
socket option. This causes an infinite loop.

We MUST drop this problematic skb, and we can simply check if skb was
already removed by another thread, by looking at skb->next :

This pointer is set to NULL by the  __skb_unlink() operation, that might
have happened only under the spinlock protection.

Many thanks to syzkaller team (and particularly Dmitry Vyukov who
provided us nice C reproducers exhibiting the lockup) and Willem de
Bruijn who provided first version for this patch and a test program.

Fixes: 627d2d6b5500 ("udp: enable MSG_PEEK at non-zero offset")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Cc: Willem de Bruijn <willemb@google.com>
---
 net/core/datagram.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/core/datagram.c b/net/core/datagram.c
index a21ca8dee5ea..8c2f4489ff8f 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -362,7 +362,7 @@ int __sk_queue_drop_skb(struct sock *sk, struct sk_buff_head *sk_queue,
 	if (flags & MSG_PEEK) {
 		err = -ENOENT;
 		spin_lock_bh(&sk_queue->lock);
-		if (skb == skb_peek(sk_queue)) {
+		if (skb->next) {
 			__skb_unlink(skb, sk_queue);
 			refcount_dec(&skb->users);
 			if (destructor)

^ permalink raw reply related

* Re: [PATCH v4 net-next] arm: eBPF JIT compiler
From: David Miller @ 2017-08-22 16:32 UTC (permalink / raw)
  To: illusionist.neo
  Cc: linux, netdev, ast, daniel, linux-arm-kernel, linux-kernel,
	keescook
In-Reply-To: <1503383772-5788-1-git-send-email-illusionist.neo@gmail.com>


You posted this 4 times. :-(

I hope I applied the right one.

Go check net-next and please send me any necessary fix up patches.

Thanks.

^ permalink raw reply

* Re: [PATCH net-next v4] arm: eBPF JIT compiler
From: David Miller @ 2017-08-22 16:28 UTC (permalink / raw)
  To: illusionist.neo
  Cc: linux, netdev, ast, daniel, linux-arm-kernel, linux-kernel,
	keescook, andrew
In-Reply-To: <1503383553-5650-1-git-send-email-illusionist.neo@gmail.com>

From: Shubham Bansal <illusionist.neo@gmail.com>
Date: Tue, 22 Aug 2017 12:02:33 +0530

> The JIT compiler emits ARM 32 bit instructions. Currently, It
> supports eBPF only. Classic BPF is supported because of the
> conversion by BPF core.
 ...

Applied to net-next, thanks.

^ permalink raw reply

* Fw: [Bug 196727] New: WARNING: CPU: 11 PID: 0 at net/sched/sch_generic.c:316 dev_watchdog+0xc5/0x122
From: Stephen Hemminger @ 2017-08-22 16:01 UTC (permalink / raw)
  To: netdev

New Intel driver timeout?

Begin forwarded message:

Date: Tue, 22 Aug 2017 06:51:58 +0000
From: bugzilla-daemon@bugzilla.kernel.org
To: stephen@networkplumber.org
Subject: [Bug 196727] New: WARNING: CPU: 11 PID: 0 at net/sched/sch_generic.c:316 dev_watchdog+0xc5/0x122


https://bugzilla.kernel.org/show_bug.cgi?id=196727

            Bug ID: 196727
           Summary: WARNING: CPU: 11 PID: 0 at net/sched/sch_generic.c:316
                    dev_watchdog+0xc5/0x122
           Product: Networking
           Version: 2.5
    Kernel Version: 4.12.8
          Hardware: Intel
                OS: Linux
              Tree: Mainline
            Status: NEW
          Severity: high
          Priority: P1
         Component: Other
          Assignee: stephen@networkplumber.org
          Reporter: pstaszewski@artcom.pl
        Regression: No

[ 2452.163445] NETDEV WATCHDOG: eth0 (ixgbe): transmit queue 0 timed out
[ 2452.163467] ------------[ cut here ]------------
[ 2452.163475] WARNING: CPU: 11 PID: 0 at net/sched/sch_generic.c:316
dev_watchdog+0xc5/0x122
[ 2452.163476] Modules linked in: ipmi_si x86_pkg_temp_thermal
[ 2452.163482] CPU: 11 PID: 0 Comm: swapper/11 Tainted: G          I     4.12.8
#1
[ 2452.163483] task: ffff88086d8fe200 task.stack: ffffc90003214000
[ 2452.163485] RIP: 0010:dev_watchdog+0xc5/0x122
[ 2452.163485] RSP: 0018:ffff88087f843ea0 EFLAGS: 00010286
[ 2452.163486] RAX: 0000000000000039 RBX: ffff88046ca78000 RCX:
0000000000000000
[ 2452.163487] RDX: ffff88087f853310 RSI: ffff88087f84caa8 RDI:
ffff88087f84caa8
[ 2452.163487] RBP: ffff88087f843eb0 R08: 0000000000000000 R09:
0000000000000000
[ 2452.163488] R10: 00000000003d0900 R11: ffff88087ff9194c R12:
0000000000000000
[ 2452.163489] R13: ffffffff815a37a2 R14: ffff88046ca78438 R15:
ffff88046ca78000
[ 2452.163490] FS:  0000000000000000(0000) GS:ffff88087f840000(0000)
knlGS:0000000000000000
[ 2452.163490] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2452.163491] CR2: 00000000006b2008 CR3: 0000000001c09000 CR4:
00000000001406e0
[ 2452.163492] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[ 2452.163492] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7:
0000000000000400
[ 2452.163493] Call Trace:
[ 2452.163494]  <IRQ>
[ 2452.163500]  call_timer_fn+0x5b/0x123
[ 2452.163501]  run_timer_softirq+0x137/0x15a
[ 2452.163503]  ? tk_clock_read+0xc/0xe
[ 2452.163505]  ? timekeeping_get_ns+0x1d/0x31
[ 2452.163506]  ? ktime_get+0x2d/0x3e
[ 2452.163508]  __do_softirq+0xe4/0x23a
[ 2452.163512]  ? tick_program_event+0x5d/0x64
[ 2452.163513]  irq_exit+0x4d/0x5b
[ 2452.163518]  smp_apic_timer_interrupt+0x29/0x34
[ 2452.163520]  apic_timer_interrupt+0x86/0x90
[ 2452.163524] RIP: 0010:cpuidle_enter_state+0x12f/0x184
[ 2452.163525] RSP: 0018:ffffc90003217ea0 EFLAGS: 00000246 ORIG_RAX:
ffffffffffffff10
[ 2452.163526] RAX: 0000023af054988b RBX: 0000000000000002 RCX:
000000000000001f
[ 2452.163527] RDX: 0000000000000000 RSI: 000000000000000b RDI:
0000000000000000
[ 2452.163527] RBP: ffffc90003217ed0 R08: 00000000ffffffe3 R09:
000000003ff003ff
[ 2452.163528] R10: ffffc90003217e70 R11: 0000000000000004 R12:
ffff88086c10d400
[ 2452.163528] R13: 0000023af054988b R14: 0000000000000002 R15:
0000023af0528d14
[ 2452.163529]  </IRQ>
[ 2452.163531]  cpuidle_enter+0x12/0x14
[ 2452.163534]  do_idle+0x10e/0x166
[ 2452.163535]  cpu_startup_entry+0x1a/0x1c
[ 2452.163537]  start_secondary+0xd0/0xd3
[ 2452.163540]  secondary_startup_64+0x9f/0x9f
[ 2452.163541] Code: 70 15 73 00 00 75 38 48 89 df c6 05 64 15 73 00 01 e8 1d
4a fe ff 44 89 e1 48 89 de 48 c7 c7 eb 8f a9 81 48 89 c2 e8 b4 ab b3 ff <0f> ff
eb 10 41 ff c4 48 05 40 01 00 00 41 39 f4 75 9a eb 0d 48
[ 2452.163559] ---[ end trace e35aaedfdb6bf6da ]---
[ 2452.163562] ixgbe 0000:02:00.0 eth0: initiating reset due to tx timeout
[ 2452.163579] ixgbe 0000:02:00.0 eth0: Reset adapter
[ 2473.173038] ixgbe 0000:02:00.0 eth0: detected SFP+: 5
[ 2473.325081] ixgbe 0000:02:00.0 eth0: NIC Link is Up 10 Gbps, Flow Control:
None
[ 2473.450701] ixgbe 0000:02:00.0 eth0: NIC Link is Down
[ 2473.450784] ixgbe 0000:02:00.0 eth0: initiating reset to clear Tx work after
link loss
[ 2473.537116] ixgbe 0000:02:00.0 eth0: Reset adapter
[ 2473.821091] ixgbe 0000:02:00.0 eth0: detected SFP+: 5
[ 2473.969178] ixgbe 0000:02:00.0 eth0: NIC Link is Up 10 Gbps, Flow Control:
None
[ 2474.112745] ixgbe 0000:02:00.0 eth0: NIC Link is Down
[ 2474.112830] ixgbe 0000:02:00.0 eth0: initiating reset to clear Tx work after
link loss
[ 2474.177126] ixgbe 0000:02:00.0 eth0: Reset adapter
[ 2474.461154] ixgbe 0000:02:00.0 eth0: detected SFP+: 5
[ 2474.613208] ixgbe 0000:02:00.0 eth0: NIC Link is Up 10 Gbps, Flow Control:
None

-- 
You are receiving this mail because:
You are the assignee for the bug.

^ permalink raw reply

* Re: [PATCH net-next 4/4] bpf/verifier: document liveness analysis
From: Alexei Starovoitov @ 2017-08-22 15:59 UTC (permalink / raw)
  To: Edward Cree, davem, Alexei Starovoitov, Daniel Borkmann
  Cc: netdev, iovisor-dev
In-Reply-To: <127935e3-d7a0-d626-09ca-462152b2a9cc@solarflare.com>

On 8/22/17 8:55 AM, Edward Cree wrote:
> On 22/08/17 16:42, Alexei Starovoitov wrote:
>> On 8/22/17 6:27 AM, Edward Cree wrote:
>>>  static bool do_propagate_liveness(const struct bpf_verifier_state *state,
>>>                    struct bpf_verifier_state *parent)
>>>  {
>>> @@ -3457,6 +3463,15 @@ static bool do_propagate_liveness(const struct bpf_verifier_state *state,
>>>      return touched;
>>>  }
>>>
>>> +/* "parent" is "a state from which we reach the current state", but initially
>>> + * it is not the state->parent (i.e. "the state whose straight-line code leads
>>> + * to the current state"), instead it is the state that happened to arrive at
>>> + * a (prunable) equivalent of the current state.  See comment above
>>> + * do_propagate_liveness() for consequences of this.
>>> + * This function is just a more efficient way of calling mark_reg_read() or
>>> + * mark_stack_slot_read() on each reg in "parent" that is read in "state", so
>>> + * long as parent != state->parent.
>>> + */
>>
>> i'm confused with 'so long as parent != state->parent' which implies
>> looping and multiple iterations, whereas 'parent != state->parent'
>> condition is true only for the first iteration of
>> 'while (do_propagate_liveness(state, parent))' loop.
>> right ?
> I phrased it badly.  I mean that, the statement "this function is just a
>  way to mark_reg_read() all the things" is true only "so long as" (i.e.
>  under the condition) parent != state->parent.

got it.

> How about
> /* This function is just a more efficient way of calling mark_reg_read() or
>  * mark_stack_slot_read() on each reg in "parent" that is read in "state",
>  * though it requires that parent != state->parent in the call arguments.
>  */

Thanks. It's more clear to me. Ack

^ permalink raw reply

* Re: [PATCH net-next 4/4] bpf/verifier: document liveness analysis
From: Edward Cree @ 2017-08-22 15:55 UTC (permalink / raw)
  To: Alexei Starovoitov, davem, Alexei Starovoitov, Daniel Borkmann
  Cc: netdev, iovisor-dev
In-Reply-To: <36605f53-479d-a32d-ed2e-721c13f0080a@fb.com>

On 22/08/17 16:42, Alexei Starovoitov wrote:
> On 8/22/17 6:27 AM, Edward Cree wrote:
>>  static bool do_propagate_liveness(const struct bpf_verifier_state *state,
>>                    struct bpf_verifier_state *parent)
>>  {
>> @@ -3457,6 +3463,15 @@ static bool do_propagate_liveness(const struct bpf_verifier_state *state,
>>      return touched;
>>  }
>>
>> +/* "parent" is "a state from which we reach the current state", but initially
>> + * it is not the state->parent (i.e. "the state whose straight-line code leads
>> + * to the current state"), instead it is the state that happened to arrive at
>> + * a (prunable) equivalent of the current state.  See comment above
>> + * do_propagate_liveness() for consequences of this.
>> + * This function is just a more efficient way of calling mark_reg_read() or
>> + * mark_stack_slot_read() on each reg in "parent" that is read in "state", so
>> + * long as parent != state->parent.
>> + */
>
> i'm confused with 'so long as parent != state->parent' which implies
> looping and multiple iterations, whereas 'parent != state->parent'
> condition is true only for the first iteration of
> 'while (do_propagate_liveness(state, parent))' loop.
> right ?
I phrased it badly.  I mean that, the statement "this function is just a
 way to mark_reg_read() all the things" is true only "so long as" (i.e.
 under the condition) parent != state->parent.
How about
/* This function is just a more efficient way of calling mark_reg_read() or
 * mark_stack_slot_read() on each reg in "parent" that is read in "state",
 * though it requires that parent != state->parent in the call arguments.
 */
?

^ permalink raw reply

* Re: [PATCH net-next 3/4] bpf/verifier: when pruning a branch, ignore its write marks
From: Edward Cree via iovisor-dev @ 2017-08-22 15:50 UTC (permalink / raw)
  To: Alexei Starovoitov, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	Alexei Starovoitov, Daniel Borkmann
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, iovisor-dev
In-Reply-To: <0ba423e6-8629-37b1-b772-0734f1fb5489-b10kYP2dOMg@public.gmane.org>

On 22/08/17 16:24, Alexei Starovoitov wrote:
> On 8/22/17 6:27 AM, Edward Cree wrote:
>> The fact that writes occurred in reaching the continuation state does
>>  not screen off its reads from us, because we're not really its parent.
>> So detect 'not really the parent' in do_propagate_liveness, and ignore
>>  write marks in that case.
>>
>> Fixes: dc503a8ad984 ("bpf/verifier: track liveness for pruning")
>> Signed-off-by: Edward Cree <ecree-s/n/eUQHGBpZroRs9YW3xA@public.gmane.org>
>> ---
>>  kernel/bpf/verifier.c | 9 +++++++--
>>  1 file changed, 7 insertions(+), 2 deletions(-)
>>
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index 1e3f56c..711bdbd 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -3420,6 +3420,7 @@ static bool states_equal(struct bpf_verifier_env *env,
>>  static bool do_propagate_liveness(const struct bpf_verifier_state *state,
>>                    struct bpf_verifier_state *parent)
>>  {
>> +    bool writes = parent == state->parent; /* Observe write marks */
>>      bool touched = false; /* any changes made? */
>>      int i;
>>
>> @@ -3431,7 +3432,9 @@ static bool do_propagate_liveness(const struct bpf_verifier_state *state,
>>      for (i = 0; i < BPF_REG_FP; i++) {
>>          if (parent->regs[i].live & REG_LIVE_READ)
>>              continue;
>> -        if (state->regs[i].live == REG_LIVE_READ) {
>> +        if (writes && (state->regs[i].live & REG_LIVE_WRITTEN))
>> +            continue;
>> +        if (state->regs[i].live & REG_LIVE_READ) {
>
> makes sense to me.
> if i understand correctly it not only should make the liveness marking
> correct, but improve the numbers, since smaller number of states
> will have READ marks.
Other way round; it means we sometimes ignore WRITTEN marks, so more states
 get READ marks.  On the cilium progs, the bpf_lxc.o get about 100 extra
 insns processed, the others are unchanged.
> Do you have a test case for this by any chance?
I haven't constructed one; my test was just to put in some debug code that
 checked on each propagate_liveness call whether there were any write marks
 in the first state.
I think something like
    if (cond)
        r0=0;
    if (cond)
        r0=0;
    return r0;
might tickle the bug, but I'm not sure.

^ permalink raw reply

* Re: [PATCHv3 net-next] gre: introduce native tunnel support for ERSPAN
From: William Tu @ 2017-08-22 15:44 UTC (permalink / raw)
  To: David Miller
  Cc: Linux Kernel Network Developers, Meenakshi Vohra,
	Alexey Kuznetsov, Hideaki YOSHIFUJI
In-Reply-To: <20170821.110226.325505016722205417.davem@davemloft.net>

>> +     struct metadata_dst *tun_dst = NULL;
>> +     const struct iphdr *iph;
>> +     struct erspanhdr *ershdr;
>> +     __be32 index;
>> +     __be32 session_id;
>> +     int len;
>
> Please order local variables from longest to shortest line, ie. reverse
> christmas tree format.
>
thanks for the review, I will fix the ordering in next version.

>> +
>> +     itn = net_generic(net, erspan_net_id);
>> +     iph = ip_hdr(skb);
>> +     len =  iph->ihl * 4 + gre_hdr_len + sizeof(*ershdr);
>> +
>> +     if (unlikely(!pskb_may_pull(skb, len)))
>> +             return -ENOMEM;
>
> I think the len passed here is wrong, it should be
> "gre_hdr_len + sizeof(*ershdr)".

yes, thanks.
The skb->data at this point points to the beginning of GRE header. So
I should check pull of gre + erspan header.

Regards,
William

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox