Netdev List
 help / color / mirror / Atom feed
* [PATCH 03/11] can: at91_can: don't copy data to rx'ed RTR frames
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
In-Reply-To: <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Acked-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
---
 drivers/net/can/at91_can.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index afd0f5d..5358d70 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -513,12 +513,14 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb,
 		cf->can_id = (reg_mid >> 18) & CAN_SFF_MASK;
 
 	reg_msr = at91_read(priv, AT91_MSR(mb));
-	if (reg_msr & AT91_MSR_MRTR)
-		cf->can_id |= CAN_RTR_FLAG;
 	cf->can_dlc = get_can_dlc((reg_msr >> 16) & 0xf);
 
-	*(u32 *)(cf->data + 0) = at91_read(priv, AT91_MDL(mb));
-	*(u32 *)(cf->data + 4) = at91_read(priv, AT91_MDH(mb));
+	if (reg_msr & AT91_MSR_MRTR)
+		cf->can_id |= CAN_RTR_FLAG;
+	else {
+		*(u32 *)(cf->data + 0) = at91_read(priv, AT91_MDL(mb));
+		*(u32 *)(cf->data + 4) = at91_read(priv, AT91_MDH(mb));
+	}
 
 	/* allow RX of extended frames */
 	at91_write(priv, AT91_MID(mb), AT91_MID_MIDE);
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 04/11] can: at91_can: let get_tx_* functions return unsigned int
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
In-Reply-To: <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 drivers/net/can/at91_can.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 5358d70..716f22b 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -186,17 +186,17 @@ static struct can_bittiming_const at91_bittiming_const = {
 	.brp_inc	= 1,
 };
 
-static inline int get_tx_next_mb(const struct at91_priv *priv)
+static inline unsigned int get_tx_next_mb(const struct at91_priv *priv)
 {
 	return (priv->tx_next & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST;
 }
 
-static inline int get_tx_next_prio(const struct at91_priv *priv)
+static inline unsigned int get_tx_next_prio(const struct at91_priv *priv)
 {
 	return (priv->tx_next >> AT91_NEXT_PRIO_SHIFT) & 0xf;
 }
 
-static inline int get_tx_echo_mb(const struct at91_priv *priv)
+static inline unsigned int get_tx_echo_mb(const struct at91_priv *priv)
 {
 	return (priv->tx_echo & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST;
 }
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 07/11] can: at91_can: convert derived mailbox constants into functions
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
In-Reply-To: <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

This is the first of two patches converting the at91_can driver from a
compile time mailbox setup to a dynamic one.

This patch converts all derived mailbox constants to functions.

Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 drivers/net/can/at91_can.c |  125 +++++++++++++++++++++++++++++---------------
 1 files changed, 83 insertions(+), 42 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 8699484..900ff67 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -54,18 +54,7 @@
 
 #define AT91_MB_MASK(i)		((1 << (i)) - 1)
 #define AT91_MB_RX_SPLIT	8
-#define AT91_MB_RX_LOW_LAST	(AT91_MB_RX_SPLIT - 1)
-#define AT91_MB_RX_LOW_MASK	(AT91_MB_MASK(AT91_MB_RX_SPLIT) & \
-				 ~AT91_MB_MASK(AT91_MB_RX_FIRST))
 
-#define AT91_MB_TX_NUM		(1 << AT91_MB_TX_SHIFT)
-#define AT91_MB_TX_FIRST	(AT91_MB_RX_LAST + 1)
-#define AT91_MB_TX_LAST		(AT91_MB_TX_FIRST + AT91_MB_TX_NUM - 1)
-
-#define AT91_NEXT_PRIO_SHIFT	(AT91_MB_TX_SHIFT)
-#define AT91_NEXT_PRIO_MASK	(0xf << AT91_MB_TX_SHIFT)
-#define AT91_NEXT_MB_MASK	(AT91_MB_MASK(AT91_MB_TX_SHIFT))
-#define AT91_NEXT_MASK		((AT91_MB_TX_NUM - 1) | AT91_NEXT_PRIO_MASK)
 
 /* Common registers */
 enum at91_reg {
@@ -127,12 +116,6 @@ enum at91_mb_mode {
 };
 
 /* Interrupt mask bits */
-#define AT91_IRQ_MB_RX		(AT91_MB_MASK(AT91_MB_RX_LAST + 1) & \
-				 ~AT91_MB_MASK(AT91_MB_RX_FIRST))
-#define AT91_IRQ_MB_TX		(AT91_MB_MASK(AT91_MB_TX_LAST + 1) & \
-				 ~AT91_MB_MASK(AT91_MB_TX_FIRST))
-#define AT91_IRQ_MB_ALL		(AT91_IRQ_MB_RX | AT91_IRQ_MB_TX)
-
 #define AT91_IRQ_ERRA		(1 << 16)
 #define AT91_IRQ_WARN		(1 << 17)
 #define AT91_IRQ_ERRP		(1 << 18)
@@ -185,19 +168,77 @@ static struct can_bittiming_const at91_bittiming_const = {
 	.brp_inc	= 1,
 };
 
+static inline unsigned int get_mb_rx_low_last(const struct at91_priv *priv)
+{
+	return AT91_MB_RX_SPLIT - 1;
+}
+
+static inline unsigned int get_mb_rx_low_mask(const struct at91_priv *priv)
+{
+	return AT91_MB_MASK(AT91_MB_RX_SPLIT) &
+		~AT91_MB_MASK(AT91_MB_RX_FIRST);
+}
+
+static inline unsigned int get_mb_tx_num(const struct at91_priv *priv)
+{
+	return 1 << AT91_MB_TX_SHIFT;
+}
+
+static inline unsigned int get_mb_tx_first(const struct at91_priv *priv)
+{
+	return AT91_MB_RX_LAST + 1;
+}
+
+static inline unsigned int get_mb_tx_last(const struct at91_priv *priv)
+{
+	return get_mb_tx_first(priv) + get_mb_tx_num(priv) - 1;
+}
+
+static inline unsigned int get_next_prio_shift(const struct at91_priv *priv)
+{
+	return AT91_MB_TX_SHIFT;
+}
+
+static inline unsigned int get_next_prio_mask(const struct at91_priv *priv)
+{
+	return 0xf << AT91_MB_TX_SHIFT;
+}
+
+static inline unsigned int get_next_mb_mask(const struct at91_priv *priv)
+{
+	return AT91_MB_MASK(AT91_MB_TX_SHIFT);
+}
+
+static inline unsigned int get_next_mask(const struct at91_priv *priv)
+{
+	return get_next_mb_mask(priv) | get_next_prio_mask(priv);
+}
+
+static inline unsigned int get_irq_mb_rx(const struct at91_priv *priv)
+{
+	return AT91_MB_MASK(AT91_MB_RX_LAST + 1) &
+		~AT91_MB_MASK(AT91_MB_RX_FIRST);
+}
+
+static inline unsigned int get_irq_mb_tx(const struct at91_priv *priv)
+{
+	return AT91_MB_MASK(get_mb_tx_last(priv) + 1) &
+		~AT91_MB_MASK(get_mb_tx_first(priv));
+}
+
 static inline unsigned int get_tx_next_mb(const struct at91_priv *priv)
 {
-	return (priv->tx_next & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST;
+	return (priv->tx_next & get_next_mb_mask(priv)) + get_mb_tx_first(priv);
 }
 
 static inline unsigned int get_tx_next_prio(const struct at91_priv *priv)
 {
-	return (priv->tx_next >> AT91_NEXT_PRIO_SHIFT) & 0xf;
+	return (priv->tx_next >> get_next_prio_shift(priv)) & 0xf;
 }
 
 static inline unsigned int get_tx_echo_mb(const struct at91_priv *priv)
 {
-	return (priv->tx_echo & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST;
+	return (priv->tx_echo & get_next_mb_mask(priv)) + get_mb_tx_first(priv);
 }
 
 static inline u32 at91_read(const struct at91_priv *priv, enum at91_reg reg)
@@ -275,7 +316,7 @@ static void at91_setup_mailboxes(struct net_device *dev)
 	}
 
 	/* The last 4 mailboxes are used for transmitting. */
-	for (i = AT91_MB_TX_FIRST; i <= AT91_MB_TX_LAST; i++)
+	for (i = get_mb_tx_first(priv); i <= get_mb_tx_last(priv); i++)
 		set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0);
 
 	/* Reset tx and rx helper pointers */
@@ -335,7 +376,7 @@ static void at91_chip_start(struct net_device *dev)
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
 	/* Enable interrupts */
-	reg_ier = AT91_IRQ_MB_RX | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME;
+	reg_ier = get_irq_mb_rx(priv) | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME;
 	at91_write(priv, AT91_IDR, AT91_IRQ_ALL);
 	at91_write(priv, AT91_IER, reg_ier);
 }
@@ -416,7 +457,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	stats->tx_bytes += cf->can_dlc;
 
 	/* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */
-	can_put_echo_skb(skb, dev, mb - AT91_MB_TX_FIRST);
+	can_put_echo_skb(skb, dev, mb - get_mb_tx_first(priv));
 
 	/*
 	 * we have to stop the queue and deliver all messages in case
@@ -429,7 +470,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	priv->tx_next++;
 	if (!(at91_read(priv, AT91_MSR(get_tx_next_mb(priv))) &
 	      AT91_MSR_MRDY) ||
-	    (priv->tx_next & AT91_NEXT_MASK) == 0)
+	    (priv->tx_next & get_next_mask(priv)) == 0)
 		netif_stop_queue(dev);
 
 	/* Enable interrupt for this mailbox */
@@ -446,7 +487,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
  */
 static inline void at91_activate_rx_low(const struct at91_priv *priv)
 {
-	u32 mask = AT91_MB_RX_LOW_MASK;
+	u32 mask = get_mb_rx_low_mask(priv);
 	at91_write(priv, AT91_TCR, mask);
 }
 
@@ -611,23 +652,23 @@ static int at91_poll_rx(struct net_device *dev, int quota)
 	unsigned int mb;
 	int received = 0;
 
-	if (priv->rx_next > AT91_MB_RX_LOW_LAST &&
-	    reg_sr & AT91_MB_RX_LOW_MASK)
+	if (priv->rx_next > get_mb_rx_low_last(priv) &&
+	    reg_sr & get_mb_rx_low_mask(priv))
 		netdev_info(dev,
 			"order of incoming frames cannot be guaranteed\n");
 
  again:
-	for (mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, priv->rx_next);
-	     mb < AT91_MB_RX_LAST + 1 && quota > 0;
+	for (mb = find_next_bit(addr, get_mb_tx_first(priv), priv->rx_next);
+	     mb < get_mb_tx_first(priv) && quota > 0;
 	     reg_sr = at91_read(priv, AT91_SR),
-	     mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, ++priv->rx_next)) {
+	     mb = find_next_bit(addr, get_mb_tx_first(priv), ++priv->rx_next)) {
 		at91_read_msg(dev, mb);
 
 		/* reactivate mailboxes */
-		if (mb == AT91_MB_RX_LOW_LAST)
+		if (mb == get_mb_rx_low_last(priv))
 			/* all lower mailboxed, if just finished it */
 			at91_activate_rx_low(priv);
-		else if (mb > AT91_MB_RX_LOW_LAST)
+		else if (mb > get_mb_rx_low_last(priv))
 			/* only the mailbox we read */
 			at91_activate_rx_mb(priv, mb);
 
@@ -636,7 +677,7 @@ static int at91_poll_rx(struct net_device *dev, int quota)
 	}
 
 	/* upper group completed, look again in lower */
-	if (priv->rx_next > AT91_MB_RX_LOW_LAST &&
+	if (priv->rx_next > get_mb_rx_low_last(priv) &&
 	    quota > 0 && mb > AT91_MB_RX_LAST) {
 		priv->rx_next = AT91_MB_RX_FIRST;
 		goto again;
@@ -721,7 +762,7 @@ static int at91_poll(struct napi_struct *napi, int quota)
 	u32 reg_sr = at91_read(priv, AT91_SR);
 	int work_done = 0;
 
-	if (reg_sr & AT91_IRQ_MB_RX)
+	if (reg_sr & get_irq_mb_rx(priv))
 		work_done += at91_poll_rx(dev, quota - work_done);
 
 	/*
@@ -735,7 +776,7 @@ static int at91_poll(struct napi_struct *napi, int quota)
 	if (work_done < quota) {
 		/* enable IRQs for frame errors and all mailboxes >= rx_next */
 		u32 reg_ier = AT91_IRQ_ERR_FRAME;
-		reg_ier |= AT91_IRQ_MB_RX & ~AT91_MB_MASK(priv->rx_next);
+		reg_ier |= get_irq_mb_rx(priv) & ~AT91_MB_MASK(priv->rx_next);
 
 		napi_complete(napi);
 		at91_write(priv, AT91_IER, reg_ier);
@@ -784,7 +825,7 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr)
 		if (likely(reg_msr & AT91_MSR_MRDY &&
 			   ~reg_msr & AT91_MSR_MABT)) {
 			/* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */
-			can_get_echo_skb(dev, mb - AT91_MB_TX_FIRST);
+			can_get_echo_skb(dev, mb - get_mb_tx_first(priv));
 			dev->stats.tx_packets++;
 		}
 	}
@@ -794,8 +835,8 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr)
 	 * we get a TX int for the last can frame directly before a
 	 * wrap around.
 	 */
-	if ((priv->tx_next & AT91_NEXT_MASK) != 0 ||
-	    (priv->tx_echo & AT91_NEXT_MASK) == 0)
+	if ((priv->tx_next & get_next_mask(priv)) != 0 ||
+	    (priv->tx_echo & get_next_mask(priv)) == 0)
 		netif_wake_queue(dev);
 }
 
@@ -969,19 +1010,19 @@ static irqreturn_t at91_irq(int irq, void *dev_id)
 	handled = IRQ_HANDLED;
 
 	/* Receive or error interrupt? -> napi */
-	if (reg_sr & (AT91_IRQ_MB_RX | AT91_IRQ_ERR_FRAME)) {
+	if (reg_sr & (get_irq_mb_rx(priv) | AT91_IRQ_ERR_FRAME)) {
 		/*
 		 * The error bits are clear on read,
 		 * save for later use.
 		 */
 		priv->reg_sr = reg_sr;
 		at91_write(priv, AT91_IDR,
-			   AT91_IRQ_MB_RX | AT91_IRQ_ERR_FRAME);
+			   get_irq_mb_rx(priv) | AT91_IRQ_ERR_FRAME);
 		napi_schedule(&priv->napi);
 	}
 
 	/* Transmission complete interrupt */
-	if (reg_sr & AT91_IRQ_MB_TX)
+	if (reg_sr & get_irq_mb_tx(priv))
 		at91_irq_tx(dev, reg_sr);
 
 	at91_irq_err(dev);
@@ -1158,7 +1199,7 @@ static int __devinit at91_can_probe(struct platform_device *pdev)
 		goto exit_release;
 	}
 
-	dev = alloc_candev(sizeof(struct at91_priv), AT91_MB_TX_NUM);
+	dev = alloc_candev(sizeof(struct at91_priv), 1 << AT91_MB_TX_SHIFT);
 	if (!dev) {
 		err = -ENOMEM;
 		goto exit_iounmap;
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 08/11] can: at91_can: add id_table and convert prime mailbox constats to functions
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
In-Reply-To: <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

This is the second of two patches converting the at91_can driver from a
compile time mailbox setup to a dynamic one.

This patch first adds a id_table to the platform driver. Depending on the
driver_data the constants for the mailbox setup is selected. Then all
remaining prime mailbox constants are converted to functions, using the
run time selected mailbox constants.

Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 drivers/net/can/at91_can.c |  137 +++++++++++++++++++++++++++++++------------
 1 files changed, 99 insertions(+), 38 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 900ff67..248e03f 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -41,20 +41,7 @@
 
 #include <mach/board.h>
 
-#define AT91_NAPI_WEIGHT	11
-
-/*
- * RX/TX Mailbox split
- * don't dare to touch
- */
-#define AT91_MB_TX_SHIFT	2
-
-#define AT91_MB_RX_FIRST	1
-#define AT91_MB_RX_LAST		11
-
 #define AT91_MB_MASK(i)		((1 << (i)) - 1)
-#define AT91_MB_RX_SPLIT	8
-
 
 /* Common registers */
 enum at91_reg {
@@ -138,6 +125,18 @@ enum at91_mb_mode {
 
 #define AT91_IRQ_ALL		(0x1fffffff)
 
+enum at91_devtype {
+	AT91_DEVTYPE_SAM9263,
+};
+
+struct at91_devtype_data {
+	unsigned int rx_first;
+	unsigned int rx_split;
+	unsigned int rx_last;
+	unsigned int tx_shift;
+	enum at91_devtype type;
+};
+
 struct at91_priv {
 	struct can_priv can;		/* must be the first member! */
 	struct net_device *dev;
@@ -149,6 +148,7 @@ struct at91_priv {
 	unsigned int tx_next;
 	unsigned int tx_echo;
 	unsigned int rx_next;
+	struct at91_devtype_data devtype_data;
 
 	struct clk *clk;
 	struct at91_can_data *pdata;
@@ -156,6 +156,15 @@ struct at91_priv {
 	canid_t mb0_id;
 };
 
+static const struct at91_devtype_data at91_devtype_data[] __devinitconst = {
+	[AT91_DEVTYPE_SAM9263] = {
+		.rx_first = 1,
+		.rx_split = 8,
+		.rx_last = 11,
+		.tx_shift = 2,
+	},
+};
+
 static struct can_bittiming_const at91_bittiming_const = {
 	.name		= KBUILD_MODNAME,
 	.tseg1_min	= 4,
@@ -168,25 +177,58 @@ static struct can_bittiming_const at91_bittiming_const = {
 	.brp_inc	= 1,
 };
 
+#define AT91_IS(_model) \
+static inline int at91_is_sam##_model(const struct at91_priv *priv) \
+{ \
+	return priv->devtype_data.type == AT91_DEVTYPE_SAM##_model; \
+}
+
+AT91_IS(9263);
+
+static inline unsigned int get_mb_rx_first(const struct at91_priv *priv)
+{
+	return priv->devtype_data.rx_first;
+}
+
+static inline unsigned int get_mb_rx_last(const struct at91_priv *priv)
+{
+	return priv->devtype_data.rx_last;
+}
+
+static inline unsigned int get_mb_rx_split(const struct at91_priv *priv)
+{
+	return priv->devtype_data.rx_split;
+}
+
+static inline unsigned int get_mb_rx_num(const struct at91_priv *priv)
+{
+	return get_mb_rx_last(priv) - get_mb_rx_first(priv) + 1;
+}
+
 static inline unsigned int get_mb_rx_low_last(const struct at91_priv *priv)
 {
-	return AT91_MB_RX_SPLIT - 1;
+	return get_mb_rx_split(priv) - 1;
 }
 
 static inline unsigned int get_mb_rx_low_mask(const struct at91_priv *priv)
 {
-	return AT91_MB_MASK(AT91_MB_RX_SPLIT) &
-		~AT91_MB_MASK(AT91_MB_RX_FIRST);
+	return AT91_MB_MASK(get_mb_rx_split(priv)) &
+		~AT91_MB_MASK(get_mb_rx_first(priv));
+}
+
+static inline unsigned int get_mb_tx_shift(const struct at91_priv *priv)
+{
+	return priv->devtype_data.tx_shift;
 }
 
 static inline unsigned int get_mb_tx_num(const struct at91_priv *priv)
 {
-	return 1 << AT91_MB_TX_SHIFT;
+	return 1 << get_mb_tx_shift(priv);
 }
 
 static inline unsigned int get_mb_tx_first(const struct at91_priv *priv)
 {
-	return AT91_MB_RX_LAST + 1;
+	return get_mb_rx_last(priv) + 1;
 }
 
 static inline unsigned int get_mb_tx_last(const struct at91_priv *priv)
@@ -196,17 +238,17 @@ static inline unsigned int get_mb_tx_last(const struct at91_priv *priv)
 
 static inline unsigned int get_next_prio_shift(const struct at91_priv *priv)
 {
-	return AT91_MB_TX_SHIFT;
+	return get_mb_tx_shift(priv);
 }
 
 static inline unsigned int get_next_prio_mask(const struct at91_priv *priv)
 {
-	return 0xf << AT91_MB_TX_SHIFT;
+	return 0xf << get_mb_tx_shift(priv);
 }
 
 static inline unsigned int get_next_mb_mask(const struct at91_priv *priv)
 {
-	return AT91_MB_MASK(AT91_MB_TX_SHIFT);
+	return AT91_MB_MASK(get_mb_tx_shift(priv));
 }
 
 static inline unsigned int get_next_mask(const struct at91_priv *priv)
@@ -216,8 +258,8 @@ static inline unsigned int get_next_mask(const struct at91_priv *priv)
 
 static inline unsigned int get_irq_mb_rx(const struct at91_priv *priv)
 {
-	return AT91_MB_MASK(AT91_MB_RX_LAST + 1) &
-		~AT91_MB_MASK(AT91_MB_RX_FIRST);
+	return AT91_MB_MASK(get_mb_rx_last(priv) + 1) &
+		~AT91_MB_MASK(get_mb_rx_first(priv));
 }
 
 static inline unsigned int get_irq_mb_tx(const struct at91_priv *priv)
@@ -299,18 +341,18 @@ static void at91_setup_mailboxes(struct net_device *dev)
 	 * overflow.
 	 */
 	reg_mid = at91_can_id_to_reg_mid(priv->mb0_id);
-	for (i = 0; i < AT91_MB_RX_FIRST; i++) {
+	for (i = 0; i < get_mb_rx_first(priv); i++) {
 		set_mb_mode(priv, i, AT91_MB_MODE_DISABLED);
 		at91_write(priv, AT91_MID(i), reg_mid);
 		at91_write(priv, AT91_MCR(i), 0x0);	/* clear dlc */
 	}
 
-	for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++)
+	for (i = get_mb_rx_first(priv); i < get_mb_rx_last(priv); i++)
 		set_mb_mode(priv, i, AT91_MB_MODE_RX);
-	set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR);
+	set_mb_mode(priv, get_mb_rx_last(priv), AT91_MB_MODE_RX_OVRWR);
 
 	/* reset acceptance mask and id register */
-	for (i = AT91_MB_RX_FIRST; i <= AT91_MB_RX_LAST; i++) {
+	for (i = get_mb_rx_first(priv); i <= get_mb_rx_last(priv); i++) {
 		at91_write(priv, AT91_MAM(i), 0x0);
 		at91_write(priv, AT91_MID(i), AT91_MID_MIDE);
 	}
@@ -321,7 +363,7 @@ static void at91_setup_mailboxes(struct net_device *dev)
 
 	/* Reset tx and rx helper pointers */
 	priv->tx_next = priv->tx_echo = 0;
-	priv->rx_next = AT91_MB_RX_FIRST;
+	priv->rx_next = get_mb_rx_first(priv);
 }
 
 static int at91_set_bittiming(struct net_device *dev)
@@ -415,8 +457,8 @@ static void at91_chip_stop(struct net_device *dev, enum can_state state)
  * mailbox, but without the offset AT91_MB_TX_FIRST. The lower bits
  * encode the mailbox number, the upper 4 bits the mailbox priority:
  *
- * priv->tx_next = (prio << AT91_NEXT_PRIO_SHIFT) |
- *                 (mb - AT91_MB_TX_FIRST);
+ * priv->tx_next = (prio << get_next_prio_shift(priv)) |
+ *                 (mb - get_mb_tx_first(priv));
  *
  */
 static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -565,7 +607,7 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb,
 	/* allow RX of extended frames */
 	at91_write(priv, AT91_MID(mb), AT91_MID_MIDE);
 
-	if (unlikely(mb == AT91_MB_RX_LAST && reg_msr & AT91_MSR_MMI))
+	if (unlikely(mb == get_mb_rx_last(priv) && reg_msr & AT91_MSR_MMI))
 		at91_rx_overflow_err(dev);
 }
 
@@ -603,8 +645,9 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb)
  *
  * Theory of Operation:
  *
- * 11 of the 16 mailboxes on the chip are reserved for RX. we split
- * them into 2 groups. The lower group holds 7 and upper 4 mailboxes.
+ * About 3/4 of the mailboxes (get_mb_rx_first()...get_mb_rx_last())
+ * on the chip are reserved for RX. We split them into 2 groups. The
+ * lower group ranges from get_mb_rx_first() to get_mb_rx_low_last().
  *
  * Like it or not, but the chip always saves a received CAN message
  * into the first free mailbox it finds (starting with the
@@ -678,8 +721,8 @@ static int at91_poll_rx(struct net_device *dev, int quota)
 
 	/* upper group completed, look again in lower */
 	if (priv->rx_next > get_mb_rx_low_last(priv) &&
-	    quota > 0 && mb > AT91_MB_RX_LAST) {
-		priv->rx_next = AT91_MB_RX_FIRST;
+	    quota > 0 && mb > get_mb_rx_last(priv)) {
+		priv->rx_next = get_mb_rx_first(priv);
 		goto again;
 	}
 
@@ -1165,6 +1208,8 @@ static struct attribute_group at91_sysfs_attr_group = {
 
 static int __devinit at91_can_probe(struct platform_device *pdev)
 {
+	const struct at91_devtype_data *devtype_data;
+	enum at91_devtype devtype;
 	struct net_device *dev;
 	struct at91_priv *priv;
 	struct resource *res;
@@ -1172,6 +1217,9 @@ static int __devinit at91_can_probe(struct platform_device *pdev)
 	void __iomem *addr;
 	int err, irq;
 
+	devtype = pdev->id_entry->driver_data;
+	devtype_data = &at91_devtype_data[devtype];
+
 	clk = clk_get(&pdev->dev, "can_clk");
 	if (IS_ERR(clk)) {
 		dev_err(&pdev->dev, "no clock defined\n");
@@ -1199,7 +1247,8 @@ static int __devinit at91_can_probe(struct platform_device *pdev)
 		goto exit_release;
 	}
 
-	dev = alloc_candev(sizeof(struct at91_priv), 1 << AT91_MB_TX_SHIFT);
+	dev = alloc_candev(sizeof(struct at91_priv),
+			   1 << devtype_data->tx_shift);
 	if (!dev) {
 		err = -ENOMEM;
 		goto exit_iounmap;
@@ -1216,13 +1265,15 @@ static int __devinit at91_can_probe(struct platform_device *pdev)
 	priv->can.do_set_mode = at91_set_mode;
 	priv->can.do_get_berr_counter = at91_get_berr_counter;
 	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
-	priv->reg_base = addr;
 	priv->dev = dev;
+	priv->reg_base = addr;
+	priv->devtype_data = *devtype_data;
+	priv->devtype_data.type = devtype;
 	priv->clk = clk;
 	priv->pdata = pdev->dev.platform_data;
 	priv->mb0_id = 0x7ff;
 
-	netif_napi_add(dev, &priv->napi, at91_poll, AT91_NAPI_WEIGHT);
+	netif_napi_add(dev, &priv->napi, at91_poll, get_mb_rx_num(priv));
 
 	dev_set_drvdata(&pdev->dev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
@@ -1272,6 +1323,15 @@ static int __devexit at91_can_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct platform_device_id at91_can_id_table[] = {
+	{
+		.name = "at91_can",
+		.driver_data = AT91_DEVTYPE_SAM9263,
+	}, {
+		/* sentinel */
+	}
+};
+
 static struct platform_driver at91_can_driver = {
 	.probe = at91_can_probe,
 	.remove = __devexit_p(at91_can_remove),
@@ -1279,6 +1339,7 @@ static struct platform_driver at91_can_driver = {
 		.name = KBUILD_MODNAME,
 		.owner = THIS_MODULE,
 	},
+	.id_table = at91_can_id_table,
 };
 
 static int __init at91_can_module_init(void)
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 10/11] can: at91_can: add support for the AT91SAM9X5 SOCs
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
In-Reply-To: <1307367780-30715-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

The AT91SAM9X5 SOCs have a similar CAN core, but they only have 8 compared
to 16 mailboxes on the AT91SAM9263 SOC. Another difference is that the bits
defining the state of the CAN core are cleared on read, thus the driver
has to derive the state by looking at the error counters.

Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 drivers/net/can/at91_can.c |   69 +++++++++++++++++++++++++++++++++++---------
 1 files changed, 55 insertions(+), 14 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 2b97281..121ede6 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -127,6 +127,7 @@ enum at91_mb_mode {
 
 enum at91_devtype {
 	AT91_DEVTYPE_SAM9263,
+	AT91_DEVTYPE_SAM9X5,
 };
 
 struct at91_devtype_data {
@@ -163,6 +164,12 @@ static const struct at91_devtype_data at91_devtype_data[] __devinitconst = {
 		.rx_last = 11,
 		.tx_shift = 2,
 	},
+	[AT91_DEVTYPE_SAM9X5] = {
+		.rx_first = 0,
+		.rx_split = 4,
+		.rx_last = 5,
+		.tx_shift = 1,
+	},
 };
 
 static struct can_bittiming_const at91_bittiming_const = {
@@ -184,6 +191,7 @@ static inline int at91_is_sam##_model(const struct at91_priv *priv) \
 }
 
 AT91_IS(9263);
+AT91_IS(9X5);
 
 static inline unsigned int get_mb_rx_first(const struct at91_priv *priv)
 {
@@ -991,6 +999,29 @@ static void at91_irq_err_state(struct net_device *dev,
 	at91_write(priv, AT91_IER, reg_ier);
 }
 
+static int at91_get_state_by_bec(const struct net_device *dev,
+		enum can_state *state)
+{
+	struct can_berr_counter bec;
+	int err;
+
+	err = at91_get_berr_counter(dev, &bec);
+	if (err)
+		return err;
+
+	if (bec.txerr < 96 && bec.rxerr < 96)
+		*state = CAN_STATE_ERROR_ACTIVE;
+	else if (bec.txerr < 128 && bec.rxerr < 128)
+		*state = CAN_STATE_ERROR_WARNING;
+	else if (bec.txerr < 256 && bec.rxerr < 256)
+		*state = CAN_STATE_ERROR_PASSIVE;
+	else
+		*state = CAN_STATE_BUS_OFF;
+
+	return 0;
+}
+
+
 static void at91_irq_err(struct net_device *dev)
 {
 	struct at91_priv *priv = netdev_priv(dev);
@@ -998,21 +1029,28 @@ static void at91_irq_err(struct net_device *dev)
 	struct can_frame *cf;
 	enum can_state new_state;
 	u32 reg_sr;
+	int err;
 
-	reg_sr = at91_read(priv, AT91_SR);
-
-	/* we need to look at the unmasked reg_sr */
-	if (unlikely(reg_sr & AT91_IRQ_BOFF))
-		new_state = CAN_STATE_BUS_OFF;
-	else if (unlikely(reg_sr & AT91_IRQ_ERRP))
-		new_state = CAN_STATE_ERROR_PASSIVE;
-	else if (unlikely(reg_sr & AT91_IRQ_WARN))
-		new_state = CAN_STATE_ERROR_WARNING;
-	else if (likely(reg_sr & AT91_IRQ_ERRA))
-		new_state = CAN_STATE_ERROR_ACTIVE;
-	else {
-		netdev_err(dev, "BUG! hardware in undefined state\n");
-		return;
+	if (at91_is_sam9263(priv)) {
+		reg_sr = at91_read(priv, AT91_SR);
+
+		/* we need to look at the unmasked reg_sr */
+		if (unlikely(reg_sr & AT91_IRQ_BOFF))
+			new_state = CAN_STATE_BUS_OFF;
+		else if (unlikely(reg_sr & AT91_IRQ_ERRP))
+			new_state = CAN_STATE_ERROR_PASSIVE;
+		else if (unlikely(reg_sr & AT91_IRQ_WARN))
+			new_state = CAN_STATE_ERROR_WARNING;
+		else if (likely(reg_sr & AT91_IRQ_ERRA))
+			new_state = CAN_STATE_ERROR_ACTIVE;
+		else {
+			netdev_err(dev, "BUG! hardware in undefined state\n");
+			return;
+		}
+	} else {
+		err = at91_get_state_by_bec(dev, &new_state);
+		if (err)
+			return;
 	}
 
 	/* state hasn't changed */
@@ -1330,6 +1368,9 @@ static const struct platform_device_id at91_can_id_table[] = {
 		.name = "at91_can",
 		.driver_data = AT91_DEVTYPE_SAM9263,
 	}, {
+		.name = "at91sam9x5_can",
+		.driver_data = AT91_DEVTYPE_SAM9X5,
+	}, {
 		/* sentinel */
 	}
 };
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 06/11] can: at91_can: rename AT91_MB_RX_MASK to AT91_IRQ_MB_RX
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
  To: davem; +Cc: socketcan-core, netdev, Marc Kleine-Budde
In-Reply-To: <1307367780-30715-1-git-send-email-mkl@pengutronix.de>

... and use it for AT91_NEXT_MB_MASK,
AT91_IRQ_MB_RX and AT91_IRQ_MB_RX, too.

Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 9ce00fa..8699484 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -52,11 +52,11 @@
 #define AT91_MB_RX_FIRST	1
 #define AT91_MB_RX_LAST		11
 
-#define AT91_MB_RX_MASK(i)	((1 << (i)) - 1)
+#define AT91_MB_MASK(i)		((1 << (i)) - 1)
 #define AT91_MB_RX_SPLIT	8
 #define AT91_MB_RX_LOW_LAST	(AT91_MB_RX_SPLIT - 1)
-#define AT91_MB_RX_LOW_MASK	(AT91_MB_RX_MASK(AT91_MB_RX_SPLIT) & \
-				 ~AT91_MB_RX_MASK(AT91_MB_RX_FIRST))
+#define AT91_MB_RX_LOW_MASK	(AT91_MB_MASK(AT91_MB_RX_SPLIT) & \
+				 ~AT91_MB_MASK(AT91_MB_RX_FIRST))
 
 #define AT91_MB_TX_NUM		(1 << AT91_MB_TX_SHIFT)
 #define AT91_MB_TX_FIRST	(AT91_MB_RX_LAST + 1)
@@ -64,7 +64,7 @@
 
 #define AT91_NEXT_PRIO_SHIFT	(AT91_MB_TX_SHIFT)
 #define AT91_NEXT_PRIO_MASK	(0xf << AT91_MB_TX_SHIFT)
-#define AT91_NEXT_MB_MASK	(AT91_MB_TX_NUM - 1)
+#define AT91_NEXT_MB_MASK	(AT91_MB_MASK(AT91_MB_TX_SHIFT))
 #define AT91_NEXT_MASK		((AT91_MB_TX_NUM - 1) | AT91_NEXT_PRIO_MASK)
 
 /* Common registers */
@@ -127,10 +127,10 @@ enum at91_mb_mode {
 };
 
 /* Interrupt mask bits */
-#define AT91_IRQ_MB_RX		((1 << (AT91_MB_RX_LAST + 1)) \
-				 - (1 << AT91_MB_RX_FIRST))
-#define AT91_IRQ_MB_TX		((1 << (AT91_MB_TX_LAST + 1)) \
-				 - (1 << AT91_MB_TX_FIRST))
+#define AT91_IRQ_MB_RX		(AT91_MB_MASK(AT91_MB_RX_LAST + 1) & \
+				 ~AT91_MB_MASK(AT91_MB_RX_FIRST))
+#define AT91_IRQ_MB_TX		(AT91_MB_MASK(AT91_MB_TX_LAST + 1) & \
+				 ~AT91_MB_MASK(AT91_MB_TX_FIRST))
 #define AT91_IRQ_MB_ALL		(AT91_IRQ_MB_RX | AT91_IRQ_MB_TX)
 
 #define AT91_IRQ_ERRA		(1 << 16)
@@ -735,7 +735,7 @@ static int at91_poll(struct napi_struct *napi, int quota)
 	if (work_done < quota) {
 		/* enable IRQs for frame errors and all mailboxes >= rx_next */
 		u32 reg_ier = AT91_IRQ_ERR_FRAME;
-		reg_ier |= AT91_IRQ_MB_RX & ~AT91_MB_RX_MASK(priv->rx_next);
+		reg_ier |= AT91_IRQ_MB_RX & ~AT91_MB_MASK(priv->rx_next);
 
 		napi_complete(napi);
 		at91_write(priv, AT91_IER, reg_ier);
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 09/11] can: at91_can: register mb0 sysfs entry only on at91sam9263
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
  To: davem; +Cc: socketcan-core, netdev, Marc Kleine-Budde
In-Reply-To: <1307367780-30715-1-git-send-email-mkl@pengutronix.de>

This patch prepares the driver for the at91sam9X5 processors,
which don't have the mb0 bug.
(See commit 3a5655a5b545e9647c3437473ee3d815fe1b9050 for more details.)

Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 248e03f..2b97281 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -1257,7 +1257,6 @@ static int __devinit at91_can_probe(struct platform_device *pdev)
 	dev->netdev_ops	= &at91_netdev_ops;
 	dev->irq = irq;
 	dev->flags |= IFF_ECHO;
-	dev->sysfs_groups[0] = &at91_sysfs_attr_group;
 
 	priv = netdev_priv(dev);
 	priv->can.clock.freq = clk_get_rate(clk);
@@ -1275,6 +1274,9 @@ static int __devinit at91_can_probe(struct platform_device *pdev)
 
 	netif_napi_add(dev, &priv->napi, at91_poll, get_mb_rx_num(priv));
 
+	if (at91_is_sam9263(priv))
+		dev->sysfs_groups[0] = &at91_sysfs_attr_group;
+
 	dev_set_drvdata(&pdev->dev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 11/11] net/can: allow CAN_AT91 on AT91SAM9X5
From: Marc Kleine-Budde @ 2011-06-06 13:43 UTC (permalink / raw)
  To: davem; +Cc: socketcan-core, netdev, Uwe Kleine-König, Marc Kleine-Budde
In-Reply-To: <1307367780-30715-1-git-send-email-mkl@pengutronix.de>

From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/Kconfig |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 1d699e3..bbf06f7 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -58,9 +58,10 @@ config CAN_CALC_BITTIMING
 
 config CAN_AT91
 	tristate "Atmel AT91 onchip CAN controller"
-	depends on CAN_DEV && ARCH_AT91SAM9263
+	depends on CAN_DEV && (ARCH_AT91SAM9263 || ARCH_AT91SAM9X5)
 	---help---
-	  This is a driver for the SoC CAN controller in Atmel's AT91SAM9263.
+	  This is a driver for the SoC CAN controller in Atmel's AT91SAM9263
+	  and AT91SAM9X5 processors.
 
 config CAN_TI_HECC
 	depends on CAN_DEV && ARCH_OMAP3
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 05/11] can: at91_can: directly define AT91_MB_RX_LAST
From: Marc Kleine-Budde @ 2011-06-06 13:42 UTC (permalink / raw)
  To: davem; +Cc: socketcan-core, netdev, Marc Kleine-Budde
In-Reply-To: <1307367780-30715-1-git-send-email-mkl@pengutronix.de>

...instead of deriving it from AT91_MB_RX_FIRST and AT91_MB_RX_NUM.
This removes a level of computation, when switching the driver from
compile time constants to runtime values.

Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 716f22b..9ce00fa 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -47,11 +47,10 @@
  * RX/TX Mailbox split
  * don't dare to touch
  */
-#define AT91_MB_RX_NUM		11
 #define AT91_MB_TX_SHIFT	2
 
 #define AT91_MB_RX_FIRST	1
-#define AT91_MB_RX_LAST		(AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1)
+#define AT91_MB_RX_LAST		11
 
 #define AT91_MB_RX_MASK(i)	((1 << (i)) - 1)
 #define AT91_MB_RX_SPLIT	8
-- 
1.7.4.1


^ permalink raw reply related

* Multicast IP packet routed between 2 ports nic on the same host
From: BONNEAU Guy @ 2011-06-06 13:40 UTC (permalink / raw)
  To: netdev@vger.kernel.org

I am trying to receive multicast data packets from a multicast router to my Linux Ubuntu Desktop Workstation using kernel 2.6.35. The Linux Desktop has an Intel 82576 dual NIC adapter. Each NIC is configured to receive IP data from 2 different subnet. One is from 172.30.8.xx and another one from 10.0.xx.xx. Multicast IP data can only be received from 172.30.8.xx since there is no multicast source on subnet 10.0.xx.xx and IT that administrates the subnet 10.0.xx.xx disabled multicast capability of the switches and routers sitting on that subnet. The subnet 172.30.8.xx has multicast source broadcasting on multicast group 239.255.200.200:8000. 

I am using the application mreceived (version 2.2) from : http://www.cs.virginia.edu/~mngroup/software/ to test the network multicast set-up and capability of my Ubuntu Desktop Workstation. 

I open a first console and I use mreceive to join multicast group 239.255.200.200:8000 to receive multicast data from subnet 10.0.xx.xx using the console command : ./mreceive -g 239.255.200.200 -p 8000 -i 10.0.9.164 to the eth0 adapter of my workstation. The application is idle and no multicast data is received. This is the expected behaviour.

I open a second console and I use mreceive to join the same multicast group 239.255.200.200:8000 to receive multicast data from subnet 172.30.8.xx using the console command : ./mreceive -g 239.255.200.200 -p 8000 -i 172.30.8.31 to the eth1 adapter of my workstation. The application starts to receive multicast data and advertises the data received. This is also the expected behaviour.

Now this is where the problem begins. As soon as the multicast data begin to be received on the eth1 adapter the first console begins to advertise multicast data received on eth0 adapter. I am well aware that the Linux kernel implements a multicast level 2 routing capability. Thus at first glance this seems to be the expected behaviour. However... I have forwarding disabled as well as mc_forwarding disabled and rp_filter is enabled for both adapters. Thus I don't expect the kernel to forward the multicast data from eth1 to eth0. 

I have recompiled the kernel with IP Multicast Routing disabled and got the same behavior. I also tried kernel 2.6.38 and had the same issue.

At this point I am inclined to think that the kernel multicast routing might have an issue? I might have missing a network configuration setting but at this point I am baffled.  I checked the kernel bugbase with the multicast tagging and couldn't find a filled bug regarding this matter. The only remaining options for me are to fill a bug and trace the kernel code (ipmr.c) to understand what going on. Can someone shade light on this? Is this an expected behavior or an issue?

Thanks
GB 
      

^ permalink raw reply

* Re: Bad behaviour when unintentionally mixing ipv4 and ipv6 addresses
From: Reinhard Max @ 2011-06-06 13:47 UTC (permalink / raw)
  To: David Miller; +Cc: meissner, netdev
In-Reply-To: <20110601.210359.2079286191194442010.davem@davemloft.net>


On Wed, 1 Jun 2011 at 21:03, David Miller wrote:

> Since we haven't been validating the sin_family field for 18+ years, 
> the chance to break some applications is very real.
>
> But I think it's more important to fix this (and force any broken 
> apps to set sin_family correctly).  So I will apply this, thanks.

I think a corresponding check should also go into inet6_bind() in 
net/ipv6/af_inet6.c .


cu
 	Reinhard

^ permalink raw reply

* Re: ethtool -E rejects magic >= 80000000
From: Jens Rottmann @ 2011-06-06 13:39 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: Martin Hein, Jeff Garzik, netdev
In-Reply-To: <1307357436.2765.20.camel@bwh-desktop>

Ben,

> Please can you test the attached patch ...

Tested on top of ethtool 2.6.39, works fine.

Thanks!
Jens

^ permalink raw reply

* Re: Multicast IP packet routed between 2 ports nic on the same host
From: Eric Dumazet @ 2011-06-06 14:09 UTC (permalink / raw)
  To: BONNEAU Guy; +Cc: netdev@vger.kernel.org
In-Reply-To: <24665DDC0D7CF047BD6471A56E615EA628ABF4DE@CA-OPS-MAILBOX.miranda.com>

Le lundi 06 juin 2011 à 13:40 +0000, BONNEAU Guy a écrit :
> I am trying to receive multicast data packets from a multicast router
> to my Linux Ubuntu Desktop Workstation using kernel 2.6.35. The Linux
> Desktop has an Intel 82576 dual NIC adapter. Each NIC is configured to
> receive IP data from 2 different subnet. One is from 172.30.8.xx and
> another one from 10.0.xx.xx. Multicast IP data can only be received
> from 172.30.8.xx since there is no multicast source on subnet
> 10.0.xx.xx and IT that administrates the subnet 10.0.xx.xx disabled
> multicast capability of the switches and routers sitting on that
> subnet. The subnet 172.30.8.xx has multicast source broadcasting on
> multicast group 239.255.200.200:8000. 
> 

Hi

Not clear if eth0 and eth1 are on both networks ?

Please send us

ip link
ip addr
ip ro

Thanks

> I am using the application mreceived (version 2.2) from :
> http://www.cs.virginia.edu/~mngroup/software/ to test the network
> multicast set-up and capability of my Ubuntu Desktop Workstation. 
> 
> I open a first console and I use mreceive to join multicast group
> 239.255.200.200:8000 to receive multicast data from subnet 10.0.xx.xx
> using the console command : ./mreceive -g 239.255.200.200 -p 8000 -i
> 10.0.9.164 to the eth0 adapter of my workstation. The application is
> idle and no multicast data is received. This is the expected
> behaviour.
> 
> I open a second console and I use mreceive to join the same multicast
> group 239.255.200.200:8000 to receive multicast data from subnet
> 172.30.8.xx using the console command : ./mreceive -g 239.255.200.200
> -p 8000 -i 172.30.8.31 to the eth1 adapter of my workstation. The
> application starts to receive multicast data and advertises the data
> received. This is also the expected behaviour.
> 
> Now this is where the problem begins. As soon as the multicast data
> begin to be received on the eth1 adapter the first console begins to
> advertise multicast data received on eth0 adapter. I am well aware
> that the Linux kernel implements a multicast level 2 routing
> capability. Thus at first glance this seems to be the expected
> behaviour. However... I have forwarding disabled as well as
> mc_forwarding disabled and rp_filter is enabled for both adapters.
> Thus I don't expect the kernel to forward the multicast data from eth1
> to eth0. 
> 
> I have recompiled the kernel with IP Multicast Routing disabled and
> got the same behavior. I also tried kernel 2.6.38 and had the same
> issue.
> 
> At this point I am inclined to think that the kernel multicast routing
> might have an issue? I might have missing a network configuration
> setting but at this point I am baffled.  I checked the kernel bugbase
> with the multicast tagging and couldn't find a filled bug regarding
> this matter. The only remaining options for me are to fill a bug and
> trace the kernel code (ipmr.c) to understand what going on. Can
> someone shade light on this? Is this an expected behavior or an issue?
> 
> Thanks
> GB 
>      



^ permalink raw reply

* Re: bridge/netfilter: regression in 2.6.39.1
From: Eric Dumazet @ 2011-06-06 14:26 UTC (permalink / raw)
  To: Alexander Holler
  Cc: Neil Horman, linux-kernel, David Miller, Herbert Xu, netdev
In-Reply-To: <4DECD657.9010807@ahsoftware.de>

From: Alexander Holler <holler@ahsoftware.de>

Le lundi 06 juin 2011 à 15:29 +0200, Alexander Holler a écrit :
> > Nice, now please submit a patch with 0972ddb237 as a guideline.
> >
> > BTW, you could also check other struct dst_ops methods for
> > bridge/netfilter:
> 
> Sorry, but I prefer to submit patches I understand by myself and for 
> stuff I know something about. The patch in my first mail was just meant 
> as a quick fix (which seemed to work here).
> 
> So even if I might be able to construct a working patch using commit 
> 0972ddb237, I don't think I should do that.

OK, I'll do it for you then, I am surprised you dont understand my
review / suggestion.

One patch submitter is supposed to followup and send a new version to
take into account reviews/comments, not wait that eventually everybody
says "OK, lets take it as is"


[PATCH] bridge: provide a cow_metrics method for fake_ops

Like in commit 0972ddb237 (provide cow_metrics() methods to blackhole
dst_ops), we must provide a cow_metrics for bridges fake_dst_ops as
well.

This fixes a regression coming from commits 62fa8a846d7d (net: Implement
read-only protection and COW'ing of metrics.) and 33eb9873a28 (bridge:
initialize fake_rtable metrics)

ip link set mybridge mtu 1234
-->
[  136.546243] Pid: 8415, comm: ip Tainted: P 
2.6.39.1-00006-g40545b7 #103 ASUSTeK Computer Inc.         V1Sn 
        /V1Sn
[  136.546256] EIP: 0060:[<00000000>] EFLAGS: 00010202 CPU: 0
[  136.546268] EIP is at 0x0
[  136.546273] EAX: f14a389c EBX: 000005d4 ECX: f80d32c0 EDX: f80d1da1
[  136.546279] ESI: f14a3000 EDI: f255bf10 EBP: f15c3b54 ESP: f15c3b48
[  136.546285]  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
[  136.546293] Process ip (pid: 8415, ti=f15c2000 task=f4741f80 
task.ti=f15c2000)
[  136.546297] Stack:
[  136.546301]  f80c658f f14a3000 ffffffed f15c3b64 c12cb9c8 f80d1b80 
ffffffa1 f15c3bbc
[  136.546315]  c12da347 c12d9c7d 00000000 f7670b00 00000000 f80d1b80 
ffffffa6 f15c3be4
[  136.546329]  00000004 f14a3000 f255bf20 00000008 f15c3bbc c11d6cae 
00000000 00000000
[  136.546343] Call Trace:
[  136.546359]  [<f80c658f>] ? br_change_mtu+0x5f/0x80 [bridge]
[  136.546372]  [<c12cb9c8>] dev_set_mtu+0x38/0x80
[  136.546381]  [<c12da347>] do_setlink+0x1a7/0x860
[  136.546390]  [<c12d9c7d>] ? rtnl_fill_ifinfo+0x9bd/0xc70
[  136.546400]  [<c11d6cae>] ? nla_parse+0x6e/0xb0
[  136.546409]  [<c12db931>] rtnl_newlink+0x361/0x510
[  136.546420]  [<c1023240>] ? vmalloc_sync_all+0x100/0x100
[  136.546429]  [<c1362762>] ? error_code+0x5a/0x60
[  136.546438]  [<c12db5d0>] ? rtnl_configure_link+0x80/0x80
[  136.546446]  [<c12db27a>] rtnetlink_rcv_msg+0xfa/0x210
[  136.546454]  [<c12db180>] ? __rtnl_unlock+0x20/0x20
[  136.546463]  [<c12ee0fe>] netlink_rcv_skb+0x8e/0xb0
[  136.546471]  [<c12daf1c>] rtnetlink_rcv+0x1c/0x30
[  136.546479]  [<c12edafa>] netlink_unicast+0x23a/0x280
[  136.546487]  [<c12ede6b>] netlink_sendmsg+0x26b/0x2f0
[  136.546497]  [<c12bb828>] sock_sendmsg+0xc8/0x100
[  136.546508]  [<c10adf61>] ? __alloc_pages_nodemask+0xe1/0x750
[  136.546517]  [<c11d0602>] ? _copy_from_user+0x42/0x60
[  136.546525]  [<c12c5e4c>] ? verify_iovec+0x4c/0xc0
[  136.546534]  [<c12bd805>] sys_sendmsg+0x1c5/0x200
[  136.546542]  [<c10c2150>] ? __do_fault+0x310/0x410
[  136.546549]  [<c10c2c46>] ? do_wp_page+0x1d6/0x6b0
[  136.546557]  [<c10c47d1>] ? handle_pte_fault+0xe1/0x720
[  136.546565]  [<c12bd1af>] ? sys_getsockname+0x7f/0x90
[  136.546574]  [<c10c4ec1>] ? handle_mm_fault+0xb1/0x180
[  136.546582]  [<c1023240>] ? vmalloc_sync_all+0x100/0x100
[  136.546589]  [<c10233b3>] ? do_page_fault+0x173/0x3d0
[  136.546596]  [<c12bd87b>] ? sys_recvmsg+0x3b/0x60
[  136.546605]  [<c12bdd83>] sys_socketcall+0x293/0x2d0
[  136.546614]  [<c13629d0>] sysenter_do_call+0x12/0x26
[  136.546619] Code:  Bad EIP value.
[  136.546627] EIP: [<00000000>] 0x0 SS:ESP 0068:f15c3b48
[  136.546645] CR2: 0000000000000000
[  136.546652] ---[ end trace 6909b560e78934fa ]---

Signed-off-by: Alexander Holler <holler@ahsoftware.de>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Neil Horman <nhorman@tuxdriver.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
---
net/bridge/br_netfilter.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 3fa1231..23b43d2 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -104,10 +104,16 @@ static void fake_update_pmtu(struct dst_entry *dst, u32 mtu)
 {
 }
 
+static u32 *fake_cow_metrics(struct dst_entry *dst, unsigned long old)
+{
+	return NULL;
+}
+
 static struct dst_ops fake_dst_ops = {
 	.family =		AF_INET,
 	.protocol =		cpu_to_be16(ETH_P_IP),
 	.update_pmtu =		fake_update_pmtu,
+	.cow_metrics =		fake_cow_metrics,
 };
 
 /*

^ permalink raw reply related

* [net-next-2.6 PATCH] macvlan: add VLAN filters to lowerdev
From: John Fastabend @ 2011-06-06 14:27 UTC (permalink / raw)
  To: davem; +Cc: netdev

Stacking VLANs on top of the macvlan device does not
work if the lowerdev device is using vlan filters set
by NETIF_F_HW_VLAN_FILTER. Add ndo ops to pass vlan
calls to lowerdev.

Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---

 drivers/net/macvlan.c |   39 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index d6aeaa5..cc67cbe 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -414,7 +414,8 @@ static struct lock_class_key macvlan_netdev_addr_lock_key;
 #define MACVLAN_FEATURES \
 	(NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
 	 NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \
-	 NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM)
+	 NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \
+	 NETIF_F_HW_VLAN_FILTER)
 
 #define MACVLAN_STATE_MASK \
 	((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT))
@@ -509,6 +510,39 @@ static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev,
 	return stats;
 }
 
+static void macvlan_vlan_rx_register(struct net_device *dev,
+				     struct vlan_group *grp)
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+	struct net_device *lowerdev = vlan->lowerdev;
+	const struct net_device_ops *ops = lowerdev->netdev_ops;
+
+	if (ops->ndo_vlan_rx_register)
+		ops->ndo_vlan_rx_register(lowerdev, grp);
+}
+
+static void macvlan_vlan_rx_add_vid(struct net_device *dev,
+				    unsigned short vid)
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+	struct net_device *lowerdev = vlan->lowerdev;
+	const struct net_device_ops *ops = lowerdev->netdev_ops;
+
+	if (ops->ndo_vlan_rx_add_vid)
+		ops->ndo_vlan_rx_add_vid(lowerdev, vid);
+}
+
+static void macvlan_vlan_rx_kill_vid(struct net_device *dev,
+				     unsigned short vid)
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+	struct net_device *lowerdev = vlan->lowerdev;
+	const struct net_device_ops *ops = lowerdev->netdev_ops;
+
+	if (ops->ndo_vlan_rx_kill_vid)
+		ops->ndo_vlan_rx_kill_vid(lowerdev, vid);
+}
+
 static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
 					struct ethtool_drvinfo *drvinfo)
 {
@@ -541,6 +575,9 @@ static const struct net_device_ops macvlan_netdev_ops = {
 	.ndo_set_multicast_list	= macvlan_set_multicast_list,
 	.ndo_get_stats64	= macvlan_dev_get_stats64,
 	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_vlan_rx_register	= macvlan_vlan_rx_register,
+	.ndo_vlan_rx_add_vid	= macvlan_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid	= macvlan_vlan_rx_kill_vid,
 };
 
 void macvlan_common_setup(struct net_device *dev)


^ permalink raw reply related

* Re: [PATCH] vlan: Fix the ingress VLAN_FLAG_REORDER_HDR check v2
From: Jiri Pirko @ 2011-06-06 14:48 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Changli Gao, David Miller, shemminger, greearb, nicolas.2p.debian,
	netdev, kaber, fubar, eric.dumazet, andy, jesse
In-Reply-To: <m1ipsob6f8.fsf@fess.ebiederm.org>

Thu, Jun 02, 2011 at 05:26:51PM CEST, ebiederm@xmission.com wrote:
>Changli Gao <xiaosuo@gmail.com> writes:
>
>> On Thu, Jun 2, 2011 at 9:03 PM, Eric W. Biederman <ebiederm@xmission.com> wrote:
>>>
>>> -static struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
>>> +static struct sk_buff *vlan_reorder_header(struct sk_buff *skb)
>>>  {
>>> -       if (vlan_dev_info(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) {
>>> -               if (skb_cow(skb, skb_headroom(skb)) < 0)
>>> -                       skb = NULL;
>>> -               if (skb) {
>>> -                       /* Lifted from Gleb's VLAN code... */
>>> -                       memmove(skb->data - ETH_HLEN,
>>> -                               skb->data - VLAN_ETH_HLEN, 12);
>>> -                       skb->mac_header += VLAN_HLEN;
>>> -               }
>>> +       if (skb_cow(skb, skb_headroom(skb)) < 0)
>>> +               skb = NULL;
>>> +       if (skb) {
>>
>> I think an else branch maybe more readable here.
>
>Probably most readable would be simply returning NULL immediately on
>error.  In this patch I just removed the if statement, and I would like
>to avoid mixing different bug fixes in the same patch if possible.
>
>>> +               /* Lifted from Gleb's VLAN code... */
>>> +               memmove(skb->data - ETH_HLEN,
>>> +                       skb->data - VLAN_ETH_HLEN, 12);
>>> +               skb->mac_header += VLAN_HLEN;
>>
>> skb->mac_len should be adjusted too.
>
>Given how vlan_untag is called at the moment it does appear
>that the skb->mac_len = skb->network_header - skb->mac_header
>in __netif_receive_skb that used to handle this for is no longer
>doing this for us.
>
>My feel is that either we need to do all of the header resets and the
>vlan_untagging together.  So we either need this all together before or
>after the another_round label:
>
>So the proper fix is probably something like this.
>
>diff --git a/net/core/dev.c b/net/core/dev.c
>index bcb05cb..8fe50d4 100644
>--- a/net/core/dev.c
>+++ b/net/core/dev.c
>@@ -3102,9 +3102,6 @@ static int __netif_receive_skb(struct sk_buff *skb)
> 		skb->skb_iif = skb->dev->ifindex;
> 	orig_dev = skb->dev;
> 
>-	skb_reset_network_header(skb);
>-	skb_reset_transport_header(skb);
>-	skb->mac_len = skb->network_header - skb->mac_header;
> 
> 	pt_prev = NULL;
> 
>@@ -3119,6 +3116,9 @@ another_round:
> 		if (unlikely(!skb))
> 			goto out;
> 	}
>+	skb_reset_network_header(skb);
>+	skb_reset_transport_header(skb);
>+	skb->mac_len = skb->network_header - skb->mac_header;
> 
> #ifdef CONFIG_NET_CLS_ACT
> 	if (skb->tc_verd & TC_NCLS) {


This looks good to me. This does not need to be done before vlan_untag.


^ permalink raw reply

* Re: [PATCH] usbnet/cdc_ncm: add missing .reset_resume hook
From: Greg KH @ 2011-06-06 15:06 UTC (permalink / raw)
  To: Stefan (metze) Metzmacher
  Cc: David Miller, oliver, linux-usb, netdev, linux-kernel
In-Reply-To: <4DECC6B4.5020108@samba.org>

On Mon, Jun 06, 2011 at 02:23:16PM +0200, Stefan (metze) Metzmacher wrote:
> Hi David,
> 
> > From: Stefan Metzmacher <metze@samba.org>
> > Date: Wed,  1 Jun 2011 14:01:41 +0200
> > 
> >> This avoids messages like this after suspend:
> >>
> >>    cdc_ncm 2-1.4:1.6: no reset_resume for driver cdc_ncm?
> >>    cdc_ncm 2-1.4:1.7: no reset_resume for driver cdc_ncm?
> >>    cdc_ncm 2-1.4:1.6: usb0: unregister 'cdc_ncm' usb-0000:00:1d.0-1.4, CDC NCM
> >>
> >> This is important for the Ericsson F5521gw GSM/UMTS modem.
> >> Otherwise modemmanager looses the fact that the cdc_ncm and cdc_acm devices
> >> belong together.
> >>
> >> The cdc_ether module does the same.
> >>
> >> Signed-off-by: Stefan Metzmacher <metze@samba.org>
> > 
> > Applied and queued up for -stable, thanks.
> 
> It seems to be part of 3.0-rc2, but I'm not seeing it in any stable tree
> yet...
> 
> When can I expect it in stable trees like 2.6.38.y?

The .38.y tree is closed and will not have new releases, so you will
never see it there, sorry.

greg k-h

^ permalink raw reply

* Re: bridge/netfilter: regression in 2.6.39.1
From: Neil Horman @ 2011-06-06 15:32 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Alexander Holler, linux-kernel, David Miller, Herbert Xu, netdev
In-Reply-To: <1307370363.3098.37.camel@edumazet-laptop>

On Mon, Jun 06, 2011 at 04:26:03PM +0200, Eric Dumazet wrote:
> From: Alexander Holler <holler@ahsoftware.de>
> 
> Le lundi 06 juin 2011 à 15:29 +0200, Alexander Holler a écrit :
> > > Nice, now please submit a patch with 0972ddb237 as a guideline.
> > >
> > > BTW, you could also check other struct dst_ops methods for
> > > bridge/netfilter:
> > 
> > Sorry, but I prefer to submit patches I understand by myself and for 
> > stuff I know something about. The patch in my first mail was just meant 
> > as a quick fix (which seemed to work here).
> > 
> > So even if I might be able to construct a working patch using commit 
> > 0972ddb237, I don't think I should do that.
> 
> OK, I'll do it for you then, I am surprised you dont understand my
> review / suggestion.
> 
> One patch submitter is supposed to followup and send a new version to
> take into account reviews/comments, not wait that eventually everybody
> says "OK, lets take it as is"
> 
> 
> [PATCH] bridge: provide a cow_metrics method for fake_ops
> 
> Like in commit 0972ddb237 (provide cow_metrics() methods to blackhole
> dst_ops), we must provide a cow_metrics for bridges fake_dst_ops as
> well.
> 
> This fixes a regression coming from commits 62fa8a846d7d (net: Implement
> read-only protection and COW'ing of metrics.) and 33eb9873a28 (bridge:
> initialize fake_rtable metrics)
> 
> ip link set mybridge mtu 1234
> -->
> [  136.546243] Pid: 8415, comm: ip Tainted: P 
> 2.6.39.1-00006-g40545b7 #103 ASUSTeK Computer Inc.         V1Sn 
>         /V1Sn
> [  136.546256] EIP: 0060:[<00000000>] EFLAGS: 00010202 CPU: 0
> [  136.546268] EIP is at 0x0
> [  136.546273] EAX: f14a389c EBX: 000005d4 ECX: f80d32c0 EDX: f80d1da1
> [  136.546279] ESI: f14a3000 EDI: f255bf10 EBP: f15c3b54 ESP: f15c3b48
> [  136.546285]  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
> [  136.546293] Process ip (pid: 8415, ti=f15c2000 task=f4741f80 
> task.ti=f15c2000)
> [  136.546297] Stack:
> [  136.546301]  f80c658f f14a3000 ffffffed f15c3b64 c12cb9c8 f80d1b80 
> ffffffa1 f15c3bbc
> [  136.546315]  c12da347 c12d9c7d 00000000 f7670b00 00000000 f80d1b80 
> ffffffa6 f15c3be4
> [  136.546329]  00000004 f14a3000 f255bf20 00000008 f15c3bbc c11d6cae 
> 00000000 00000000
> [  136.546343] Call Trace:
> [  136.546359]  [<f80c658f>] ? br_change_mtu+0x5f/0x80 [bridge]
> [  136.546372]  [<c12cb9c8>] dev_set_mtu+0x38/0x80
> [  136.546381]  [<c12da347>] do_setlink+0x1a7/0x860
> [  136.546390]  [<c12d9c7d>] ? rtnl_fill_ifinfo+0x9bd/0xc70
> [  136.546400]  [<c11d6cae>] ? nla_parse+0x6e/0xb0
> [  136.546409]  [<c12db931>] rtnl_newlink+0x361/0x510
> [  136.546420]  [<c1023240>] ? vmalloc_sync_all+0x100/0x100
> [  136.546429]  [<c1362762>] ? error_code+0x5a/0x60
> [  136.546438]  [<c12db5d0>] ? rtnl_configure_link+0x80/0x80
> [  136.546446]  [<c12db27a>] rtnetlink_rcv_msg+0xfa/0x210
> [  136.546454]  [<c12db180>] ? __rtnl_unlock+0x20/0x20
> [  136.546463]  [<c12ee0fe>] netlink_rcv_skb+0x8e/0xb0
> [  136.546471]  [<c12daf1c>] rtnetlink_rcv+0x1c/0x30
> [  136.546479]  [<c12edafa>] netlink_unicast+0x23a/0x280
> [  136.546487]  [<c12ede6b>] netlink_sendmsg+0x26b/0x2f0
> [  136.546497]  [<c12bb828>] sock_sendmsg+0xc8/0x100
> [  136.546508]  [<c10adf61>] ? __alloc_pages_nodemask+0xe1/0x750
> [  136.546517]  [<c11d0602>] ? _copy_from_user+0x42/0x60
> [  136.546525]  [<c12c5e4c>] ? verify_iovec+0x4c/0xc0
> [  136.546534]  [<c12bd805>] sys_sendmsg+0x1c5/0x200
> [  136.546542]  [<c10c2150>] ? __do_fault+0x310/0x410
> [  136.546549]  [<c10c2c46>] ? do_wp_page+0x1d6/0x6b0
> [  136.546557]  [<c10c47d1>] ? handle_pte_fault+0xe1/0x720
> [  136.546565]  [<c12bd1af>] ? sys_getsockname+0x7f/0x90
> [  136.546574]  [<c10c4ec1>] ? handle_mm_fault+0xb1/0x180
> [  136.546582]  [<c1023240>] ? vmalloc_sync_all+0x100/0x100
> [  136.546589]  [<c10233b3>] ? do_page_fault+0x173/0x3d0
> [  136.546596]  [<c12bd87b>] ? sys_recvmsg+0x3b/0x60
> [  136.546605]  [<c12bdd83>] sys_socketcall+0x293/0x2d0
> [  136.546614]  [<c13629d0>] sysenter_do_call+0x12/0x26
> [  136.546619] Code:  Bad EIP value.
> [  136.546627] EIP: [<00000000>] 0x0 SS:ESP 0068:f15c3b48
> [  136.546645] CR2: 0000000000000000
> [  136.546652] ---[ end trace 6909b560e78934fa ]---
> 
> Signed-off-by: Alexander Holler <holler@ahsoftware.de>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> CC: Neil Horman <nhorman@tuxdriver.com>
> CC: Herbert Xu <herbert@gondor.apana.org.au>
> ---
> net/bridge/br_netfilter.c |    6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
> index 3fa1231..23b43d2 100644
> --- a/net/bridge/br_netfilter.c
> +++ b/net/bridge/br_netfilter.c
> @@ -104,10 +104,16 @@ static void fake_update_pmtu(struct dst_entry *dst, u32 mtu)
>  {
>  }
>  
> +static u32 *fake_cow_metrics(struct dst_entry *dst, unsigned long old)
> +{
> +	return NULL;
> +}
> +
>  static struct dst_ops fake_dst_ops = {
>  	.family =		AF_INET,
>  	.protocol =		cpu_to_be16(ETH_P_IP),
>  	.update_pmtu =		fake_update_pmtu,
> +	.cow_metrics =		fake_cow_metrics,
>  };
>  
>  /*
> 
> 
Not to drag this out further, but since you illustrated the correct way to do
this with the blackhole_ops test, and this modification now gives us two
instances of that case, would it perhaps be better to just do this in
dst_metrics_write_ptr:

return dst->ops->cow_metrics ? return dst->ops->cow_metrics(dst, p) : NULL;

Then we could eliminate the two functions that do nothing be retun NULL (along
with their respective call instructions), and save any future users from having
to remember to include a dummy cow_metrics method if they happen to set the read
only flag on thier dst_ops?

Neil

> --
> 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: [PATCHv3] net: Define enum for the bits used in features.
From: Michael S. Tsirkin @ 2011-06-06 15:32 UTC (permalink / raw)
  To: David Miller; +Cc: maheshb, netdev, therbert, mirqus, shemminger
In-Reply-To: <20110605.221537.899061768025493519.davem@davemloft.net>

On Sun, Jun 05, 2011 at 10:15:37PM -0700, David Miller wrote:
> From: "Michael S. Tsirkin" <mst@redhat.com>
> Date: Mon, 6 Jun 2011 06:58:08 +0300
> 
> > I've been thinking about this as well. It turns out most
> > things above can be done with the spatch (aka coccinelle) tool.
> > But I think the largest problem is what to do with multiple-feature
> > macros such as NETIF_F_GSO_SOFTWARE.
> > 
> > If we keep them an 'or' of bits, we more or less commit to
> > an implementation that can represent them all in a single
> > constant.
> > 
> > I played with variadic macros but could not come up with something
> > that does not generate a lot of code.
> 
> Since the GSO accessors deal with mutliple bits, you can create
> special GSO specific interfaces to manipulate them.

Yes but it's not just GSO.
It's anything that includes more than 1 feature.
Examples:
NETIF_F_ALL_CSUM
NETIF_F_ALL_TX_OFFLOADS
NETIF_F_V6_CSUM
NETIF_F_SOFT_FEATURES

etc

Creating many accessors for each will need a lot
of code duplication ...

-- 
MST

^ permalink raw reply

* RE: Multicast IP packet routed between 2 ports nic on the same host
From: BONNEAU Guy @ 2011-06-06 15:31 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev@vger.kernel.org
In-Reply-To: <1307369342.3098.26.camel@edumazet-laptop>

Here are the requested info.

ip link :

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:00:5a:11:60:4e brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:21:70:d8:b4:f7 brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 00:24:2b:66:73:a5 brd ff:ff:ff:ff:ff:ff

ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:00:5a:11:60:4e brd ff:ff:ff:ff:ff:ff
    inet 172.30.8.31/24 brd 172.30.8.255 scope global eth1
    inet6 fe80::200:5aff:fe11:604e/64 scope link 
       valid_lft forever preferred_lft forever
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:21:70:d8:b4:f7 brd ff:ff:ff:ff:ff:ff
    inet 10.0.9.164/16 brd 10.0.255.255 scope global eth0
    inet6 fe80::221:70ff:fed8:b4f7/64 scope link 
       valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 00:24:2b:66:73:a5 brd ff:ff:ff:ff:ff:ff

ip ro

172.30.8.0/24 dev eth1  proto kernel  scope link  src 172.30.8.31  metric 1 
10.0.0.0/16 dev eth0  proto kernel  scope link  src 10.0.9.164  metric 1 
169.254.0.0/16 dev eth0  scope link  metric 1000 
default via 10.0.0.62 dev eth0  proto static 


> I am trying to receive multicast data packets from a multicast router
> to my Linux Ubuntu Desktop Workstation using kernel 2.6.35. The Linux
> Desktop has an Intel 82576 dual NIC adapter. Each NIC is configured to
> receive IP data from 2 different subnet. One is from 172.30.8.xx and
> another one from 10.0.xx.xx. Multicast IP data can only be received
> from 172.30.8.xx since there is no multicast source on subnet
> 10.0.xx.xx and IT that administrates the subnet 10.0.xx.xx disabled
> multicast capability of the switches and routers sitting on that
> subnet. The subnet 172.30.8.xx has multicast source broadcasting on
> multicast group 239.255.200.200:8000.
>

Hi

Not clear if eth0 and eth1 are on both networks ?

Please send us

ip link
ip addr
ip ro

Thanks

> I am using the application mreceived (version 2.2) from :
> http://www.cs.virginia.edu/~mngroup/software/ to test the network
> multicast set-up and capability of my Ubuntu Desktop Workstation.
>
> I open a first console and I use mreceive to join multicast group
> 239.255.200.200:8000 to receive multicast data from subnet 10.0.xx.xx
> using the console command : ./mreceive -g 239.255.200.200 -p 8000 -i
> 10.0.9.164 to the eth0 adapter of my workstation. The application is
> idle and no multicast data is received. This is the expected
> behaviour.
>
> I open a second console and I use mreceive to join the same multicast
> group 239.255.200.200:8000 to receive multicast data from subnet
> 172.30.8.xx using the console command : ./mreceive -g 239.255.200.200
> -p 8000 -i 172.30.8.31 to the eth1 adapter of my workstation. The
> application starts to receive multicast data and advertises the data
> received. This is also the expected behaviour.
>
> Now this is where the problem begins. As soon as the multicast data
> begin to be received on the eth1 adapter the first console begins to
> advertise multicast data received on eth0 adapter. I am well aware
> that the Linux kernel implements a multicast level 2 routing
> capability. Thus at first glance this seems to be the expected
> behaviour. However... I have forwarding disabled as well as
> mc_forwarding disabled and rp_filter is enabled for both adapters.
> Thus I don't expect the kernel to forward the multicast data from eth1
> to eth0.
>
> I have recompiled the kernel with IP Multicast Routing disabled and
> got the same behavior. I also tried kernel 2.6.38 and had the same
> issue.
>
> At this point I am inclined to think that the kernel multicast routing
> might have an issue? I might have missing a network configuration
> setting but at this point I am baffled.  I checked the kernel bugbase
> with the multicast tagging and couldn't find a filled bug regarding
> this matter. The only remaining options for me are to fill a bug and
> trace the kernel code (ipmr.c) to understand what going on. Can
> someone shade light on this? Is this an expected behavior or an issue?
>
> Thanks
> GB
>



^ permalink raw reply

* Re: [PATCHv3] net: Define enum for the bits used in features.
From: Michał Mirosław @ 2011-06-06 15:48 UTC (permalink / raw)
  To: David Miller; +Cc: maheshb, netdev, therbert, shemminger
In-Reply-To: <20110604.133438.1450652272927306428.davem@davemloft.net>

2011/6/4 David Miller <davem@davemloft.net>:
> From: Mahesh Bandewar <maheshb@google.com>
> Date: Wed, 25 May 2011 15:42:16 -0700
>> Little bit cleanup by defining enum for all bits used. Also use those enum
>> values to redefine flags.
>>
>> Signed-off-by: Mahesh Bandewar <maheshb@google.com>
>> ---
>> Changes since v2:
>>  (1) Removed the include which was part of the other patch (split mishap).
>>  (2) Changed the enums to add NETIF_F_ prefix.
>
> I hate to be a pain after you've put so much work into these patches,
> but I simply don't like this approach.
>
> I think the abstracted interfaces should come first.  You don't need to
> change any of the NETIF_F_* defines in order to do that.  You should only
> need to add the netdev_{set,clear,test}_*() macros.

I suggested that it's better to first introduce the enum because it
can be used right away (e.g. in ethtool.c feature name table).
Whatever the new access scheme will be, it will also use that enum.

Best Regards,
Michał Mirosław

^ permalink raw reply

* [PATCH] net/ipv6: check for mistakenly passed in non-AF_INET6 sockaddrs
From: Marcus Meissner @ 2011-06-06 16:00 UTC (permalink / raw)
  To: Reinhard Max, David Miller, netdev
In-Reply-To: <alpine.LNX.2.00.1106061538210.13876@nitsch.suse.de>

On Mon, Jun 06, 2011 at 03:47:30PM +0200, Reinhard Max wrote:
> 
> On Wed, 1 Jun 2011 at 21:03, David Miller wrote:
> 
> >Since we haven't been validating the sin_family field for 18+ years, 
> >the chance to break some applications is very real.
> >
> >But I think it's more important to fix this (and force any broken 
> >apps to set sin_family correctly).  So I will apply this, thanks.
> 
> I think a corresponding check should also go into inet6_bind() in 
> net/ipv6/af_inet6.c .

Good idea,

Same check as for IPv4, also do for IPv6.

(If you passed in a IPv4 sockaddr_in here, the sizeof check
 in the line before would have triggered already though.)

Signed-off-by: Marcus Meissner <meissner@suse.de>
Cc: Reinhard Max <max@suse.de>

Ciao, Marcus
---
 net/ipv6/af_inet6.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index b7919f9..d450a2f 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -272,6 +272,10 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 
 	if (addr_len < SIN6_LEN_RFC2133)
 		return -EINVAL;
+
+	if (addr->sin6_family != AF_INET6)
+		return -EINVAL;
+
 	addr_type = ipv6_addr_type(&addr->sin6_addr);
 	if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
 		return -EINVAL;
-- 
1.7.4.1


^ permalink raw reply related

* Re: bridge/netfilter: regression in 2.6.39.1
From: Eric Dumazet @ 2011-06-06 16:11 UTC (permalink / raw)
  To: Neil Horman
  Cc: Alexander Holler, linux-kernel, David Miller, Herbert Xu, netdev
In-Reply-To: <20110606153213.GC1000@hmsreliant.think-freely.org>

Le lundi 06 juin 2011 à 11:32 -0400, Neil Horman a écrit :

> Not to drag this out further, but since you illustrated the correct way to do
> this with the blackhole_ops test, and this modification now gives us two
> instances of that case, would it perhaps be better to just do this in
> dst_metrics_write_ptr:
> 
> return dst->ops->cow_metrics ? return dst->ops->cow_metrics(dst, p) : NULL;
> 
> Then we could eliminate the two functions that do nothing be retun NULL (along
> with their respective call instructions), and save any future users from having
> to remember to include a dummy cow_metrics method if they happen to set the read
> only flag on thier dst_ops?

Well, I prefer how David coded the thing.
We can add selective traces where we want.

Having a default behavior might give much more work to find a bug in
this area. A NULL pointer access gives us an immediate indication.

Its a bit late to add an "if (dst->ops->cow_metrics)" test now that we
covered all call sites ;)

But we probably have more bugs elsewhere, because of many dst changes in
2.6.39




^ permalink raw reply

* Re: [PATCH net-next] bonding: make 802.3ad use update lacp_rate (v2)
From: Américo Wang @ 2011-06-06 16:24 UTC (permalink / raw)
  To: Weiping Pan
  Cc: Jay Vosburgh, Andy Gospodarek, open list:BONDING DRIVER,
	open list
In-Reply-To: <1307243793-31007-1-git-send-email-panweiping3@gmail.com>

On Sun, Jun 5, 2011 at 11:16 AM, Weiping Pan <panweiping3@gmail.com> wrote:
> There is a bug that when you modify lacp_rate via sysfs,
> 802.3ad won't use the new value of lacp_rate to transmit packets.
> That is because port->actor_oper_port_state isn't changed.
>
> Change Notes:
> v2)
> 1 Hold read_lock(&bond->lock) when iterate slaves, suggested by Jiri Pirko.
> 2 Modify actor_oper_port_state via a helper function in bond_3ad.c,
> suggested by Jay Vosburgh.
> 3 Hold slave->state_machine_lock,
> so we can modify port->actor_oper_port_state, no matter bond is up or down.
>
> Signed-off-by: Weiping Pan <panweiping3@gmail.com>
> ---
>  drivers/net/bonding/bond_3ad.c   |   27 +++++++++++++++++++++++++++
>  drivers/net/bonding/bond_3ad.h   |    1 +
>  drivers/net/bonding/bond_sysfs.c |    1 +
>  3 files changed, 29 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
> index c7537abc..5111e0d 100644
> --- a/drivers/net/bonding/bond_3ad.c
> +++ b/drivers/net/bonding/bond_3ad.c
> @@ -2473,3 +2473,30 @@ void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
>        bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);
>        read_unlock(&bond->lock);
>  }
> +
> +/*
> + * When modify lacp_rate parameter via sysfs,
> + * update actor_oper_port_state of each port.
> + *
> + * Hold slave->state_machine_lock,
> + * so we can modify port->actor_oper_port_state,
> + * no matter bond is up or down.
> + */
> +void bond_3ad_update_lacp_rate(struct bonding *bond)
> +{
> +       int i;
> +       struct slave *slave;
> +       struct port *port = NULL;
> +
> +       read_lock(&bond->lock);
> +       bond_for_each_slave(bond, slave, i) {
> +               port = &(slave->ad_info.port);

Please use SLAVE_AD_INFO().

Other than this, it looks good to me,

Reviewed-by: WANG Cong <xiyou.wangcong@gmail.com>

Thanks!

^ permalink raw reply

* Re: [RFC Patch] bonding: move to net/ directory
From: Américo Wang @ 2011-06-06 16:34 UTC (permalink / raw)
  To: Michał Mirosław
  Cc: Neil Horman, Andy Gospodarek, Linux Kernel Network Developers,
	David Miller, Jay Vosburgh
In-Reply-To: <BANLkTikrsr5sZ4aZ5aEmfBSvPE0mEL8g0g@mail.gmail.com>

2011/5/26 Michał Mirosław <mirqus@gmail.com>:
> 2011/5/26 Neil Horman <nhorman@tuxdriver.com>:
>> On Thu, May 26, 2011 at 05:32:08PM +0800, Américo Wang wrote:
>>> I don't think other drivers are supposed to use this function to register
>>> a packet handler, which is an important difference from my view.
>> Note you just referred to the bridge/bond and vlan code as 'drivers' :).  And
>> why is that function the gating factor?  Why not register_netdev?  or
>> netif_receive_skb or dev_add_pack?  They all relate to the creation of device
>> interface and the reception of network data.
>>
>> The fact is, bonding/bridging/vlans/tunnels/etc all have aspects that
>> make them more than just drivers.  They are where they are for a myrriad of
>> reasons.  Moving them around changes their location, but does _nothing_ about
>> the underlying fact that they're driver code plus other stuff, and as such
>> provides no real advantage in terms of organization.
>
> If you want to draw a line between net/ and drivers/net I propose
> following idea:
>
> net/ - everything that is about networking (or library for it) and
> interacts only within the system (kernel<->user, or in-kernel)
> drivers/net/ - everything that is a connecting point between the
> system and external world - be it hardware, other VMs or hypervisor.
>
> net/ would include wireless stack, all kinds of loopback devices,
> tunnels (incl. vlan), bridging, bonding, tuntap, etc.
> drivers/net/ would keep only what is hardware or external ABI dependent
>

I agree with this, IMHO this would help to organize the code better.
And currently only tuntap and bonding are still in net/ directory.

In any aspects, now we are mixing net/ and drivers/net/ currently,
which could be improved.

Thanks!

^ permalink raw reply


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