* [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 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 06/10] stmmac: Replace infinite loops by timeouts in mdio r/w
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 removes the infinite waits from the mdio read and
write interfaces. These infinite waits have been replaced by
the timeout handling. In case if a time out occurs, an error is
returned.
Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 32 ++++++++++++++++----
1 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 7319532..83292f4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -34,6 +34,22 @@
#define MII_BUSY 0x00000001
#define MII_WRITE 0x00000002
+static int stmmac_mdio_busy_wait(void __iomem *ioaddr, unsigned int mii_addr)
+{
+ unsigned long curr;
+ unsigned long finish = jiffies + 3 * HZ;
+
+ do {
+ curr = jiffies;
+ if (readl(ioaddr + mii_addr) & MII_BUSY)
+ cpu_relax();
+ else
+ return 0;
+ } while (!time_after_eq(curr, finish));
+
+ return -EBUSY;
+}
+
/**
* stmmac_mdio_read
* @bus: points to the mii_bus structure
@@ -56,9 +72,13 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
((phyreg << 6) & (0x000007C0)));
regValue |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
- do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
+ if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
+ return -EBUSY;
+
writel(regValue, priv->ioaddr + mii_address);
- do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
+
+ if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
+ return -EBUSY;
/* Read the data from the MII data register */
data = (int)readl(priv->ioaddr + mii_data);
@@ -88,18 +108,16 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
value |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
-
/* Wait until any existing MII operation is complete */
- do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
+ if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
+ return -EBUSY;
/* Set the MII address register to write */
writel(phydata, priv->ioaddr + mii_data);
writel(value, priv->ioaddr + mii_address);
/* Wait until any existing MII operation is complete */
- do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
-
- return 0;
+ return stmmac_mdio_busy_wait(priv->ioaddr, mii_address);
}
/**
--
1.7.4.4
^ permalink raw reply related
* [PATCH 07/10] stmmac: add clk management support
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>
this patch adds the way to enable/disable the MAC
clock when call the open/close and resume/restore
functions.
This has been tested on ST platforms and SPEAr; thanks
to Francesco and Deepak.
Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Tested-by: Francesco Virlinzi <francesco.virlinzi@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 43 +++++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 25 ++++++++++--
2 files changed, 63 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index b65d787..7182f15 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -22,6 +22,8 @@
#define STMMAC_RESOURCE_NAME "stmmaceth"
#define DRV_MODULE_VERSION "Feb_2012"
+
+#include <linux/clk.h>
#include <linux/stmmac.h>
#include <linux/phy.h>
#include "common.h"
@@ -79,6 +81,9 @@ struct stmmac_priv {
struct stmmac_counters mmc;
struct dma_features dma_cap;
int hw_cap_support;
+#ifdef CONFIG_HAVE_CLK
+ struct clk *stmmac_clk;
+#endif
};
extern int phyaddr;
@@ -97,3 +102,41 @@ int stmmac_dvr_remove(struct net_device *ndev);
struct stmmac_priv *stmmac_dvr_probe(struct device *device,
struct plat_stmmacenet_data *plat_dat,
void __iomem *addr);
+
+#ifdef CONFIG_HAVE_CLK
+static inline int stmmac_clk_enable(struct stmmac_priv *priv)
+{
+ if (priv->stmmac_clk)
+ return clk_enable(priv->stmmac_clk);
+
+ return 0;
+}
+
+static inline void stmmac_clk_disable(struct stmmac_priv *priv)
+{
+ if (priv->stmmac_clk)
+ clk_disable(priv->stmmac_clk);
+}
+static inline int stmmac_clk_get(struct stmmac_priv *priv)
+{
+ priv->stmmac_clk = clk_get(priv->device, NULL);
+
+ if (IS_ERR(priv->stmmac_clk)) {
+ pr_err("%s: ERROR clk_get failed\n", __func__);
+ return PTR_ERR(priv->stmmac_clk);
+ }
+ return 0;
+}
+#else
+static inline int stmmac_clk_enable(struct stmmac_priv *priv)
+{
+ return 0;
+}
+static inline void stmmac_clk_disable(struct stmmac_priv *priv)
+{
+}
+static inline int stmmac_clk_get(struct stmmac_priv *priv)
+{
+ return 0;
+}
+#endif /* CONFIG_HAVE_CLK */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 7ac13d5..08b4d05 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -904,6 +904,8 @@ static int stmmac_open(struct net_device *dev)
struct stmmac_priv *priv = netdev_priv(dev);
int ret;
+ stmmac_clk_enable(priv);
+
stmmac_check_ether_addr(priv);
/* MDIO bus Registration */
@@ -911,13 +913,15 @@ static int stmmac_open(struct net_device *dev)
if (ret < 0) {
pr_debug("%s: MDIO bus (id: %d) registration failed",
__func__, priv->plat->bus_id);
- return ret;
+ goto open_clk_dis;
}
#ifdef CONFIG_STMMAC_TIMER
priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
- if (unlikely(priv->tm == NULL))
- return -ENOMEM;
+ if (unlikely(priv->tm == NULL)) {
+ ret = -ENOMEM;
+ goto open_clk_dis;
+ }
priv->tm->freq = tmrate;
@@ -1034,6 +1038,8 @@ open_error:
if (priv->phydev)
phy_disconnect(priv->phydev);
+open_clk_dis:
+ stmmac_clk_disable(priv);
return ret;
}
@@ -1086,6 +1092,7 @@ static int stmmac_release(struct net_device *dev)
stmmac_exit_fs();
#endif
stmmac_mdio_unregister(dev);
+ stmmac_clk_disable(priv);
return 0;
}
@@ -1872,6 +1879,9 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
goto error;
}
+ if (stmmac_clk_get(priv))
+ goto error;
+
return priv;
error:
@@ -1941,9 +1951,11 @@ int stmmac_suspend(struct net_device *ndev)
/* Enable Power down mode by programming the PMT regs */
if (device_may_wakeup(priv->device))
priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
- else
+ else {
stmmac_set_mac(priv->ioaddr, false);
-
+ /* Disable clock in case of PWM is off */
+ stmmac_clk_disable(priv);
+ }
spin_unlock(&priv->lock);
return 0;
}
@@ -1964,6 +1976,9 @@ int stmmac_resume(struct net_device *ndev)
* from another devices (e.g. serial console). */
if (device_may_wakeup(priv->device))
priv->hw->mac->pmt(priv->ioaddr, 0);
+ else
+ /* enable the clk prevously disabled */
+ stmmac_clk_enable(priv);
netif_device_attach(ndev);
--
1.7.4.4
^ permalink raw reply related
* [PATCH 08/10] stmmac: extend CSR Clock Range programming
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>
The CSR Clock Range has been reworked and new macros has
been added in the platform header to allow the CSR Clock
Range selection in the GMII Address Register.
The previous work didn't add the other fields
that can be used to achieve MDC clock of frequency
higher than the IEEE 802.3 specified frequency limit
of 2.5 MHz and program a clock divider of lower value.
On such platforms, these are used indeed so this patch
adds them.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 4 +-
include/linux/stmmac.h | 31 +++++++++++----------
2 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 83292f4..1a42014 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -70,7 +70,7 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
int data;
u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
((phyreg << 6) & (0x000007C0)));
- regValue |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
+ regValue |= MII_BUSY | ((priv->plat->clk_csr & 0xF) << 2);
if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
return -EBUSY;
@@ -106,7 +106,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
(((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
| MII_WRITE;
- value |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
+ value |= MII_BUSY | ((priv->plat->clk_csr & 0xF) << 2);
/* Wait until any existing MII operation is complete */
if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 4aef9ba..cf64031 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -37,28 +37,29 @@
* 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
+#define STMMAC_CSR_60_100M 0x0 /* MDC = clk_scr_i/42 */
+#define STMMAC_CSR_100_150M 0x1 /* MDC = clk_scr_i/62 */
+#define STMMAC_CSR_20_35M 0x2 /* MDC = clk_scr_i/16 */
+#define STMMAC_CSR_35_60M 0x3 /* MDC = clk_scr_i/26 */
+#define STMMAC_CSR_150_250M 0x4 /* MDC = clk_scr_i/102 */
+#define STMMAC_CSR_250_300M 0x5 /* MDC = clk_scr_i/122 */
+
+/* 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 */
+ */
+#define STMMAC_CSR_I_4 0x8 /* clk_csr_i/4 */
+#define STMMAC_CSR_I_6 0x9 /* clk_csr_i/6 */
+#define STMMAC_CSR_I_8 0xA /* clk_csr_i/8 */
+#define STMMAC_CSR_I_10 0xB /* clk_csr_i/10 */
+#define STMMAC_CSR_I_12 0xC /* clk_csr_i/12 */
+#define STMMAC_CSR_I_14 0xD /* clk_csr_i/14 */
+#define STMMAC_CSR_I_16 0xE /* clk_csr_i/16 */
+#define STMMAC_CSR_I_18 0xF /* clk_csr_i/18 */
/* AXI DMA Burst length suported */
#define DMA_AXI_BLEN_4 (1 << 1)
--
1.7.4.4
^ permalink raw reply related
* [PATCH 09/10] stmmac: MDC clock dynamically based on the csr clock input
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>
If a specific clk_csr value is passed from the platform
this means that the CSR Clock Range selection cannot be
changed at run-time and it is fixed (as reported in the driver
documentation). Viceversa the driver will try to set the MDC
clock dynamically according to the actual clock input.
Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Reviewed-by: Francesco Virlinzi <francesco.virlinzi@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
Documentation/networking/stmmac.txt | 2 +-
drivers/net/ethernet/stmicro/stmmac/common.h | 10 +++++
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 40 +++++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 4 +-
5 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index eacb640..ab1e8d7 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -137,7 +137,7 @@ Where:
o pbl: the Programmable Burst Length is maximum number of beats to
be transferred in one DMA transaction.
GMAC also enables the 4xPBL by default.
- o clk_csr: CSR Clock range selection.
+ o clk_csr: fixed CSR Clock range selection.
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.
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index f4df1eb..312e3f1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -97,6 +97,16 @@ struct stmmac_extra_stats {
unsigned long normal_irq_n;
};
+/* CSR Frequency Access Defines*/
+#define CSR_F_35M 35000000
+#define CSR_F_60M 60000000
+#define CSR_F_100M 100000000
+#define CSR_F_150M 150000000
+#define CSR_F_250M 50000000
+#define CSR_F_300M 300000000
+
+#define MAC_CSR_H_FRQ_MASK 0x20
+
#define HASH_TABLE_SIZE 64
#define PAUSE_TIME 0x200
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 7182f15..ddd0769 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -84,6 +84,7 @@ struct stmmac_priv {
#ifdef CONFIG_HAVE_CLK
struct clk *stmmac_clk;
#endif
+ int clk_csr;
};
extern int phyaddr;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 08b4d05..c0d83ad 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -163,6 +163,35 @@ static void stmmac_verify_args(void)
pause = PAUSE_TIME;
}
+static void stmmac_clk_csr_set(struct stmmac_priv *priv)
+{
+#ifdef CONFIG_HAVE_CLK
+ u32 clk_rate;
+
+ clk_rate = clk_get_rate(priv->stmmac_clk);
+
+ /* Platform provided default clk_csr would be assumed valid
+ * for all other cases except for the below mentioned ones. */
+ if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) {
+ if (clk_rate < CSR_F_35M)
+ priv->clk_csr = STMMAC_CSR_20_35M;
+ else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M))
+ priv->clk_csr = STMMAC_CSR_35_60M;
+ else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M))
+ priv->clk_csr = STMMAC_CSR_60_100M;
+ else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M))
+ priv->clk_csr = STMMAC_CSR_100_150M;
+ else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M))
+ priv->clk_csr = STMMAC_CSR_150_250M;
+ else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M))
+ priv->clk_csr = STMMAC_CSR_250_300M;
+ } /* For values higher than the IEEE 802.3 specified frequency
+ * we can not estimate the proper divider as it is not known
+ * the frequency of clk_csr_i. So we do not change the default
+ * divider. */
+#endif
+}
+
#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
static void print_pkt(unsigned char *buf, int len)
{
@@ -1882,6 +1911,17 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
if (stmmac_clk_get(priv))
goto error;
+ /* If a specific clk_csr value is passed from the platform
+ * this means that the CSR Clock Range selection cannot be
+ * changed at run-time and it is fixed. Viceversa the driver'll try to
+ * set the MDC clock dynamically according to the csr actual
+ * clock input.
+ */
+ if (!priv->plat->clk_csr)
+ stmmac_clk_csr_set(priv);
+ else
+ priv->clk_csr = priv->plat->clk_csr;
+
return priv;
error:
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 1a42014..ade1082 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -70,7 +70,7 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
int data;
u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
((phyreg << 6) & (0x000007C0)));
- regValue |= MII_BUSY | ((priv->plat->clk_csr & 0xF) << 2);
+ regValue |= MII_BUSY | ((priv->clk_csr & 0xF) << 2);
if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
return -EBUSY;
@@ -106,7 +106,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
(((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
| MII_WRITE;
- value |= MII_BUSY | ((priv->plat->clk_csr & 0xF) << 2);
+ value |= MII_BUSY | ((priv->clk_csr & 0xF) << 2);
/* Wait until any existing MII operation is complete */
if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
--
1.7.4.4
^ permalink raw reply related
* [PATCH 10/10] stmmac: update the driver version 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
In-Reply-To: <1332493721-28309-1-git-send-email-peppe.cavallaro@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index ddd0769..9f2435c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -21,7 +21,7 @@
*******************************************************************************/
#define STMMAC_RESOURCE_NAME "stmmaceth"
-#define DRV_MODULE_VERSION "Feb_2012"
+#define DRV_MODULE_VERSION "March_2012"
#include <linux/clk.h>
#include <linux/stmmac.h>
--
1.7.4.4
^ permalink raw reply related
* [PATCH 0/5] netfilter updates for net (3.4) tree
From: pablo @ 2012-03-23 9:34 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Pablo Neira Ayuso <pablo@netfilter.org>
Hi David,
The following are five fixes for xt_LOG and the cttimeout
infrastructure that got into your tree in the previous development
cycle. This contains:
* One fix for missing symbol in xt_LOG reported by Randy Dunlap.
* Fix module dependency between cttimeout and nf_conntrack_proto_*
friends from me. Now, we make sure that protocol trackers modules
cannot be unloaded if there's any cttimeout object refering to
them.
* Fix missing rcu_read_lock section in xt_CT while dereferencing
a RCU pointer.
* Fix the assignation of a custom timeout policy for the generic
protocol tracker.
* Fix possible inconsistencies in the application of the cttimeout
policy by permanently attaching it to the conntrack entry. Before
this patch, the timeout policy was attached per packet which may
result in applying the timeout policy only in one traffic
direction.
You can pull this changes from:
git://1984.lsi.us.es/net master
Thanks!
Pablo Neira Ayuso (5):
netfilter: xt_LOG: use CONFIG_IP6_NF_IPTABLES instead of CONFIG_IPV6
netfilter: cttimeout: fix dependency with l4protocol conntrack module
netfilter: xt_CT: missing rcu_read_lock section in timeout assignment
netfilter: xt_CT: fix assignation of the generic protocol tracker
netfilter: nf_conntrack: permanently attach timeout policy to conntrack
include/net/netfilter/nf_conntrack_l4proto.h | 4 ++
include/net/netfilter/nf_conntrack_timeout.h | 2 +-
net/netfilter/nf_conntrack_core.c | 39 ++++++++++++----------
net/netfilter/nf_conntrack_proto.c | 21 ++++++++++++
net/netfilter/nfnetlink_cttimeout.c | 45 +++++++++++++------------
net/netfilter/xt_CT.c | 31 +++++++++++++----
net/netfilter/xt_LOG.c | 12 +++---
7 files changed, 100 insertions(+), 54 deletions(-)
--
1.7.2.5
^ permalink raw reply
* [PATCH 1/5] netfilter: xt_LOG: use CONFIG_IP6_NF_IPTABLES instead of CONFIG_IPV6
From: pablo @ 2012-03-23 9:34 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1332495257-3149-1-git-send-email-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
This fixes the following linking error:
xt_LOG.c:(.text+0x789b1): undefined reference to `ip6t_ext_hdr'
ifdefs have to use CONFIG_IP6_NF_IPTABLES instead of CONFIG_IPV6.
Acked-by: Randy Dunlap <rdunlap@xenotime.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/xt_LOG.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c
index f99f8de..ff5f75f 100644
--- a/net/netfilter/xt_LOG.c
+++ b/net/netfilter/xt_LOG.c
@@ -480,7 +480,7 @@ ipt_log_packet(u_int8_t pf,
sb_close(m);
}
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
/* One level of recursion won't kill us */
static void dump_ipv6_packet(struct sbuff *m,
const struct nf_loginfo *info,
@@ -824,7 +824,7 @@ log_tg(struct sk_buff *skb, const struct xt_action_param *par)
if (par->family == NFPROTO_IPV4)
ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in,
par->out, &li, loginfo->prefix);
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
else if (par->family == NFPROTO_IPV6)
ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in,
par->out, &li, loginfo->prefix);
@@ -864,7 +864,7 @@ static struct xt_target log_tg_regs[] __read_mostly = {
.checkentry = log_tg_check,
.me = THIS_MODULE,
},
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
{
.name = "LOG",
.family = NFPROTO_IPV6,
@@ -882,7 +882,7 @@ static struct nf_logger ipt_log_logger __read_mostly = {
.me = THIS_MODULE,
};
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
static struct nf_logger ip6t_log_logger __read_mostly = {
.name = "ip6t_LOG",
.logfn = &ip6t_log_packet,
@@ -899,7 +899,7 @@ static int __init log_tg_init(void)
return ret;
nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
nf_log_register(NFPROTO_IPV6, &ip6t_log_logger);
#endif
return 0;
@@ -908,7 +908,7 @@ static int __init log_tg_init(void)
static void __exit log_tg_exit(void)
{
nf_log_unregister(&ipt_log_logger);
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
nf_log_unregister(&ip6t_log_logger);
#endif
xt_unregister_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
--
1.7.2.5
^ permalink raw reply related
* [PATCH 2/5] netfilter: cttimeout: fix dependency with l4protocol conntrack module
From: pablo @ 2012-03-23 9:34 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1332495257-3149-1-git-send-email-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
This patch introduces nf_conntrack_l4proto_find_get() and
nf_conntrack_l4proto_put() to fix module dependencies between
timeout objects and l4-protocol conntrack modules.
Thus, we make sure that the module cannot be removed if it is
used by any of the cttimeout objects.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_conntrack_l4proto.h | 4 ++
include/net/netfilter/nf_conntrack_timeout.h | 2 +-
net/netfilter/nf_conntrack_proto.c | 21 ++++++++++++
net/netfilter/nfnetlink_cttimeout.c | 45 +++++++++++++------------
net/netfilter/xt_CT.c | 6 ++-
5 files changed, 53 insertions(+), 25 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index 90c67c7..3b572bb 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -118,6 +118,10 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_generic;
extern struct nf_conntrack_l4proto *
__nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto);
+extern struct nf_conntrack_l4proto *
+nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t l4proto);
+extern void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p);
+
/* Protocol registration. */
extern int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *proto);
extern void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *proto);
diff --git a/include/net/netfilter/nf_conntrack_timeout.h b/include/net/netfilter/nf_conntrack_timeout.h
index 0e04db4..34ec89f 100644
--- a/include/net/netfilter/nf_conntrack_timeout.h
+++ b/include/net/netfilter/nf_conntrack_timeout.h
@@ -15,7 +15,7 @@ struct ctnl_timeout {
atomic_t refcnt;
char name[CTNL_TIMEOUT_NAME_MAX];
__u16 l3num;
- __u8 l4num;
+ struct nf_conntrack_l4proto *l4proto;
char data[0];
};
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 5701c8d..be3da2c 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -127,6 +127,27 @@ void nf_ct_l3proto_module_put(unsigned short l3proto)
}
EXPORT_SYMBOL_GPL(nf_ct_l3proto_module_put);
+struct nf_conntrack_l4proto *
+nf_ct_l4proto_find_get(u_int16_t l3num, u_int8_t l4num)
+{
+ struct nf_conntrack_l4proto *p;
+
+ rcu_read_lock();
+ p = __nf_ct_l4proto_find(l3num, l4num);
+ if (!try_module_get(p->me))
+ p = &nf_conntrack_l4proto_generic;
+ rcu_read_unlock();
+
+ return p;
+}
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_find_get);
+
+void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p)
+{
+ module_put(p->me);
+}
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_put);
+
static int kill_l3proto(struct nf_conn *i, void *data)
{
return nf_ct_l3num(i) == ((struct nf_conntrack_l3proto *)data)->l3proto;
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index fec29a4..2b9e79f 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -98,11 +98,13 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
break;
}
- l4proto = __nf_ct_l4proto_find(l3num, l4num);
+ l4proto = nf_ct_l4proto_find_get(l3num, l4num);
/* This protocol is not supportted, skip. */
- if (l4proto->l4proto != l4num)
- return -EOPNOTSUPP;
+ if (l4proto->l4proto != l4num) {
+ ret = -EOPNOTSUPP;
+ goto err_proto_put;
+ }
if (matching) {
if (nlh->nlmsg_flags & NLM_F_REPLACE) {
@@ -110,20 +112,25 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
* different kind, sorry.
*/
if (matching->l3num != l3num ||
- matching->l4num != l4num)
- return -EINVAL;
+ matching->l4proto->l4proto != l4num) {
+ ret = -EINVAL;
+ goto err_proto_put;
+ }
ret = ctnl_timeout_parse_policy(matching, l4proto,
cda[CTA_TIMEOUT_DATA]);
return ret;
}
- return -EBUSY;
+ ret = -EBUSY;
+ goto err_proto_put;
}
timeout = kzalloc(sizeof(struct ctnl_timeout) +
l4proto->ctnl_timeout.obj_size, GFP_KERNEL);
- if (timeout == NULL)
- return -ENOMEM;
+ if (timeout == NULL) {
+ ret = -ENOMEM;
+ goto err_proto_put;
+ }
ret = ctnl_timeout_parse_policy(timeout, l4proto,
cda[CTA_TIMEOUT_DATA]);
@@ -132,13 +139,15 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
strcpy(timeout->name, nla_data(cda[CTA_TIMEOUT_NAME]));
timeout->l3num = l3num;
- timeout->l4num = l4num;
+ timeout->l4proto = l4proto;
atomic_set(&timeout->refcnt, 1);
list_add_tail_rcu(&timeout->head, &cttimeout_list);
return 0;
err:
kfree(timeout);
+err_proto_put:
+ nf_ct_l4proto_put(l4proto);
return ret;
}
@@ -149,7 +158,7 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
struct nlmsghdr *nlh;
struct nfgenmsg *nfmsg;
unsigned int flags = pid ? NLM_F_MULTI : 0;
- struct nf_conntrack_l4proto *l4proto;
+ struct nf_conntrack_l4proto *l4proto = timeout->l4proto;
event |= NFNL_SUBSYS_CTNETLINK_TIMEOUT << 8;
nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
@@ -163,20 +172,10 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
NLA_PUT_STRING(skb, CTA_TIMEOUT_NAME, timeout->name);
NLA_PUT_BE16(skb, CTA_TIMEOUT_L3PROTO, htons(timeout->l3num));
- NLA_PUT_U8(skb, CTA_TIMEOUT_L4PROTO, timeout->l4num);
+ NLA_PUT_U8(skb, CTA_TIMEOUT_L4PROTO, timeout->l4proto->l4proto);
NLA_PUT_BE32(skb, CTA_TIMEOUT_USE,
htonl(atomic_read(&timeout->refcnt)));
- l4proto = __nf_ct_l4proto_find(timeout->l3num, timeout->l4num);
-
- /* If the timeout object does not match the layer 4 protocol tracker,
- * then skip dumping the data part since we don't know how to
- * interpret it. This may happen for UPDlite, SCTP and DCCP since
- * you can unload the module.
- */
- if (timeout->l4num != l4proto->l4proto)
- goto out;
-
if (likely(l4proto->ctnl_timeout.obj_to_nlattr)) {
struct nlattr *nest_parms;
int ret;
@@ -192,7 +191,7 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
nla_nest_end(skb, nest_parms);
}
-out:
+
nlmsg_end(skb, nlh);
return skb->len;
@@ -293,6 +292,7 @@ static int ctnl_timeout_try_del(struct ctnl_timeout *timeout)
if (atomic_dec_and_test(&timeout->refcnt)) {
/* We are protected by nfnl mutex. */
list_del_rcu(&timeout->head);
+ nf_ct_l4proto_put(timeout->l4proto);
kfree_rcu(timeout, rcu_head);
} else {
/* still in use, restore reference counter. */
@@ -417,6 +417,7 @@ static void __exit cttimeout_exit(void)
/* We are sure that our objects have no clients at this point,
* it's safe to release them all without checking refcnt.
*/
+ nf_ct_l4proto_put(cur->l4proto);
kfree_rcu(cur, rcu_head);
}
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index b873445..80c39f0 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -16,6 +16,7 @@
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_ecache.h>
+#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_timeout.h>
#include <net/netfilter/nf_conntrack_zones.h>
@@ -243,11 +244,12 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
info->timeout, timeout->l3num);
goto err3;
}
- if (timeout->l4num != e->ip.proto) {
+ if (timeout->l4proto->l4proto != e->ip.proto) {
ret = -EINVAL;
pr_info("Timeout policy `%s' can only be "
"used by L4 protocol number %d\n",
- info->timeout, timeout->l4num);
+ info->timeout,
+ timeout->l4proto->l4proto);
goto err3;
}
timeout_ext = nf_ct_timeout_ext_add(ct, timeout,
--
1.7.2.5
^ permalink raw reply related
* [PATCH 3/5] netfilter: xt_CT: missing rcu_read_lock section in timeout assignment
From: pablo @ 2012-03-23 9:34 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1332495257-3149-1-git-send-email-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
Fix a dereference to pointer without rcu_read_lock held.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/xt_CT.c | 18 ++++++++++++------
1 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index 80c39f0..33a02b4 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -218,6 +218,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
struct ctnl_timeout *timeout;
struct nf_conn_timeout *timeout_ext;
+ rcu_read_lock();
timeout_find_get =
rcu_dereference(nf_ct_timeout_find_get_hook);
@@ -228,21 +229,21 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
ret = -EINVAL;
pr_info("You cannot use inversion on "
"L4 protocol\n");
- goto err3;
+ goto err4;
}
timeout = timeout_find_get(info->timeout);
if (timeout == NULL) {
ret = -ENOENT;
pr_info("No such timeout policy \"%s\"\n",
info->timeout);
- goto err3;
+ goto err4;
}
if (timeout->l3num != par->family) {
ret = -EINVAL;
pr_info("Timeout policy `%s' can only be "
"used by L3 protocol number %d\n",
info->timeout, timeout->l3num);
- goto err3;
+ goto err4;
}
if (timeout->l4proto->l4proto != e->ip.proto) {
ret = -EINVAL;
@@ -250,19 +251,20 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
"used by L4 protocol number %d\n",
info->timeout,
timeout->l4proto->l4proto);
- goto err3;
+ goto err4;
}
timeout_ext = nf_ct_timeout_ext_add(ct, timeout,
GFP_KERNEL);
if (timeout_ext == NULL) {
ret = -ENOMEM;
- goto err3;
+ goto err4;
}
} else {
ret = -ENOENT;
pr_info("Timeout policy base is empty\n");
- goto err3;
+ goto err4;
}
+ rcu_read_unlock();
}
#endif
@@ -272,6 +274,8 @@ out:
info->ct = ct;
return 0;
+err4:
+ rcu_read_unlock();
err3:
nf_conntrack_free(ct);
err2:
@@ -313,6 +317,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
nf_ct_l3proto_module_put(par->family);
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
+ rcu_read_lock();
timeout_put = rcu_dereference(nf_ct_timeout_put_hook);
if (timeout_put) {
@@ -320,6 +325,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
if (timeout_ext)
timeout_put(timeout_ext->timeout);
}
+ rcu_read_unlock();
#endif
}
nf_ct_put(info->ct);
--
1.7.2.5
^ permalink raw reply related
* [PATCH 4/5] netfilter: xt_CT: fix assignation of the generic protocol tracker
From: pablo @ 2012-03-23 9:34 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1332495257-3149-1-git-send-email-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
`iptables -p all' uses 0 to match all protocols, while the conntrack
subsystem uses 255. We still need `-p all' to attach the custom
timeout policies for the generic protocol tracker.
Moreover, we may use `iptables -p sctp' while the SCTP tracker is
not loaded. In that case, we have to default on the generic protocol
tracker.
Another possibility is `iptables -p ip' that should be supported
as well. This patch makes sure we validate all possible scenarios.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/xt_CT.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index 33a02b4..0c8e438 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -14,6 +14,7 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_CT.h>
#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
@@ -224,6 +225,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
if (timeout_find_get) {
const struct ipt_entry *e = par->entryinfo;
+ struct nf_conntrack_l4proto *l4proto;
if (e->ip.invflags & IPT_INV_PROTO) {
ret = -EINVAL;
@@ -245,7 +247,12 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
info->timeout, timeout->l3num);
goto err4;
}
- if (timeout->l4proto->l4proto != e->ip.proto) {
+ /* Make sure the timeout policy matches any existing
+ * protocol tracker, otherwise default to generic.
+ */
+ l4proto = __nf_ct_l4proto_find(par->family,
+ e->ip.proto);
+ if (timeout->l4proto->l4proto != l4proto->l4proto) {
ret = -EINVAL;
pr_info("Timeout policy `%s' can only be "
"used by L4 protocol number %d\n",
--
1.7.2.5
^ permalink raw reply related
* [PATCH 5/5] netfilter: nf_conntrack: permanently attach timeout policy to conntrack
From: pablo @ 2012-03-23 9:34 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1332495257-3149-1-git-send-email-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
We need to permanently attach the timeout policy to the conntrack,
otherwise we may apply the custom timeout policy inconsistently.
Without this patch, the following example:
nfct timeout add test inet icmp timeout 100
iptables -I PREROUTING -t raw -p icmp -s 1.1.1.1 -j CT --timeout test
Will only apply the custom timeout policy to outgoing packets from
1.1.1.1, but not to reply packets from 2.2.2.2 going to 1.1.1.1.
To fix this issue, this patch modifies the current logic to attach the
timeout policy when the first packet is seen (which is when the
conntrack entry is created). Then, we keep using the attached timeout
policy until the conntrack entry is destroyed.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_core.c | 39 ++++++++++++++++++++----------------
1 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 7b48035..cbdb754 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -768,8 +768,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
struct nf_conntrack_l3proto *l3proto,
struct nf_conntrack_l4proto *l4proto,
struct sk_buff *skb,
- unsigned int dataoff, u32 hash,
- unsigned int *timeouts)
+ unsigned int dataoff, u32 hash)
{
struct nf_conn *ct;
struct nf_conn_help *help;
@@ -777,6 +776,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
struct nf_conntrack_ecache *ecache;
struct nf_conntrack_expect *exp;
u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE;
+ struct nf_conn_timeout *timeout_ext;
+ unsigned int *timeouts;
if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) {
pr_debug("Can't invert tuple.\n");
@@ -788,12 +789,21 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
if (IS_ERR(ct))
return (struct nf_conntrack_tuple_hash *)ct;
+ timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL;
+ if (timeout_ext)
+ timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
+ else
+ timeouts = l4proto->get_timeouts(net);
+
if (!l4proto->new(ct, skb, dataoff, timeouts)) {
nf_conntrack_free(ct);
pr_debug("init conntrack: can't track with proto module\n");
return NULL;
}
+ if (timeout_ext)
+ nf_ct_timeout_ext_add(ct, timeout_ext->timeout, GFP_ATOMIC);
+
nf_ct_acct_ext_add(ct, GFP_ATOMIC);
nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
@@ -854,8 +864,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
struct nf_conntrack_l3proto *l3proto,
struct nf_conntrack_l4proto *l4proto,
int *set_reply,
- enum ip_conntrack_info *ctinfo,
- unsigned int *timeouts)
+ enum ip_conntrack_info *ctinfo)
{
struct nf_conntrack_tuple tuple;
struct nf_conntrack_tuple_hash *h;
@@ -875,7 +884,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
h = __nf_conntrack_find_get(net, zone, &tuple, hash);
if (!h) {
h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto,
- skb, dataoff, hash, timeouts);
+ skb, dataoff, hash);
if (!h)
return NULL;
if (IS_ERR(h))
@@ -964,19 +973,8 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
goto out;
}
- /* Decide what timeout policy we want to apply to this flow. */
- if (tmpl) {
- timeout_ext = nf_ct_timeout_find(tmpl);
- if (timeout_ext)
- timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
- else
- timeouts = l4proto->get_timeouts(net);
- } else
- timeouts = l4proto->get_timeouts(net);
-
ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum,
- l3proto, l4proto, &set_reply, &ctinfo,
- timeouts);
+ l3proto, l4proto, &set_reply, &ctinfo);
if (!ct) {
/* Not valid part of a connection */
NF_CT_STAT_INC_ATOMIC(net, invalid);
@@ -993,6 +991,13 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
NF_CT_ASSERT(skb->nfct);
+ /* Decide what timeout policy we want to apply to this flow. */
+ timeout_ext = nf_ct_timeout_find(ct);
+ if (timeout_ext)
+ timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
+ else
+ timeouts = l4proto->get_timeouts(net);
+
ret = l4proto->packet(ct, skb, dataoff, ctinfo, pf, hooknum, timeouts);
if (ret <= 0) {
/* Invalid: inverse of the return code tells
--
1.7.2.5
^ permalink raw reply related
* RE: [PATCH 2/9] ocrdma: Driver for Emulex OneConnect RDMA adapter
From: David Laight @ 2012-03-23 9:41 UTC (permalink / raw)
To: Jason Gunthorpe, Parav.Pandit-iH1Dq9VlAzfQT0dZR+AlfA
Cc: roland-BHEL68pLQRGGvPXPguhicg, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20120322224429.GA12980-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> > struct {
> > u64 fielda
> > u32 field;
> > };
>
> In this case: On 64 bit: the u64 is aligned to 8 and the u32
> is aligned to 4. So
> the structure is aligned to 8. A pad is inserted at the end of the
> struct to bring it out. On 32 bit, the u64 is aligned to 4, so the
> struct is aligned to 4, so no pad is added.
That is true for 32bit i386, some 32bit ABI may require 64bit
alignment for 64bit items.
...
> The aligned attribute overrides the automatic determination of the
> alignment based on the contents and just forces it.
>
> So, as an example, if you have this hardware layout:
>
> struct {
> u32 fielda;
> u64 fieldb;
> } attribute ((aligned(4));
>
> David is saying you will get a 12 byte struct and fieldb will be
> unaligned. Since 12 is aligned to 4 no padding is added.
I was actually suggesting defining (modulo syntax errors):
typedef u64 u64_aligned_8 attribute ((aligned(8));
Then you can define:
struct foo {
u32 fielda;
u64_aligned_8 fieldb;
};
and know that the aligment should be the same on all systems.
(But I'd still add the explicit pad in the above.)
This is actually more useful when you need to process structures
that have misaligned 64bit items - as happens when doing 'compat 32'
code in a 64bit kernel. Or trying to map the x86 disk mbr.
> For hardware facing structures I'd combine this with a static assert
> to verify structure size at compile time.
Also useful if you need to ensure a structure doesn't accidentally
change size when you need to preserve a userspace interface.
> So..
>
> 1) Avoid using attributes unless the structure has unaligned members.
> 2) Avoid creating structures with unaligned members (eg for userspace
> communication)
> 3) Frown at hardware/firmware developers who make communication
> structures with unaligned members :)
> 4) Be explicit about padding in your layout for 64/32
> compatibility.
Agreed.
David
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" 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: [PATCH 09/10] stmmac: MDC clock dynamically based on the csr clock input
From: David Laight @ 2012-03-23 9:53 UTC (permalink / raw)
To: Giuseppe CAVALLARO, netdev
Cc: davem, srinivas.kandagatla, deepak.sikri, spear-devel,
shiraz.hashim, viresh.kumar, bhutchings
In-Reply-To: <1332493721-28309-10-git-send-email-peppe.cavallaro@st.com>
> -----Original Message-----
> From: netdev-owner@vger.kernel.org
> [mailto:netdev-owner@vger.kernel.org] On Behalf Of Giuseppe CAVALLARO
> Sent: 23 March 2012 09:09
> To: netdev@vger.kernel.org
> Cc: davem@davemloft.net; srinivas.kandagatla@st.com;
> deepak.sikri@st.com; spear-devel@list.st.com;
> shiraz.hashim@st.com; viresh.kumar@st.com;
> bhutchings@solarflare.com; Giuseppe Cavallaro
> Subject: [PATCH 09/10] stmmac: MDC clock dynamically based on
> the csr clock input
>
> If a specific clk_csr value is passed from the platform
> this means that the CSR Clock Range selection cannot be
> changed at run-time and it is fixed (as reported in the driver
> documentation). Viceversa the driver will try to set the MDC
> clock dynamically according to the actual clock input.
>
> Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
> Reviewed-by: Francesco Virlinzi <francesco.virlinzi@st.com>
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> ---
> Documentation/networking/stmmac.txt | 2 +-
> drivers/net/ethernet/stmicro/stmmac/common.h | 10 +++++
> drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 40
> +++++++++++++++++++++
> drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 4 +-
> 5 files changed, 54 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/networking/stmmac.txt
> b/Documentation/networking/stmmac.txt
> index eacb640..ab1e8d7 100644
> --- a/Documentation/networking/stmmac.txt
> +++ b/Documentation/networking/stmmac.txt
> @@ -137,7 +137,7 @@ Where:
> o pbl: the Programmable Burst Length is maximum number of beats to
> be transferred in one DMA transaction.
> GMAC also enables the 4xPBL by default.
> - o clk_csr: CSR Clock range selection.
> + o clk_csr: fixed CSR Clock range selection.
> 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.
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h
> b/drivers/net/ethernet/stmicro/stmmac/common.h
> index f4df1eb..312e3f1 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -97,6 +97,16 @@ struct stmmac_extra_stats {
> unsigned long normal_irq_n;
> };
>
> +/* CSR Frequency Access Defines*/
> +#define CSR_F_35M 35000000
> +#define CSR_F_60M 60000000
> +#define CSR_F_100M 100000000
> +#define CSR_F_150M 150000000
> +#define CSR_F_250M 50000000
> +#define CSR_F_300M 300000000
The value of CSR_F_250M looks like a typo.
These defines look rather pointless to me though!
Another patch has:
> -----------------------------------------
> 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
I detect a pattern ...
David
^ permalink raw reply
* Re: [PATCH][RFC] bonding: delete migrated IP addresses from the rlb hash table
From: Jiri Bohac @ 2012-03-23 10:33 UTC (permalink / raw)
To: WeipingPan; +Cc: Jiri Bohac, Jay Vosburgh, Andy Gospodarek, netdev
In-Reply-To: <4F6C21D7.2000609@gmail.com>
On Fri, Mar 23, 2012 at 03:10:15PM +0800, WeipingPan wrote:
> On 02/28/2012 01:34 AM, Jiri Bohac wrote:
> >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 ?
No, NetworkA and NetworkB are the same subnet, same L2 network.
It may be two ethernet segments that are bridge by the br0
bridge. A more common scenario is that HostB is a virtual machine
that communicates through br0->bond0->ethX with HostA.
In this setup, bond0 can not solve the original bug (stale ARP
information in the rlb hash table) simply by monitoring the
removal of IP addresses on the local host. The IP address that is
about to be migrated from HostB to HostA is _not_ configured on
any of the interfaces of the machine running bond0.
The patch solves the problem by looking at ARP requests coming
from NetworkA and deleting RLB hash table entries that were
created while the ARP's src_ip was still assigned in NetworkB.
--
Jiri Bohac <jbohac@suse.cz>
SUSE Labs, SUSE CZ
^ permalink raw reply
* [PATCH RFC] net: hardware limited MTU for 802.1Q frames
From: Mike Sinkovsky @ 2012-03-23 10:51 UTC (permalink / raw)
To: netdev; +Cc: msink
Some chips (WIZnet as example) have hardware limited MTU -
plain ethernet frame works with MTU 1500, but for 802.1Q
frames MTU must be limited to 1496.
This patch add callback in net_device_ops, called from 8021q
code to check for this hardware limitation.
If callback is not set in driver - vlan works as before,
in hope that underlaying device always can handle
additional 4 byte in frame length.
---
include/linux/netdevice.h | 20 ++++++++++++++++++++
net/8021q/vlan.c | 13 ++++++-------
net/8021q/vlan_dev.c | 8 ++++----
net/8021q/vlan_netlink.c | 4 ++--
4 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 8debe29..3cbf2a4 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -790,6 +790,13 @@ struct netdev_fcoe_hbainfo {
* of a device. If not defined, any request to change MTU will
* will return an error.
*
+ * int (*ndo_get_hard_mtu)(struct net_device *dev)
+ * If defined, returns hardware limit for MTU.
+ * Called when a slave device needs to set MTU, to make sure that
+ * this limit is not exceed.
+ * If not defined, dev->mtu is used in hope the underlying device can
+ * handle it.
+ *
* void (*ndo_tx_timeout)(struct net_device *dev);
* Callback uses when the transmitter has not made any progress
* for dev->watchdog ticks.
@@ -926,6 +933,7 @@ struct net_device_ops {
struct ifmap *map);
int (*ndo_change_mtu)(struct net_device *dev,
int new_mtu);
+ int (*ndo_get_hard_mtu)(struct net_device *dev);
int (*ndo_neigh_setup)(struct net_device *dev,
struct neigh_parms *);
void (*ndo_tx_timeout) (struct net_device *dev);
@@ -2677,6 +2685,18 @@ static inline bool netif_supports_nofcs(struct net_device *dev)
return dev->priv_flags & IFF_SUPP_NOFCS;
}
+static inline int netdev_get_mtu(struct net_device *dev, int hlen)
+{
+ const struct net_device_ops *ops = dev->netdev_ops;
+ int mtu = dev->mtu;
+ if (ops->ndo_get_hard_mtu) {
+ int hard_mtu = ops->ndo_get_hard_mtu(dev);
+ if (mtu + hlen > hard_mtu)
+ mtu = hard_mtu - hlen;
+ }
+ return mtu;
+}
+
extern struct pernet_operations __net_initdata loopback_net_ops;
/* Logging, debugging and troubleshooting/diagnostic helpers. */
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index efea35b..ecf3089 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -238,10 +238,8 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
return -ENOBUFS;
dev_net_set(new_dev, net);
- /* need 4 bytes for extra VLAN header info,
- * hope the underlying device can handle it.
- */
- new_dev->mtu = real_dev->mtu;
+
+ new_dev->mtu = netdev_get_mtu(real_dev, VLAN_HLEN);
vlan_dev_priv(new_dev)->vlan_id = vlan_id;
vlan_dev_priv(new_dev)->real_dev = real_dev;
@@ -326,7 +324,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
struct net_device *dev = ptr;
struct vlan_group *grp;
struct vlan_info *vlan_info;
- int i, flgs;
+ int i, flgs, mtu;
struct net_device *vlandev;
struct vlan_dev_priv *vlan;
LIST_HEAD(list);
@@ -378,15 +376,16 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
break;
case NETDEV_CHANGEMTU:
+ mtu = netdev_get_mtu(dev, VLAN_HLEN);
for (i = 0; i < VLAN_N_VID; i++) {
vlandev = vlan_group_get_device(grp, i);
if (!vlandev)
continue;
- if (vlandev->mtu <= dev->mtu)
+ if (vlandev->mtu <= mtu)
continue;
- dev_set_mtu(vlandev, dev->mtu);
+ dev_set_mtu(vlandev, mtu);
}
break;
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 9988d4a..bd52428 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -180,10 +180,10 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
{
- /* TODO: gotta make sure the underlying layer can handle it,
- * maybe an IFF_VLAN_CAPABLE flag for devices?
- */
- if (vlan_dev_priv(dev)->real_dev->mtu < new_mtu)
+ struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
+
+ /* make sure the underlying layer can handle it */
+ if (new_mtu > netdev_get_mtu(real_dev, VLAN_HLEN))
return -ERANGE;
dev->mtu = new_mtu;
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index 5071136..c83420c 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -127,8 +127,8 @@ static int vlan_newlink(struct net *src_net, struct net_device *dev,
return err;
if (!tb[IFLA_MTU])
- dev->mtu = real_dev->mtu;
- else if (dev->mtu > real_dev->mtu)
+ dev->mtu = netdev_get_mtu(real_dev, VLAN_HLEN);
+ else if (dev->mtu > netdev_get_mtu(real_dev, VLAN_HLEN))
return -EINVAL;
err = vlan_changelink(dev, tb, data);
^ permalink raw reply related
* [RFC] skb truesize last offenders
From: Eric Dumazet @ 2012-03-23 12:51 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Wey-Yi Guy
iwlwifi and some other users of skb_add_rx_frag() lie about skb
truesize, because of API being lazy.
iwlwifi can use order-0 or order-1 pages and skb truesize is wrong.
network sbs can use uncharged kernel memory and eventually crash machine
in OOM.
I plan :
1) adding a @truesize parameter to skb_add_rx_frag() in a neutral patch
2) fix drivers that dont charge the real size of fragment
3) niu could then use skb_add_rx_frag() instead of custom code.
^ permalink raw reply
* [PATCH] e1000e: clear REQ and GNT in EECD (82571 && 82572)
From: Richard Alpe @ 2012-03-23 12:55 UTC (permalink / raw)
To: jeffrey.t.kirsher, jesse.brandeburg, bruce.w.allan,
carolyn.wyborny, donald.c.skidmore, gregory.v.rose,
peter.p.waskiewicz.jr, alexander.h.duyck, john.ronciak,
e1000-devel, netdev
Cc: linux-kernel, Richard Alpe
Clear the REQ and GNT bit in the eeprom control register (EECD).
This is required if the eeprom is to be accessed with auto read
EERD register.
After a cold reset this doesn't matter but if PBIST MAC test was
executed before booting, the register was left in a dirty state
(the 2 bits where set), which caused the read operation to time out
and returning 0.
Reference (page 312):
http://download.intel.com/design/network/manuals/316080.pdf
Reported-by: Aleksandar Igic <aleksandar.igic@dektech.com.au>
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
---
drivers/net/ethernet/intel/e1000e/82571.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c
index b3fdc69..51f7d2e 100644
--- a/drivers/net/ethernet/intel/e1000e/82571.c
+++ b/drivers/net/ethernet/intel/e1000e/82571.c
@@ -1001,6 +1001,7 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active)
static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
{
u32 ctrl, ctrl_ext;
+ u32 ctrl, ctrl_ext, eecd;
s32 ret_val;
/*
@@ -1099,6 +1100,16 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
if (hw->phy.media_type == e1000_media_type_internal_serdes)
hw->mac.serdes_link_state = e1000_serdes_link_down;
+ /*
+ * 82571 and 82572 need EEC.EE_REQ and EEC.EE_GNT cleared
+ * when using EERD to access the EEPROM
+ */
+ if ((hw->mac.type == e1000_82571) || (hw->mac.type == e1000_82572)) {
+ eecd = er32(EECD);
+ eecd &= ~(E1000_EECD_REQ | E1000_EECD_GNT);
+ ew32(EECD, eecd);
+ }
+
return 0;
}
--
1.7.2.5
^ permalink raw reply related
* [PATCH] net: add a truesize parameter to skb_add_rx_frag()
From: Eric Dumazet @ 2012-03-23 13:17 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Wey-Yi Guy
skb_add_rx_frag() API is misleading.
Network skbs built with this helper can use uncharged kernel memory and
eventually stress/crash machine in OOM.
Add a 'truesize' parameter and then fix drivers in followup patches.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
drivers/net/usb/cdc-phonet.c | 6 ++++--
drivers/net/wireless/iwlegacy/3945.c | 3 ++-
drivers/net/wireless/iwlegacy/4965-mac.c | 3 ++-
drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 2 +-
include/linux/skbuff.h | 2 +-
net/core/skbuff.c | 4 ++--
6 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c
index 790cbde..3886b30 100644
--- a/drivers/net/usb/cdc-phonet.c
+++ b/drivers/net/usb/cdc-phonet.c
@@ -164,12 +164,14 @@ static void rx_complete(struct urb *req)
/* Can't use pskb_pull() on page in IRQ */
memcpy(skb_put(skb, 1), page_address(page), 1);
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
- page, 1, req->actual_length);
+ page, 1, req->actual_length,
+ req->actual_length);
page = NULL;
}
} else {
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
- page, 0, req->actual_length);
+ page, 0, req->actual_length,
+ req->actual_length);
page = NULL;
}
if (req->actual_length < PAGE_SIZE)
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c
index c5b1d19..b25c01b 100644
--- a/drivers/net/wireless/iwlegacy/3945.c
+++ b/drivers/net/wireless/iwlegacy/3945.c
@@ -499,7 +499,8 @@ il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb,
le32_to_cpu(rx_end->status), stats);
skb_add_rx_frag(skb, 0, rxb->page,
- (void *)rx_hdr->payload - (void *)pkt, len);
+ (void *)rx_hdr->payload - (void *)pkt, len,
+ len);
il_update_stats(il, false, fc, len);
memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 7b54dbb..17f1c68 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -596,7 +596,8 @@ il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr,
return;
}
- skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
+ skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len,
+ len);
il_update_stats(il, false, fc, len);
memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index 44c6f71..f4b84d1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -796,7 +796,7 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
offset = (void *)hdr - rxb_addr(rxb);
p = rxb_steal_page(rxb);
- skb_add_rx_frag(skb, 0, p, offset, len);
+ skb_add_rx_frag(skb, 0, p, offset, len, len);
iwl_update_stats(priv, false, fc, len);
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index a2b9953..681a187 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1244,7 +1244,7 @@ static inline void skb_fill_page_desc(struct sk_buff *skb, int i,
}
extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page,
- int off, int size);
+ int off, int size, unsigned int truesize);
#define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags)
#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_has_frag_list(skb))
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 6eb656a..a690cae 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -321,12 +321,12 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
EXPORT_SYMBOL(__netdev_alloc_skb);
void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
- int size)
+ int size, unsigned int truesize)
{
skb_fill_page_desc(skb, i, page, off, size);
skb->len += size;
skb->data_len += size;
- skb->truesize += size;
+ skb->truesize += truesize;
}
EXPORT_SYMBOL(skb_add_rx_frag);
^ permalink raw reply related
* [PATCH linux-next] dmaengine: add context parameter fixups
From: Alexandre Bounine @ 2012-03-23 14:00 UTC (permalink / raw)
To: paul.gortmaker, vinod.koul, dan.j.williams
Cc: Alexandre Bounine, samuel, lrg, broonie, perex, tiwai,
linux-kernel, linux-next, netdev, fabio.estevam, alsa-devel
This patch fixes drivers that use device_prep_slave_sg() and
device_prep_dma_cyclic() interfaces and have been missed during the initial
release of interface changing patches.
This patch is based on linux-next-20120322 code tree.
See https://lkml.org/lkml/2012/3/22/339 for build failure report.
Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Reported-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
drivers/dma/sa11x0-dma.c | 2 +-
drivers/net/irda/sa1100_ir.c | 2 +-
sound/soc/sh/fsi.c | 7 +++----
sound/soc/soc-dmaengine-pcm.c | 2 +-
4 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
index 16a6b48..ec78cce 100644
--- a/drivers/dma/sa11x0-dma.c
+++ b/drivers/dma/sa11x0-dma.c
@@ -585,7 +585,7 @@ static dma_cookie_t sa11x0_dma_tx_submit(struct dma_async_tx_descriptor *tx)
static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg(
struct dma_chan *chan, struct scatterlist *sg, unsigned int sglen,
- enum dma_transfer_direction dir, unsigned long flags)
+ enum dma_transfer_direction dir, unsigned long flags, void *context)
{
struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
struct sa11x0_dma_desc *txd;
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index a0d1913..e250675 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -147,7 +147,7 @@ static void sa1100_irda_dma_start(struct sa1100_buf *buf,
struct dma_async_tx_descriptor *desc;
struct dma_chan *chan = buf->chan;
- desc = chan->device->device_prep_slave_sg(chan, &buf->sg, 1, dir,
+ desc = dmaengine_prep_slave_sg(chan, &buf->sg, 1, dir,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (desc) {
desc->callback = cb;
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 378cc5b..9e730ad 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -1001,11 +1001,10 @@ static void fsi_dma_do_tasklet(unsigned long data)
sg_dma_address(&sg) = buf;
sg_dma_len(&sg) = len;
- desc = chan->device->device_prep_slave_sg(chan, &sg, 1, dir,
- DMA_PREP_INTERRUPT |
- DMA_CTRL_ACK);
+ desc = dmaengine_prep_slave_sg(chan, &sg, 1, dir,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
- dev_err(dai->dev, "device_prep_slave_sg() fail\n");
+ dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n");
return;
}
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
index 4420b70..4756952 100644
--- a/sound/soc/soc-dmaengine-pcm.c
+++ b/sound/soc/soc-dmaengine-pcm.c
@@ -143,7 +143,7 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
direction = snd_pcm_substream_to_dma_direction(substream);
prtd->pos = 0;
- desc = chan->device->device_prep_dma_cyclic(chan,
+ desc = dmaengine_prep_dma_cyclic(chan,
substream->runtime->dma_addr,
snd_pcm_lib_buffer_bytes(substream),
snd_pcm_lib_period_bytes(substream), direction);
--
1.7.8.4
^ permalink raw reply related
* Re: [PATCH] e1000: Silence sparse warnings by correcting type
From: Andrei Emeltchenko @ 2012-03-23 14:01 UTC (permalink / raw)
To: netdev
In-Reply-To: <1332233951-31129-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
ping
On Tue, Mar 20, 2012 at 10:59 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Silence sparse warnings shown below:
> ...
> drivers/net/ethernet/intel/e1000/e1000_main.c:3435:17: warning:
> cast to restricted __le64
> drivers/net/ethernet/intel/e1000/e1000_main.c:3435:17: warning:
> cast to restricted __le64
> ...
>
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> ---
> drivers/net/ethernet/intel/e1000/e1000_main.c | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
> index 6419a88..1bf73cf 100644
> --- a/drivers/net/ethernet/intel/e1000/e1000_main.c
> +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
> @@ -3377,7 +3377,7 @@ static void e1000_dump(struct e1000_adapter *adapter)
> for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
> struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i);
> struct e1000_buffer *buffer_info = &tx_ring->buffer_info[i];
> - struct my_u { u64 a; u64 b; };
> + struct my_u { __le64 a; __le64 b; };
> struct my_u *u = (struct my_u *)tx_desc;
> const char *type;
>
> @@ -3421,7 +3421,7 @@ rx_ring_summary:
> for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) {
> struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i);
> struct e1000_buffer *buffer_info = &rx_ring->buffer_info[i];
> - struct my_u { u64 a; u64 b; };
> + struct my_u { __le64 a; __le64 b; };
> struct my_u *u = (struct my_u *)rx_desc;
> const char *type;
>
> --
> 1.7.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* RE: [PATCH 2/9] ocrdma: Driver for Emulex OneConnect RDMA adapter
From: Parav.Pandit-iH1Dq9VlAzfQT0dZR+AlfA @ 2012-03-23 14:03 UTC (permalink / raw)
To: jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/
Cc: David.Laight-ZS65k/vG3HxXrIkS9f7CXA,
roland-BHEL68pLQRGGvPXPguhicg, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20120322224429.GA12980-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> -----Original Message-----
> From: Jason Gunthorpe [mailto:jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org]
> Sent: Friday, March 23, 2012 4:14 AM
> To: Pandit, Parav
> Cc: David.Laight-ZS65k/vG3HxXrIkS9f7CXA@public.gmane.org; roland-BHEL68pLQRGGvPXPguhicg@public.gmane.org; linux-
> rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Subject: Re: [PATCH 2/9] ocrdma: Driver for Emulex OneConnect RDMA
> adapter
>
> On Thu, Mar 22, 2012 at 02:20:28PM -0700, Parav.Pandit-iH1Dq9VlAzfQT0dZR+AlfA@public.gmane.org
> wrote:
> > I got a question here lately.
> >
> > aligned directive will ensure that it will fall on boundary. Say
> > aligned(4) ensures that structure is aligned to 4 byte boundary.
> > Compiler can (at least theoretically) still have 4 byte structure
> > aligned to 8 byte boundary on 64-bit platform (which is 4 byte aligned
> > too).
>
> There are very specific rules defined in the platform's ABI for how C
> structures are layed out in memory, each ABI (ie CPU) has its own specific
> quirks, but broadly in Linux land you can boil it down to:
>
> 1) The alignment of a structure is the greatest alignment of all the
> members
> 2) Each member is aligned to its alignment.
>
> The alignment of the structure drives the total size of the structure, and
> specifically the padding added at the end to reach that alignment.
>
> So, no, a compiler that increased the alignment of a struct with one
> u32 to 8 would violate the various ABIs and not be usuable for Linux. It is
> important to bear in mind that Linux targets a particular set of ABI
> conventions, and it is not 'anything goes'.
>
> > struct {
> > u32 field;
> > };
>
> So in this case: the u32 is aligned to 4, the structure is aligned to
> 4 and the total size of the structure is 4 on everything linux supports.
>
> > struct {
> > u64 fielda
> > u32 field;
> > };
>
> In this case: On 64 bit: the u64 is aligned to 8 and the u32 is aligned to 4. So
> the structure is aligned to 8. A pad is inserted at the end of the struct to bring
> it out. On 32 bit, the u64 is aligned to 4, so the struct is aligned to 4, so no pad
> is added.
>
> > struct {
> > __float128 fielda
> > u32 field;
> > };
>
> In this case the float128 is aligned to 16 and thus the structure is aligned to 16
> and 12 pad bytes are added.
>
> > However requirement is to have this structure only 4 byte size(
> > because adapter excepts it to be 4B sise) and therefor packed is used.
> > I don't know the way to ensure size of 4 byte and alignment too. Or I
> > am misunderstanding?
>
> Yes, you are mis-understanding the rules for padding.. Structures are only
> padded out to their alignment, which depends on their constituent types.
> This is so arrays of structures have each array element starting on its natural
> alignment.
>
> The aligned attribute overrides the automatic determination of the
> alignment based on the contents and just forces it.
>
> So, as an example, if you have this hardware layout:
>
> struct {
> u32 fielda;
> u64 fieldb;
> } attribute ((aligned(4));
>
> David is saying you will get a 12 byte struct and fieldb will be unaligned. Since
> 12 is aligned to 4 no padding is added.
So I decided to experiment above example before implementing in driver. However I find structure of 16 bytes (instead of 12) with padding after fielda in below example.
Am I missing some compiler option or syntax error in attribute? Sorry to ask this silly question.
I tried __attribute__((__aligned__(4))); too based on usage in other kernel code.
#include <linux/module.h>
struct foo {
u32 a;
u64 b;
} __attribute__((aligned(4)));
static int __init main_init(void)
{
printk("<1> sizeof foo=%ld\n", sizeof(struct foo));
printk("<1> offset of a=%ld\n", offsetof(struct foo, a));
printk("<1> offset of b=%ld\n", offsetof(struct foo, b));
return 0;
}
static void __exit main_exit(void)
{
}
module_init(main_init);
module_exit(main_exit);
Output:
Mar 24 05:44:10 parav-sles11-sp1-64 kernel: [2006356.094931] sizeof foo=16
Mar 24 05:44:10 parav-sles11-sp1-64 kernel: [2006356.094934] offset of a=0
Mar 24 05:44:10 parav-sles11-sp1-64 kernel: [2006356.094936] offset of b=8
Gcc version is below.
Using built-in specs.
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.3 --enable-ssp --disable-libssp --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --program-suffix=-4.3 --enable-linux-futex --without-system-libunwind --with-cpu=generic --build=x86_64-suse-linux
Thread model: posix
gcc version 4.3.4 [gcc-4_3-branch revision 152973] (SUSE Linux)
> For hardware facing structures I'd combine this with a static assert to verify
> structure size at compile time.
>
> So..
>
> 1) Avoid using attributes unless the structure has unaligned members.
> 2) Avoid creating structures with unaligned members (eg for userspace
> communication)
> 3) Frown at hardware/firmware developers who make communication
> structures with unaligned members :)
> 4) Be explicit about padding in your layout for 64/32
> compatibility.
>
> Jason
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" 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: [PATCH RFC] net: hardware limited MTU for 802.1Q frames
From: David Lamparter @ 2012-03-23 14:41 UTC (permalink / raw)
To: Mike Sinkovsky; +Cc: netdev
In-Reply-To: <1332499886-1126-1-git-send-email-msink@permonline.ru>
On Fri, Mar 23, 2012 at 03:51:26PM +0500, Mike Sinkovsky wrote:
> This patch add callback in net_device_ops, called from 8021q
> code to check for this hardware limitation.
[...]
> + * int (*ndo_get_hard_mtu)(struct net_device *dev)
> + * If defined, returns hardware limit for MTU.
> + * Called when a slave device needs to set MTU, to make sure that
> + * this limit is not exceed.
> + * If not defined, dev->mtu is used in hope the underlying device can
> + * handle it.
> + *
This is, in my opinion, not thought through enough. In particular, there
are two interacting factors that your patch does not consider:
- there are devices that support 802.1Q outside of the actual hard MTU
limitation. (example: i think AT91SAM on-chip ethernet). In these
cases, the device has a hard MTU of (random example) 1536 bytes, but
supports sending the extra 4 bytes of 802.1Q "outside" of that.
(in a case with MTU 1536, the driver can well choose to ignore that.
But if the device supports only 1500, plus an .1Q extra tag, that
needs to be reflected or we lose proper VLAN support.)
- there are other protocols that also need ethernet headroom. Here's a
short list:
- MPLS
- 802.1ad
- 802.1ah
and very importantly:
- 802.1Q stacked in 802.1Q
- or any other stacking essentially
If anything, the semantics of your new callback need to be defined much
better; in reality I think we should pass down the protocol stacking to
the driver and ask for the resulting MTU.
Obviously these concerns are of the future-proofing nature, though I
wouldn't think adding this is wise when there are foreseeable
inadequacies.
-David
^ permalink raw reply
* [PULL net] vhost-net/virtio: fixes for 3.4
From: Michael S. Tsirkin @ 2012-03-23 15:28 UTC (permalink / raw)
To: David Miller
Cc: kvm, virtualization, netdev, linux-kernel, levinsasha928, mst,
nyh, nyh
Hi David,
The following changes since commit 5ffca28a4ac7abb8a254fafe6bd03b2f83667df7:
Merge git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs (2012-02-27 07:59:33 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git vhost-net
for you to fetch changes up to ea5d404655ba3b356d0c06d6a3c4f24112124522:
vhost: fix release path lockdep checks (2012-02-28 09:13:22 +0200)
----------------------------------------------------------------
vhost/virtio: fixes for 3.4
This includes a couple of vhost-net bugfixes,
and fixes tools/virtio making it useful again.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
----------------------------------------------------------------
Michael S. Tsirkin (4):
tools/virtio: add linux/module.h stub
tools/virtio: add linux/hrtimer.h stub
tools/virtio: stub out strong barriers
vhost: fix release path lockdep checks
Nadav Har'El (1):
vhost: don't forget to schedule()
drivers/vhost/net.c | 2 +-
drivers/vhost/vhost.c | 11 +++++++----
drivers/vhost/vhost.h | 2 +-
tools/virtio/linux/virtio.h | 3 +++
4 files changed, 12 insertions(+), 6 deletions(-)
create mode 100644 tools/virtio/linux/hrtimer.h
create mode 100644 tools/virtio/linux/module.h
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).