Netdev List
 help / color / mirror / Atom feed
* [PATCH 03/10] stmmac: sanitize the rx coe and add the type-1 csum
From: Giuseppe CAVALLARO @ 2012-03-23  9:08 UTC (permalink / raw)
  To: netdev
  Cc: davem, srinivas.kandagatla, deepak.sikri, spear-devel,
	shiraz.hashim, viresh.kumar, bhutchings
In-Reply-To: <1332493721-28309-1-git-send-email-peppe.cavallaro@st.com>

From: Deepak SIKRI <deepak.sikri@st.com>

This patch sanities the RX coe and adds the Type-1 Rx checksum offload engine (COE).

So the RX COE can be passed through the platform but can be fixed
at run-time in case of the core has the HW capability register.

Also to support the Type-1 Rx COE the driver must append the
HW checksum at the end of payload in case the Rx checksum
engine was used to  offload the HW checksum.

Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Hacked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/common.h       |    4 +--
 .../net/ethernet/stmicro/stmmac/dwmac1000_core.c   |   13 ----------
 .../net/ethernet/stmicro/stmmac/dwmac100_core.c    |    6 -----
 drivers/net/ethernet/stmicro/stmmac/enh_desc.c     |   13 +++++++++-
 drivers/net/ethernet/stmicro/stmmac/norm_desc.c    |   13 +++++++++-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |    2 -
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |   24 ++++++++++++++-----
 7 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 0319d64..386b100 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -228,7 +228,7 @@ struct stmmac_desc_ops {
 	int (*get_rx_owner) (struct dma_desc *p);
 	void (*set_rx_owner) (struct dma_desc *p);
 	/* Get the receive frame size */
-	int (*get_rx_frame_len) (struct dma_desc *p);
+	int (*get_rx_frame_len) (struct dma_desc *p, int rx_coe_type);
 	/* Return the reception status looking at the RDES1 */
 	int (*rx_status) (void *data, struct stmmac_extra_stats *x,
 			  struct dma_desc *p);
@@ -261,8 +261,6 @@ struct stmmac_dma_ops {
 struct stmmac_ops {
 	/* MAC core initialization */
 	void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned;
-	/* Support checksum offload engine */
-	int  (*rx_coe) (void __iomem *ioaddr);
 	/* Dump MAC registers */
 	void (*dump_regs) (void __iomem *ioaddr);
 	/* Handle extra events on specific interrupts hw dependent */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index b1c48b9..342fe8d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -46,18 +46,6 @@ static void dwmac1000_core_init(void __iomem *ioaddr)
 #endif
 }
 
-static int dwmac1000_rx_coe_supported(void __iomem *ioaddr)
-{
-	u32 value = readl(ioaddr + GMAC_CONTROL);
-
-	value |= GMAC_CONTROL_IPC;
-	writel(value, ioaddr + GMAC_CONTROL);
-
-	value = readl(ioaddr + GMAC_CONTROL);
-
-	return !!(value & GMAC_CONTROL_IPC);
-}
-
 static void dwmac1000_dump_regs(void __iomem *ioaddr)
 {
 	int i;
@@ -211,7 +199,6 @@ static void dwmac1000_irq_status(void __iomem *ioaddr)
 
 static const struct stmmac_ops dwmac1000_ops = {
 	.core_init = dwmac1000_core_init,
-	.rx_coe = dwmac1000_rx_coe_supported,
 	.dump_regs = dwmac1000_dump_regs,
 	.host_irq_status = dwmac1000_irq_status,
 	.set_filter = dwmac1000_set_filter,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
index 138fb8d..9faf010 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -43,11 +43,6 @@ static void dwmac100_core_init(void __iomem *ioaddr)
 #endif
 }
 
-static int dwmac100_rx_coe_supported(void __iomem *ioaddr)
-{
-	return 0;
-}
-
 static void dwmac100_dump_mac_regs(void __iomem *ioaddr)
 {
 	pr_info("\t----------------------------------------------\n"
@@ -160,7 +155,6 @@ static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode)
 
 static const struct stmmac_ops dwmac100_ops = {
 	.core_init = dwmac100_core_init,
-	.rx_coe = dwmac100_rx_coe_supported,
 	.dump_regs = dwmac100_dump_mac_regs,
 	.host_irq_status = dwmac100_irq_status,
 	.set_filter = dwmac100_set_filter,
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
index ad1b627..2fc8ef9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
@@ -22,6 +22,7 @@
   Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
 *******************************************************************************/
 
+#include <linux/stmmac.h>
 #include "common.h"
 #include "descs_com.h"
 
@@ -309,9 +310,17 @@ static void enh_desc_close_tx_desc(struct dma_desc *p)
 	p->des01.etx.interrupt = 1;
 }
 
-static int enh_desc_get_rx_frame_len(struct dma_desc *p)
+static int enh_desc_get_rx_frame_len(struct dma_desc *p, int rx_coe_type)
 {
-	return p->des01.erx.frame_length;
+	/* The type-1 checksum offload engines append the checksum at
+	 * the end of frame and the two bytes of checksum are added in
+	 * the length.
+	 * Adjust for that in the framelen for type-1 checksum offload
+	 * engines. */
+	if (rx_coe_type == STMMAC_RX_COE_TYPE1)
+		return p->des01.erx.frame_length - 2;
+	else
+		return p->des01.erx.frame_length;
 }
 
 const struct stmmac_desc_ops enh_desc_ops = {
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
index 25953bb..68962c5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
@@ -22,6 +22,7 @@
   Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
 *******************************************************************************/
 
+#include <linux/stmmac.h>
 #include "common.h"
 #include "descs_com.h"
 
@@ -201,9 +202,17 @@ static void ndesc_close_tx_desc(struct dma_desc *p)
 	p->des01.tx.interrupt = 1;
 }
 
-static int ndesc_get_rx_frame_len(struct dma_desc *p)
+static int ndesc_get_rx_frame_len(struct dma_desc *p, int rx_coe_type)
 {
-	return p->des01.rx.frame_length;
+	/* The type-1 checksum offload engines append the checksum at
+	 * the end of frame and the two bytes of checksum are added in
+	 * the length.
+	 * Adjust for that in the framelen for type-1 checksum offload
+	 * engines. */
+	if (rx_coe_type == STMMAC_RX_COE_TYPE1)
+		return p->des01.rx.frame_length - 2;
+	else
+		return p->des01.rx.frame_length;
 }
 
 const struct stmmac_desc_ops ndesc_ops = {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index b4b095f..b65d787 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -56,8 +56,6 @@ struct stmmac_priv {
 
 	struct stmmac_extra_stats xstats;
 	struct napi_struct napi;
-
-	int rx_coe;
 	int no_csum_insertion;
 
 	struct phy_device *phydev;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 860519c..a5a150d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1282,7 +1282,8 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
 			struct sk_buff *skb;
 			int frame_len;
 
-			frame_len = priv->hw->desc->get_rx_frame_len(p);
+			frame_len = priv->hw->desc->get_rx_frame_len(p,
+					priv->plat->rx_coe);
 			/* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
 			 * Type frames (LLC/LLC-SNAP) */
 			if (unlikely(status != llc_snap))
@@ -1318,7 +1319,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
 #endif
 			skb->protocol = eth_type_trans(skb, priv->dev);
 
-			if (unlikely(!priv->rx_coe)) {
+			if (unlikely(!priv->plat->rx_coe)) {
 				/* No RX COE for old mac10/100 devices */
 				skb_checksum_none_assert(skb);
 				netif_receive_skb(skb);
@@ -1465,8 +1466,10 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
 
-	if (!priv->rx_coe)
+	if (priv->plat->rx_coe == STMMAC_RX_COE_NONE)
 		features &= ~NETIF_F_RXCSUM;
+	else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1)
+		features &= ~NETIF_F_IPV6_CSUM;
 	if (!priv->plat->tx_coe)
 		features &= ~NETIF_F_ALL_CSUM;
 
@@ -1769,17 +1772,24 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
 		 * register (if supported).
 		 */
 		priv->plat->enh_desc = priv->dma_cap.enh_desc;
-		priv->plat->tx_coe = priv->dma_cap.tx_coe;
 		priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
+
+		priv->plat->tx_coe = priv->dma_cap.tx_coe;
+
+		if (priv->dma_cap.rx_coe_type2)
+			priv->plat->rx_coe = STMMAC_RX_COE_TYPE2;
+		else if (priv->dma_cap.rx_coe_type1)
+			priv->plat->rx_coe = STMMAC_RX_COE_TYPE1;
+
 	} else
 		pr_info(" No HW DMA feature register supported");
 
 	/* Select the enhnaced/normal descriptor structures */
 	stmmac_selec_desc_mode(priv);
 
-	priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
-	if (priv->rx_coe)
-		pr_info(" RX Checksum Offload Engine supported\n");
+	if (priv->plat->rx_coe)
+		pr_info(" RX Checksum Offload Engine supported (type %d)\n",
+			priv->plat->rx_coe);
 	if (priv->plat->tx_coe)
 		pr_info(" TX Checksum insertion supported\n");
 
-- 
1.7.4.4

^ permalink raw reply related

* [PATCH 04/10] stmmac: Define MDC clock selection macros
From: Giuseppe CAVALLARO @ 2012-03-23  9:08 UTC (permalink / raw)
  To: netdev
  Cc: davem, srinivas.kandagatla, deepak.sikri, spear-devel,
	shiraz.hashim, viresh.kumar, bhutchings
In-Reply-To: <1332493721-28309-1-git-send-email-peppe.cavallaro@st.com>

From: Deepak SIKRI <deepak.sikri@st.com>

The patch adds the macros to be used for MDC clock selection. The MDC clock
frequency is based on scaled system clock, and has to be confined to a range
of 1-2.5 MHz. Based on the input CSR clock, the scaling factor has to be
selected.
The platform specific code will provide the default value of this scaling
factor, based on the input CSR clock.
There is an option to set MDC clock higher than the IEEE 802.3 specified
frequency limit of 2.5 MHz. This applies for the interfacing chips that
support higher MDC clocks. The resultant higher clock of 12.5 MHz requires
additional Macros to be defined for the clock divider corresponding to the
to the following selection.
-----------------------------------------
	Selection	MDC Clock
-----------------------------------------
	1000 		clk_csr_i/4
	1001 		clk_csr_i/6
	1010 		clk_csr_i/8
	1011 		clk_csr_i/10
	1100 		clk_csr_i/12
	1101	 	clk_csr_i/14
	1110 		clk_csr_i/16
	1111 		clk_csr_i/18

This support has to be added both in the include file, as well as driver. The
driver need to program the registers based on the interfacing chips. This would
be more board specific information and needs to be passed through the platform
code to the driver. This work would be carried out in the future patch set
release.

Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 include/linux/stmmac.h |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index a9b4d6c..e529282 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -32,6 +32,34 @@
 #define STMMAC_RX_COE_TYPE1	1
 #define STMMAC_RX_COE_TYPE2	2
 
+/* Define the macros for CSR clock range parameters to be passed by
+ * platform code.
+ * This could also be configured at run time using CPU freq framework. */
+
+/* MDC Clock Selection define*/
+#define	STMMAC_CSR_60_100M	0	/* MDC = clk_scr_i/42 */
+#define	STMMAC_CSR_100_150M	1	/* MDC = clk_scr_i/62 */
+#define	STMMAC_CSR_20_35M	2	/* MDC = clk_scr_i/16 */
+#define	STMMAC_CSR_35_60M	3	/* MDC = clk_scr_i/26 */
+#define	STMMAC_CSR_150_250M	4	/* MDC = clk_scr_i/102 */
+#define	STMMAC_CSR_250_300M	5	/* MDC = clk_scr_i/122 */
+
+/* FIXME: The MDC clock could be set higher than the IEEE 802.3
+ * specified frequency limit 0f 2.5 MHz, by programming a clock divider
+ * of value different than the above defined values. The resultant MDIO
+ * clock frequency of 12.5 MHz is applicable for the interfacing chips
+ * supporting higher MDC clocks.
+ * The MDC clock selection macros need to be defined for MDC clock rate
+ * of 12.5 MHz, corresponding to the following selection.
+ * 1000 clk_csr_i/4
+ * 1001 clk_csr_i/6
+ * 1010 clk_csr_i/8
+ * 1011 clk_csr_i/10
+ * 1100 clk_csr_i/12
+ * 1101 clk_csr_i/14
+ * 1110 clk_csr_i/16
+ * 1111 clk_csr_i/18 */
+
 /* Platfrom data for platform device structure's platform_data field */
 
 struct stmmac_mdio_bus_data {
-- 
1.7.4.4

^ permalink raw reply related

* [PATCH 05/10] stmmac: re-work the internal GMAC DMA platf parameters
From: Giuseppe CAVALLARO @ 2012-03-23  9:08 UTC (permalink / raw)
  To: netdev
  Cc: davem, srinivas.kandagatla, deepak.sikri, spear-devel,
	shiraz.hashim, viresh.kumar, bhutchings, Vikas Manocha
In-Reply-To: <1332493721-28309-1-git-send-email-peppe.cavallaro@st.com>

From: Deepak SIKRI <deepak.sikri@st.com>

This patch re-works the internal GMAC DMA parameters
passed from the platform.
In the past, we only passed the pbl but, with new core,
other parameters can be passed and are mandatory on some
platforms.

New parameters are documented in stmmac.txt because this
patch has an impact for many platforms.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Vikas Manocha <vikas.manocha@st.com>
Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Hacked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 Documentation/networking/stmmac.txt                |   24 ++++++++++-
 drivers/net/ethernet/stmicro/stmmac/common.h       |    3 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac1000.h    |    2 +-
 .../net/ethernet/stmicro/stmmac/dwmac1000_dma.c    |   42 +++++++++++++++++--
 drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c |    6 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h    |    1 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |    4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c   |    3 +-
 include/linux/stmmac.h                             |   20 +++++++++-
 9 files changed, 89 insertions(+), 16 deletions(-)

diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index 61f40a3..eacb640 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -111,7 +111,7 @@ and detailed below as well:
 	int phy_addr;
 	int interface;
 	struct stmmac_mdio_bus_data *mdio_bus_data;
-	int pbl;
+	struct stmmac_dma_cfg *dma_cfg;
 	int clk_csr;
 	int has_gmac;
 	int enh_desc;
@@ -163,7 +163,7 @@ Where:
  o custom_cfg: this is a custom configuration that can be passed while
 	      initialising the resources.
 
-The we have:
+For MDIO bus The we have:
 
  struct stmmac_mdio_bus_data {
 	int bus_id;
@@ -180,10 +180,28 @@ Where:
  o irqs: list of IRQs, one per PHY.
  o probed_phy_irq: if irqs is NULL, use this for probed PHY.
 
+
+For DMA engine we have the following internal fields that should be
+tuned according to the HW capabilities.
+
+struct stmmac_dma_cfg {
+	int pbl;
+	int fixed_burst;
+	int burst_len_supported;
+};
+
+Where:
+ o pbl: Programmable Burst Length
+ o fixed_burst: program the DMA to use the fixed burst mode
+ o burst_len: this is the value we put in the register
+	      supported values are provided as macros in
+	      linux/stmmac.h header file.
+
+---
+
 Below an example how the structures above are using on ST platforms.
 
  static struct plat_stmmacenet_data stxYYY_ethernet_platform_data = {
-	.pbl = 32,
 	.has_gmac = 0,
 	.enh_desc = 0,
 	.fix_mac_speed = stxYYY_ethernet_fix_mac_speed,
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 386b100..f4df1eb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -236,7 +236,8 @@ struct stmmac_desc_ops {
 
 struct stmmac_dma_ops {
 	/* DMA core initialization */
-	int (*init) (void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
+	int (*init) (void __iomem *ioaddr, int pbl, int fb, int burst_len,
+			u32 dma_tx, u32 dma_rx);
 	/* Dump DMA registers */
 	void (*dump_regs) (void __iomem *ioaddr);
 	/* Set tx/rx threshold in the csr6 register
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
index cfcef0e..54339a7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -142,7 +142,7 @@ enum rx_tx_priority_ratio {
 #define DMA_BUS_MODE_RPBL_MASK	0x003e0000	/* Rx-Programmable Burst Len */
 #define DMA_BUS_MODE_RPBL_SHIFT	17
 #define DMA_BUS_MODE_USP	0x00800000
-#define DMA_BUS_MODE_4PBL	0x01000000
+#define DMA_BUS_MODE_PBL	0x01000000
 #define DMA_BUS_MODE_AAL	0x02000000
 
 /* DMA CRS Control and Status Register Mapping */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index 4d5402a..3675c57 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -30,8 +30,8 @@
 #include "dwmac1000.h"
 #include "dwmac_dma.h"
 
-static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
-			      u32 dma_rx)
+static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb,
+			      int burst_len, u32 dma_tx, u32 dma_rx)
 {
 	u32 value = readl(ioaddr + DMA_BUS_MODE);
 	int limit;
@@ -48,15 +48,47 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
 	if (limit < 0)
 		return -EBUSY;
 
-	value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
-	    ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
-	     (pbl << DMA_BUS_MODE_RPBL_SHIFT));
+	/*
+	 * Set the DMA PBL (Programmable Burst Length) mode
+	 * Before stmmac core 3.50 this mode bit was 4xPBL, and
+	 * post 3.5 mode bit acts as 8*PBL.
+	 * For core rev < 3.5, when the core is set for 4xPBL mode, the
+	 * DMA transfers the data in 4, 8, 16, 32, 64 & 128 beats
+	 * depending on pbl value.
+	 * For core rev > 3.5, when the core is set for 8xPBL mode, the
+	 * DMA transfers the data in 8, 16, 32, 64, 128 & 256 beats
+	 * depending on pbl value.
+	 */
+	value = DMA_BUS_MODE_PBL | ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
+		(pbl << DMA_BUS_MODE_RPBL_SHIFT));
+
+	/* Set the Fixed burst mode */
+	if (fb)
+		value |= DMA_BUS_MODE_FB;
 
 #ifdef CONFIG_STMMAC_DA
 	value |= DMA_BUS_MODE_DA;	/* Rx has priority over tx */
 #endif
 	writel(value, ioaddr + DMA_BUS_MODE);
 
+	/* In case of GMAC AXI configuration, program the DMA_AXI_BUS_MODE
+	 * for supported bursts.
+	 *
+	 * Note: This is applicable only for revision GMACv3.61a. For
+	 * older version this register is reserved and shall have no
+	 * effect.
+	 *
+	 * Note:
+	 *  For Fixed Burst Mode: if we directly write 0xFF to this
+	 *  register using the configurations pass from platform code,
+	 *  this would ensure that all bursts supported by core are set
+	 *  and those which are not supported would remain ineffective.
+	 *
+	 *  For Non Fixed Burst Mode: provide the maximum value of the
+	 *  burst length. Any burst equal or below the provided burst
+	 *  length would be allowed to perform. */
+	writel(burst_len, ioaddr + DMA_AXI_BUS_MODE);
+
 	/* Mask interrupts by writing to CSR7 */
 	writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
index bc17fd0..92ed2e0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
@@ -32,8 +32,8 @@
 #include "dwmac100.h"
 #include "dwmac_dma.h"
 
-static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
-			     u32 dma_rx)
+static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb,
+			     int burst_len, u32 dma_tx, u32 dma_rx)
 {
 	u32 value = readl(ioaddr + DMA_BUS_MODE);
 	int limit;
@@ -52,7 +52,7 @@ static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
 
 	/* Enable Application Access by writing to DMA CSR0 */
 	writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
-	       ioaddr + DMA_BUS_MODE);
+			ioaddr + DMA_BUS_MODE);
 
 	/* Mask interrupts by writing to CSR7 */
 	writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index 437edac..6e0360f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -32,6 +32,7 @@
 #define DMA_CONTROL		0x00001018	/* Ctrl (Operational Mode) */
 #define DMA_INTR_ENA		0x0000101c	/* Interrupt Enable */
 #define DMA_MISSED_FRAME_CTR	0x00001020	/* Missed Frame Counter */
+#define DMA_AXI_BUS_MODE       0x00001028      /* AXI Bus Mode */
 #define DMA_CUR_TX_BUF_ADDR	0x00001050	/* Current Host Tx Buffer */
 #define DMA_CUR_RX_BUF_ADDR	0x00001054	/* Current Host Rx Buffer */
 #define DMA_HW_FEATURE		0x00001058	/* HW Feature Register */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index a5a150d..7ac13d5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -944,7 +944,9 @@ static int stmmac_open(struct net_device *dev)
 	init_dma_desc_rings(dev);
 
 	/* DMA initialization and SW reset */
-	ret = priv->hw->dma->init(priv->ioaddr, priv->plat->pbl,
+	ret = priv->hw->dma->init(priv->ioaddr, priv->plat->dma_cfg->pbl,
+				  priv->plat->dma_cfg->fixed_burst,
+				  priv->plat->dma_cfg->burst_len,
 				  priv->dma_tx_phy, priv->dma_rx_phy);
 	if (ret < 0) {
 		pr_err("%s: DMA initialization failed\n", __func__);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
index da66ed7..65e0f98 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -35,7 +35,8 @@ static void stmmac_default_data(void)
 	plat_dat.bus_id = 1;
 	plat_dat.phy_addr = 0;
 	plat_dat.interface = PHY_INTERFACE_MODE_GMII;
-	plat_dat.pbl = 32;
+	plat_dat.dma_cfg->pbl = 32;
+	plat_dat.dma_cfg->burst_len = DMA_AXI_BLEN_256;
 	plat_dat.clk_csr = 2;	/* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
 	plat_dat.has_gmac = 1;
 	plat_dat.force_sf_dma_mode = 1;
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index e529282..4aef9ba 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -60,6 +60,18 @@
  * 1110 clk_csr_i/16
  * 1111 clk_csr_i/18 */
 
+/* AXI DMA Burst length suported */
+#define DMA_AXI_BLEN_4		(1 << 1)
+#define DMA_AXI_BLEN_8		(1 << 2)
+#define DMA_AXI_BLEN_16		(1 << 3)
+#define DMA_AXI_BLEN_32		(1 << 4)
+#define DMA_AXI_BLEN_64		(1 << 5)
+#define DMA_AXI_BLEN_128	(1 << 6)
+#define DMA_AXI_BLEN_256	(1 << 7)
+#define DMA_AXI_BLEN_ALL (DMA_AXI_BLEN_4 | DMA_AXI_BLEN_8 | DMA_AXI_BLEN_16 \
+			| DMA_AXI_BLEN_32 | DMA_AXI_BLEN_64 \
+			| DMA_AXI_BLEN_128 | DMA_AXI_BLEN_256)
+
 /* Platfrom data for platform device structure's platform_data field */
 
 struct stmmac_mdio_bus_data {
@@ -70,13 +82,19 @@ struct stmmac_mdio_bus_data {
 	int probed_phy_irq;
 };
 
+struct stmmac_dma_cfg {
+	int pbl;
+	int fixed_burst;
+	int burst_len;
+};
+
 struct plat_stmmacenet_data {
 	char *phy_bus_name;
 	int bus_id;
 	int phy_addr;
 	int interface;
 	struct stmmac_mdio_bus_data *mdio_bus_data;
-	int pbl;
+	struct stmmac_dma_cfg *dma_cfg;
 	int clk_csr;
 	int has_gmac;
 	int enh_desc;
-- 
1.7.4.4

^ permalink raw reply related

* [PATCH 00/10] stmmac update: March 2012
From: Giuseppe CAVALLARO @ 2012-03-23  9:08 UTC (permalink / raw)
  To: netdev
  Cc: davem, srinivas.kandagatla, deepak.sikri, spear-devel,
	shiraz.hashim, viresh.kumar, bhutchings, Giuseppe Cavallaro

This patches  update the stmmac and add all the work made
by Deepak, Srinivas and myself.

I've collected all the patches already reviewed in the mailing list
verified that all the comments provided were applied and tested them.

These patches can be applied against the net.git and net-next.git.

On-Top of these patches (for net-next) I'll resend the EEE support
reviewed by Ben.

Many thanks for all your effort and patience.

---
peppe

Deepak SIKRI (5):
  stmmac: Define CSUM offload engine Types
  stmmac: sanitize the rx coe and add the type-1 csum
  stmmac: Define MDC clock selection macros
  stmmac: re-work the internal GMAC DMA platf parameters
  stmmac: Replace infinite loops by timeouts in mdio r/w

Giuseppe Cavallaro (4):
  stmmac: add clk management support
  stmmac: extend CSR Clock Range programming
  stmmac: MDC clock dynamically based on the csr clock input
  stmmac: update the driver version March 2012

Srinivas Kandagatla (1):
  stmmac: Allow stmmac to work with other PHY buses(v3).

 Documentation/networking/stmmac.txt                |   29 +++++-
 drivers/net/ethernet/stmicro/stmmac/common.h       |   17 +++-
 drivers/net/ethernet/stmicro/stmmac/dwmac1000.h    |    2 +-
 .../net/ethernet/stmicro/stmmac/dwmac1000_core.c   |   13 ---
 .../net/ethernet/stmicro/stmmac/dwmac1000_dma.c    |   42 +++++++-
 .../net/ethernet/stmicro/stmmac/dwmac100_core.c    |    6 -
 drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c |    6 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h    |    1 +
 drivers/net/ethernet/stmicro/stmmac/enh_desc.c     |   13 ++-
 drivers/net/ethernet/stmicro/stmmac/norm_desc.c    |   13 ++-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |   48 +++++++++-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  101 +++++++++++++++++---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  |   36 +++++--
 drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c   |    3 +-
 include/linux/stmmac.h                             |   55 +++++++++++-
 15 files changed, 317 insertions(+), 68 deletions(-)

-- 
1.7.4.4

^ permalink raw reply

* [PATCH 02/10] stmmac: Define CSUM offload engine Types
From: Giuseppe CAVALLARO @ 2012-03-23  9:08 UTC (permalink / raw)
  To: netdev
  Cc: davem, srinivas.kandagatla, deepak.sikri, spear-devel,
	shiraz.hashim, viresh.kumar, bhutchings
In-Reply-To: <1332493721-28309-1-git-send-email-peppe.cavallaro@st.com>

From: Deepak SIKRI <deepak.sikri@st.com>

This patch explicitly defines the CSUM offload engine type which need
(not mandatory) to be passed from the platform code.
STMMAC core supports two check sum offload engine types- Type-1 & Type-2.
Also, there are STMMAC cores that do not have the check sum offload
capabilities.

The behaviour of Type-1 & Type-2 cores related to provision of checksum
increases the packet length for Type-1 cores by 2, as the checksum is appended
at the end of data packet and the same is made accountable in the DMA status.
The STMMAC cores beyond Version-3.5 provide HW interface registers which allows
the user to read the HW capabilities, while to support the previous cores the
information related to HW capabilities has to be provided from the platform
code.

The Type-1 cores which do not have the HW register interface need this
information.

This patch also updates the driver's doc.

Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Hacked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 Documentation/networking/stmmac.txt |    3 +++
 include/linux/stmmac.h              |    5 +++++
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index d0aeead..61f40a3 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -116,6 +116,7 @@ and detailed below as well:
 	int has_gmac;
 	int enh_desc;
 	int tx_coe;
+	int rx_coe;
 	int bugged_jumbo;
 	int pmt;
 	int force_sf_dma_mode;
@@ -140,6 +141,8 @@ Where:
  o has_gmac: uses the GMAC core.
  o enh_desc: if sets the MAC will use the enhanced descriptor structure.
  o tx_coe: core is able to perform the tx csum in HW.
+ o rx_coe: the supports three check sum offloading engine types:
+	   type_1, type_2 (full csum) and no RX coe.
  o bugged_jumbo: some HWs are not able to perform the csum in HW for
 		over-sized frames due to limited buffer sizes.
 		Setting this flag the csum will be done in SW on
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 172b5e1..a9b4d6c 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -28,6 +28,10 @@
 
 #include <linux/platform_device.h>
 
+#define STMMAC_RX_COE_NONE	0
+#define STMMAC_RX_COE_TYPE1	1
+#define STMMAC_RX_COE_TYPE2	2
+
 /* Platfrom data for platform device structure's platform_data field */
 
 struct stmmac_mdio_bus_data {
@@ -49,6 +53,7 @@ struct plat_stmmacenet_data {
 	int has_gmac;
 	int enh_desc;
 	int tx_coe;
+	int rx_coe;
 	int bugged_jumbo;
 	int pmt;
 	int force_sf_dma_mode;
-- 
1.7.4.4

^ permalink raw reply related

* [PATCH 01/10] stmmac: Allow stmmac to work with other PHY buses(v3).
From: Giuseppe CAVALLARO @ 2012-03-23  9:08 UTC (permalink / raw)
  To: netdev
  Cc: davem, srinivas.kandagatla, deepak.sikri, spear-devel,
	shiraz.hashim, viresh.kumar, bhutchings, Giuseppe Cavallaro
In-Reply-To: <1332493721-28309-1-git-send-email-peppe.cavallaro@st.com>

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

As stmmac mdio bus name prefix is hardcoded in the driver, this allows
only phys on stmmac mdio buses to connect, however stmmac should allow
phys on other mdio buses too.

This patch adds new variable phy_bus_name to plat_stmmacenet_data
struct to let the BSP decide which phy bus to be used by stmmac driver.
A typical use-case is to have generic MDIO buses like mdio-gpio on top
of stmmac.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Acked-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |    8 +++++++-
 include/linux/stmmac.h                            |    1 +
 2 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index e85ffbd..860519c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -307,7 +307,13 @@ static int stmmac_init_phy(struct net_device *dev)
 	priv->speed = 0;
 	priv->oldduplex = -1;
 
-	snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", priv->plat->bus_id);
+	if (priv->plat->phy_bus_name)
+		snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
+				priv->plat->phy_bus_name, priv->plat->bus_id);
+	else
+		snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
+				priv->plat->bus_id);
+
 	snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
 		 priv->plat->phy_addr);
 	pr_debug("stmmac_init_phy:  trying to attach to %s\n", phy_id);
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 0dddc9e..172b5e1 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -39,6 +39,7 @@ struct stmmac_mdio_bus_data {
 };
 
 struct plat_stmmacenet_data {
+	char *phy_bus_name;
 	int bus_id;
 	int phy_addr;
 	int interface;
-- 
1.7.4.4

^ permalink raw reply related

* Re: Regression due to: net/usbnet: avoid recursive locking in usbnet_stop()
From: Oliver Neukum @ 2012-03-23  7:21 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Sebastian Andrzej Siewior, David S. Miller, netdev, linux-usb,
	linux-kernel@vger.kernel.org, Greg Kroah-Hartman, Willy Tarreau,
	Alan Stern
In-Reply-To: <4F6BAE34.7010805@wwwdotorg.org>

Am Donnerstag, 22. März 2012, 23:56:52 schrieb Stephen Warren:
> It looks like commit 4231d47e6fe69f061f96c98c30eaf9fb4c14b96d
> "net/usbnet: avoid recursive locking in usbnet_stop()" causes a problem
> for me.
> 
> When I reboot or shutdown, I see the error spew below at least 50% of
> the time. Reverting the above patch fixes this, at least for 10 reboot
> attempts.

The patch "usbnet: increase URB reference count before usb_unlink_urb" has just been
applied. Could you test whether it fixes your proble?

	Regards
		Oliver

^ permalink raw reply

* Re: [PATCH][RFC] bonding: delete migrated IP addresses from the rlb hash table
From: WeipingPan @ 2012-03-23  7:10 UTC (permalink / raw)
  To: Jiri Bohac; +Cc: Jay Vosburgh, Andy Gospodarek, netdev
In-Reply-To: <20120227173400.GB816@midget.suse.cz>

On 02/28/2012 01:34 AM, Jiri Bohac wrote:
> Bonding in balance-alb mode records information from ARP packets
> passing through the bond in a hash table (rx_hashtbl).
>
> At certain situations (e.g. link change of a slave),
> rlb_update_rx_clients() will send out ARP packets to update ARP
> caches of other hosts on the network to achieve RX load balancing.
>
> The problem is that once an IP address is recorded in the hash
> table, it stays there indefinitely [1]. If this IP address is
> migrated to a different host in the network, bonding still sends
> out ARP packets that poison other systems' ARP caches with
> invalid information.
>
> This patch solves this by looking at all incoming ARP packets,
> and checking if the source IP address is one of the source
> addresses stored in the rx_hashtbl. If it is, the corresponding
> hash table entries are removed. Thus, when an IP address is
> migrated, the first ARP broadcast by its new owner will purge the
> offending entries of rx_hashtbl.
>
>    (a simpler approach, where bonding would monitor IP address
>     changes on the local system does not work for setups like:
>     HostA --- NetworkA --- eth0-bond0-br0 --- NetworkB --- hostB
>     and an IP address migrating from HostB to HostA)
Hi, Jiri,
Do "NetworkA" and "NetworkB" mean different subnet ?
How to configure bonding and bridge to make HostA communicate with hostB ?
What is the problem for this setup ?

I will appreciate it if you can elaborate the problem.

thanks
Weiping Pan

^ permalink raw reply

* Re: [PATCH net V2 2/2] bonding:delete rlb entry at regular intervals
From: Jay Vosburgh @ 2012-03-23  6:08 UTC (permalink / raw)
  To: Weiping Pan; +Cc: netdev, andy, linux-kernel
In-Reply-To: <200ebddbbe5037adde0a440f06f0c08181f085b6.1332405098.git.panweiping3@gmail.com>

Weiping Pan <panweiping3@gmail.com> wrote:

>Jiri Bohac(jbohac@suse.cz) found that once an IP address is recorded in the
>rlb hash table, it stays there indefinitely. If this IP address is migrated
>to a different host in the network, bonding still sends out ARP packets
>that poison other systems' ARP caches with invalid information.
>
>Assume the rlb entry is like <source ip, dest ip, dest mac>.
>
>There are some kinds of migration.
>
>1 delete ip address from bond device
>If one ip address is deleted from bond device, the rlb table still contains
>the old mapping.
>
>2 swap ip address between bond0 and HostB
>before the change:
>                            ---- HostC(ipC)--
>HostA(ipA) ----- switch ---|-- eth0 - bond0  |
>HostB(ipB) -----/       \--|-- eth1 -/       |
>                            -----------------
>
>Like this topo, HostC and HostB can swap their ip addresses.
>after the change:
>                            ---- HostC(ipB)--
>HostA(ipA) ----- switch ---|-- eth0 - bond0  |
>HostB(ipC) -----/       \--|-- eth1 -/       |
>                            -----------------
>Then bonding will still send arp replies to HostA with the source ip  is ipC,
>and it will poison arp cache of HostA, so HostA can not ping HostB now.

	If I understand correctly, the first patch of this series
"bonding:delete rlb entry if bond's ip is deleted," would resolve this
case, because the table entries for source "ipC" will be purged.  Is
that correct?

	It might also be worthwhile having that patch purge entries
associated with a given IP address when it is added to the bond, not
just when it is removed, for the case that the new IP is moving in from
another host on the subnet.

>3 clients change their ip address, even swap them
>before the change:
>                           ----- HostC(ipC)--
>HostA(ipA) ----- switch ---|-- eth0 - bond0  |
>HostB(ipB) -----/       \--|-- eth1 -/       |
>                            -----------------
>
>after the change:
>                            ---- HostC(ipC)--
>HostA(ipB) ----- switch ---|-- eth0 - bond0  |
>HostB(ipA) -----/       \--|-- eth1 -/       |
>                            -----------------
>
>Then rlb table still contains old mapping, that is <ipC, ipA, macA> and
><ipC, ipB, macB>, and continues to send arp replies to them.

	This one may be difficult to handle every possible case; the rlb
code already watches for incoming ARP replies; perhaps rlb_arp_recv
should also watch for incoming broadcast ARP requests that match entries
in the table.  E.g., when ipA moves to hostB, it will at some point
likely issue an ARP "who-has" request as a broadcast that the rlb code
could see and check the table for an rlb_client_info->mac_dst or ip_dst
that matches and update or purge as appropriate.

	I haven't tried this; I'm just thinking out loud, but why would
this not work?  It probably has some coverage gaps for things like, oh,
static ARP entries, but for the common case I wonder if it would work.

>4 bond can be enslave to a bridge
>before the change:
>                                 br0
>                                  |
>                                bond0
>                               ___|___
>                              |       |
>HostA(ipA) --- NetworkA --- eth0     eth1 --- NetworkB --- hostB(ipB)
>
>after the change:
>                                 br0
>                                  |
>                                bond0
>                               ___|___
>                              |       |
>HostA(ipB) --- NetworkA --- eth0     eth1 --- NetworkB --- hostB(ipA)
>
>Then rlb table still contains old mapping, that is <ipA, ipB, macB>,
>and continues to send arp replies to HostB, it will poison arp cache of HostB.

	I'm not sure I understand this diagram correctly; are "NetworkA"
and "NetworkB" actual separate networks (i.e., eth0 and eth1 are not in
the same ethernet broadcast domain)?  For balance-alb mode to function
properly, every slave must be able to reach all possible destinations.

	I'm not sure how this is different than the case 3, above,
unless NetworkA and NetworkB actually are different networks, in which
case I don't believe it's a valid topology for balance-alb.  I'm also
not clear on what the significance of the bridge is, since the bond will
be only one port of the bridge.

	Can you elaborate on this case?

>There are some attempts to fix this problem, 
>http://marc.info/?l=linux-netdev&m=133036407906892&w=4
>http://marc.info/?l=linux-netdev&m=133057427414043&w=4
>
>But they did not fix the root cause of the problem, that rlb table does not
>have a aging mechanism, the entry is valid for ever unless it is replaced.
>
>In this patchset I want to add aging mechanism to rlb table.
>
>Assume RLB_MONITOR_DELAY is 2 seconds and RLB_WORK_COUNTER_TIMES is 3.
>Every 6 seconds bonding will make all entries invalid.
>Every 2 seconds, bonding will send arp requests to its all
>clients, then if it receives corresponding arp reply, bonding will deem that
>this entry is valid.
>And we give a entry 3 opportunities to survive in 6 seconds.

	This feels at first reading to be overkill; how common an
occurance is moving IP addresses around that it warrants sending an ARP
probe and response for each table entry every two seconds?  Presuming a
table filled with 100 active entries, that will be two hundred ARPs, 100
each request and reply, every two seconds.

	Now, that said, I think the rlb table entries do need a system
to expire inactive entries.  There is already an rlb_rebalance()
mechanism that takes place when a slave changes link state or is added
or removed.  Perhaps, as the tlb side already does, the rlb side should
periodically rebalance all of the clients.  Right now, that never occurs
in normal practice, so it's possible for the balance of traffic to
become uneven if traffic rates to particular clients vary.  The downside
to that is that rlb rebalancing involves active notification to each
peer, so it's not something to be done lightly, and, ideally, not the
entire table all at once.  Perhaps individual rlb_choose_channel
assignments should have a particular lifetime (one minute?), after which
a new channel must be chosen if the channel is still in use.

	-J

>TODO:
>The ntt (need to transmit) mechanism of rlb has duplicate functions with this
>patch, if this patch is accepted, ntt mechanism can be deleted.
>
>Signed-off-by: Weiping Pan <panweiping3@gmail.com>
>---
> drivers/net/bonding/bond_alb.c  |   95 ++++++++++++++++++++++++++++++++++----
> drivers/net/bonding/bond_alb.h  |    7 +++
> drivers/net/bonding/bond_main.c |   10 +++-
> 3 files changed, 100 insertions(+), 12 deletions(-)
>
>diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
>index bca1039..4be5bf1 100644
>--- a/drivers/net/bonding/bond_alb.c
>+++ b/drivers/net/bonding/bond_alb.c
>@@ -333,12 +333,15 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
>
> 	if ((client_info->assigned) &&
> 	    (client_info->ip_src == arp->ip_dst) &&
>-	    (client_info->ip_dst == arp->ip_src) &&
>-	    (compare_ether_addr_64bits(client_info->mac_dst, arp->mac_src))) {
>-		/* update the clients MAC address */
>-		memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN);
>-		client_info->ntt = 1;
>-		bond_info->rx_ntt = 1;
>+	    (client_info->ip_dst == arp->ip_src)) {
>+		if (compare_ether_addr_64bits(client_info->mac_dst,
>+						arp->mac_src)) {
>+			/* update the clients MAC address */
>+			memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN);
>+			client_info->ntt = 1;
>+			bond_info->rx_ntt = 1;
>+		} else
>+			client_info->used = 1;
> 	}
>
> 	_unlock_rx_hashtbl_bh(bond);
>@@ -485,14 +488,20 @@ static void rlb_update_client(struct rlb_client_info *client_info)
> {
> 	int i;
>
>+	if (client_info->used)
>+		return;
>+
> 	if (!client_info->slave) {
> 		return;
> 	}
>
>+	if (is_zero_ether_addr(client_info->mac_dst))
>+		return;
>+
> 	for (i = 0; i < RLB_ARP_BURST_SIZE; i++) {
> 		struct sk_buff *skb;
>
>-		skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
>+		skb = arp_create(ARPOP_REQUEST, ETH_P_ARP,
> 				 client_info->ip_dst,
> 				 client_info->slave->dev,
> 				 client_info->ip_src,
>@@ -521,7 +530,7 @@ static void rlb_update_client(struct rlb_client_info *client_info)
> }
>
> /* sends ARP REPLIES that update the clients that need updating */
>-static void rlb_update_rx_clients(struct bonding *bond)
>+static void rlb_update_rx_clients(struct bonding *bond, bool force)
> {
> 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
> 	struct rlb_client_info *client_info;
>@@ -532,7 +541,7 @@ static void rlb_update_rx_clients(struct bonding *bond)
> 	hash_index = bond_info->rx_hashtbl_head;
> 	for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
> 		client_info = &(bond_info->rx_hashtbl[hash_index]);
>-		if (client_info->ntt) {
>+		if (client_info->ntt || force) {
> 			rlb_update_client(client_info);
> 			if (bond_info->rlb_update_retry_counter == 0) {
> 				client_info->ntt = 0;
>@@ -776,6 +785,67 @@ static void rlb_init_table_entry(struct rlb_client_info *entry)
> 	entry->prev = RLB_NULL_INDEX;
> }
>
>+/*
>+ * bond_rlb_monitor
>+ *
>+ * Every RLB_MONITOR_DELAY seconds, send arp requests for all clients.
>+ * And if bond receives corresponding arp reply from client,
>+ * rlb_client_info->used will be set to 1.
>+ * If rlb_client_info->used is not set to 1 during
>+ * RLB_WORK_COUNTER_TIMES * RLB_MONITOR_DELAY seconds,
>+ * then delete the rlb entry.
>+ */
>+void bond_rlb_monitor(struct work_struct *work)
>+{
>+	struct alb_bond_info *bond_info = container_of(work, struct alb_bond_info,
>+					    rlb_work.work);
>+
>+	struct bonding *bond = container_of(bond_info, struct bonding,
>+					    alb_info);
>+	struct rlb_client_info *client_info;
>+	u32 curr_index;
>+
>+	_lock_rx_hashtbl_bh(bond);
>+	if (bond_info->rlb_work_counter++ < RLB_WORK_COUNTER_TIMES) {
>+		_lock_rx_hashtbl_bh(bond);
>+		rlb_update_rx_clients(bond, true);
>+		queue_delayed_work(bond->wq, &bond_info->rlb_work, RLB_MONITOR_DELAY);
>+		return;
>+	}
>+
>+	bond_info->rlb_work_counter = 0;
>+
>+	curr_index = bond_info->rx_hashtbl_head;
>+	for (; curr_index != RLB_NULL_INDEX;) {
>+		u32 next_index;
>+		u32 prev_index;
>+		client_info = &(bond_info->rx_hashtbl[curr_index]);
>+		next_index = client_info->next;
>+		prev_index = client_info->prev;
>+		if (client_info->used != 1) {
>+			/* delete this rlb entry */
>+			if (curr_index == bond_info->rx_hashtbl_head) {
>+				bond_info->rx_hashtbl_head = next_index;
>+			}
>+			if (prev_index != RLB_NULL_INDEX) {
>+				bond_info->rx_hashtbl[prev_index].next = next_index;
>+			}
>+			if (next_index != RLB_NULL_INDEX) {
>+				bond_info->rx_hashtbl[next_index].prev = prev_index;
>+			}
>+
>+			rlb_init_table_entry(client_info);
>+		} else
>+			client_info->used = 0;
>+
>+		curr_index = next_index;
>+	}
>+
>+	_unlock_rx_hashtbl_bh(bond);
>+
>+	queue_delayed_work(bond->wq, &bond_info->rlb_work, RLB_MONITOR_DELAY);
>+}
>+
> static int rlb_initialize(struct bonding *bond)
> {
> 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
>@@ -804,6 +874,9 @@ static int rlb_initialize(struct bonding *bond)
> 	/* register to receive ARPs */
> 	bond->recv_probe = rlb_arp_recv;
>
>+	INIT_DELAYED_WORK(&bond_info->rlb_work, bond_rlb_monitor);
>+	queue_delayed_work(bond->wq, &bond_info->rlb_work, 0);
>+
> 	return 0;
> }
>
>@@ -818,6 +891,8 @@ static void rlb_deinitialize(struct bonding *bond)
> 	bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
>
> 	_unlock_rx_hashtbl_bh(bond);
>+
>+	cancel_delayed_work_sync(&bond_info->rlb_work);
> }
>
> static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
>@@ -1497,7 +1572,7 @@ void bond_alb_monitor(struct work_struct *work)
> 			if (bond_info->rlb_update_delay_counter) {
> 				--bond_info->rlb_update_delay_counter;
> 			} else {
>-				rlb_update_rx_clients(bond);
>+				rlb_update_rx_clients(bond, false);
> 				if (bond_info->rlb_update_retry_counter) {
> 					--bond_info->rlb_update_retry_counter;
> 				} else {
>diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
>index 38863fc..5b7c433 100644
>--- a/drivers/net/bonding/bond_alb.h
>+++ b/drivers/net/bonding/bond_alb.h
>@@ -68,6 +68,9 @@ struct slave;
>  */
> #define RLB_PROMISC_TIMEOUT	(10*ALB_TIMER_TICKS_PER_SEC)
>
>+#define RLB_MONITOR_DELAY 2 * HZ
>+#define RLB_WORK_COUNTER_TIMES 3
>+
>
> struct tlb_client_info {
> 	struct slave *tx_slave;	/* A pointer to slave used for transmiting
>@@ -104,6 +107,8 @@ struct rlb_client_info {
> 	u32 next;		/* The next Hash table entry index */
> 	u32 prev;		/* The previous Hash table entry index */
> 	u8  assigned;		/* checking whether this entry is assigned */
>+	u8  used;		/* checking whether this entry is used during
>+				   RLB_MONITOR_DELAY seconds*/
> 	u8  ntt;		/* flag - need to transmit client info */
> 	struct slave *slave;	/* the slave assigned to this client */
> 	u8 tag;			/* flag - need to tag skb */
>@@ -135,6 +140,8 @@ struct alb_bond_info {
> 	u8			rx_ntt;	/* flag - need to transmit
> 					 * to all rx clients
> 					 */
>+	struct delayed_work 	rlb_work;
>+	int 			rlb_work_counter;
> 	struct slave		*next_rx_slave;/* next slave to be assigned
> 						* to a new rx client for
> 						*/
>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>index ec071b9..b2bd96f 100644
>--- a/drivers/net/bonding/bond_main.c
>+++ b/drivers/net/bonding/bond_main.c
>@@ -4351,16 +4351,22 @@ static void bond_setup(struct net_device *bond_dev)
>
> static void bond_work_cancel_all(struct bonding *bond)
> {
>+	struct alb_bond_info *bond_info = &BOND_ALB_INFO(bond);
>+
> 	if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
> 		cancel_delayed_work_sync(&bond->mii_work);
>
> 	if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
> 		cancel_delayed_work_sync(&bond->arp_work);
>
>-	if (bond->params.mode == BOND_MODE_ALB &&
>-	    delayed_work_pending(&bond->alb_work))
>+	if (bond->params.mode == BOND_MODE_ALB) {
>+	    if (delayed_work_pending(&bond->alb_work))
> 		cancel_delayed_work_sync(&bond->alb_work);
>
>+	    if (delayed_work_pending(&bond_info->rlb_work))
>+		cancel_delayed_work_sync(&bond_info->rlb_work);
>+	}
>+
> 	if (bond->params.mode == BOND_MODE_8023AD &&
> 	    delayed_work_pending(&bond->ad_work))
> 		cancel_delayed_work_sync(&bond->ad_work);
>-- 
>1.7.4
>

---
	-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com

^ permalink raw reply

* Re: [PATCH net V4 2/2] igb: offer a PTP Hardware Clock instead of the timecompare method
From: Richard Cochran @ 2012-03-23  6:05 UTC (permalink / raw)
  To: Keller, Jacob E
  Cc: chetan loke, netdev@vger.kernel.org,
	e1000-devel@lists.sourceforge.net, Kirsher, Jeffrey T,
	Ronciak, John, john.stultz@linaro.org, tglx@linutronix.de
In-Reply-To: <02874ECE860811409154E81DA85FBB580DB022@ORSMSX105.amr.corp.intel.com>

On Thu, Mar 22, 2012 at 09:59:01PM +0000, Keller, Jacob E wrote:
> 
> This means that readers don't block at all, and as long as the
> readers don't conflict with each other, there is no contention or
> writer starvation. It is possible for readers to 'live' lock, due to
> a large number of write operations. However, the lock is designed
> for few-writers, many readers. Which is what we have.

The readers do conflict with each other simply by reading the
registers E1000_SYSTIML and E1000_SYSTIMH. The locking is needed in
order to make these two reads "atomic."

Thanks,
Richard

^ permalink raw reply

* Re: [PATCH net V4 2/2] igb: offer a PTP Hardware Clock instead of the timecompare method
From: Richard Cochran @ 2012-03-23  5:59 UTC (permalink / raw)
  To: chetan loke
  Cc: Keller, Jacob E, netdev@vger.kernel.org,
	e1000-devel@lists.sourceforge.net, Kirsher, Jeffrey T,
	Ronciak, John, john.stultz@linaro.org, tglx@linutronix.de
In-Reply-To: <CAAsGZS6A3Cz9eb9v94MKTeonW0YitHh5h7owpkRofKzgzUKF_Q@mail.gmail.com>

On Thu, Mar 22, 2012 at 07:13:42PM -0400, chetan loke wrote:

> /* users can keep re-trying - dont really care */

[Sigh] No, they do in fact care...

> igb_gettime_locking (...) {
>      unsigned int seq;
>      u64 ns;
>      do {
>      seq = read_seqbegin( &pigb->tmreg_seq_lock);
>      ns = timecounter_read(&pigb->tc);

And what happens here?

timecounter_read()
 timecounter_read_delta()
  tc->cc->read() == igb_825xx_systim_read()

   lo = rd32(E1000_SYSTIML); /* this read latches the time value */
   hi = rd32(E1000_SYSTIMH); /* and here is your race */

If two readers enter this code at nearly the same time, then they can
corrupt each other's hi/lo values.

>      } while (read_seqretry(&pigb->tmreg_seq_lock, seq));
>      // process ns
> }
> 
> 
> copyright 2012 - Chetan Loke <lokechetan@gmail.com>
> 
> // trip cnt will ensure/enforce - evil adjtime user-space code can
> still not block us.
> // called from igb_tx[rx]_hwtstamp
> driver_rx_tx_path_locking( ... ) {
>      unsigned int seq, trip_cnt = 0;
>      u64 ns;
>      do {
>      seq = read_seqbegin( &pigb->tmreg_seq_lock);
>      trip_cnt++;
>      ns = timecounter_read(&pigb->tc);

Same here.

Thanks,
Richard

^ permalink raw reply

* FEC MAC with ethernet switch chip
From: Peter Rusko @ 2012-03-22 16:46 UTC (permalink / raw)
  To: netdev

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

Hi all,

I'm trying to get a Marvell ethernet switch (88E6065) working with the
FEC driver (on an i.mx28 cpu). The original driver doesn't support it
because of the multiple ports/phys. It probes the bus and assigns the hw
with the first address to fec0 and the second to fec1. This results the
loss of fec1 when I disconnect the cable from the first port (the phy
driver brings the connection down).

I have two solutions, but don't really know which one is better.

1. There is a DSA (Distributed Switch Architecture) interface used in
the kernel for these chips. These drivers don't need PHY's so I simply
disabled the PHY driver (and made it configurable through
platform_data). An attached patch shows this simple solution. It works
perfectly, but I still have to configure the chip. (btw, I had serious
problems adding the platform_dev because it needs a reference to a
struct ndev. Is there a good solution for this?)

2. A PHY driver would solve the problem, though it's not a PHY.

Which one should I use? Or is there a better one?

Regards,
-- 
Ruskó Péter
Fejlesztőmérnök

Prolan Zrt. / Prolan Co.
Hungary 2011 Budakalász, Szentendrei út 1-3.
Tel./Phone: +36 20 954 3118
Fax: +36 26 540 420
E-mail: rusko.peter@prolan.hu
Web: www.prolan.hu
Timezone:CET

[-- Attachment #2: fecphy.patch --]
[-- Type: text/x-patch, Size: 2399 bytes --]

diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index a13eb30..293432f 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -239,6 +239,7 @@ struct fec_enet_private {
 	int	mii_timeout;
 	uint	phy_speed;
 	phy_interface_t	phy_interface;
+	unsigned phy_type;
 	int	link;
 	int	full_duplex;
 	struct	completion mdio_done;
@@ -978,6 +979,17 @@ static int fec_enet_mii_probe(struct net_device *ndev)
 
 	fep->phy_dev = NULL;
 
+	if (fep->phy_type == FEC_PHY_SWITCH) {
+		fep->link = 1;
+		netif_carrier_on(ndev); // always up
+
+		fep->full_duplex = 1; // full duplex
+
+		fec_restart(ndev, fep->full_duplex);
+
+		return 0;
+	}
+
 	/* check for attached phy */
 	for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {
 		if ((fep->mii_bus->phy_mask & (1 << phy_id)))
@@ -1170,8 +1182,20 @@ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 	if (!netif_running(ndev))
 		return -EINVAL;
 
-	if (!phydev)
-		return -ENODEV;
+	if (!phydev) {
+		// On i.mx28, this is not necessarily needed
+		// TODO: remove?
+		struct mii_ioctl_data *mii_data = if_mii(rq);
+
+		if (cmd == SIOCGMIIREG)
+			mdiobus_write(fep->mii_bus, mii_data->phy_id,
+					mii_data->reg_num, mii_data->val_in);
+		else if (cmd == SIOCSMIIREG)
+			mii_data->val_out = mdiobus_read(fep->mii_bus,
+					mii_data->phy_id, mii_data->reg_num);
+		else return -ENODEV;
+		return 0;
+	}
 
 	return phy_mii_ioctl(phydev, rq, cmd);
 }
@@ -1274,7 +1298,8 @@ fec_enet_open(struct net_device *ndev)
 		fec_enet_free_buffers(ndev);
 		return ret;
 	}
-	phy_start(fep->phy_dev);
+	if (fep->phy_type == FEC_PHY_NORMAL)
+		phy_start(fep->phy_dev);
 	netif_start_queue(ndev);
 	fep->opened = 1;
 	return 0;
@@ -1598,6 +1623,9 @@ fec_probe(struct platform_device *pdev)
 		fep->phy_interface = ret;
 	}
 
+	if (pdata)
+		fep->phy_type = pdata->phy_type;
+
 	fec_reset_phy(pdev);
 
 	for (i = 0; i < FEC_IRQ_NUM; i++) {
diff --git a/include/linux/fec.h b/include/linux/fec.h
index bcff455..701fb2a 100644
--- a/include/linux/fec.h
+++ b/include/linux/fec.h
@@ -14,10 +14,15 @@
 #ifndef __LINUX_FEC_H__
 #define __LINUX_FEC_H__
 
+#define FEC_PHY_NORMAL 0
+#define FEC_PHY_SWITCH 1
+#define FEC_PHY_NONE 2
+
 #include <linux/phy.h>
 
 struct fec_platform_data {
 	phy_interface_t phy;
+	unsigned phy_type;
 	unsigned char mac[ETH_ALEN];
 };
 

^ permalink raw reply related

* [PATCH v2] sh: sh_eth: Add support SH7734
From: Nobuhiro Iwamatsu @ 2012-03-23  4:55 UTC (permalink / raw)
  To: netdev; +Cc: Nobuhiro Iwamatsu

Add define of SH7734 register and sh_eth_reset_hw_crc function.

V2: Do not split line of #if defined.

Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
---
 drivers/net/ethernet/renesas/Kconfig  |    9 +++++----
 drivers/net/ethernet/renesas/sh_eth.c |   22 +++++++++++++++++++---
 drivers/net/ethernet/renesas/sh_eth.h |   10 ++++++++--
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig
index 9755b49..077528b 100644
--- a/drivers/net/ethernet/renesas/Kconfig
+++ b/drivers/net/ethernet/renesas/Kconfig
@@ -5,9 +5,10 @@
 config SH_ETH
 	tristate "Renesas SuperH Ethernet support"
 	depends on SUPERH && \
-		(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
-		 CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
-		 CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7757)
+		(CPU_SUBTYPE_SH7619 || \
+		 CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
+		 CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \
+		 CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7757)
 	select CRC32
 	select NET_CORE
 	select MII
@@ -16,4 +17,4 @@ config SH_ETH
 	---help---
 	  Renesas SuperH Ethernet device driver.
 	  This driver supporting CPUs are:
-		- SH7710, SH7712, SH7763, SH7619, SH7724, and SH7757.
+		- SH7619, SH7710, SH7712, SH7724, SH7734, SH7763 and SH7757.
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 87b6501..63fc224 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1,8 +1,8 @@
 /*
  *  SuperH Ethernet device driver
  *
- *  Copyright (C) 2006-2008 Nobuhiro Iwamatsu
- *  Copyright (C) 2008-2009 Renesas Solutions Corp.
+ *  Copyright (C) 2006-2011 Nobuhiro Iwamatsu
+ *  Copyright (C) 2008-2011 Renesas Solutions Corp.
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms and conditions of the GNU General Public License,
@@ -40,6 +40,7 @@
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
 #include <linux/sh_eth.h>
+#include <linux/clk.h>
 
 #include "sh_eth.h"
 
@@ -97,6 +98,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
 	.tpauser	= 1,
 	.hw_swap	= 1,
 	.rpadir		= 1,
+	.hw_crc		= 0,
 	.rpadir_value	= 0x00020000, /* NET_IP_ALIGN assumed to be 2 */
 };
 #elif defined(CONFIG_CPU_SUBTYPE_SH7757)
@@ -147,6 +149,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
 	.hw_swap	= 1,
 	.no_ade		= 1,
 	.rpadir		= 1,
+	.hw_crc		= 0,
 	.rpadir_value   = 2 << 16,
 };
 
@@ -269,6 +272,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
 	.rpadir_value   = 2 << 16,
 	.no_trimd	= 1,
 	.no_ade		= 1,
+	.hw_crc		= 0,
 };
 
 static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
@@ -279,8 +283,9 @@ static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
 		return &sh_eth_my_cpu_data;
 }
 
-#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
 #define SH_ETH_HAS_TSU	1
+static void sh_eth_reset_hw_crc(struct net_device *ndev);
 static void sh_eth_chip_reset(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -314,6 +319,9 @@ static void sh_eth_reset(struct net_device *ndev)
 	sh_eth_write(ndev, 0x0, RDFAR);
 	sh_eth_write(ndev, 0x0, RDFXR);
 	sh_eth_write(ndev, 0x0, RDFFR);
+
+	/* Reset HW CRC register */
+	sh_eth_reset_hw_crc(ndev);
 }
 
 static void sh_eth_set_duplex(struct net_device *ndev)
@@ -370,8 +378,15 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
 	.no_trimd	= 1,
 	.no_ade		= 1,
 	.tsu		= 1,
+	.hw_crc		= 1,
 };
 
+static void sh_eth_reset_hw_crc(struct net_device *ndev)
+{
+	if (sh_eth_my_cpu_data.hw_crc)
+		sh_eth_write(ndev, 0x0, CSMR);
+}
+
 #elif defined(CONFIG_CPU_SUBTYPE_SH7619)
 #define SH_ETH_RESET_DEFAULT	1
 static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
@@ -381,6 +396,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
 	.mpr		= 1,
 	.tpauser	= 1,
 	.hw_swap	= 1,
+	.hw_crc		= 0,
 };
 #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
 #define SH_ETH_RESET_DEFAULT	1
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index cdbd844..da384d2 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -1,7 +1,7 @@
 /*
  *  SuperH Ethernet device driver
  *
- *  Copyright (C) 2006-2008 Nobuhiro Iwamatsu
+ *  Copyright (C) 2006-2008, 2011 Nobuhiro Iwamatsu
  *  Copyright (C) 2008-2011 Renesas Solutions Corp.
  *
  *  This program is free software; you can redistribute it and/or modify it
@@ -59,6 +59,8 @@ enum {
 	TRIMD,
 	RBWAR,
 	TBRAR,
+	CSMR,
+	RMII_MII,
 
 	/* Ether registers */
 	ECMR,
@@ -170,6 +172,8 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
 	[RMCR]	= 0x0458,
 	[RPADIR]	= 0x0460,
 	[FCFTR]	= 0x0468,
+	[CSMR] = 0x04E4,
+	[RMII_MII] =  0x0790,
 
 	[ECMR]	= 0x0500,
 	[ECSR]	= 0x0510,
@@ -375,7 +379,8 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
 /*
  * Register's bits
  */
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
+#if defined(CONFIG_CPU_SUBTYPE_SH7734) ||\
+	defined(CONFIG_CPU_SUBTYPE_SH7763)
 /* EDSR */
 enum EDSR_BIT {
 	EDSR_ENT = 0x01, EDSR_ENR = 0x02,
@@ -745,6 +750,7 @@ struct sh_eth_cpu_data {
 	unsigned rpadir:1;		/* E-DMAC have RPADIR */
 	unsigned no_trimd:1;		/* E-DMAC DO NOT have TRIMD */
 	unsigned no_ade:1;	/* E-DMAC DO NOT have ADE bit in EESR */
+	unsigned hw_crc:1;		/* E-DMAC have CSMR */
 };
 
 struct sh_eth_private {
-- 
1.7.9.1

^ permalink raw reply related

* Re: [PATCH] sh: sh_eth: Add support SH7734
From: Nobuhiro Iwamatsu @ 2012-03-23  4:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20120321.165818.1166540551487888245.davem@davemloft.net>

David Miller さんは書きました:
> From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
> Date: Wed, 21 Mar 2012 16:13:34 +0900
> 
>> Add define of SH7734 register and sh_eth_reset_hw_crc function.
>>
>> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
> 
> This patch doesn't apply cleanly at all, also:
> 
>> -#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
>> +#elif defined(CONFIG_CPU_SUBTYPE_SH7734) ||\
>> +		defined(CONFIG_CPU_SUBTYPE_SH7763)
> 
> This looks terrible, please don't split this line up like that.
> 
> If you have to, at least put a space before the backslash at the end
> of the first line and make the "defined" on the second line match up,
> column wise, with the "defined" on the previous line.
> 

OK, I will fix this.
Thank you.

Nobuhiro

^ permalink raw reply

* Re: [PATCH] gianfar: Fix possible overrun and simplify interrupt name field creation
From: David Miller @ 2012-03-23  3:34 UTC (permalink / raw)
  To: joe; +Cc: netdev, linux-kernel, sandeep.kumar
In-Reply-To: <20120321.223457.641438956547942596.davem@davemloft.net>

From: David Miller <davem@davemloft.net>
Date: Wed, 21 Mar 2012 22:34:57 -0400 (EDT)

> From: Joe Perches <joe@perches.com>
> Date: Sat, 17 Mar 2012 12:05:38 -0700
> 
>> Space allocated for int_name_<foo> is unsufficient for
>> maximal device name, expand it.
>> 
>> Code to create int_name_<foo> is obscure, simplify it
>> by using sprintf.
>> 
>> Found by looking for unnecessary \ line continuations.
>> Uncompiled, untested.
>> 
>> Signed-off-by: Joe Perches <joe@perches.com>
> 
> Can a gianfar expert please review and test this patch?

If you gianfar guys don't show a sign of life in the next 24 hours I'm
just going to apply Joe's patch as-is.  I refuse to just let it rot in
patchwork like this.

And then you don't get to complain if his change breaks your driver
because I asked multiple times for testing and/or review.

^ permalink raw reply

* [GIT] Networking
From: David Miller @ 2012-03-23  3:32 UTC (permalink / raw)
  To: torvalds; +Cc: akpm, netdev, linux-kernel


1) L2TP doesn't get autoloaded when you try to open an L2TP socket
   due to a missing module alias, fix from Benjamin LaHaise.

2) Netlabel and RDS should propagate gfp flags given to them by
   callers, fixes from Dan Carpeneter.

3) Recursive locking fix in usbnet wasn't bulletproof and can result
   in objects going away mid-flight due to races, fix from
   Ming Lei.

4) Fix up some confusion about a bool module parameter in netfilter's
   iptable_filter and ip6table_filter, from Rusty Russell.

5) If SKB recycling is used via napi_reuse_skb() we end up with
   different amounts of headroom reserved than we had at the original
   SKB allocation.  Fix from Eric Dumazet.

6) Fix races in TG3 driver ring refilling, from Michael Chan.

7) We have callbacks for IPSEC replay notifiers, but some call sites
   were not using the ops method and instead were calling one of the
   implementations directly.  Oops.  Fix from Steffen Klassert.

8) Fix IP address validation properly in the bonding driver, the previous
   fix only works with netlink where the subnet mask and IP address are
   changed in one atomic operation.  When 'ifconfig' ioctls are used
   the IP address and the subnet mask are changed in two distinct
   operations.  Fix from Andy Gospodarek.

9) Provide a sky2 module operation to work around power management
   issues with some BIOSes.  From Stephen Hemminger.

Please pull, thanks a lot.

The following changes since commit 4f5b1affdda3e0c48cac674182f52004137b0ffc:

  Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lliubbo/blackfin (2012-03-22 18:20:02 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git master

Andy Gospodarek (1):
      bonding: remove entries for master_ip and vlan_ip and query devices instead

Benjamin LaHaise (1):
      l2tp: enable automatic module loading for l2tp_ppp

Dan Carpenter (2):
      netlabel: use GFP flags from caller instead of GFP_ATOMIC
      RDS: use gfp flags from caller in conn_alloc()

Eric Dumazet (1):
      net: fix napi_reuse_skb() skb reserve

Michael Chan (2):
      tg3: Fix RSS ring refill race condition
      cnic: Fix parity error code conflict

Oliver Neukum (1):
      usbnet: consider device busy at each recieved packet

Rusty Russell (1):
      netfilter: remove forward module param confusion.

Steffen Klassert (2):
      xfrm: Remove unused xfrm_state from xfrm_state_check_space
      xfrm: Access the replay notify functions via the registered callbacks

stephen hemminger (1):
      sky2: override for PCI legacy power management

tom.leiming@gmail.com (2):
      usbnet: increase URB reference count before usb_unlink_urb
      usbnet: don't clear urb->dev in tx_complete

 drivers/net/bonding/bond_main.c           |   82 +++++-----------------------
 drivers/net/bonding/bonding.h             |   18 ++++++-
 drivers/net/ethernet/broadcom/cnic.c      |   12 +++--
 drivers/net/ethernet/broadcom/cnic_defs.h |   28 +---------
 drivers/net/ethernet/broadcom/cnic_if.h   |    4 +-
 drivers/net/ethernet/broadcom/tg3.c       |   25 ++++++++-
 drivers/net/ethernet/broadcom/tg3.h       |    1 +
 drivers/net/ethernet/marvell/sky2.c       |   11 ++++
 drivers/net/usb/usbnet.c                  |   11 ++++-
 drivers/scsi/bnx2fc/bnx2fc_constants.h    |    1 +
 drivers/scsi/bnx2i/57xx_iscsi_constants.h |    1 +
 net/core/dev.c                            |    3 +-
 net/ipv4/devinet.c                        |    1 +
 net/ipv4/netfilter/iptable_filter.c       |    9 +---
 net/ipv6/netfilter/ip6table_filter.c      |    9 +---
 net/l2tp/l2tp_ppp.c                       |    1 +
 net/netlabel/netlabel_kapi.c              |    2 +-
 net/rds/ib_cm.c                           |    2 +-
 net/rds/iw_cm.c                           |    2 +-
 net/rds/loop.c                            |    2 +-
 net/xfrm/xfrm_output.c                    |    4 +-
 net/xfrm/xfrm_replay.c                    |    6 +-
 22 files changed, 104 insertions(+), 131 deletions(-)

^ permalink raw reply

* Re: Regression due to: net/usbnet: avoid recursive locking in usbnet_stop()
From: Ming Lei @ 2012-03-23  3:28 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Sebastian Andrzej Siewior, Oliver Neukum, David S. Miller, netdev,
	linux-usb, linux-kernel@vger.kernel.org, Greg Kroah-Hartman,
	Willy Tarreau, Alan Stern
In-Reply-To: <4F6BAE34.7010805@wwwdotorg.org>

On Fri, Mar 23, 2012 at 6:56 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> It looks like commit 4231d47e6fe69f061f96c98c30eaf9fb4c14b96d
> "net/usbnet: avoid recursive locking in usbnet_stop()" causes a problem
> for me.
>
> When I reboot or shutdown, I see the error spew below at least 50% of
> the time. Reverting the above patch fixes this, at least for 10 reboot
> attempts.

The two patches[1][2] should fix your problem, please try them.
Both have been applied into David's tree.


[1], http://marc.info/?l=linux-usb&m=133242262312402&w=2
[2], http://marc.info/?l=linux-usb&m=133242264412410&w=2

Thanks,
-- 
Ming Lei

^ permalink raw reply

* Re: [PATCH] usbnet: consider device busy at each recieved packet
From: David Miller @ 2012-03-23  3:05 UTC (permalink / raw)
  To: oliver-GvhC2dPhHPQdnm+yROfE0A
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, tony.hill-3WKxDLwmzFNWk0Htik3J/w,
	linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <201203222135.07331.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org>

From: Oliver Neukum <oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org>
Date: Thu, 22 Mar 2012 21:35:07 +0100

> usbnet should centrally handle busy reporting in the rx path
> so subdrivers need not worry. This hurts use cases which do
> rx only or predominantly.
> 
> Signed-off-by: Oliver Neukum <oneukum-l3A5Bk7waGM@public.gmane.org>

Applied, thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" 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

* Re: [STRAW MAN PATCH] sch_teql doesn't load-balance ppp(oatm) slaves
From: David Miller @ 2012-03-23  3:03 UTC (permalink / raw)
  To: dwmw2; +Cc: netdev
In-Reply-To: <1332450218.32446.79.camel@shinybook.infradead.org>

From: David Woodhouse <dwmw2@infradead.org>
Date: Thu, 22 Mar 2012 21:03:38 +0000

> teql_dequeue() will *always* give up a skb when it's called, if there is
> one. If there's *not*, and the tx queue becomes empty, then the device
> for which teql_dequeue() was called is 'promoted' to the front of the
> line (master->slaves). That device will receive the next packet that
> comes in, even if there are other devices which are *also* idle and
> waiting for packets. Whenever a new packet comes in, the *last* device
> to call teql_dequeue() gets it.

The teql master ->ndo_start_xmit() method is where the slave iteration
occurs, and it occurs on every successful transmit of a single packet.

But this cannot, and is documented not to, work when device stacking
is involved.

If you're dealing with (what amounts to) virtual devices, you cannot
use TEQL and must use something like drivers/net/eql.c

^ permalink raw reply

* Re: [PATCH] net: NETDEV_ALIGN should match L1_CACHE_BYTES
From: David Miller @ 2012-03-23  2:57 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <1332454760.6521.9.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 22 Mar 2012 15:19:20 -0700

> 32 bytes alignment had a meaning 10 years ago, it is not anymore the
> case.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

This value is supposed to conceptually be ARCH_DMA_MINALIGN.

Drivers, like the AMD Lance, would DMA in and out of the netdev
private struct.  And as such DMA alignments have to be adhered
to.

There is way too much ISA and ancient crap out there to mess with
this, I think.  Maybe we could set it to ARCH_DMA_MINALIGN (you'd need
to use a CPP test since architectures are not required to set this,
and use L1_CACHE_BYTES if it's not).  But certainly we can't
unilaterally change it to L1_CACHE_BYTES.

^ permalink raw reply

* Re: [PATCH net-next][v3] bonding: remove entries for master_ip and vlan_ip and query devices instead
From: David Miller @ 2012-03-23  2:36 UTC (permalink / raw)
  To: andy; +Cc: netdev, ralf.zeidler
In-Reply-To: <1332468869-17553-1-git-send-email-andy@greyhouse.net>

From: Andy Gospodarek <andy@greyhouse.net>
Date: Thu, 22 Mar 2012 22:14:29 -0400

> The following patch aimed to resolve an issue where secondary, tertiary,
> etc. addresses added to bond interfaces could overwrite the
> bond->master_ip and vlan_ip values.
 ...
> Signed-off-by: Andy Gospodarek <andy@greyhouse.net>

Applied.

^ permalink raw reply

* Re: [PATCH] netfilter: remove forward module param confusion.
From: David Miller @ 2012-03-23  2:36 UTC (permalink / raw)
  To: rusty; +Cc: dan.carpenter, netdev, netfilter-devel
In-Reply-To: <8739909sqt.fsf@rustcorp.com.au>

From: Rusty Russell <rusty@rustcorp.com.au>
Date: Fri, 23 Mar 2012 08:57:06 +1030

> It used to be an int, and it got changed to a bool parameter at least
> 7 years ago.  It happens that NF_ACCEPT and NF_DROP are 0 and 1, so
> this works, but it's unclear, and the check that it's in range is not
> required.
> 
> Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

Applied.

^ permalink raw reply

* Re: [PATCH 1/2] ptp/ptp_pch: Modified according to the mainter's comments
From: David Miller @ 2012-03-23  2:35 UTC (permalink / raw)
  To: tshimizu818
  Cc: jeffrey.t.kirsher, lucas.demarchi, mirq-linux, paul.gortmaker,
	jdmason, john.stultz, richardcochran, arnd, khc, netdev,
	linux-kernel, qi.wang, yong.y.wang, joel.clark, kok.howg.ewe
In-Reply-To: <1332468760-2525-1-git-send-email-tshimizu818@gmail.com>


You've sent three sets of patches.

And you've numbered them individually within each set.

And this is totally confusing.

Does one set need to be applied before another set?  And if so,
in what order.

I'm tossing all of your patches, submit your changes properly,
orderred together as one single set of numberred patches.

^ permalink raw reply

* [PATCH] net/pch_gbe: Corrected the bug of PTP Rx filter
From: Takahiro Shimizu @ 2012-03-23  2:20 UTC (permalink / raw)
  To: jeffrey.t.kirsher, davem, lucas.demarchi, mirq-linux,
	paul.gortmaker, jdmason, john.stultz, richardcochran, arnd, khc,
	netdev, linux-kernel
  Cc: qi.wang, yong.y.wang, joel.clark, kok.howg.ewe, Takahiro Shimizu


Signed-off-by: Takahiro Shimizu <tshimizu818@gmail.com>
---
 .../net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c   |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 776bcf2..463e61c 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -135,7 +135,10 @@ static int pch_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid)
 	u32 lo;
 
 	sk_filter = sk_run_filter(skb, ptp_filter);
-	if ((sk_filter != PTP_CLASS_V2) && (sk_filter != PTP_CLASS_V1))
+	if ((sk_filter != PTP_CLASS_V2_IPV4) &&
+	     (sk_filter != PTP_CLASS_V1_IPV4) &&
+	     (sk_filter != PTP_CLASS_V2_IPV6) &&
+	     (sk_filter != PTP_CLASS_V1_IPV6))
 		return 0;
 
 	offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
-- 
1.7.4.4

^ permalink raw reply related

* [PATCH 2/2] net/pch_gbe: Changed PTP supporting mode
From: Takahiro Shimizu @ 2012-03-23  2:18 UTC (permalink / raw)
  To: jeffrey.t.kirsher, davem, lucas.demarchi, mirq-linux,
	paul.gortmaker, jdmason, john.stultz, richardcochran, arnd, khc,
	netdev, linux-kernel
  Cc: qi.wang, yong.y.wang, joel.clark, kok.howg.ewe, Takahiro Shimizu
In-Reply-To: <1332469139-2654-1-git-send-email-tshimizu818@gmail.com>


Signed-off-by: Takahiro Shimizu <tshimizu818@gmail.com>
---
 drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h    |    1 +
 .../net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c   |   14 +++++++++++++-
 2 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
index dd14915..9f3dbc4 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
@@ -660,6 +660,7 @@ extern u32 pch_src_uuid_lo_read(struct pci_dev *pdev);
 extern u32 pch_src_uuid_hi_read(struct pci_dev *pdev);
 extern u64 pch_rx_snap_read(struct pci_dev *pdev);
 extern u64 pch_tx_snap_read(struct pci_dev *pdev);
+extern int pch_set_station_address(u8 *addr, struct pci_dev *pdev);
 #endif
 
 /* pch_gbe_param.c */
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 56089ca..776bcf2 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -111,6 +111,9 @@ const char pch_driver_version[] = DRV_VERSION;
 /* 0x44 Time Synchronization Channel Event Register Bits */
 #define TX_SNAPSHOT_LOCKED (1<<0)
 #define RX_SNAPSHOT_LOCKED (1<<1)
+
+#define PTP_L4_MULTICAST_SA "01:00:5e:00:01:81"
+#define PTP_L2_MULTICAST_SA "01:1b:19:00:00:00"
 #endif
 
 static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT;
@@ -235,6 +238,7 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 	struct hwtstamp_config cfg;
 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 	struct pci_dev *pdev;
+	u8 station[20];
 
 	if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
 		return -EFAULT;
@@ -268,9 +272,17 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 		adapter->hwts_rx_en = 1;
 		pch_ch_control_write(pdev, MASTER_MODE | CAP_MODE0);
 		break;
-	case HWTSTAMP_FILTER_PTP_V2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+		adapter->hwts_rx_en = 1;
+		pch_ch_control_write(pdev, V2_MODE | CAP_MODE2);
+		strcpy(station, PTP_L4_MULTICAST_SA);
+		pch_set_station_address(station, pdev);
+		break;
+	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
 		adapter->hwts_rx_en = 1;
 		pch_ch_control_write(pdev, V2_MODE | CAP_MODE2);
+		strcpy(station, PTP_L2_MULTICAST_SA);
+		pch_set_station_address(station, pdev);
 		break;
 	default:
 		return -ERANGE;
-- 
1.7.4.4

^ permalink raw reply related


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