Netdev List
 help / color / mirror / Atom feed
* [PATCH v2 7/9] clk: rockchip: add clock-id for rk3036 emac pll source clock
From: Caesar Wang @ 2016-03-13  9:07 UTC (permalink / raw)
  To: Heiko Stuebner, David S. Miller, Rob Herring
  Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA,
	sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8, Xing Zheng,
	Ian Campbell, netdev-u79uwXL29TY76Z2rM5mHXA, Kumar Gala,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Pawel Moll,
	keescook-hpIqsD4AKlfQT0dZR+AlfA, leozwang-hpIqsD4AKlfQT0dZR+AlfA,
	Caesar Wang
In-Reply-To: <1457860062-5514-1-git-send-email-wxt-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

From: Xing Zheng <zhengxing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

Suitable PLLs for the emac on the rk3036 are difficult to find
and one of them is the (continuously changing) APLL. So in most
cases it will be necessary to select a PLL manually.
So add a clock-id for it.

Signed-off-by: Xing Zheng <zhengxing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
Signed-off-by: Caesar Wang <wxt-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---

Changes in v2: None

 include/dt-bindings/clock/rk3036-cru.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/clock/rk3036-cru.h b/include/dt-bindings/clock/rk3036-cru.h
index 3396591..de44109 100644
--- a/include/dt-bindings/clock/rk3036-cru.h
+++ b/include/dt-bindings/clock/rk3036-cru.h
@@ -54,6 +54,7 @@
 #define SCLK_PVTM_VIDEO		125
 #define SCLK_MAC		151
 #define SCLK_MACREF		152
+#define SCLK_MACPLL		153
 #define SCLK_SFC		160
 
 /* aclk gates */
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 6/9] clk: rockchip: associate the rk3036 HCLK_EMAC clock-id
From: Caesar Wang @ 2016-03-13  9:07 UTC (permalink / raw)
  To: Heiko Stuebner, David S. Miller, Rob Herring
  Cc: sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8, Xing Zheng,
	netdev-u79uwXL29TY76Z2rM5mHXA, Michael Turquette, Stephen Boyd,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	keescook-hpIqsD4AKlfQT0dZR+AlfA, linux-clk-u79uwXL29TY76Z2rM5mHXA,
	leozwang-hpIqsD4AKlfQT0dZR+AlfA, Caesar Wang
In-Reply-To: <1457860062-5514-1-git-send-email-wxt-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

From: Xing Zheng <zhengxing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

Associate the new clock id the clock.

Signed-off-by: Xing Zheng <zhengxing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
Signed-off-by: Caesar Wang <wxt-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---

Changes in v2: None

 drivers/clk/rockchip/clk-rk3036.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c
index 0703c8f..cc66e5f 100644
--- a/drivers/clk/rockchip/clk-rk3036.c
+++ b/drivers/clk/rockchip/clk-rk3036.c
@@ -408,7 +408,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
 	GATE(HCLK_OTG1, "hclk_otg1", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 3, GFLAGS),
 	GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS),
 	GATE(0, "hclk_sfc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS),
-	GATE(0, "hclk_mac", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 15, GFLAGS),
+	GATE(HCLK_MAC, "hclk_mac", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS),
 
 	/* pclk_peri gates */
 	GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS),
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 4/9] net: arc: trivial: cleanup the emac driver
From: Caesar Wang @ 2016-03-13  9:07 UTC (permalink / raw)
  To: Heiko Stuebner, David S. Miller, Rob Herring
  Cc: Jiri Kosina, Xing Zheng,
	sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8,
	Alexander Kochetkov, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	keescook-hpIqsD4AKlfQT0dZR+AlfA, leozwang-hpIqsD4AKlfQT0dZR+AlfA,
	Caesar Wang
In-Reply-To: <1457860062-5514-1-git-send-email-wxt-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

This patch will make the driver more readability

The emac has the error and warnings if you run
'scripts/checkpatch.pl -f --subjective xxx' to check.

Let's clean up such trivial details.

Signed-off-by: Caesar Wang <wxt-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---

Changes in v2:
- As the robot notice the build error since overflow in implicit
  constant conversion.

 drivers/net/ethernet/arc/emac.h          | 54 +++++++++++++++++---------------
 drivers/net/ethernet/arc/emac_main.c     | 35 ++++++++++-----------
 drivers/net/ethernet/arc/emac_mdio.c     |  2 +-
 drivers/net/ethernet/arc/emac_rockchip.c | 41 +++++++++++++++++-------
 4 files changed, 75 insertions(+), 57 deletions(-)

diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h
index 1a40403..ca562bc 100644
--- a/drivers/net/ethernet/arc/emac.h
+++ b/drivers/net/ethernet/arc/emac.h
@@ -14,36 +14,36 @@
 #include <linux/clk.h>
 
 /* STATUS and ENABLE Register bit masks */
-#define TXINT_MASK	(1<<0)	/* Transmit interrupt */
-#define RXINT_MASK	(1<<1)	/* Receive interrupt */
-#define ERR_MASK	(1<<2)	/* Error interrupt */
-#define TXCH_MASK	(1<<3)	/* Transmit chaining error interrupt */
-#define MSER_MASK	(1<<4)	/* Missed packet counter error */
-#define RXCR_MASK	(1<<8)	/* RXCRCERR counter rolled over  */
-#define RXFR_MASK	(1<<9)	/* RXFRAMEERR counter rolled over */
-#define RXFL_MASK	(1<<10)	/* RXOFLOWERR counter rolled over */
-#define MDIO_MASK	(1<<12)	/* MDIO complete interrupt */
-#define TXPL_MASK	(1<<31)	/* Force polling of BD by EMAC */
+#define TXINT_MASK	(1 << 0)	/* Transmit interrupt */
+#define RXINT_MASK	(1 << 1)	/* Receive interrupt */
+#define ERR_MASK	(1 << 2)	/* Error interrupt */
+#define TXCH_MASK	(1 << 3)	/* Transmit chaining error interrupt */
+#define MSER_MASK	(1 << 4)	/* Missed packet counter error */
+#define RXCR_MASK	(1 << 8)	/* RXCRCERR counter rolled over  */
+#define RXFR_MASK	(1 << 9)	/* RXFRAMEERR counter rolled over */
+#define RXFL_MASK	(1 << 10)	/* RXOFLOWERR counter rolled over */
+#define MDIO_MASK	(1 << 12)	/* MDIO complete interrupt */
+#define TXPL_MASK	(1 << 31)	/* Force polling of BD by EMAC */
 
 /* CONTROL Register bit masks */
-#define EN_MASK		(1<<0)	/* VMAC enable */
-#define TXRN_MASK	(1<<3)	/* TX enable */
-#define RXRN_MASK	(1<<4)	/* RX enable */
-#define DSBC_MASK	(1<<8)	/* Disable receive broadcast */
-#define ENFL_MASK	(1<<10)	/* Enable Full-duplex */
-#define PROM_MASK	(1<<11)	/* Promiscuous mode */
+#define EN_MASK		(1 << 0)	/* VMAC enable */
+#define TXRN_MASK	(1 << 3)	/* TX enable */
+#define RXRN_MASK	(1 << 4)	/* RX enable */
+#define DSBC_MASK	(1 << 8)	/* Disable receive broadcast */
+#define ENFL_MASK	(1 << 10)	/* Enable Full-duplex */
+#define PROM_MASK	(1 << 11)	/* Promiscuous mode */
 
 /* Buffer descriptor INFO bit masks */
-#define OWN_MASK	(1<<31)	/* 0-CPU owns buffer, 1-EMAC owns buffer */
-#define FIRST_MASK	(1<<16)	/* First buffer in chain */
-#define LAST_MASK	(1<<17)	/* Last buffer in chain */
+#define OWN_MASK	(1 << 31)	/* 0-CPU or 1-EMAC owns buffer */
+#define FIRST_MASK	(1 << 16)	/* First buffer in chain */
+#define LAST_MASK	(1 << 17)	/* Last buffer in chain */
 #define LEN_MASK	0x000007FF	/* last 11 bits */
-#define CRLS		(1<<21)
-#define DEFR		(1<<22)
-#define DROP		(1<<23)
-#define RTRY		(1<<24)
-#define LTCL		(1<<28)
-#define UFLO		(1<<29)
+#define CRLS		(1 << 21)
+#define DEFR		(1 << 22)
+#define DROP		(1 << 23)
+#define RTRY		(1 << 24)
+#define LTCL		(1 << 28)
+#define UFLO		(1 << 29)
 
 #define FOR_EMAC	OWN_MASK
 #define FOR_CPU		0
@@ -66,7 +66,7 @@ enum {
 	R_MDIO,
 };
 
-#define TX_TIMEOUT		(400*HZ/1000)	/* Transmission timeout */
+#define TX_TIMEOUT		(400 * HZ / 1000) /* Transmission timeout */
 
 #define ARC_EMAC_NAPI_WEIGHT	40		/* Workload for NAPI */
 
@@ -196,6 +196,7 @@ static inline unsigned int arc_reg_get(struct arc_emac_priv *priv, int reg)
 static inline void arc_reg_or(struct arc_emac_priv *priv, int reg, int mask)
 {
 	unsigned int value = arc_reg_get(priv, reg);
+
 	arc_reg_set(priv, reg, value | mask);
 }
 
@@ -211,6 +212,7 @@ static inline void arc_reg_or(struct arc_emac_priv *priv, int reg, int mask)
 static inline void arc_reg_clr(struct arc_emac_priv *priv, int reg, int mask)
 {
 	unsigned int value = arc_reg_get(priv, reg);
+
 	arc_reg_set(priv, reg, value & ~mask);
 }
 
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index 6446af1..a3a9392 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -26,7 +26,6 @@
 
 #include "emac.h"
 
-
 /**
  * arc_emac_tx_avail - Return the number of available slots in the tx ring.
  * @priv: Pointer to ARC EMAC private data structure.
@@ -66,7 +65,7 @@ static void arc_emac_adjust_link(struct net_device *ndev)
 	if (priv->duplex != phy_dev->duplex) {
 		reg = arc_reg_get(priv, R_CTRL);
 
-		if (DUPLEX_FULL == phy_dev->duplex)
+		if (phy_dev->duplex == DUPLEX_FULL)
 			reg |= ENFL_MASK;
 		else
 			reg &= ~ENFL_MASK;
@@ -466,9 +465,9 @@ static int arc_emac_open(struct net_device *ndev)
 
 	/* Set CONTROL */
 	arc_reg_set(priv, R_CTRL,
-		     (RX_BD_NUM << 24) |	/* RX BD table length */
-		     (TX_BD_NUM << 16) |	/* TX BD table length */
-		     TXRN_MASK | RXRN_MASK);
+		    (RX_BD_NUM << 24) |	/* RX BD table length */
+		    (TX_BD_NUM << 16) |	/* TX BD table length */
+		    TXRN_MASK | RXRN_MASK);
 
 	napi_enable(&priv->napi);
 
@@ -533,8 +532,10 @@ static void arc_free_tx_queue(struct net_device *ndev)
 		struct buffer_state *tx_buff = &priv->tx_buff[i];
 
 		if (tx_buff->skb) {
-			dma_unmap_single(&ndev->dev, dma_unmap_addr(tx_buff, addr),
-					 dma_unmap_len(tx_buff, len), DMA_TO_DEVICE);
+			dma_unmap_single(&ndev->dev,
+					 dma_unmap_addr(tx_buff, addr),
+					 dma_unmap_len(tx_buff, len),
+					 DMA_TO_DEVICE);
 
 			/* return the sk_buff to system */
 			dev_kfree_skb_irq(tx_buff->skb);
@@ -562,8 +563,10 @@ static void arc_free_rx_queue(struct net_device *ndev)
 		struct buffer_state *rx_buff = &priv->rx_buff[i];
 
 		if (rx_buff->skb) {
-			dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr),
-					dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE);
+			dma_unmap_single(&ndev->dev,
+					 dma_unmap_addr(rx_buff, addr),
+					 dma_unmap_len(rx_buff, len),
+					 DMA_FROM_DEVICE);
 
 			/* return the sk_buff to system */
 			dev_kfree_skb_irq(rx_buff->skb);
@@ -717,8 +720,8 @@ static void arc_emac_set_address_internal(struct net_device *ndev)
 	struct arc_emac_priv *priv = netdev_priv(ndev);
 	unsigned int addr_low, addr_hi;
 
-	addr_low = le32_to_cpu(*(__le32 *) &ndev->dev_addr[0]);
-	addr_hi = le16_to_cpu(*(__le16 *) &ndev->dev_addr[4]);
+	addr_low = le32_to_cpu(*(__le32 *)&ndev->dev_addr[0]);
+	addr_hi = le16_to_cpu(*(__le16 *)&ndev->dev_addr[4]);
 
 	arc_reg_set(priv, R_ADDRL, addr_low);
 	arc_reg_set(priv, R_ADDRH, addr_hi);
@@ -774,7 +777,6 @@ int arc_emac_probe(struct net_device *ndev, int interface)
 	unsigned int id, clock_frequency, irq;
 	int err;
 
-
 	/* Get PHY from device tree */
 	phy_node = of_parse_phandle(dev->of_node, "phy", 0);
 	if (!phy_node) {
@@ -796,7 +798,6 @@ int arc_emac_probe(struct net_device *ndev, int interface)
 		return -ENODEV;
 	}
 
-
 	ndev->netdev_ops = &arc_emac_netdev_ops;
 	ndev->ethtool_ops = &arc_emac_ethtool_ops;
 	ndev->watchdog_timeo = TX_TIMEOUT;
@@ -807,9 +808,9 @@ int arc_emac_probe(struct net_device *ndev, int interface)
 	priv->dev = dev;
 
 	priv->regs = devm_ioremap_resource(dev, &res_regs);
-	if (IS_ERR(priv->regs)) {
+	if (IS_ERR(priv->regs))
 		return PTR_ERR(priv->regs);
-	}
+
 	dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs);
 
 	if (priv->clk) {
@@ -930,10 +931,8 @@ int arc_emac_remove(struct net_device *ndev)
 	unregister_netdev(ndev);
 	netif_napi_del(&priv->napi);
 
-	if (!IS_ERR(priv->clk)) {
+	if (!IS_ERR(priv->clk))
 		clk_disable_unprepare(priv->clk);
-	}
-
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/arc/emac_mdio.c b/drivers/net/ethernet/arc/emac_mdio.c
index 946ea54..0800127 100644
--- a/drivers/net/ethernet/arc/emac_mdio.c
+++ b/drivers/net/ethernet/arc/emac_mdio.c
@@ -93,7 +93,7 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
 		phy_addr, reg_num, value);
 
 	arc_reg_set(priv, R_MDIO,
-		     0x50020000 | (phy_addr << 23) | (reg_num << 18) | value);
+		    0x50020000 | (phy_addr << 23) | (reg_num << 18) | value);
 
 	return arc_mdio_complete_wait(priv);
 }
diff --git a/drivers/net/ethernet/arc/emac_rockchip.c b/drivers/net/ethernet/arc/emac_rockchip.c
index 85e821c..e278e3d 100644
--- a/drivers/net/ethernet/arc/emac_rockchip.c
+++ b/drivers/net/ethernet/arc/emac_rockchip.c
@@ -50,7 +50,7 @@ static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed)
 	u32 data;
 	int err = 0;
 
-	switch(speed) {
+	switch (speed) {
 	case 10:
 		data = (1 << (speed_offset + 16)) | (0 << speed_offset);
 		break;
@@ -83,9 +83,18 @@ static const struct emac_rockchip_soc_data emac_rk3188_emac_data = {
 };
 
 static const struct of_device_id emac_rockchip_dt_ids[] = {
-	{ .compatible = "rockchip,rk3036-emac", .data = &emac_rk3036_emac_data },
-	{ .compatible = "rockchip,rk3066-emac", .data = &emac_rk3066_emac_data },
-	{ .compatible = "rockchip,rk3188-emac", .data = &emac_rk3188_emac_data },
+	{
+		.compatible = "rockchip,rk3036-emac",
+		.data = &emac_rk3036_emac_data,
+	},
+	{
+		.compatible = "rockchip,rk3066-emac",
+		.data = &emac_rk3066_emac_data,
+	},
+	{
+		.compatible = "rockchip,rk3188-emac",
+		.data = &emac_rk3188_emac_data,
+	},
 	{ /* Sentinel */ }
 };
 
@@ -123,9 +132,11 @@ static int emac_rockchip_probe(struct platform_device *pdev)
 		goto out_netdev;
 	}
 
-	priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
+	priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+						    "rockchip,grf");
 	if (IS_ERR(priv->grf)) {
-		dev_err(dev, "failed to retrieve global register file (%ld)\n", PTR_ERR(priv->grf));
+		dev_err(dev, "failed to retrieve global register file (%ld)\n",
+			PTR_ERR(priv->grf));
 		err = PTR_ERR(priv->grf);
 		goto out_netdev;
 	}
@@ -135,14 +146,16 @@ static int emac_rockchip_probe(struct platform_device *pdev)
 
 	priv->emac.clk = devm_clk_get(dev, "hclk");
 	if (IS_ERR(priv->emac.clk)) {
-		dev_err(dev, "failed to retrieve host clock (%ld)\n", PTR_ERR(priv->emac.clk));
+		dev_err(dev, "failed to retrieve host clock (%ld)\n",
+			PTR_ERR(priv->emac.clk));
 		err = PTR_ERR(priv->emac.clk);
 		goto out_netdev;
 	}
 
 	priv->refclk = devm_clk_get(dev, "macref");
 	if (IS_ERR(priv->refclk)) {
-		dev_err(dev, "failed to retrieve reference clock (%ld)\n", PTR_ERR(priv->refclk));
+		dev_err(dev, "failed to retrieve reference clock (%ld)\n",
+			PTR_ERR(priv->refclk));
 		err = PTR_ERR(priv->refclk);
 		goto out_netdev;
 	}
@@ -179,19 +192,22 @@ static int emac_rockchip_probe(struct platform_device *pdev)
 
 	err = regmap_write(priv->grf, priv->soc_data->grf_offset, data);
 	if (err) {
-		dev_err(dev, "unable to apply initial settings to grf (%d)\n", err);
+		dev_err(dev, "unable to apply initial settings to grf (%d)\n",
+			err);
 		goto out_regulator_disable;
 	}
 
 	/* RMII interface needs always a rate of 50MHz */
 	err = clk_set_rate(priv->refclk, 50000000);
 	if (err)
-		dev_err(dev, "failed to change reference clock rate (%d)\n", err);
+		dev_err(dev,
+			"failed to change reference clock rate (%d)\n", err);
 
 	if (priv->soc_data->need_div_macclk) {
 		priv->macclk = devm_clk_get(dev, "macclk");
 		if (IS_ERR(priv->macclk)) {
-			dev_err(dev, "failed to retrieve mac clock (%ld)\n", PTR_ERR(priv->macclk));
+			dev_err(dev, "failed to retrieve mac clock (%ld)\n",
+				PTR_ERR(priv->macclk));
 			err = PTR_ERR(priv->macclk);
 			goto out_regulator_disable;
 		}
@@ -205,7 +221,8 @@ static int emac_rockchip_probe(struct platform_device *pdev)
 		/* RMII TX/RX needs always a rate of 25MHz */
 		err = clk_set_rate(priv->macclk, 25000000);
 		if (err)
-			dev_err(dev, "failed to change mac clock rate (%d)\n", err);
+			dev_err(dev,
+				"failed to change mac clock rate (%d)\n", err);
 	}
 
 	err = arc_emac_probe(ndev, interface);
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 3/9] net: arc_emac: support the phy reset for emac driver
From: Caesar Wang @ 2016-03-13  9:07 UTC (permalink / raw)
  To: Heiko Stuebner, David S. Miller, Rob Herring
  Cc: sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	keescook-hpIqsD4AKlfQT0dZR+AlfA, leozwang-hpIqsD4AKlfQT0dZR+AlfA,
	Caesar Wang
In-Reply-To: <1457860062-5514-1-git-send-email-wxt-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

This patch adds to support the emac phy reset.

Different boards may require different phy reset duration. Add property
phy-reset-duration for emac driver, so that the boards that need
a longer reset duration can specify it in their device tree.

Signed-off-by: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
Signed-off-by: Caesar Wang <wxt-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

---

Changes in v2:
- As the pervious version, Sergei and Heiko comments on
  https://patchwork.kernel.org/patch/8564571/.
- Nevermind, add signed-off since Heiko the original patch,
  refer the Heiko's test patch on
  https://github.com/mmind/linux-rockchip/commit/a943c588783438ff1c508dfa8c79f1709aa5775e
  :)

 drivers/net/ethernet/arc/emac.h      |  6 ++++++
 drivers/net/ethernet/arc/emac_mdio.c | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h
index dae1ac3..1a40403 100644
--- a/drivers/net/ethernet/arc/emac.h
+++ b/drivers/net/ethernet/arc/emac.h
@@ -102,6 +102,11 @@ struct buffer_state {
 	DEFINE_DMA_UNMAP_LEN(len);
 };
 
+struct arc_emac_mdio_bus_data {
+	struct gpio_desc *reset_gpio;
+	int msec;
+};
+
 /**
  * struct arc_emac_priv - Storage of EMAC's private information.
  * @dev:	Pointer to the current device.
@@ -131,6 +136,7 @@ struct arc_emac_priv {
 	struct device *dev;
 	struct phy_device *phy_dev;
 	struct mii_bus *bus;
+	struct arc_emac_mdio_bus_data bus_data;
 
 	void __iomem *regs;
 	struct clk *clk;
diff --git a/drivers/net/ethernet/arc/emac_mdio.c b/drivers/net/ethernet/arc/emac_mdio.c
index d5ee986..946ea54 100644
--- a/drivers/net/ethernet/arc/emac_mdio.c
+++ b/drivers/net/ethernet/arc/emac_mdio.c
@@ -99,6 +99,25 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
 }
 
 /**
+ * arc_mdio_reset
+ * @bus: points to the mii_bus structure
+ * Description: reset the MII bus
+ */
+int arc_mdio_reset(struct mii_bus *bus)
+{
+	struct arc_emac_priv *priv = bus->priv;
+	struct arc_emac_mdio_bus_data *data = &priv->bus_data;
+
+	if (data->reset_gpio) {
+		gpiod_set_value_cansleep(data->reset_gpio, 1);
+		msleep(data->msec);
+		gpiod_set_value_cansleep(data->reset_gpio, 0);
+	}
+
+	return 0;
+}
+
+/**
  * arc_mdio_probe - MDIO probe function.
  * @priv:	Pointer to ARC EMAC private data structure.
  *
@@ -109,6 +128,8 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
  */
 int arc_mdio_probe(struct arc_emac_priv *priv)
 {
+	struct arc_emac_mdio_bus_data *data = &priv->bus_data;
+	struct device_node *np = priv->dev->of_node;
 	struct mii_bus *bus;
 	int error;
 
@@ -122,6 +143,21 @@ int arc_mdio_probe(struct arc_emac_priv *priv)
 	bus->name = "Synopsys MII Bus",
 	bus->read = &arc_mdio_read;
 	bus->write = &arc_mdio_write;
+	bus->reset = &arc_mdio_reset;
+
+	/* optional reset-related properties */
+	data->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
+						   GPIOD_OUT_LOW);
+	if (IS_ERR(data->reset_gpio)) {
+		error = PTR_ERR(data->reset_gpio);
+		dev_err(priv->dev, "Failed to request gpio: %d\n", error);
+		return error;
+	}
+
+	of_property_read_u32(np, "phy-reset-duration", &data->msec);
+	/* A sane reset duration should not be longer than 1s */
+	if (data->msec > 1000)
+		data->msec = 1;
 
 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name);
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 2/9] net: arc_emac: add phy reset is optional for device tree
From: Caesar Wang @ 2016-03-13  9:07 UTC (permalink / raw)
  To: Heiko Stuebner, David S. Miller, Rob Herring
  Cc: linux-rockchip, keescook, leozwang, sergei.shtylyov, netdev,
	Caesar Wang, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	devicetree, linux-kernel
In-Reply-To: <1457860062-5514-1-git-send-email-wxt@rock-chips.com>

This patch adds the following property for arc_emac.

1) reset-gpios:
The phy reset-gpio is an optional property for arc emac device tree boot.
Change the binding document to match the driver code.

2) phy-reset-duration:
Different boards may require different phy reset duration. Add property
phy-reset-duration for device tree probe, so that the boards that need
a longer reset duration can specify it in their device tree.

Anyway, we can add the above property for arc emac.

Signed-off-by: Caesar Wang <wxt@rock-chips.com>
---

Changes in v2: None

 Documentation/devicetree/bindings/net/arc_emac.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/arc_emac.txt b/Documentation/devicetree/bindings/net/arc_emac.txt
index a1d71eb..8e84b52 100644
--- a/Documentation/devicetree/bindings/net/arc_emac.txt
+++ b/Documentation/devicetree/bindings/net/arc_emac.txt
@@ -7,6 +7,13 @@ Required properties:
 - max-speed: see ethernet.txt file in the same directory.
 - phy: see ethernet.txt file in the same directory.
 
+Optional properties:
+- reset-gpios : Should specify the gpio for phy reset
+- phy-reset-duration : Reset duration in milliseconds.  Should present
+  only if property "reset-gpios" is available.  Missing the property
+  will have the duration be 1 millisecond.  Numbers greater than 1000 are
+  invalid and 1 millisecond will be used instead.
+
 Clock handling:
 The clock frequency is needed to calculate and set polling period of EMAC.
 It must be provided by one of:
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 1/9] net: arc_emac: make the rockchip emac document more compatible
From: Caesar Wang @ 2016-03-13  9:07 UTC (permalink / raw)
  To: Heiko Stuebner, David S. Miller, Rob Herring
  Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel Moll,
	sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8, Ian Campbell,
	netdev-u79uwXL29TY76Z2rM5mHXA, Kumar Gala,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	keescook-hpIqsD4AKlfQT0dZR+AlfA, leozwang-hpIqsD4AKlfQT0dZR+AlfA,
	Caesar Wang
In-Reply-To: <1457860062-5514-1-git-send-email-wxt-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

Add the rk3036 SoCs to match driver for document since he emac driver
has supported the rk3036 SoCs.

This patch adds the rk3036/rk3066/rk3188 SoCS to compatible for rockchip
emac ducument. Also, that will suit for other SoCs in the future.

Signed-off-by: Caesar Wang <wxt-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

---

Changes in v2:
- change the commit and remove the repeat the name 'rockchip'.

 Documentation/devicetree/bindings/net/emac_rockchip.txt | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/emac_rockchip.txt b/Documentation/devicetree/bindings/net/emac_rockchip.txt
index 8dc1c79..05bd7da 100644
--- a/Documentation/devicetree/bindings/net/emac_rockchip.txt
+++ b/Documentation/devicetree/bindings/net/emac_rockchip.txt
@@ -1,8 +1,10 @@
-* ARC EMAC 10/100 Ethernet platform driver for Rockchip Rk3066/RK3188 SoCs
+* ARC EMAC 10/100 Ethernet platform driver for Rockchip RK3036/RK3066/RK3188 SoCs
 
 Required properties:
-- compatible: Should be "rockchip,rk3066-emac" or "rockchip,rk3188-emac"
-  according to the target SoC.
+- compatible: should be "rockchip,<name>-emac"
+   "rockchip,rk3036-emac": found on RK3036 SoCs
+   "rockchip,rk3066-emac": found on RK3066 SoCs
+   "rockchip,rk3188-emac": found on RK3188 SoCs
 - reg: Address and length of the register set for the device
 - interrupts: Should contain the EMAC interrupts
 - rockchip,grf: phandle to the syscon grf used to control speed and mode
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 0/9] arc_emac: fixes the emac issues and cleanup emac drivers
From: Caesar Wang @ 2016-03-13  9:07 UTC (permalink / raw)
  To: Heiko Stuebner, David S. Miller, Rob Herring
  Cc: linux-rockchip, keescook, leozwang, sergei.shtylyov, netdev,
	Caesar Wang, devicetree, Michael Turquette, Alexander Kochetkov,
	Russell King, Stephen Boyd, Kumar Gala, linux-kernel,
	Ian Campbell, Jiri Kosina, Pawel Moll, Mark Rutland, linux-clk,
	linux-arm-kernel, Xing Zheng

Hi all,
This series patches are based on kernel 4.5-rc7+ version.
Linux version 4.5.0-rc7-next-20160311+ (wxt@nb) (...) #45 SMP Sun Mar 13 16:17:56

The history patch in here:
Patch-v1: https://lkml.org/lkml/2016/3/11/209

Verified on kylin board with my github.
https://github.com/Caesar-github/rockchip/tree/kylin/next

That's verified on kylin board with ubuntu os.

How to test and verify?

You can refer to the following wiki document.
http://rockchip.wikidot.com/linux-develop-guide

bootup log:
   1.268113] rockchip_emac 10200000.ethernet: no regulator found
   [    1.286682] rockchip_emac 10200000.ethernet: ARC EMAC detected with id: 0x7fd02
   [    1.294007] rockchip_emac 10200000.ethernet: IRQ is 29
   [    1.299453] rockchip_emac 10200000.ethernet: MAC address is now 1e:cd:18:78:90:25
   [    1.726564] rockchip_emac 10200000.ethernet: connected to Generic PHY phy with id 0x1cc816
   [    8.936862] rockchip_emac 10200000.ethernet eth0: Link is Up - 100Mbps/Full - flow control off

root@localhost:/# busybox ping www.baidu.com
PING www.baidu.com (14.215.177.38): 56 data bytes
64 bytes from 14.215.177.38: seq=0 ttl=48 time=35.046 ms
64 bytes from 14.215.177.38: seq=1 ttl=48 time=35.095 ms
64 bytes from 14.215.177.38: seq=2 ttl=48 time=34.203 ms
64 bytes from 14.215.177.38: seq=3 ttl=48 time=38.516 ms
...
---

1) This series has 6 patches: (1--->9)
net: arc_emac: make the rockchip emac document more compatible
net: arc_emac: add phy reset is optional for device tree
net: arc_emac: support the phy reset for emac driver
net: arc: trivial: cleanup the emac driver
clk: rockchip: add node-id for rk3036 emac hclk
clk: rockchip: associate the rk3036 HCLK_EMAC clock-id
clk: rockchip: add clock-id for rk3036 emac pll source clock
clk: rockchip: associate SCLK_MAC_PLL and disable reparenting on rk3036
ARM: dts: rockchip: add support emac for RK3036

2) This series patches have the following descriptions:

Hi Rob, David:
PATCH[1/9-2/9]: ====>
net: arc_emac: make the rockchip emac document more compatible
net: arc_emac: add phy reset is optional for device tree

The patches change the rockchip emac document for more compatible and
Add the phy reset property for document.
---

Hi David
PATCH[3/9]: ====>
net: arc_emac: support the phy reset for emac driver

The emac didn't work on kylin board since in some case the clocks parent changed.
The kylin hardware connects the phy reset pin, we should use it with real world.
As the previous patch discuss on https://patchwork.kernel.org/patch/8186801/

And as sergei/Heiko suggestions on
https://patchwork.kernel.org/patch/8564571/
---

Hi David
PATCH[4/9]: ====>
net: arc: trivial: cleanup the emac driver

The first time to look the emac drivers, I think that have to cleanup the drivers with scripts.
Although it's the trivial things, in order to be more read.
---

Hi Heiko,Michael,Stephen:
PATCH[5/9-8/9]: ====> clk: rockchip: rk3036: fix and add node id for emac clock

Four-part from https://patchwork.kernel.org/patch/8564581/
clk: rockchip: add node-id for rk3036 emac hclk
clk: rockchip: associate the rk3036 HCLK_EMAC clock-id
clk: rockchip: add clock-id for rk3036 emac pll source clock
clk: rockchip: associate SCLK_MAC_PLL and disable reparenting on rk3036

Add the emac needed clocks for rk3036 SOCs
---

Hi Heiko:
PATCH[9/9]: ====>
ARM: dts: rockchip: add support emac for RK3036

Add the emac needed main info for rk3036 dts.
---

Thanks your reviewing! :)


Changes in v2:
- change the commit and remove the repeat the name 'rockchip'.
- As the pervious version, Sergei and Heiko comments on
  https://patchwork.kernel.org/patch/8564571/.
- Nevermind, add signed-off since Heiko the original patch,
  refer the Heiko's test patch on
  https://github.com/mmind/linux-rockchip/commit/a943c588783438ff1c508dfa8c79f1709aa5775e
  :)
- As the robot notice the build error since overflow in implicit
  constant conversion.

Caesar Wang (4):
  net: arc_emac: make the rockchip emac document more compatible
  net: arc_emac: add phy reset is optional for device tree
  net: arc_emac: support the phy reset for emac driver
  net: arc: trivial: cleanup the emac driver

Heiko Stuebner (1):
  clk: rockchip: associate SCLK_MAC_PLL and disable reparenting on
    rk3036

Xing Zheng (3):
  clk: rockchip: add node-id for rk3036 emac hclk
  clk: rockchip: associate the rk3036 HCLK_EMAC clock-id
  clk: rockchip: add clock-id for rk3036 emac pll source clock

zhengxing (1):
  ARM: dts: rockchip: add support emac for RK3036

 Documentation/devicetree/bindings/net/arc_emac.txt |  7 +++
 .../devicetree/bindings/net/emac_rockchip.txt      |  8 +--
 arch/arm/boot/dts/rk3036-evb.dts                   | 23 +++++++++
 arch/arm/boot/dts/rk3036-kylin.dts                 | 20 ++++++++
 arch/arm/boot/dts/rk3036.dtsi                      | 39 ++++++++++++++
 drivers/clk/rockchip/clk-rk3036.c                  |  4 +-
 drivers/net/ethernet/arc/emac.h                    | 60 ++++++++++++----------
 drivers/net/ethernet/arc/emac_main.c               | 35 ++++++-------
 drivers/net/ethernet/arc/emac_mdio.c               | 38 +++++++++++++-
 drivers/net/ethernet/arc/emac_rockchip.c           | 41 ++++++++++-----
 include/dt-bindings/clock/rk3036-cru.h             |  2 +
 11 files changed, 215 insertions(+), 62 deletions(-)

-- 
1.9.1


^ permalink raw reply

* Re: [RFC PATCH net-next 3/3] net: dsa: refine netdev event notifier
From: Ido Schimmel @ 2016-03-13  7:32 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Jiri Pirko, Kevin Smith
In-Reply-To: <1457851346-26257-4-git-send-email-vivien.didelot@savoirfairelinux.com>

Hi Vivien,

Sun, Mar 13, 2016 at 08:42:26AM IST, vivien.didelot@savoirfairelinux.com wrote:
>Rework the netdev event handler, similar to what the Mellanox Spectrum
>driver does, to eventually welcome NETDEV_PRECHANGEUPPER actions and use
>netdev helpers, such as netif_is_bridge_master.
>
>Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
>---
> net/dsa/slave.c | 55 +++++++++++++++++++++++++++++++------------------------
> 1 file changed, 31 insertions(+), 24 deletions(-)
>
>diff --git a/net/dsa/slave.c b/net/dsa/slave.c
>index 54976c4..27f7886 100644
>--- a/net/dsa/slave.c
>+++ b/net/dsa/slave.c
>@@ -451,7 +451,7 @@ static int dsa_slave_bridge_port_join(struct net_device *dev,
> 	if (ds->drv->port_bridge_join)
> 		ret = ds->drv->port_bridge_join(ds, p->port, br);
> 
>-	return ret;
>+	return ret == -EOPNOTSUPP ? 0 : ret;
> }
> 
> static void dsa_slave_bridge_port_leave(struct net_device *dev)
>@@ -1139,40 +1139,47 @@ static bool dsa_slave_dev_check(struct net_device *dev)
> 	return dev->netdev_ops == &dsa_slave_netdev_ops;
> }
> 
>-static int dsa_slave_master_changed(struct net_device *dev)
>+static int dsa_slave_port_upper_event(struct net_device *dev,
>+				      unsigned long event, void *ptr)
> {
>-	struct net_device *master = netdev_master_upper_dev_get(dev);
>-	struct dsa_slave_priv *p = netdev_priv(dev);
>+	struct netdev_notifier_changeupper_info *info = ptr;
>+	struct net_device *upper = info->upper_dev;
> 	int err = 0;
> 
>-	if (master && master->rtnl_link_ops &&
>-	    !strcmp(master->rtnl_link_ops->kind, "bridge"))
>-		err = dsa_slave_bridge_port_join(dev, master);
>-	else if (dsa_port_is_bridged(p))
>-		dsa_slave_bridge_port_leave(dev);
>+	switch (event) {
>+	case NETDEV_CHANGEUPPER:
>+		if (netif_is_bridge_master(upper)) {
>+			if (info->linking)
>+				err = dsa_slave_bridge_port_join(dev, upper);
>+			else
>+				dsa_slave_bridge_port_leave(dev);
>+		}
> 
>-	return err;
>+		break;
>+	}
>+
>+	return notifier_from_errno(err);
> }
> 
>-int dsa_slave_netdevice_event(struct notifier_block *unused,
>-			      unsigned long event, void *ptr)
>+static int dsa_slave_port_event(struct net_device *dev, unsigned long event,
>+				void *ptr)
> {
>-	struct net_device *dev;
>-	int err = 0;
>-
> 	switch (event) {
>+	case NETDEV_PRECHANGEUPPER:

Why do you need this here? It seems you are always ignoring it in
dsa_slave_port_upper_event()? Probably better to introduce it when you
actually need it.

Other than that, it looks good to me.

> 	case NETDEV_CHANGEUPPER:
>-		dev = netdev_notifier_info_to_dev(ptr);
>-		if (!dsa_slave_dev_check(dev))
>-			goto out;
>+		return dsa_slave_port_upper_event(dev, event, ptr);
>+	}
> 
>-		err = dsa_slave_master_changed(dev);
>-		if (err && err != -EOPNOTSUPP)
>-			netdev_warn(dev, "failed to reflect master change\n");
>+	return NOTIFY_DONE;
>+}
> 
>-		break;
>-	}
>+int dsa_slave_netdevice_event(struct notifier_block *unused,
>+			      unsigned long event, void *ptr)
>+{
>+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
>+
>+	if (dsa_slave_dev_check(dev))
>+		return dsa_slave_port_event(dev, event, ptr);
> 
>-out:
> 	return NOTIFY_DONE;
> }
>-- 
>2.7.2
>

^ permalink raw reply

* Re: [PATCH RFC v2 00/32] Make DSA switches linux devices.
From: Vivien Didelot @ 2016-03-13  7:26 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli; +Cc: netdev
In-Reply-To: <20160312170827.GA2186@lunn.ch>

Hi Andrew, Florian,

Andrew Lunn <andrew@lunn.ch> writes:

> It probably means we need to turn slave.c and parts of dsa.c into a
> library. Add a new dsa_v2.c file, containing the new binding
> code. With things like having the switch devices instantiate there own
> MDIO bus, fixed phys on a compatible MDIO bus referenced via phandles,
> etc, I hope we can make parts of the dsa_v2 simpler.

Nothing critical here, but as we are talking about better isolation of
the DSA slave code, wouldn't it be the good moment to make it a
dsa_switch driver, instead of a library? This code is actually pretty
generic, and for example home routers could register an instance of such
module.

Thanks,
-v

^ permalink raw reply

* [PATCH 3/3] libceph: use KMEM_CACHE macro
From: Geliang Tang @ 2016-03-13  7:18 UTC (permalink / raw)
  To: Ilya Dryomov, Yan, Zheng, Sage Weil, David S. Miller
  Cc: Geliang Tang, ceph-devel, netdev, linux-kernel
In-Reply-To: <9242267d62daeec8a0de5a1230f750ca486d62cd.1457853190.git.geliangtang@163.com>

Use KMEM_CACHE() instead of kmem_cache_create() to simplify the code.

Signed-off-by: Geliang Tang <geliangtang@163.com>
---
 net/ceph/messenger.c  | 10 ++--------
 net/ceph/osd_client.c |  5 +----
 2 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 9382619..32c997e 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -235,18 +235,12 @@ static struct workqueue_struct *ceph_msgr_wq;
 static int ceph_msgr_slab_init(void)
 {
 	BUG_ON(ceph_msg_cache);
-	ceph_msg_cache = kmem_cache_create("ceph_msg",
-					sizeof (struct ceph_msg),
-					__alignof__(struct ceph_msg), 0, NULL);
-
+	ceph_msg_cache = KMEM_CACHE(ceph_msg, 0);
 	if (!ceph_msg_cache)
 		return -ENOMEM;
 
 	BUG_ON(ceph_msg_data_cache);
-	ceph_msg_data_cache = kmem_cache_create("ceph_msg_data",
-					sizeof (struct ceph_msg_data),
-					__alignof__(struct ceph_msg_data),
-					0, NULL);
+	ceph_msg_data_cache = KMEM_CACHE(ceph_msg_data, 0);
 	if (ceph_msg_data_cache)
 		return 0;
 
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 5bc0537..7558855 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -2783,10 +2783,7 @@ EXPORT_SYMBOL(ceph_osdc_writepages);
 int ceph_osdc_setup(void)
 {
 	BUG_ON(ceph_osd_request_cache);
-	ceph_osd_request_cache = kmem_cache_create("ceph_osd_request",
-					sizeof (struct ceph_osd_request),
-					__alignof__(struct ceph_osd_request),
-					0, NULL);
+	ceph_osd_request_cache = KMEM_CACHE(ceph_osd_request, 0);
 
 	return ceph_osd_request_cache ? 0 : -ENOMEM;
 }
-- 
2.5.0

^ permalink raw reply related

* Re: [PATCH net-next 1/5] dsa: Rename mv88e6123_61_65 to mv88e6123 to be consistent
From: Vivien Didelot @ 2016-03-13  7:10 UTC (permalink / raw)
  To: Andrew Lunn, David Miller; +Cc: netdev, Florian Fainelli, Andrew Lunn
In-Reply-To: <1457737300-23660-2-git-send-email-andrew@lunn.ch>

Andrew Lunn <andrew@lunn.ch> writes:

> All the drivers support multiple chips, but mv88e6123_61_65 is the
> only one that reflects this in its naming. Change it to be consistent
> with the other drivers.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>

When mv88e6xxx will become a driver by its own supporting different
devices, it'll be good to rename it to a reference driver as well, say
mv88e6352.

[...]

> diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
> new file mode 100644
> index 000000000000..69a6f79dcb10
> --- /dev/null
> +++ b/drivers/net/dsa/mv88e6123.c
> @@ -0,0 +1,124 @@

Note that to avoid the big diff above, you can use the -M option of
git-format-patch to detect file renames.

Thanks,
Vivien

^ permalink raw reply

* Re: [RFC PATCH net-next 0/3] net: dsa: finer bridging control
From: Vivien Didelot @ 2016-03-13  6:49 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Jiri Pirko, Ido Schimmel, Kevin Smith
In-Reply-To: <1457851346-26257-1-git-send-email-vivien.didelot@savoirfairelinux.com>

Hi David,

Vivien Didelot <vivien.didelot@savoirfairelinux.com> writes:

> This patchset renames the bridging routines of the DSA layer, make the
> unbridging routine return void, and rework the DSA netdev notifier handler,
> similar to what the Mellanox Spectrum driver does.

This is not an RFC, but a normal patchset. I badly reused a previous
git-format-patch command. Please let me know if I need to resend.

Thank you,
Vivien

^ permalink raw reply

* [RFC PATCH net-next 2/3] net: dsa: make port_bridge_leave return void
From: Vivien Didelot @ 2016-03-13  6:42 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Jiri Pirko, Ido Schimmel, Kevin Smith,
	Vivien Didelot
In-Reply-To: <1457851346-26257-1-git-send-email-vivien.didelot@savoirfairelinux.com>

netdev_upper_dev_unlink() which notifies NETDEV_CHANGEUPPER, returns
void, as well as del_nbp(). So there's no advantage to catch an eventual
error from the port_bridge_leave routine at the DSA level.

Make this routine void for the DSA layer and its existing drivers.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/bcm_sf2.c   |  4 +---
 drivers/net/dsa/mv88e6xxx.c | 28 +++++++++-------------------
 drivers/net/dsa/mv88e6xxx.h |  2 +-
 include/net/dsa.h           |  2 +-
 net/dsa/slave.c             |  9 +++------
 5 files changed, 15 insertions(+), 30 deletions(-)

diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 4bcc9eb..95944d5 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -516,7 +516,7 @@ static int bcm_sf2_sw_br_join(struct dsa_switch *ds, int port,
 	return 0;
 }
 
-static int bcm_sf2_sw_br_leave(struct dsa_switch *ds, int port)
+static void bcm_sf2_sw_br_leave(struct dsa_switch *ds, int port)
 {
 	struct bcm_sf2_priv *priv = ds_to_priv(ds);
 	struct net_device *bridge = priv->port_sts[port].bridge_dev;
@@ -543,8 +543,6 @@ static int bcm_sf2_sw_br_leave(struct dsa_switch *ds, int port)
 	core_writel(priv, p_ctl, CORE_PORT_VLAN_CTL_PORT(port));
 	priv->port_sts[port].vlan_ctl_mask = p_ctl;
 	priv->port_sts[port].bridge_dev = NULL;
-
-	return 0;
 }
 
 static int bcm_sf2_sw_br_set_stp_state(struct dsa_switch *ds, int port,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 5f07524..448d4ef 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2219,39 +2219,29 @@ unlock:
 	return err;
 }
 
-int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
+void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	struct net_device *bridge = ps->ports[port].bridge_dev;
 	u16 fid;
-	int i, err;
+	int i;
 
 	mutex_lock(&ps->smi_mutex);
 
 	/* Give the port a fresh Filtering Information Database */
-	err = _mv88e6xxx_fid_new(ds, &fid);
-	if (err)
-		goto unlock;
-
-	err = _mv88e6xxx_port_fid_set(ds, port, fid);
-	if (err)
-		goto unlock;
+	if (_mv88e6xxx_fid_new(ds, &fid) ||
+	    _mv88e6xxx_port_fid_set(ds, port, fid))
+		netdev_warn(ds->ports[port], "failed to assign a new FID\n");
 
 	/* Unassign the bridge and remap each port's VLANTable */
 	ps->ports[port].bridge_dev = NULL;
 
-	for (i = 0; i < ps->num_ports; ++i) {
-		if (i == port || ps->ports[i].bridge_dev == bridge) {
-			err = _mv88e6xxx_port_based_vlan_map(ds, i);
-			if (err)
-				break;
-		}
-	}
+	for (i = 0; i < ps->num_ports; ++i)
+		if (i == port || ps->ports[i].bridge_dev == bridge)
+			if (_mv88e6xxx_port_based_vlan_map(ds, i))
+				netdev_warn(ds->ports[i], "failed to remap\n");
 
-unlock:
 	mutex_unlock(&ps->smi_mutex);
-
-	return err;
 }
 
 static void mv88e6xxx_bridge_work(struct work_struct *work)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 3425616..afd495c 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -488,7 +488,7 @@ int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
 		      struct phy_device *phydev, struct ethtool_eee *e);
 int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
 			       struct net_device *bridge);
-int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port);
+void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port);
 int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state);
 int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
 				  bool vlan_filtering);
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 004e034..6463bb2 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -298,7 +298,7 @@ struct dsa_switch_driver {
 	 */
 	int	(*port_bridge_join)(struct dsa_switch *ds, int port,
 				    struct net_device *bridge);
-	int	(*port_bridge_leave)(struct dsa_switch *ds, int port);
+	void	(*port_bridge_leave)(struct dsa_switch *ds, int port);
 	int	(*port_stp_update)(struct dsa_switch *ds, int port,
 				   u8 state);
 
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index b997ee1..54976c4 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -454,15 +454,14 @@ static int dsa_slave_bridge_port_join(struct net_device *dev,
 	return ret;
 }
 
-static int dsa_slave_bridge_port_leave(struct net_device *dev)
+static void dsa_slave_bridge_port_leave(struct net_device *dev)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
 	struct dsa_switch *ds = p->parent;
-	int ret = -EOPNOTSUPP;
 
 
 	if (ds->drv->port_bridge_leave)
-		ret = ds->drv->port_bridge_leave(ds, p->port);
+		ds->drv->port_bridge_leave(ds, p->port);
 
 	p->bridge_dev = NULL;
 
@@ -470,8 +469,6 @@ static int dsa_slave_bridge_port_leave(struct net_device *dev)
 	 * so allow it to be in BR_STATE_FORWARDING to be kept functional
 	 */
 	dsa_slave_stp_update(dev, BR_STATE_FORWARDING);
-
-	return ret;
 }
 
 static int dsa_slave_port_attr_get(struct net_device *dev,
@@ -1152,7 +1149,7 @@ static int dsa_slave_master_changed(struct net_device *dev)
 	    !strcmp(master->rtnl_link_ops->kind, "bridge"))
 		err = dsa_slave_bridge_port_join(dev, master);
 	else if (dsa_port_is_bridged(p))
-		err = dsa_slave_bridge_port_leave(dev);
+		dsa_slave_bridge_port_leave(dev);
 
 	return err;
 }
-- 
2.7.2

^ permalink raw reply related

* [RFC PATCH net-next 1/3] net: dsa: rename port_*_bridge routines
From: Vivien Didelot @ 2016-03-13  6:42 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Jiri Pirko, Ido Schimmel, Kevin Smith,
	Vivien Didelot
In-Reply-To: <1457851346-26257-1-git-send-email-vivien.didelot@savoirfairelinux.com>

Rename DSA port_join_bridge and port_leave_bridge routines to
respectively port_bridge_join and port_bridge_leave in order to respect
an implicit Port::Bridge namespace.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 Documentation/networking/dsa/dsa.txt | 4 ++--
 drivers/net/dsa/bcm_sf2.c            | 4 ++--
 drivers/net/dsa/mv88e6171.c          | 4 ++--
 drivers/net/dsa/mv88e6352.c          | 4 ++--
 include/net/dsa.h                    | 4 ++--
 net/dsa/slave.c                      | 8 ++++----
 6 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/Documentation/networking/dsa/dsa.txt b/Documentation/networking/dsa/dsa.txt
index 974e9c3..3b196c3 100644
--- a/Documentation/networking/dsa/dsa.txt
+++ b/Documentation/networking/dsa/dsa.txt
@@ -521,12 +521,12 @@ See Documentation/hwmon/sysfs-interface for details.
 Bridge layer
 ------------
 
-- port_join_bridge: bridge layer function invoked when a given switch port is
+- port_bridge_join: bridge layer function invoked when a given switch port is
   added to a bridge, this function should be doing the necessary at the switch
   level to permit the joining port from being added to the relevant logical
   domain for it to ingress/egress traffic with other members of the bridge.
 
-- port_leave_bridge: bridge layer function invoked when a given switch port is
+- port_bridge_leave: bridge layer function invoked when a given switch port is
   removed from a bridge, this function should be doing the necessary at the
   switch level to deny the leaving port from ingress/egress traffic from the
   remaining bridge members. When the port leaves the bridge, it should be aged
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 3f62759..4bcc9eb 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -1387,8 +1387,8 @@ static struct dsa_switch_driver bcm_sf2_switch_driver = {
 	.port_disable		= bcm_sf2_port_disable,
 	.get_eee		= bcm_sf2_sw_get_eee,
 	.set_eee		= bcm_sf2_sw_set_eee,
-	.port_join_bridge	= bcm_sf2_sw_br_join,
-	.port_leave_bridge	= bcm_sf2_sw_br_leave,
+	.port_bridge_join	= bcm_sf2_sw_br_join,
+	.port_bridge_leave	= bcm_sf2_sw_br_leave,
 	.port_stp_update	= bcm_sf2_sw_br_set_stp_state,
 	.port_fdb_prepare	= bcm_sf2_sw_fdb_prepare,
 	.port_fdb_add		= bcm_sf2_sw_fdb_add,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index d72ccbd..c0164b9 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -103,8 +103,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
 #endif
 	.get_regs_len		= mv88e6xxx_get_regs_len,
 	.get_regs		= mv88e6xxx_get_regs,
-	.port_join_bridge	= mv88e6xxx_port_bridge_join,
-	.port_leave_bridge	= mv88e6xxx_port_bridge_leave,
+	.port_bridge_join	= mv88e6xxx_port_bridge_join,
+	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
 	.port_stp_update        = mv88e6xxx_port_stp_update,
 	.port_vlan_filtering	= mv88e6xxx_port_vlan_filtering,
 	.port_vlan_prepare	= mv88e6xxx_port_vlan_prepare,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index a41fa50..5f528ab 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -324,8 +324,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
 	.set_eeprom		= mv88e6352_set_eeprom,
 	.get_regs_len		= mv88e6xxx_get_regs_len,
 	.get_regs		= mv88e6xxx_get_regs,
-	.port_join_bridge	= mv88e6xxx_port_bridge_join,
-	.port_leave_bridge	= mv88e6xxx_port_bridge_leave,
+	.port_bridge_join	= mv88e6xxx_port_bridge_join,
+	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
 	.port_stp_update	= mv88e6xxx_port_stp_update,
 	.port_vlan_filtering	= mv88e6xxx_port_vlan_filtering,
 	.port_vlan_prepare	= mv88e6xxx_port_vlan_prepare,
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 26c0a3f..004e034 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -296,9 +296,9 @@ struct dsa_switch_driver {
 	/*
 	 * Bridge integration
 	 */
-	int	(*port_join_bridge)(struct dsa_switch *ds, int port,
+	int	(*port_bridge_join)(struct dsa_switch *ds, int port,
 				    struct net_device *bridge);
-	int	(*port_leave_bridge)(struct dsa_switch *ds, int port);
+	int	(*port_bridge_leave)(struct dsa_switch *ds, int port);
 	int	(*port_stp_update)(struct dsa_switch *ds, int port,
 				   u8 state);
 
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 27bf03d..b997ee1 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -448,8 +448,8 @@ static int dsa_slave_bridge_port_join(struct net_device *dev,
 
 	p->bridge_dev = br;
 
-	if (ds->drv->port_join_bridge)
-		ret = ds->drv->port_join_bridge(ds, p->port, br);
+	if (ds->drv->port_bridge_join)
+		ret = ds->drv->port_bridge_join(ds, p->port, br);
 
 	return ret;
 }
@@ -461,8 +461,8 @@ static int dsa_slave_bridge_port_leave(struct net_device *dev)
 	int ret = -EOPNOTSUPP;
 
 
-	if (ds->drv->port_leave_bridge)
-		ret = ds->drv->port_leave_bridge(ds, p->port);
+	if (ds->drv->port_bridge_leave)
+		ret = ds->drv->port_bridge_leave(ds, p->port);
 
 	p->bridge_dev = NULL;
 
-- 
2.7.2

^ permalink raw reply related

* [RFC PATCH net-next 3/3] net: dsa: refine netdev event notifier
From: Vivien Didelot @ 2016-03-13  6:42 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Jiri Pirko, Ido Schimmel, Kevin Smith,
	Vivien Didelot
In-Reply-To: <1457851346-26257-1-git-send-email-vivien.didelot@savoirfairelinux.com>

Rework the netdev event handler, similar to what the Mellanox Spectrum
driver does, to eventually welcome NETDEV_PRECHANGEUPPER actions and use
netdev helpers, such as netif_is_bridge_master.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 net/dsa/slave.c | 55 +++++++++++++++++++++++++++++++------------------------
 1 file changed, 31 insertions(+), 24 deletions(-)

diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 54976c4..27f7886 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -451,7 +451,7 @@ static int dsa_slave_bridge_port_join(struct net_device *dev,
 	if (ds->drv->port_bridge_join)
 		ret = ds->drv->port_bridge_join(ds, p->port, br);
 
-	return ret;
+	return ret == -EOPNOTSUPP ? 0 : ret;
 }
 
 static void dsa_slave_bridge_port_leave(struct net_device *dev)
@@ -1139,40 +1139,47 @@ static bool dsa_slave_dev_check(struct net_device *dev)
 	return dev->netdev_ops == &dsa_slave_netdev_ops;
 }
 
-static int dsa_slave_master_changed(struct net_device *dev)
+static int dsa_slave_port_upper_event(struct net_device *dev,
+				      unsigned long event, void *ptr)
 {
-	struct net_device *master = netdev_master_upper_dev_get(dev);
-	struct dsa_slave_priv *p = netdev_priv(dev);
+	struct netdev_notifier_changeupper_info *info = ptr;
+	struct net_device *upper = info->upper_dev;
 	int err = 0;
 
-	if (master && master->rtnl_link_ops &&
-	    !strcmp(master->rtnl_link_ops->kind, "bridge"))
-		err = dsa_slave_bridge_port_join(dev, master);
-	else if (dsa_port_is_bridged(p))
-		dsa_slave_bridge_port_leave(dev);
+	switch (event) {
+	case NETDEV_CHANGEUPPER:
+		if (netif_is_bridge_master(upper)) {
+			if (info->linking)
+				err = dsa_slave_bridge_port_join(dev, upper);
+			else
+				dsa_slave_bridge_port_leave(dev);
+		}
 
-	return err;
+		break;
+	}
+
+	return notifier_from_errno(err);
 }
 
-int dsa_slave_netdevice_event(struct notifier_block *unused,
-			      unsigned long event, void *ptr)
+static int dsa_slave_port_event(struct net_device *dev, unsigned long event,
+				void *ptr)
 {
-	struct net_device *dev;
-	int err = 0;
-
 	switch (event) {
+	case NETDEV_PRECHANGEUPPER:
 	case NETDEV_CHANGEUPPER:
-		dev = netdev_notifier_info_to_dev(ptr);
-		if (!dsa_slave_dev_check(dev))
-			goto out;
+		return dsa_slave_port_upper_event(dev, event, ptr);
+	}
 
-		err = dsa_slave_master_changed(dev);
-		if (err && err != -EOPNOTSUPP)
-			netdev_warn(dev, "failed to reflect master change\n");
+	return NOTIFY_DONE;
+}
 
-		break;
-	}
+int dsa_slave_netdevice_event(struct notifier_block *unused,
+			      unsigned long event, void *ptr)
+{
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+
+	if (dsa_slave_dev_check(dev))
+		return dsa_slave_port_event(dev, event, ptr);
 
-out:
 	return NOTIFY_DONE;
 }
-- 
2.7.2

^ permalink raw reply related

* [RFC PATCH net-next 0/3] net: dsa: finer bridging control
From: Vivien Didelot @ 2016-03-13  6:42 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Jiri Pirko, Ido Schimmel, Kevin Smith,
	Vivien Didelot

This patchset renames the bridging routines of the DSA layer, make the
unbridging routine return void, and rework the DSA netdev notifier handler,
similar to what the Mellanox Spectrum driver does.

Vivien Didelot (3):
  net: dsa: rename port_*_bridge routines
  net: dsa: make port_bridge_leave return void
  net: dsa: refine netdev event notifier

 Documentation/networking/dsa/dsa.txt |  4 +--
 drivers/net/dsa/bcm_sf2.c            |  8 ++---
 drivers/net/dsa/mv88e6171.c          |  4 +--
 drivers/net/dsa/mv88e6352.c          |  4 +--
 drivers/net/dsa/mv88e6xxx.c          | 28 +++++----------
 drivers/net/dsa/mv88e6xxx.h          |  2 +-
 include/net/dsa.h                    |  4 +--
 net/dsa/slave.c                      | 68 +++++++++++++++++++-----------------
 8 files changed, 57 insertions(+), 65 deletions(-)

-- 
2.7.2

^ permalink raw reply

* Re: [PATCH 0/6] arc_emac: fixes the emac issues oand cleanup emac drivers
From: Caesar Wang @ 2016-03-13  4:04 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Caesar Wang, Mark Rutland, Heiko Stuebner, Alexander Kochetkov,
	Michael Turquette, linux-clk, Russell King, zhengxing,
	linux-rockchip, Caesar Wang, devicetree, Pawel Moll, Ian Campbell,
	Kumar Gala, Rob Herring, linux-arm-kernel, Jiri Kosina, netdev,
	Stephen Boyd, linux-kernel, keescook, David S. Miller, leozwang
In-Reply-To: <56E3126C.7000100@cogentembedded.com>



在 2016年03月12日 02:46, Sergei Shtylyov 写道:
> Hello.
>
> On 03/11/2016 05:48 PM, Caesar Wang wrote:
>
> [...]
>
>>>> Hi Rob, David:
>>>> PATCH[1/6-2/6]: ====>
>>>> net: arc_emac: make the rockchip emac document more compatible
>>>> net: arc_emac: add phy-reset-* are optional for device tree
>>>>
>>>> The patches change the rockchip emac document for more compatible and
>>>> Add the phy-reset-* property for document.
>>>>
>>>> This patch adds the following property for arc_emac.
>>>>
>>>> phy-reset-* include the following:
>>>> 1) phy-reset-gpios:
>>>> The phy-reset-gpios is an optional property for arc emac device 
>>>> tree boot.
>>>> Change the binding document to match the driver code.
>>>>
>>>> 2) phy-reset-duration:
>>>> Different boards may require different phy reset duration. Add 
>>>> property
>>>> phy-reset-duration for device tree probe, so that the boards that need
>>>> a longer reset duration can specify it in their device tree.
>>>>
>>>> 3) phy-reset-active-high:
>>>> We need that for a custom hardware that needs the reverse reset 
>>>> sequence.
>>>
>>>    Why not infer this from the "phy-reset-gpios" prop?
>>
>> See:
>> https://patchwork.kernel.org/patch/8564511/
> >
>> phy-reset-active-high : If present then the reset sequence using the 
>> GPIO
>>   specified in the "phy-reset-gpios" property is reversed (H=reset 
>> state,
>>   L=operation state).
>
>    Referring to your own suggested bindings isn't an answer. If the 
> driver that you're copying from here (fec) had a reason to handle the 
> GPIO sense with the help of an extra prop (legacy code), it doesn't 
> mean your new driver needs to mimic this as well, AFAIU...

I know your suggestion is a fair request.

Oh, that copy from the 'freescale/fec_main.c' ....

So, The exist way was old and unwise in mainline. :(

wxt@nb:~/kernel/drivers/net/ethernet$ ag reset-gpios
micrel/ks8851.c
1427:    gpio = of_get_named_gpio_flags(spi->dev.of_node, "reset-gpios",

arc/emac_main.c
787:    phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
797:        dev_err(dev, "failed to get phy-reset-gpios: %d\n", err);

arc/emac_main.c~
784:    phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
794:        dev_err(dev, "failed to get phy-reset-gpios: %d\n", err);

davicom/dm9000.c
1451:    reset_gpios = of_get_named_gpio_flags(dev->of_node, 
"reset-gpios", 0,

freescale/fec_main.c
3206:    phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
3216:        dev_err(&pdev->dev, "failed to get phy-reset-gpios: %d\n", 
err);

cadence/macb.c
2958:        int gpio = of_get_named_gpio(phy_node, "reset-gpios", 0);

...


Anyway, I will update it with your suggestion.

Thanks,


Caesar





>
>> Thanks,
>>
>> Caesar
>
> MBR, Sergei
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


-- 
Thanks,
Caesar


^ permalink raw reply

* Re: [PATCH 3/6] net: arc_emac: support the phy reset for emac driver
From: Caesar Wang @ 2016-03-13  3:57 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Caesar Wang, Heiko Stuebner, David S. Miller, Rob Herring,
	Alexander Kochetkov, netdev, linux-kernel, linux-rockchip,
	keescook, leozwang
In-Reply-To: <56E30FE5.1080607@cogentembedded.com>

Hi Sergei,

在 2016年03月12日 02:35, Sergei Shtylyov 写道:
> On 03/11/2016 01:55 PM, Caesar Wang wrote:
>
>> This patch adds to support the emac phy reset.
>>
>> 1) phy-reset-gpios:
>> The phy-reset-gpios is an optional property for arc emac device tree 
>> boot.
>> Change the binding document to match the driver code.
>
>    The binding document is apparently changed in another patch. Not 
> sure what you wanted to say here...
>
>> 2) phy-reset-duration:
>> Different boards may require different phy reset duration. Add property
>> phy-reset-duration for device tree probe, so that the boards that need
>> a longer reset duration can specify it in their device tree.
>>
>> 3) phy-reset-active-high:
>> We need that for a custom hardware that needs the reverse reset 
>> sequence.
>
>    No, we don't really need that, "phy-reset-gpio" prop can contain 
> this data.
>
>> Of course, this patch will fix the issue on
>> https://patchwork.kernel.org/patch/8186801/.
>>
>> In some cases, the emac couldn't work if you don't have reset the phy.
>> Let's add it to happy work.
>>
>> Signed-off-by: Caesar Wang <wxt@rock-chips.com>
>> ---
>>
>>   drivers/net/ethernet/arc/emac_main.c | 41 
>> ++++++++++++++++++++++++++++++++++++
>>   1 file changed, 41 insertions(+)
>>
>> diff --git a/drivers/net/ethernet/arc/emac_main.c 
>> b/drivers/net/ethernet/arc/emac_main.c
>> index 6446af1..42384f6a 100644
>> --- a/drivers/net/ethernet/arc/emac_main.c
>> +++ b/drivers/net/ethernet/arc/emac_main.c
>> @@ -764,6 +764,45 @@ static const struct net_device_ops 
>> arc_emac_netdev_ops = {
>>   #endif
>>   };
>>
>> +#ifdef CONFIG_OF
>> +static void emac_reset_phy(struct net_device *pdev)
>> +{
>> +    int err, phy_reset;
>> +    bool active_high = false;
>> +    int msec = 10;
>> +    struct device *dev = pdev->dev.parent;
>> +    struct device_node *np = dev->of_node;
>> +
>> +    if (!np)
>> +        return;
>> +
>> +    of_property_read_u32(np, "phy-reset-duration", &msec);
>> +    /* A sane reset duration should not be longer than 1s */
>> +    if (msec > 1000)
>> +        msec = 1;
>> +
>> +    phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
>
>    Forgot to say that these old integer-base GPIO APIs shouldn't be 
> used by the new code, there's new 'struct gpio_desc' based APIs, like 
> devm_gpiod_get() etc.
>
>> +    if (!gpio_is_valid(phy_reset))
>> +        return;
>> +
>> +    active_high = of_property_read_bool(np, "phy-reset-active-high");
>
>    Well, I still don't understand why this prop is needed, while the 
> GPIO sense is transparently handled by the gpiolib (at least when 
> using DT).

Okay, I have to admit that reference the exist way to do...


wxt@nb:~/kernel/drivers/net/ethernet$ ag reset-gpios
micrel/ks8851.c
1427:    gpio = of_get_named_gpio_flags(spi->dev.of_node, "reset-gpios",

arc/emac_main.c
787:    phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
797:        dev_err(dev, "failed to get phy-reset-gpios: %d\n", err);

arc/emac_main.c~
784:    phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
794:        dev_err(dev, "failed to get phy-reset-gpios: %d\n", err);

davicom/dm9000.c
1451:    reset_gpios = of_get_named_gpio_flags(dev->of_node, 
"reset-gpios", 0,

freescale/fec_main.c
3206:    phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
3216:        dev_err(&pdev->dev, "failed to get phy-reset-gpios: %d\n", 
err);

cadence/macb.c
2958:        int gpio = of_get_named_gpio(phy_node, "reset-gpios", 0);

...

Yep, the gpiolib that can include the prop to work with the same ways.



>
> [...]
>
> MBR, Sergei
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


-- 
Thanks,
Caesar

^ permalink raw reply

* Re: [PATCH 2/2] mISDN: Support DR6 indication in mISDNipac driver
From: isdn @ 2016-03-13  3:13 UTC (permalink / raw)
  To: Maciej S. Szmigiero; +Cc: netdev, linux-kernel
In-Reply-To: <56E4A3EB.4050507@maciej.szmigiero.name>

Acked-by: Karsten Keil <keil@b1-systems.de>
Am 13.03.2016 um 00:19 schrieb Maciej S. Szmigiero:
> According to figure 39 in PEB3086 data sheet, version 1.4 this indication
> replaces DR when layer 1 transition source state is F6.
> 
> This fixes mISDN layer 1 getting stuck in F6 state in TE mode on
> Dialogic Diva 2.02 card (and possibly others) when NT deactivates it.
> 
> Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
> ---
>  drivers/isdn/hardware/mISDN/ipac.h      | 1 +
>  drivers/isdn/hardware/mISDN/mISDNipac.c | 2 ++
>  2 files changed, 3 insertions(+)
> 
> diff --git a/drivers/isdn/hardware/mISDN/ipac.h b/drivers/isdn/hardware/mISDN/ipac.h
> index 76aa6f8f298e..720ee72aab6a 100644
> --- a/drivers/isdn/hardware/mISDN/ipac.h
> +++ b/drivers/isdn/hardware/mISDN/ipac.h
> @@ -217,6 +217,7 @@ struct ipac_hw {
>  #define ISAC_IND_SD		0x2
>  #define ISAC_IND_DIS		0x3
>  #define ISAC_IND_RSY		0x4
> +#define ISAC_IND_DR6		0x5
>  #define ISAC_IND_EI		0x6
>  #define ISAC_IND_PU		0x7
>  #define ISAC_IND_ARD		0x8
> diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c
> index cb428b9ee441..aa9b6c3cadc1 100644
> --- a/drivers/isdn/hardware/mISDN/mISDNipac.c
> +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c
> @@ -80,6 +80,7 @@ isac_ph_state_bh(struct dchannel *dch)
>  		l1_event(dch->l1, HW_DEACT_CNF);
>  		break;
>  	case ISAC_IND_DR:
> +	case ISAC_IND_DR6:
>  		dch->state = 3;
>  		l1_event(dch->l1, HW_DEACT_IND);
>  		break;
> @@ -660,6 +661,7 @@ isac_l1cmd(struct dchannel *dch, u32 cmd)
>  		spin_lock_irqsave(isac->hwlock, flags);
>  		if ((isac->state == ISAC_IND_EI) ||
>  		    (isac->state == ISAC_IND_DR) ||
> +		    (isac->state == ISAC_IND_DR6) ||
>  		    (isac->state == ISAC_IND_RS))
>  			ph_command(isac, ISAC_CMD_TIM);
>  		else
> 
> 

^ permalink raw reply

* Re: [PATCH 1/2] mISDN: Order IPAC register defines
From: isdn @ 2016-03-13  3:13 UTC (permalink / raw)
  To: Maciej S. Szmigiero; +Cc: netdev, linux-kernel
In-Reply-To: <56E4A3AE.8050407@maciej.szmigiero.name>

Acked-by: Karsten Keil <keil@b1-systems.de>
Am 13.03.2016 um 00:18 schrieb Maciej S. Szmigiero:
> It looks like IPAC/ISAC chips register defines weren't in any particular
> order.
> 
> Order them by their number to make it easier to spot holes.
> 
> Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
> ---
>  drivers/isdn/hardware/mISDN/ipac.h | 40 +++++++++++++++++++-------------------
>  1 file changed, 20 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/isdn/hardware/mISDN/ipac.h b/drivers/isdn/hardware/mISDN/ipac.h
> index 8121e046b739..76aa6f8f298e 100644
> --- a/drivers/isdn/hardware/mISDN/ipac.h
> +++ b/drivers/isdn/hardware/mISDN/ipac.h
> @@ -99,32 +99,32 @@ struct ipac_hw {
>  
>  /* All registers original Siemens Spec  */
>  /* IPAC/ISAC registers */
> -#define ISAC_MASK		0x20
>  #define ISAC_ISTA		0x20
> -#define ISAC_STAR		0x21
> +#define ISAC_MASK		0x20
>  #define ISAC_CMDR		0x21
> +#define ISAC_STAR		0x21
> +#define ISAC_MODE		0x22
> +#define ISAC_TIMR		0x23
>  #define ISAC_EXIR		0x24
> -#define ISAC_ADF2		0x39
> +#define ISAC_RBCL		0x25
> +#define ISAC_RSTA		0x27
> +#define ISAC_RBCH		0x2A
>  #define ISAC_SPCR		0x30
> -#define ISAC_ADF1		0x38
>  #define ISAC_CIR0		0x31
>  #define ISAC_CIX0		0x31
> -#define ISAC_CIR1		0x33
> -#define ISAC_CIX1		0x33
> -#define ISAC_STCR		0x37
> -#define ISAC_MODE		0x22
> -#define ISAC_RSTA		0x27
> -#define ISAC_RBCL		0x25
> -#define ISAC_RBCH		0x2A
> -#define ISAC_TIMR		0x23
> -#define ISAC_SQXR		0x3b
> -#define ISAC_SQRR		0x3b
> -#define ISAC_MOSR		0x3a
> -#define ISAC_MOCR		0x3a
>  #define ISAC_MOR0		0x32
>  #define ISAC_MOX0		0x32
> +#define ISAC_CIR1		0x33
> +#define ISAC_CIX1		0x33
>  #define ISAC_MOR1		0x34
>  #define ISAC_MOX1		0x34
> +#define ISAC_STCR		0x37
> +#define ISAC_ADF1		0x38
> +#define ISAC_ADF2		0x39
> +#define ISAC_MOCR		0x3a
> +#define ISAC_MOSR		0x3a
> +#define ISAC_SQRR		0x3b
> +#define ISAC_SQXR		0x3b
>  
>  #define ISAC_RBCH_XAC		0x80
>  
> @@ -212,13 +212,13 @@ struct ipac_hw {
>  #define ISAC_CMD_DUI		0xF
>  
>  /* ISAC/ISACX/IPAC/IPACX L1 indications */
> -#define ISAC_IND_RS		0x1
> -#define ISAC_IND_PU		0x7
>  #define ISAC_IND_DR		0x0
> +#define ISAC_IND_RS		0x1
>  #define ISAC_IND_SD		0x2
>  #define ISAC_IND_DIS		0x3
> -#define ISAC_IND_EI		0x6
>  #define ISAC_IND_RSY		0x4
> +#define ISAC_IND_EI		0x6
> +#define ISAC_IND_PU		0x7
>  #define ISAC_IND_ARD		0x8
>  #define ISAC_IND_TI		0xA
>  #define ISAC_IND_ATI		0xB
> @@ -339,9 +339,9 @@ struct ipac_hw {
>  #define ISACX__AUX		0x08
>  #define ISACX__CIC		0x10
>  #define ISACX__ST		0x20
> +#define IPACX__ON		0x2C
>  #define IPACX__ICB		0x40
>  #define IPACX__ICA		0x80
> -#define IPACX__ON		0x2C
>  
>  /* ISACX/IPACX _CMDRD (W) */
>  #define ISACX_CMDRD_XRES	0x01
> 
> 

^ permalink raw reply

* [PATCH] bridge:Fix incorrect variable assignment on error path in br_sysfs_addbr
From: Nicholas Krause @ 2016-03-13  2:46 UTC (permalink / raw)
  To: stephen; +Cc: netdev, bridge, davem, linux-kernel

This fixes the incorrect variable assignment on error path in
br_sysfs_addbr for when the call to kobject_create_and_add
fails to assign the value of -EINVAL to the returned variable of
err rather then incorrectly return zero making callers think this
function has succeededed due to the previous assignment being
assigned zero when assigning it the successful return value of
the call to sysfs_create_group which is zero.

Signed-off-by: Nicholas Krause <xerofoify@gmail.com>
---
 net/bridge/br_sysfs_br.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 6b80914..6833d25 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -872,6 +872,7 @@ int br_sysfs_addbr(struct net_device *dev)
 	if (!br->ifobj) {
 		pr_info("%s: can't add kobject (directory) %s/%s\n",
 			__func__, dev->name, SYSFS_BRIDGE_PORT_SUBDIR);
+		err = -EINVAL;
 		goto out3;
 	}
 	return 0;
-- 
2.5.0

^ permalink raw reply related

* [PATCH] netfilter: fix race condition in ipset save and delete
From: Vishwanath Pai @ 2016-03-13  2:33 UTC (permalink / raw)
  To: pablo, kaber, kadlec, netfilter-devel; +Cc: coreteam, johunt, netdev

netfilter: fix race condition in ipset save and delete

This fix adds a new reference counter (ref_kernel) for the struct ip_set.
The other reference counter (ref) is used to track references from the
userspace and we need a separate counter to keep track of in-kernel
references. Using the same ref counter for both userspace and kernel
references causes a race condition which can be demonstrated by the
following script:

#!/bin/sh
ipset create hash_ip1 hash:ip family inet hashsize 1024 maxelem 500000 \
counters
ipset create hash_ip2 hash:ip family inet hashsize 300000 maxelem 500000 \
counters
ipset create hash_ip3 hash:ip family inet hashsize 1024 maxelem 500000 \
counters

ipset save &

ipset swap hash_ip3 hash_ip2
ipset destroy hash_ip3 /* will crash the machine */

Swap will exchange the values of ref so destroy will see ref = 0 instead of
ref = 1. With this fix in place swap will not suceed because ipset save
still has ref_kernel on the set (ip_set_swap doesn't swap ref_kernel).

Both delete and swap will error out if ref_kernel != 0 on the set.

Note: The changes to *_head functions is because previously we would
increment ref whenever we called these functions, we don't do that
anymore.

Reviewed-by: Joshua Hunt <johunt@akamai.com>
Signed-off-by: Vishwanath Pai <vpai@akamai.com>

--

diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index 0e1f433..86d86db 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -234,6 +234,9 @@ struct ip_set {
 	spinlock_t lock;
 	/* References to the set */
 	u32 ref;
+	/* the above ref can be swapped out by ip_set_swap and
+	   cannot be used to keep track of references within ipset code */
+	u32 ref_kernel;
 	/* The core set type */
 	struct ip_set_type *type;
 	/* The type variant doing the real job */
diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h
index b0bc475..2e8e7e5 100644
--- a/net/netfilter/ipset/ip_set_bitmap_gen.h
+++ b/net/netfilter/ipset/ip_set_bitmap_gen.h
@@ -95,7 +95,7 @@ mtype_head(struct ip_set *set, struct sk_buff *skb)
 	if (!nested)
 		goto nla_put_failure;
 	if (mtype_do_head(skb, map) ||
-	    nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
+	    nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) ||
 	    nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)))
 		goto nla_put_failure;
 	if (unlikely(ip_set_put_flags(skb, set)))
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 95db43f..a055f29 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -497,6 +497,26 @@ __ip_set_put(struct ip_set *set)
 	write_unlock_bh(&ip_set_ref_lock);
 }
 
+/* The above two functions keep track of references from the userspace, the
+ * _internal functions keep track of references in-kernel
+ */
+static inline void
+__ip_set_get_internal(struct ip_set *set)
+{
+	write_lock_bh(&ip_set_ref_lock);
+	set->ref_kernel++;
+	write_unlock_bh(&ip_set_ref_lock);
+}
+
+static inline void
+__ip_set_put_internal(struct ip_set *set)
+{
+	write_lock_bh(&ip_set_ref_lock);
+	BUG_ON(set->ref_kernel == 0);
+	set->ref_kernel--;
+	write_unlock_bh(&ip_set_ref_lock);
+}
+
 /* Add, del and test set entries from kernel.
  *
  * The set behind the index must exist and must be referenced
@@ -999,7 +1019,7 @@ static int ip_set_destroy(struct net *net, struct sock *ctnl,
 	if (!attr[IPSET_ATTR_SETNAME]) {
 		for (i = 0; i < inst->ip_set_max; i++) {
 			s = ip_set(inst, i);
-			if (s && s->ref) {
+			if (s && (s->ref || s->ref_kernel)) {
 				ret = -IPSET_ERR_BUSY;
 				goto out;
 			}
@@ -1021,7 +1041,7 @@ static int ip_set_destroy(struct net *net, struct sock *ctnl,
 		if (!s) {
 			ret = -ENOENT;
 			goto out;
-		} else if (s->ref) {
+		} else if (s->ref || s->ref_kernel) {
 			ret = -IPSET_ERR_BUSY;
 			goto out;
 		}
@@ -1168,6 +1188,9 @@ static int ip_set_swap(struct net *net, struct sock *ctnl, struct sk_buff *skb,
 	      from->family == to->family))
 		return -IPSET_ERR_TYPE_MISMATCH;
 
+	if (from->ref_kernel || to->ref_kernel)
+		return -EBUSY;
+
 	strncpy(from_name, from->name, IPSET_MAXNAMELEN);
 	strncpy(from->name, to->name, IPSET_MAXNAMELEN);
 	strncpy(to->name, from_name, IPSET_MAXNAMELEN);
@@ -1203,7 +1226,7 @@ ip_set_dump_done(struct netlink_callback *cb)
 		if (set->variant->uref)
 			set->variant->uref(set, cb, false);
 		pr_debug("release set %s\n", set->name);
-		__ip_set_put_byindex(inst, index);
+		__ip_set_put_internal(set);
 	}
 	return 0;
 }
@@ -1325,7 +1348,7 @@ dump_last:
 		if (!cb->args[IPSET_CB_ARG0]) {
 			/* Start listing: make sure set won't be destroyed */
 			pr_debug("reference set\n");
-			set->ref++;
+			set->ref_kernel++;
 		}
 		write_unlock_bh(&ip_set_ref_lock);
 		nlh = start_msg(skb, NETLINK_CB(cb->skb).portid,
@@ -1393,7 +1416,7 @@ release_refcount:
 		if (set->variant->uref)
 			set->variant->uref(set, cb, false);
 		pr_debug("release set %s\n", set->name);
-		__ip_set_put_byindex(inst, index);
+		__ip_set_put_internal(set);
 		cb->args[IPSET_CB_ARG0] = 0;
 	}
 out:
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
index e5336ab..d32fd6b 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -1082,7 +1082,7 @@ mtype_head(struct ip_set *set, struct sk_buff *skb)
 	if (nla_put_u32(skb, IPSET_ATTR_MARKMASK, h->markmask))
 		goto nla_put_failure;
 #endif
-	if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
+	if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) ||
 	    nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)))
 		goto nla_put_failure;
 	if (unlikely(ip_set_put_flags(skb, set)))
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
index bbede95..00f92ae 100644
--- a/net/netfilter/ipset/ip_set_list_set.c
+++ b/net/netfilter/ipset/ip_set_list_set.c
@@ -457,7 +457,7 @@ list_set_head(struct ip_set *set, struct sk_buff *skb)
 	if (!nested)
 		goto nla_put_failure;
 	if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) ||
-	    nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
+	    nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) ||
 	    nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
 			  htonl(sizeof(*map) + n * set->dsize)))
 		goto nla_put_failure;

^ permalink raw reply related

* [PATCH net-next 2/2] ipv6: add support for stats via RTM_GETSTATS
From: Roopa Prabhu @ 2016-03-13  1:56 UTC (permalink / raw)
  To: netdev; +Cc: jhs, davem

From: Roopa Prabhu <roopa@cumulusnetworks.com>

This patch is an example of adding af stats in
RTM_GETSTATS. It adds a new nested IFLA_STATS_INET6
attribute for ipv6 af stats. stats attributes inside
IFLA_STATS_INET6 nested attribute use the existing ipv6 stats
attributes from ipv6 IFLA_PROTINFO (I can certainly declare
new attributes if required)

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
I have added this patch only to show an example of af stats.
I have tested it to work. My real intent is to have
IFLA_STATS_MPLS implemented in the same way for mpls.
We could rethink ipv6 stats in a new way instead of carrying
over the older ipv6 stats which i am doing here.
I am not sure how popular the current ipv6 stats are.
I have not used them. Adding this note here if people prefer
dropping this and revisiting ipv6 stats at a later point.

 net/core/rtnetlink.c |  1 +
 net/ipv6/addrconf.c  | 77 ++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 70 insertions(+), 8 deletions(-)

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d1e3d17..00a04e5 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -3464,6 +3464,7 @@ nla_put_failure:
 
 static const struct nla_policy ifla_stats_policy[IFLA_STATS_MAX + 1] = {
 	[IFLA_STATS_LINK64]	= { .len = sizeof(struct rtnl_link_stats64) },
+	[IFLA_STATS_INET6]      = {. type = NLA_NESTED },
 };
 
 static size_t rtnl_link_get_af_stats_size(const struct net_device *dev,
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 8c0dab2..d700647 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4911,6 +4911,29 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
 	}
 }
 
+static int inet6_fill_ifla6_stats(struct sk_buff *skb,
+				  struct inet6_dev *idev)
+{
+	struct nlattr *nla;
+
+	nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
+	if (!nla)
+		goto nla_put_failure;
+	snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
+
+	nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS,
+			  ICMP6_MIB_MAX * sizeof(u64));
+	if (!nla)
+		goto nla_put_failure;
+	snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS,
+			 nla_len(nla));
+
+	return 0;
+
+nla_put_failure:
+	return -EMSGSIZE;
+}
+
 static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
 				  u32 ext_filter_mask)
 {
@@ -4935,15 +4958,8 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
 	if (ext_filter_mask & RTEXT_FILTER_SKIP_STATS)
 		return 0;
 
-	nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
-	if (!nla)
-		goto nla_put_failure;
-	snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
-
-	nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64));
-	if (!nla)
+	if (inet6_fill_ifla6_stats(skb, idev))
 		goto nla_put_failure;
-	snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
 
 	nla = nla_reserve(skb, IFLA_INET6_TOKEN, sizeof(struct in6_addr));
 	if (!nla)
@@ -4985,6 +5001,49 @@ static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev,
 	return 0;
 }
 
+static size_t inet6_get_link_af_stats_size(const struct net_device *dev,
+					   u32 filter_mask)
+{
+	if (!(filter_mask & IFLA_STATS_FILTER_BIT(IFLA_STATS_INET6)))
+		return 0;
+
+	if (!__in6_dev_get(dev))
+		return 0;
+
+	return nla_total_size(sizeof(struct nlattr)) /* IFLA_STATS_INET6 */
+		+ nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */
+		+ nla_total_size(ICMP6_MIB_MAX * sizeof(u64));/* IFLA_INET6_ICMP6STATS */
+}
+
+static int inet6_fill_link_af_stats(struct sk_buff *skb,
+				    const struct net_device *dev,
+				    u32 filter_mask)
+{
+	struct inet6_dev *idev = __in6_dev_get(dev);
+	struct nlattr *inet6_stats;
+
+	if (!(filter_mask & IFLA_STATS_FILTER_BIT(IFLA_STATS_INET6)))
+		return 0;
+
+	if (!idev)
+		return -ENODATA;
+
+	inet6_stats = nla_nest_start(skb, IFLA_STATS_INET6);
+	if (!inet6_stats)
+		return -EMSGSIZE;
+
+	if (inet6_fill_ifla6_stats(skb, idev) < 0)
+		goto errout;
+
+	nla_nest_end(skb, inet6_stats);
+
+	return 0;
+errout:
+	nla_nest_cancel(skb, inet6_stats);
+
+	return -EMSGSIZE;
+}
+
 static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
 {
 	struct inet6_ifaddr *ifp;
@@ -6079,6 +6138,8 @@ static struct rtnl_af_ops inet6_ops __read_mostly = {
 	.get_link_af_size = inet6_get_link_af_size,
 	.validate_link_af = inet6_validate_link_af,
 	.set_link_af	  = inet6_set_link_af,
+	.get_link_af_stats_size = inet6_get_link_af_stats_size,
+	.fill_link_af_stats = inet6_fill_link_af_stats,
 };
 
 /*
-- 
1.9.1

^ permalink raw reply related

* [PATCH net-next 1/2] rtnetlink: add new RTM_GETSTATS message to dump link stats
From: Roopa Prabhu @ 2016-03-13  1:56 UTC (permalink / raw)
  To: netdev; +Cc: jhs, davem

From: Roopa Prabhu <roopa@cumulusnetworks.com>

This patch adds a new RTM_GETSTATS message to query link stats via netlink
from the kernel. RTM_NEWLINK also dumps stats today, but RTM_NEWLINK
returns a lot more than just stats and is expensive in some cases when
frequent polling for stats from userspace is a common operation.

RTM_GETSTATS is an attempt to provide a light weight netlink message
to explicity query only link stats from the kernel on an interface.
The idea is to also keep it extensible so that new kinds of stats can be
added to it in the future.

This patch adds the following attribute for NETDEV stats:
struct nla_policy ifla_stats_policy[IFLA_STATS_MAX + 1] = {
        [IFLA_STATS_LINK64]  = { .len = sizeof(struct rtnl_link_stats64) },
};

This patch also allows for af family stats (an example af stats for IPV6
is available with the second patch in the series).

Like any other rtnetlink message, RTM_GETSTATS can be used to get stats of
a single interface or all interfaces with NLM_F_DUMP.

Future possible new types of stat attributes:
- IFLA_MPLS_STATS  (nested. for mpls/mdev stats)
- IFLA_EXTENDED_STATS (nested. extended software netdev stats like bridge,
  vlan, vxlan etc)
- IFLA_EXTENDED_HW_STATS (nested. extended hardware stats which are
  available via ethtool today)

This patch also declares a filter mask for all stat attributes.
User has to provide a mask of stats attributes to query. This will be
specified in a new hdr 'struct if_stats_msg' for stats messages.

Without any attributes in the filter_mask, no stats will be returned.

This patch has been tested with modified iproute2 ifstat.

Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
 include/net/rtnetlink.h        |   5 ++
 include/uapi/linux/if_link.h   |  19 ++++
 include/uapi/linux/rtnetlink.h |   7 ++
 net/core/rtnetlink.c           | 200 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 231 insertions(+)

diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 2f87c1b..fa68158 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -131,6 +131,11 @@ struct rtnl_af_ops {
 						    const struct nlattr *attr);
 	int			(*set_link_af)(struct net_device *dev,
 					       const struct nlattr *attr);
+	size_t			(*get_link_af_stats_size)(const struct net_device *dev,
+							  u32 filter_mask);
+	int			(*fill_link_af_stats)(struct sk_buff *skb,
+						      const struct net_device *dev,
+						      u32 filter_mask);
 };
 
 void __rtnl_af_unregister(struct rtnl_af_ops *ops);
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 249eef9..0840f3e 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -741,4 +741,23 @@ enum {
 
 #define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
 
+/* STATS section */
+
+struct if_stats_msg {
+	__u8  family;
+	__u32 ifindex;
+	__u32 filter_mask;
+};
+
+enum {
+	IFLA_STATS_UNSPEC,
+	IFLA_STATS_LINK64,
+	IFLA_STATS_INET6,
+	__IFLA_STATS_MAX,
+};
+
+#define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1)
+
+#define IFLA_STATS_FILTER_BIT(ATTR)	(1 << (ATTR))
+
 #endif /* _UAPI_LINUX_IF_LINK_H */
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index ca764b5..2bbb300 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -139,6 +139,13 @@ enum {
 	RTM_GETNSID = 90,
 #define RTM_GETNSID RTM_GETNSID
 
+	RTM_NEWSTATS = 92,
+#define RTM_NEWSTATS RTM_NEWSTATS
+	RTM_DELSTATS = 93,
+#define RTM_DELSTATS RTM_DELSTATS
+	RTM_GETSTATS = 94,
+#define RTM_GETSTATS RTM_GETSTATS
+
 	__RTM_MAX,
 #define RTM_MAX		(((__RTM_MAX + 3) & ~3) - 1)
 };
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d2d9e5e..d1e3d17 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -3410,6 +3410,203 @@ out:
 	return err;
 }
 
+static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
+			       int type, u32 pid, u32 seq, u32 change,
+			       unsigned int flags, unsigned int filter_mask)
+{
+	const struct rtnl_link_stats64 *stats;
+	struct rtnl_link_stats64 temp;
+	struct if_stats_msg *ifsm;
+	struct nlmsghdr *nlh;
+	struct rtnl_af_ops *af_ops;
+	struct nlattr *attr;
+
+	ASSERT_RTNL();
+
+	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifsm), flags);
+	if (!nlh)
+		return -EMSGSIZE;
+
+	ifsm = nlmsg_data(nlh);
+	ifsm->ifindex = dev->ifindex;
+	ifsm->filter_mask = filter_mask;
+
+	if (filter_mask & IFLA_STATS_FILTER_BIT(IFLA_STATS_LINK64)) {
+		attr = nla_reserve(skb, IFLA_STATS_LINK64,
+				   sizeof(struct rtnl_link_stats64));
+		if (!attr)
+			return -EMSGSIZE;
+
+		stats = dev_get_stats(dev, &temp);
+
+		copy_rtnl_link_stats64(nla_data(attr), stats);
+	}
+
+	list_for_each_entry(af_ops, &rtnl_af_ops, list) {
+		if (af_ops->fill_link_af_stats) {
+			int err;
+
+			err = af_ops->fill_link_af_stats(skb, dev, filter_mask);
+			if (err < 0)
+				goto nla_put_failure;
+		}
+	}
+
+	nlmsg_end(skb, nlh);
+
+	return 0;
+
+nla_put_failure:
+	nlmsg_cancel(skb, nlh);
+
+	return -EMSGSIZE;
+}
+
+static const struct nla_policy ifla_stats_policy[IFLA_STATS_MAX + 1] = {
+	[IFLA_STATS_LINK64]	= { .len = sizeof(struct rtnl_link_stats64) },
+};
+
+static size_t rtnl_link_get_af_stats_size(const struct net_device *dev,
+					  u32 filter_mask)
+{
+	struct rtnl_af_ops *af_ops;
+	size_t size = 0;
+
+	list_for_each_entry(af_ops, &rtnl_af_ops, list) {
+		if (af_ops->get_link_af_stats_size)
+			size += af_ops->get_link_af_stats_size(dev,
+							       filter_mask);
+	}
+
+	return size;
+}
+
+static noinline size_t if_nlmsg_stats_size(const struct net_device *dev,
+					   u32 filter_mask)
+{
+	size_t size = 0;
+
+	if (filter_mask & IFLA_STATS_FILTER_BIT(IFLA_STATS_LINK64))
+		size += nla_total_size(sizeof(struct rtnl_link_stats64));
+
+	size += rtnl_link_get_af_stats_size(dev, filter_mask);
+
+	return size;
+}
+
+static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh)
+{
+	struct net *net = sock_net(skb->sk);
+	struct if_stats_msg *ifsm;
+	struct net_device *dev = NULL;
+	struct sk_buff *nskb;
+	u32 filter_mask;
+	int err;
+
+	ifsm = nlmsg_data(nlh);
+	if (ifsm->ifindex > 0)
+		dev = __dev_get_by_index(net, ifsm->ifindex);
+	else
+		return -EINVAL;
+
+	if (!dev)
+		return -ENODEV;
+
+	filter_mask = ifsm->filter_mask;
+	if (!filter_mask)
+		return -EINVAL;
+
+	nskb = nlmsg_new(if_nlmsg_stats_size(dev, filter_mask), GFP_KERNEL);
+	if (!nskb)
+		return -ENOBUFS;
+
+	err = rtnl_fill_statsinfo(nskb, dev, RTM_NEWSTATS,
+				  NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0,
+				  0, filter_mask);
+	if (err < 0) {
+		/* -EMSGSIZE implies BUG in if_nlmsg_stats_size */
+		WARN_ON(err == -EMSGSIZE);
+		kfree_skb(nskb);
+	} else {
+		err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid);
+	}
+
+	return err;
+}
+
+static u16 rtnl_stats_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
+{
+	struct net *net = sock_net(skb->sk);
+	struct net_device *dev;
+	u16 min_ifinfo_dump_size = 0;
+	struct if_stats_msg *ifsm;
+	u32 filter_mask;
+
+	ifsm = nlmsg_data(nlh);
+	filter_mask = ifsm->filter_mask;
+
+	/* traverse the list of net devices and compute the minimum
+	 * buffer size based upon the filter mask.
+	 */
+	list_for_each_entry(dev, &net->dev_base_head, dev_list) {
+		min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size,
+					     if_nlmsg_stats_size(dev,
+								 filter_mask));
+	}
+
+	return min_ifinfo_dump_size;
+}
+
+static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct net *net = sock_net(skb->sk);
+	struct if_stats_msg *ifsm;
+	int h, s_h;
+	int idx = 0, s_idx;
+	struct net_device *dev;
+	struct hlist_head *head;
+	unsigned int flags = NLM_F_MULTI;
+	u32 filter_mask = 0;
+	int err;
+
+	s_h = cb->args[0];
+	s_idx = cb->args[1];
+
+	cb->seq = net->dev_base_seq;
+
+	ifsm = nlmsg_data(cb->nlh);
+	filter_mask = ifsm->filter_mask;
+
+	for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
+		idx = 0;
+		head = &net->dev_index_head[h];
+		hlist_for_each_entry(dev, head, index_hlist) {
+			if (idx < s_idx)
+				goto cont;
+			err = rtnl_fill_statsinfo(skb, dev, RTM_NEWSTATS,
+						  NETLINK_CB(cb->skb).portid,
+						  cb->nlh->nlmsg_seq, 0,
+						  flags, filter_mask);
+			/* If we ran out of room on the first message,
+			 * we're in trouble
+			 */
+			WARN_ON((err == -EMSGSIZE) && (skb->len == 0));
+
+			if (err < 0)
+				goto out;
+
+			nl_dump_check_consistent(cb, nlmsg_hdr(skb));
+cont:
+			idx++;
+		}
+	}
+out:
+	cb->args[1] = idx;
+	cb->args[0] = h;
+
+	return skb->len;
+}
+
 /* Process one rtnetlink message. */
 
 static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
@@ -3559,4 +3756,7 @@ void __init rtnetlink_init(void)
 	rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, NULL);
 	rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, NULL);
 	rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, NULL);
+
+	rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump,
+		      rtnl_stats_calcit);
 }
-- 
1.9.1

^ permalink raw reply related

* [PATCH net-next 0/2] rtnetlink: new message for stats
From: Roopa Prabhu @ 2016-03-13  1:56 UTC (permalink / raw)
  To: netdev; +Cc: jhs, davem

From: Roopa Prabhu <roopa@cumulusnetworks.com>

This patch adds a new RTM_GETSTATS message to query link stats via
netlink from the kernel. RTM_NEWLINK also dumps stats today, but
RTM_NEWLINK returns a lot more than just stats and is expensive in some
cases when frequent polling for stats from userspace is a common operation.

RTM_GETSTATS is an attempt to provide a light weight netlink message
to explicity query only link stats from the kernel on an interface.
The idea is to also keep it extensible so that new kinds of stats can be
added to it in the future.


Roopa Prabhu (2):
  rtnetlink: add new RTM_GETSTATS to dump link stats
  ipv6: add support for stats via RTM_GETSTATS

Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>

RFC to v1 (apologies for the delay in sending this version out. busy days):
        - Addressed feedback from Dave
                - removed rtnl_link_stats
                - Added hdr struct if_stats_msg to carry ifindex and
                  filter mask
                - new macro IFLA_STATS_FILTER_BIT(ATTR) for filter mask
        - split the ipv6 patch into a separate patch, need some more eyes on it
        - prefix attributes with IFLA_STATS instead of IFLA_LINK_STATS for shorter
          attribute names


 include/net/rtnetlink.h        |   5 +
 include/uapi/linux/if_link.h   |  19 ++++
 include/uapi/linux/rtnetlink.h |   7 ++
 net/core/rtnetlink.c           | 201 +++++++++++++++++++++++++++++++++++++++++
 net/ipv6/addrconf.c            |  77 ++++++++++++++--
 5 files changed, 301 insertions(+), 8 deletions(-)

-- 
1.9.1

^ 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