Netdev List
 help / color / mirror / Atom feed
* [PATCH] greth: Use return value of register_netdev
From: Tobias Klauser @ 2010-08-17 16:12 UTC (permalink / raw)
  To: David S. Miller, netdev; +Cc: kernel-janitors

Use the return value provided by register_netdev on error instead of
hard setting it to -ENOMEM.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
 drivers/net/greth.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index f15c64f..fbeaf70 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -1547,10 +1547,10 @@ static int __devinit greth_of_probe(struct platform_device *ofdev, const struct
 	dev->netdev_ops = &greth_netdev_ops;
 	dev->ethtool_ops = &greth_ethtool_ops;
 
-	if (register_netdev(dev)) {
+	err = register_netdev(dev);
+	if (err) {
 		if (netif_msg_probe(greth))
 			dev_err(greth->dev, "netdevice registration failed.\n");
-		err = -ENOMEM;
 		goto error5;
 	}
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH] tehuti: Use net_device_stats from struct net_device
From: Tobias Klauser @ 2010-08-17 16:12 UTC (permalink / raw)
  To: David S. Miller, Alexander Indenbaum, Andy Gospodarek, netdev
  Cc: kernel-janitors

struct net_device has its own struct net_device_stats member, so use
this one instead of a private copy in the bdx_priv struct.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
 drivers/net/tehuti.c |   17 ++++++++---------
 drivers/net/tehuti.h |    1 -
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 737df60..663a4e7 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -929,9 +929,7 @@ static void bdx_update_stats(struct bdx_priv *priv)
 
 static struct net_device_stats *bdx_get_stats(struct net_device *ndev)
 {
-	struct bdx_priv *priv = netdev_priv(ndev);
-	struct net_device_stats *net_stat = &priv->net_stats;
-	return net_stat;
+	return &ndev->stats;
 }
 
 static void print_rxdd(struct rxd_desc *rxdd, u32 rxd_val1, u16 len,
@@ -1220,6 +1218,7 @@ static void bdx_recycle_skb(struct bdx_priv *priv, struct rxd_desc *rxdd)
 
 static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
 {
+	struct net_device *ndev = priv->ndev;
 	struct sk_buff *skb, *skb2;
 	struct rxd_desc *rxdd;
 	struct rx_map *dm;
@@ -1273,7 +1272,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
 
 		if (unlikely(GET_RXD_ERR(rxd_val1))) {
 			DBG("rxd_err = 0x%x\n", GET_RXD_ERR(rxd_val1));
-			priv->net_stats.rx_errors++;
+			ndev->stats.rx_errors++;
 			bdx_recycle_skb(priv, rxdd);
 			continue;
 		}
@@ -1300,11 +1299,11 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
 			bdx_rxdb_free_elem(db, rxdd->va_lo);
 		}
 
-		priv->net_stats.rx_bytes += len;
+		ndev->stats.rx_bytes += len;
 
 		skb_put(skb, len);
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
-		skb->protocol = eth_type_trans(skb, priv->ndev);
+		skb->protocol = eth_type_trans(skb, ndev);
 
 		/* Non-IP packets aren't checksum-offloaded */
 		if (GET_RXD_PKT_ID(rxd_val1) == 0)
@@ -1316,7 +1315,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
 			break;
 	}
 
-	priv->net_stats.rx_packets += done;
+	ndev->stats.rx_packets += done;
 
 	/* FIXME: do smth to minimize pci accesses    */
 	WRITE_REG(priv, f->m.reg_RPTR, f->m.rptr & TXF_WPTR_WR_PTR);
@@ -1712,8 +1711,8 @@ static netdev_tx_t bdx_tx_transmit(struct sk_buff *skb,
 #ifdef BDX_LLTX
 	ndev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
 #endif
-	priv->net_stats.tx_packets++;
-	priv->net_stats.tx_bytes += skb->len;
+	ndev->stats.tx_packets++;
+	ndev->stats.tx_bytes += skb->len;
 
 	if (priv->tx_level < BDX_MIN_TX_LEVEL) {
 		DBG("%s: %s: TX Q STOP level %d\n",
diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h
index 67e3b71..b6ba860 100644
--- a/drivers/net/tehuti.h
+++ b/drivers/net/tehuti.h
@@ -269,7 +269,6 @@ struct bdx_priv {
 	u32 msg_enable;
 	int stats_flag;
 	struct bdx_stats hw_stats;
-	struct net_device_stats net_stats;
 	struct pci_dev *pdev;
 
 	struct pci_nic *nic;
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH] sunhme: Use return value of register_netdev
From: Tobias Klauser @ 2010-08-17 16:13 UTC (permalink / raw)
  To: David S. Miller, netdev; +Cc: kernel-janitors

Use the return value provided by register_netdev on error instead of
using a previously set value.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
 drivers/net/sunhme.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index bd0df1c..d96431e 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2808,7 +2808,8 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i
 	happy_meal_set_initial_advertisement(hp);
 	spin_unlock_irq(&hp->happy_lock);
 
-	if (register_netdev(hp->dev)) {
+	err = register_netdev(hp->dev);
+	if (err) {
 		printk(KERN_ERR "happymeal: Cannot register net device, "
 		       "aborting.\n");
 		goto err_out_free_coherent;
@@ -3130,7 +3131,8 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
 	happy_meal_set_initial_advertisement(hp);
 	spin_unlock_irq(&hp->happy_lock);
 
-	if (register_netdev(hp->dev)) {
+	err = register_netdev(hp->dev);
+	if (err) {
 		printk(KERN_ERR "happymeal(PCI): Cannot register net device, "
 		       "aborting.\n");
 		goto err_out_iounmap;
-- 
1.7.0.4


^ permalink raw reply related

* Re: BUG: IPv6 stops working after a while, needs ip ne del command to reset
From: Thomas Habets @ 2010-08-17 16:14 UTC (permalink / raw)
  To: Thomas Habets; +Cc: Eric Dumazet, linux-kernel, netdev
In-Reply-To: <alpine.DEB.1.10.1008171547090.21857@red.crap.retrofitta.se>

On Tue, 17 Aug 2010, Thomas Habets wrote:
> [ here i run "ip l set promisc on eth0" ]
[...]
> 2a00:800:752:1::5c:2 > 2a00:800:752:1::5c:1: ICMP6, echo request
> 2a00:800:752:1::5c:1 > 2a00:800:752:1::5c:2: ICMP6, echo reply

I should add that I turned promisc mode back off at about here. Otherwise 
the ND would work properly right after the "clear ipv6 neigbors" command.

> [ here I run "clear ipv6 neigbors" again ]
> 2a00:800:752:1::5c:2 > 2a00:800:752:1::5c:1: ICMP6, echo request
> 2a00:800:752:1::5c:2 > 2a00:800:752:1::5c:1: ICMP6, echo request

---------
typedef struct me_s {
   char name[]      = { "Thomas Habets" };
   char email[]     = { "thomas@habets.pp.se" };
   char kernel[]    = { "Linux" };
   char *pgpKey[]   = { "http://www.habets.pp.se/pubkey.txt" };
   char pgp[] = { "A8A3 D1DD 4AE0 8467 7FDE  0945 286A E90A AD48 E854" };
   char coolcmd[]   = { "echo '. ./_&. ./_'>_;. ./_" };
} me_t;

^ permalink raw reply

* [PATCH] ep93xx_eth: Use net_device_stats from struct net_device
From: Tobias Klauser @ 2010-08-17 16:14 UTC (permalink / raw)
  To: David S. Miller, Lennert Buytenhek, netdev; +Cc: kernel-janitors

struct net_device has its own struct net_device_stats member, so use
this one instead of a private copy in the ep93xx_priv struct.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
 drivers/net/arm/ep93xx_eth.c |   35 ++++++++++++++++-------------------
 1 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 4a5ec94..6b37714 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -175,8 +175,6 @@ struct ep93xx_priv
 	struct net_device	*dev;
 	struct napi_struct	napi;
 
-	struct net_device_stats	stats;
-
 	struct mii_if_info	mii;
 	u8			mdc_divisor;
 };
@@ -232,8 +230,7 @@ static void ep93xx_mdio_write(struct net_device *dev, int phy_id, int reg, int d
 
 static struct net_device_stats *ep93xx_get_stats(struct net_device *dev)
 {
-	struct ep93xx_priv *ep = netdev_priv(dev);
-	return &(ep->stats);
+	return &dev->stats;
 }
 
 static int ep93xx_rx(struct net_device *dev, int processed, int budget)
@@ -267,15 +264,15 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
 			pr_crit("entry mismatch %.8x %.8x\n", rstat0, rstat1);
 
 		if (!(rstat0 & RSTAT0_RWE)) {
-			ep->stats.rx_errors++;
+			dev->stats.rx_errors++;
 			if (rstat0 & RSTAT0_OE)
-				ep->stats.rx_fifo_errors++;
+				dev->stats.rx_fifo_errors++;
 			if (rstat0 & RSTAT0_FE)
-				ep->stats.rx_frame_errors++;
+				dev->stats.rx_frame_errors++;
 			if (rstat0 & (RSTAT0_RUNT | RSTAT0_EDATA))
-				ep->stats.rx_length_errors++;
+				dev->stats.rx_length_errors++;
 			if (rstat0 & RSTAT0_CRCE)
-				ep->stats.rx_crc_errors++;
+				dev->stats.rx_crc_errors++;
 			goto err;
 		}
 
@@ -300,10 +297,10 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
 
 			netif_receive_skb(skb);
 
-			ep->stats.rx_packets++;
-			ep->stats.rx_bytes += length;
+			dev->stats.rx_packets++;
+			dev->stats.rx_bytes += length;
 		} else {
-			ep->stats.rx_dropped++;
+			dev->stats.rx_dropped++;
 		}
 
 err:
@@ -359,7 +356,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
 	int entry;
 
 	if (unlikely(skb->len > MAX_PKT_SIZE)) {
-		ep->stats.tx_dropped++;
+		dev->stats.tx_dropped++;
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
@@ -415,17 +412,17 @@ static void ep93xx_tx_complete(struct net_device *dev)
 		if (tstat0 & TSTAT0_TXWE) {
 			int length = ep->descs->tdesc[entry].tdesc1 & 0xfff;
 
-			ep->stats.tx_packets++;
-			ep->stats.tx_bytes += length;
+			dev->stats.tx_packets++;
+			dev->stats.tx_bytes += length;
 		} else {
-			ep->stats.tx_errors++;
+			dev->stats.tx_errors++;
 		}
 
 		if (tstat0 & TSTAT0_OW)
-			ep->stats.tx_window_errors++;
+			dev->stats.tx_window_errors++;
 		if (tstat0 & TSTAT0_TXU)
-			ep->stats.tx_fifo_errors++;
-		ep->stats.collisions += (tstat0 >> 16) & 0x1f;
+			dev->stats.tx_fifo_errors++;
+		dev->stats.collisions += (tstat0 >> 16) & 0x1f;
 
 		ep->tx_clean_pointer = (entry + 1) & (TX_QUEUE_ENTRIES - 1);
 		if (ep->tx_pending == TX_QUEUE_ENTRIES)
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH] ether1: Use net_device_stats from struct net_device
From: Tobias Klauser @ 2010-08-17 16:15 UTC (permalink / raw)
  To: David S. Miller, Russell King, netdev; +Cc: linux-arm-kernel, kernel-janitors

struct net_device has its own struct net_device_stats member, so use
this one instead of a private copy in the ether1_priv struct.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
 drivers/net/arm/ether1.c |   26 +++++++++++++-------------
 drivers/net/arm/ether1.h |    1 -
 2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c
index b17ab51..430085b 100644
--- a/drivers/net/arm/ether1.c
+++ b/drivers/net/arm/ether1.c
@@ -673,7 +673,7 @@ ether1_timeout(struct net_device *dev)
 	if (ether1_init_for_open (dev))
 		printk (KERN_ERR "%s: unable to restart interface\n", dev->name);
 
-	priv(dev)->stats.tx_errors++;
+	dev->stats.tx_errors++;
 	netif_wake_queue(dev);
 }
 
@@ -802,21 +802,21 @@ again:
 
 	while (nop.nop_status & STAT_COMPLETE) {
 		if (nop.nop_status & STAT_OK) {
-			priv(dev)->stats.tx_packets ++;
-			priv(dev)->stats.collisions += (nop.nop_status & STAT_COLLISIONS);
+			dev->stats.tx_packets++;
+			dev->stats.collisions += (nop.nop_status & STAT_COLLISIONS);
 		} else {
-			priv(dev)->stats.tx_errors ++;
+			dev->stats.tx_errors++;
 
 			if (nop.nop_status & STAT_COLLAFTERTX)
-				priv(dev)->stats.collisions ++;
+				dev->stats.collisions++;
 			if (nop.nop_status & STAT_NOCARRIER)
-				priv(dev)->stats.tx_carrier_errors ++;
+				dev->stats.tx_carrier_errors++;
 			if (nop.nop_status & STAT_TXLOSTCTS)
 				printk (KERN_WARNING "%s: cts lost\n", dev->name);
 			if (nop.nop_status & STAT_TXSLOWDMA)
-				priv(dev)->stats.tx_fifo_errors ++;
+				dev->stats.tx_fifo_errors++;
 			if (nop.nop_status & STAT_COLLEXCESSIVE)
-				priv(dev)->stats.collisions += 16;
+				dev->stats.collisions += 16;
 		}
 
 		if (nop.nop_link == caddr) {
@@ -879,13 +879,13 @@ ether1_recv_done (struct net_device *dev)
 
 				skb->protocol = eth_type_trans (skb, dev);
 				netif_rx (skb);
-				priv(dev)->stats.rx_packets ++;
+				dev->stats.rx_packets++;
 			} else
-				priv(dev)->stats.rx_dropped ++;
+				dev->stats.rx_dropped++;
 		} else {
 			printk(KERN_WARNING "%s: %s\n", dev->name,
 				(rbd.rbd_status & RBD_EOF) ? "oversized packet" : "acnt not valid");
-			priv(dev)->stats.rx_dropped ++;
+			dev->stats.rx_dropped++;
 		}
 
 		nexttail = ether1_readw(dev, priv(dev)->rx_tail, rfd_t, rfd_link, NORMALIRQS);
@@ -939,7 +939,7 @@ ether1_interrupt (int irq, void *dev_id)
 				printk (KERN_WARNING "%s: RU went not ready: RU suspended\n", dev->name);
 				ether1_writew(dev, SCB_CMDRXRESUME, SCB_ADDR, scb_t, scb_command, NORMALIRQS);
 				writeb(CTRL_CA, REG_CONTROL);
-				priv(dev)->stats.rx_dropped ++;	/* we suspended due to lack of buffer space */
+				dev->stats.rx_dropped++;	/* we suspended due to lack of buffer space */
 			} else
 				printk(KERN_WARNING "%s: RU went not ready: %04X\n", dev->name,
 					ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS));
@@ -965,7 +965,7 @@ ether1_close (struct net_device *dev)
 static struct net_device_stats *
 ether1_getstats (struct net_device *dev)
 {
-	return &priv(dev)->stats;
+	return &dev->stats;
 }
 
 /*
diff --git a/drivers/net/arm/ether1.h b/drivers/net/arm/ether1.h
index c8a4b23..3a5830a 100644
--- a/drivers/net/arm/ether1.h
+++ b/drivers/net/arm/ether1.h
@@ -38,7 +38,6 @@
 
 struct ether1_priv {
 	void __iomem *base;
-	struct net_device_stats stats;
 	unsigned int tx_link;
 	unsigned int tx_head;
 	volatile unsigned int tx_tail;
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH] ether3: Use net_device_stats from struct net_device
From: Tobias Klauser @ 2010-08-17 16:15 UTC (permalink / raw)
  To: David S. Miller, Russell King, netdev; +Cc: linux-arm-kernel, kernel-janitors

struct net_device has its own struct net_device_stats member, so use
this one instead of a private copy in the ether1_priv struct.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
 drivers/net/arm/ether3.c |   20 ++++++++++----------
 drivers/net/arm/ether3.h |    1 -
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
index 1361b73..9fc411e 100644
--- a/drivers/net/arm/ether3.c
+++ b/drivers/net/arm/ether3.c
@@ -447,7 +447,7 @@ ether3_close(struct net_device *dev)
  */
 static struct net_device_stats *ether3_getstats(struct net_device *dev)
 {
-	return &priv(dev)->stats;
+	return &dev->stats;
 }
 
 /*
@@ -490,7 +490,7 @@ static void ether3_timeout(struct net_device *dev)
 	local_irq_restore(flags);
 
 	priv(dev)->regs.config2 |= CFG2_CTRLO;
-	priv(dev)->stats.tx_errors += 1;
+	dev->stats.tx_errors += 1;
 	ether3_outw(priv(dev)->regs.config2, REG_CONFIG2);
 	priv(dev)->tx_head = priv(dev)->tx_tail = 0;
 
@@ -509,7 +509,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
 
 	if (priv(dev)->broken) {
 		dev_kfree_skb(skb);
-		priv(dev)->stats.tx_dropped ++;
+		dev->stats.tx_dropped++;
 		netif_start_queue(dev);
 		return NETDEV_TX_OK;
 	}
@@ -685,14 +685,14 @@ if (next_ptr < RX_START || next_ptr >= RX_END) {
 	while (-- maxcnt);
 
 done:
-	priv(dev)->stats.rx_packets += received;
+	dev->stats.rx_packets += received;
 	priv(dev)->rx_head = next_ptr;
 	/*
 	 * If rx went off line, then that means that the buffer may be full.  We
 	 * have dropped at least one packet.
 	 */
 	if (!(ether3_inw(REG_STATUS) & STAT_RXON)) {
-		priv(dev)->stats.rx_dropped ++;
+		dev->stats.rx_dropped++;
     		ether3_outw(next_ptr, REG_RECVPTR);
 		ether3_outw(priv(dev)->regs.command | CMD_RXON, REG_COMMAND);
 	}
@@ -710,7 +710,7 @@ dropping:{
 		last_warned = jiffies;
 		printk("%s: memory squeeze, dropping packet.\n", dev->name);
 	}
-	priv(dev)->stats.rx_dropped ++;
+	dev->stats.rx_dropped++;
 	goto done;
 	}
 }
@@ -743,13 +743,13 @@ static void ether3_tx(struct net_device *dev)
 		 * Update errors
 		 */
 		if (!(status & (TXSTAT_BABBLED | TXSTAT_16COLLISIONS)))
-			priv(dev)->stats.tx_packets++;
+			dev->stats.tx_packets++;
 		else {
-			priv(dev)->stats.tx_errors ++;
+			dev->stats.tx_errors++;
 			if (status & TXSTAT_16COLLISIONS)
-				priv(dev)->stats.collisions += 16;
+				dev->stats.collisions += 16;
 			if (status & TXSTAT_BABBLED)
-				priv(dev)->stats.tx_fifo_errors ++;
+				dev->stats.tx_fifo_errors++;
 		}
 
 		tx_tail = (tx_tail + 1) & 15;
diff --git a/drivers/net/arm/ether3.h b/drivers/net/arm/ether3.h
index 1921a3a..2db63b0 100644
--- a/drivers/net/arm/ether3.h
+++ b/drivers/net/arm/ether3.h
@@ -164,7 +164,6 @@ struct dev_priv {
     unsigned char tx_head;		/* buffer nr to insert next packet	 */
     unsigned char tx_tail;		/* buffer nr of transmitting packet	 */
     unsigned int rx_head;		/* address to fetch next packet from	 */
-    struct net_device_stats stats;
     struct timer_list timer;
     int broken;				/* 0 = ok, 1 = something went wrong	 */
 };
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] greth: Use return value of register_netdev
From: Tobias Klauser @ 2010-08-17 16:14 UTC (permalink / raw)
  To: David S. Miller, netdev; +Cc: kernel-janitors
In-Reply-To: <1282061527-19429-1-git-send-email-tklauser@distanz.ch>

On 2010-08-17 at 18:12:07 +0200, Tobias Klauser <tklauser@distanz.ch> wrote:
> Use the return value provided by register_netdev on error instead of
> hard setting it to -ENOMEM.

Sorry for the duplicate, please disregard this one.

^ permalink raw reply

* Re: BUG: IPv6 stops working after a while, needs ip ne del command to reset
From: Matt Carlson @ 2010-08-17 17:11 UTC (permalink / raw)
  To: Thomas Habets
  Cc: Eric Dumazet, linux-kernel@vger.kernel.org, netdev,
	Matthew Carlson, Michael Chan
In-Reply-To: <alpine.DEB.1.10.1008171737260.21857@red.crap.retrofitta.se>

On Tue, Aug 17, 2010 at 08:58:26AM -0700, Thomas Habets wrote:
> On Tue, 17 Aug 2010, Eric Dumazet wrote:
> > Try following patch to check tg3 receives correct multicast list (its OK
> > for me, seen on dmesg output)
> >
> > [17162.120238]  add mc_addr(ha->addr=33:33:00:00:00:01)
> > [17162.120270]  add mc_addr(ha->addr=01:00:5e:00:00:01)
> > [17162.120298]  add mc_addr(ha->addr=33:33:ff:87:96:ce)
> > [17162.120326]  add mc_addr(ha->addr=33:33:ff:5c:00:02)
> > [17162.120355] filters=80000001 00000000 00400000 40000000
> 
> Right after boot:
> 
> $ dmesg | egrep 'eth0|^add mc|^filters='
> tg3 0000:03:04.0: eth0: Tigon3 [partno(N/A) rev 9003] (PCIX:133MHz:64-bit) 
> MAC address 00:24:81:a3:44:24
> tg3 0000:03:04.0: eth0: attached PHY is 5714 (10/100/1000Base-T Ethernet) 
> (WireSpeed[1])
> tg3 0000:03:04.0: eth0: RXcsums[1] LinkChgREG[0] MIirq[0] ASF[1] TSOcap[1]
> tg3 0000:03:04.0: eth0: dma_rwctrl[76148000] dma_mask[40-bit]
> add mc_addr(ha->addr=33:33:00:00:00:01)
> filters=80000000 00000000 00000000 00000000
> add mc_addr(ha->addr=33:33:00:00:00:01)
> filters=80000000 00000000 00000000 00000000
> add mc_addr(ha->addr=33:33:00:00:00:01)
> filters=80000000 00000000 00000000 00000000
> add mc_addr(ha->addr=33:33:00:00:00:01)
> add mc_addr(ha->addr=01:00:5e:00:00:01)
> filters=80000000 00000000 00000000 40000000
> ADDRCONF(NETDEV_UP): eth0: link is not ready
> add mc_addr(ha->addr=33:33:00:00:00:01)
> add mc_addr(ha->addr=01:00:5e:00:00:01)
> filters=80000000 00000000 00000000 40000000
> add mc_addr(ha->addr=33:33:00:00:00:01)
> add mc_addr(ha->addr=01:00:5e:00:00:01)
> filters=80000000 00000000 00000000 40000000
> add mc_addr(ha->addr=33:33:00:00:00:01)
> add mc_addr(ha->addr=01:00:5e:00:00:01)
> add mc_addr(ha->addr=33:33:ff:5c:00:02)
> filters=80000001 00000000 00000000 40000000
> tg3 0000:03:04.0: eth0: Link is up at 1000 Mbps, full duplex
> tg3 0000:03:04.0: eth0: Flow control is off for TX and off for RX
> ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
> add mc_addr(ha->addr=33:33:00:00:00:01)
> add mc_addr(ha->addr=01:00:5e:00:00:01)
> add mc_addr(ha->addr=33:33:ff:5c:00:02)
> add mc_addr(ha->addr=33:33:ff:a3:44:24)
> filters=80020001 00000000 00000000 40000000
> eth0: no IPv6 routers present
> 
> [ ifconfig eth0 allmulti
>    (ip l and ifconfig say ALLMULTI is on)
> ]
> 
> add mc_addr(ha->addr=33:33:00:00:00:01)
> add mc_addr(ha->addr=01:00:5e:00:00:01)
> add mc_addr(ha->addr=33:33:ff:5c:00:02)
> add mc_addr(ha->addr=33:33:ff:a3:44:24)
> filters=80020001 00000000 00000000 40000000
> 
> [
>    $ sudo ifconfig eth0 -allmulti
>    Warning: Interface eth0 still in ALLMULTI mode.
>    (ip l and ifconfig say ALLMULTI is now off)
> ]
> 
> add mc_addr(ha->addr=33:33:00:00:00:01)
> add mc_addr(ha->addr=01:00:5e:00:00:01)
> add mc_addr(ha->addr=33:33:ff:5c:00:02)
> add mc_addr(ha->addr=33:33:ff:a3:44:24)
> filters=80020001 00000000 00000000 40000000
> 
> [ ifconfig eth0 allmulti
>    (same effect)
> ]
> 
> add mc_addr(ha->addr=33:33:00:00:00:01)
> add mc_addr(ha->addr=01:00:5e:00:00:01)
> add mc_addr(ha->addr=33:33:ff:5c:00:02)
> add mc_addr(ha->addr=33:33:ff:a3:44:24)
> filters=80020001 00000000 00000000 40000000
> 
> [
>    $ sudo ifconfig eth0 -allmulti
>    Warning: Interface eth0 still in ALLMULTI mode.
>    (same effect)
> ]
> 
> add mc_addr(ha->addr=33:33:00:00:00:01)
> add mc_addr(ha->addr=01:00:5e:00:00:01)
> add mc_addr(ha->addr=33:33:ff:5c:00:02)
> add mc_addr(ha->addr=33:33:ff:a3:44:24)
> filters=80020001 00000000 00000000 40000000
> 
> 
> > But if problem remains even with "ifconfig eth0 allmulti" I suspect a
> > NIC firmware problem. (allmulti set to 1 all the 128 bits of filters)

I suspect Eric is right.

Thomas, can you give me the output of 'ethtool -i eth0'?

> If you expected more bits set in "filters" with allmulti than without it, 
> that doesn't seem to be the case.

"allmulti" has the effect of enabling all 128 bits of the multicast hash
filters.  It doesn't explicitly enable them all though.

> Applied your patch to v2.6.35.
> 
> ---------
> typedef struct me_s {
>    char name[]      = { "Thomas Habets" };
>    char email[]     = { "thomas@habets.pp.se" };
>    char kernel[]    = { "Linux" };
>    char *pgpKey[]   = { "http://www.habets.pp.se/pubkey.txt" };
>    char pgp[] = { "A8A3 D1DD 4AE0 8467 7FDE  0945 286A E90A AD48 E854" };
>    char coolcmd[]   = { "echo '. ./_&. ./_'>_;. ./_" };
> } me_t;
> 


^ permalink raw reply

* Re: BUG: IPv6 stops working after a while, needs ip ne del command to reset
From: Eric Dumazet @ 2010-08-17 17:13 UTC (permalink / raw)
  To: Thomas Habets; +Cc: linux-kernel, netdev, Matt Carlson, Michael Chan
In-Reply-To: <alpine.DEB.1.10.1008171737260.21857@red.crap.retrofitta.se>

Le mardi 17 août 2010 à 17:58 +0200, Thomas Habets a écrit :

> If you expected more bits set in "filters" with allmulti than without it, 
> that doesn't seem to be the case.


Nope, the patch displays mc list and filters bits only if not
promiscuous and not allmulti (normal ethernet mode)

If promiscuous -> a special PROMISC bit is selected on NIC (no display)
If allmulti -> all 128 bits are set (but not displayed in my patch)

I wanted to make sure the correct list of mc addrs is handled on your
machine. It seems to be the case, so there might be a hardware problem
with the multicast rx on this particular NIC

^ permalink raw reply

* Re: BUG: IPv6 stops working after a while, needs ip ne del command to reset
From: Thomas Habets @ 2010-08-17 17:29 UTC (permalink / raw)
  To: Matt Carlson
  Cc: Thomas Habets, Eric Dumazet, linux-kernel@vger.kernel.org, netdev,
	Michael Chan
In-Reply-To: <20100817171115.GA4134@mcarlson.broadcom.com>

On Tue, 17 Aug 2010, Matt Carlson wrote:
>>> But if problem remains even with "ifconfig eth0 allmulti" I suspect a
>>> NIC firmware problem. (allmulti set to 1 all the 128 bits of filters)
> Thomas, can you give me the output of 'ethtool -i eth0'?

$ sudo ethtool -i eth0
driver: tg3
version: 3.110
firmware-version: 5715-v3.28, UMP 1.15
bus-info: 0000:03:04.0

---------
typedef struct me_s {
   char name[]      = { "Thomas Habets" };
   char email[]     = { "thomas@habets.pp.se" };
   char kernel[]    = { "Linux" };
   char *pgpKey[]   = { "http://www.habets.pp.se/pubkey.txt" };
   char pgp[] = { "A8A3 D1DD 4AE0 8467 7FDE  0945 286A E90A AD48 E854" };
   char coolcmd[]   = { "echo '. ./_&. ./_'>_;. ./_" };
} me_t;

^ permalink raw reply

* [PATCH net-next 1/2] drivers/net/sungem: Use netdev_<level>, netif_<level> and pr_<level>
From: Joe Perches @ 2010-08-17 17:55 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel

Use the current logging message styles.

Signed-off-by: Joe Perches <joe@perches.com>
---
 drivers/net/sungem.c     |  211 ++++++++++++++++++----------------------------
 drivers/net/sungem_phy.c |    3 +-
 2 files changed, 85 insertions(+), 129 deletions(-)

diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 434f9d7..4ceb3cf 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -31,6 +31,8 @@
  *    about when we can start taking interrupts or get xmit() called...
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -105,7 +107,6 @@ MODULE_DESCRIPTION("Sun GEM Gbit ethernet driver");
 MODULE_LICENSE("GPL");
 
 #define GEM_MODULE_NAME	"gem"
-#define PFX GEM_MODULE_NAME ": "
 
 static DEFINE_PCI_DEVICE_TABLE(gem_pci_tbl) = {
 	{ PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_GEM,
@@ -262,8 +263,7 @@ static int gem_pcs_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
 			gp->dev->name, pcs_istat);
 
 	if (!(pcs_istat & PCS_ISTAT_LSC)) {
-		printk(KERN_ERR "%s: PCS irq but no link status change???\n",
-		       dev->name);
+		netdev_err(dev, "PCS irq but no link status change???\n");
 		return 0;
 	}
 
@@ -282,20 +282,16 @@ static int gem_pcs_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
 		 * when autoneg has completed.
 		 */
 		if (pcs_miistat & PCS_MIISTAT_RF)
-			printk(KERN_INFO "%s: PCS AutoNEG complete, "
-			       "RemoteFault\n", dev->name);
+			netdev_info(dev, "PCS AutoNEG complete, RemoteFault\n");
 		else
-			printk(KERN_INFO "%s: PCS AutoNEG complete.\n",
-			       dev->name);
+			netdev_info(dev, "PCS AutoNEG complete\n");
 	}
 
 	if (pcs_miistat & PCS_MIISTAT_LS) {
-		printk(KERN_INFO "%s: PCS link is now up.\n",
-		       dev->name);
+		netdev_info(dev, "PCS link is now up\n");
 		netif_carrier_on(gp->dev);
 	} else {
-		printk(KERN_INFO "%s: PCS link is now down.\n",
-		       dev->name);
+		netdev_info(dev, "PCS link is now down\n");
 		netif_carrier_off(gp->dev);
 		/* If this happens and the link timer is not running,
 		 * reset so we re-negotiate.
@@ -323,14 +319,12 @@ static int gem_txmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s
 		return 0;
 
 	if (txmac_stat & MAC_TXSTAT_URUN) {
-		printk(KERN_ERR "%s: TX MAC xmit underrun.\n",
-		       dev->name);
+		netdev_err(dev, "TX MAC xmit underrun\n");
 		gp->net_stats.tx_fifo_errors++;
 	}
 
 	if (txmac_stat & MAC_TXSTAT_MPE) {
-		printk(KERN_ERR "%s: TX MAC max packet size error.\n",
-		       dev->name);
+		netdev_err(dev, "TX MAC max packet size error\n");
 		gp->net_stats.tx_errors++;
 	}
 
@@ -377,8 +371,7 @@ static int gem_rxmac_reset(struct gem *gp)
 		udelay(10);
 	}
 	if (limit == 5000) {
-		printk(KERN_ERR "%s: RX MAC will not reset, resetting whole "
-                       "chip.\n", dev->name);
+		netdev_err(dev, "RX MAC will not reset, resetting whole chip\n");
 		return 1;
 	}
 
@@ -390,8 +383,7 @@ static int gem_rxmac_reset(struct gem *gp)
 		udelay(10);
 	}
 	if (limit == 5000) {
-		printk(KERN_ERR "%s: RX MAC will not disable, resetting whole "
-		       "chip.\n", dev->name);
+		netdev_err(dev, "RX MAC will not disable, resetting whole chip\n");
 		return 1;
 	}
 
@@ -403,8 +395,7 @@ static int gem_rxmac_reset(struct gem *gp)
 		udelay(10);
 	}
 	if (limit == 5000) {
-		printk(KERN_ERR "%s: RX DMA will not disable, resetting whole "
-		       "chip.\n", dev->name);
+		netdev_err(dev, "RX DMA will not disable, resetting whole chip\n");
 		return 1;
 	}
 
@@ -419,8 +410,7 @@ static int gem_rxmac_reset(struct gem *gp)
 		udelay(10);
 	}
 	if (limit == 5000) {
-		printk(KERN_ERR "%s: RX reset command will not execute, resetting "
-		       "whole chip.\n", dev->name);
+		netdev_err(dev, "RX reset command will not execute, resetting whole chip\n");
 		return 1;
 	}
 
@@ -429,8 +419,7 @@ static int gem_rxmac_reset(struct gem *gp)
 		struct gem_rxd *rxd = &gp->init_block->rxd[i];
 
 		if (gp->rx_skbs[i] == NULL) {
-			printk(KERN_ERR "%s: Parts of RX ring empty, resetting "
-			       "whole chip.\n", dev->name);
+			netdev_err(dev, "Parts of RX ring empty, resetting whole chip\n");
 			return 1;
 		}
 
@@ -479,8 +468,7 @@ static int gem_rxmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s
 	if (rxmac_stat & MAC_RXSTAT_OFLW) {
 		u32 smac = readl(gp->regs + MAC_SMACHINE);
 
-		printk(KERN_ERR "%s: RX MAC fifo overflow smac[%08x].\n",
-				dev->name, smac);
+		netdev_err(dev, "RX MAC fifo overflow smac[%08x]\n", smac);
 		gp->net_stats.rx_over_errors++;
 		gp->net_stats.rx_fifo_errors++;
 
@@ -542,19 +530,18 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
 
 	if (gp->pdev->vendor == PCI_VENDOR_ID_SUN &&
 	    gp->pdev->device == PCI_DEVICE_ID_SUN_GEM) {
-		printk(KERN_ERR "%s: PCI error [%04x] ",
-		       dev->name, pci_estat);
+		netdev_err(dev, "PCI error [%04x]", pci_estat);
 
 		if (pci_estat & GREG_PCIESTAT_BADACK)
-			printk("<No ACK64# during ABS64 cycle> ");
+			pr_cont(" <No ACK64# during ABS64 cycle>");
 		if (pci_estat & GREG_PCIESTAT_DTRTO)
-			printk("<Delayed transaction timeout> ");
+			pr_cont(" <Delayed transaction timeout>");
 		if (pci_estat & GREG_PCIESTAT_OTHER)
-			printk("<other>");
-		printk("\n");
+			pr_cont(" <other>");
+		pr_cont("\n");
 	} else {
 		pci_estat |= GREG_PCIESTAT_OTHER;
-		printk(KERN_ERR "%s: PCI error\n", dev->name);
+		netdev_err(dev, "PCI error\n");
 	}
 
 	if (pci_estat & GREG_PCIESTAT_OTHER) {
@@ -565,26 +552,20 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
 		 */
 		pci_read_config_word(gp->pdev, PCI_STATUS,
 				     &pci_cfg_stat);
-		printk(KERN_ERR "%s: Read PCI cfg space status [%04x]\n",
-		       dev->name, pci_cfg_stat);
+		netdev_err(dev, "Read PCI cfg space status [%04x]\n",
+			   pci_cfg_stat);
 		if (pci_cfg_stat & PCI_STATUS_PARITY)
-			printk(KERN_ERR "%s: PCI parity error detected.\n",
-			       dev->name);
+			netdev_err(dev, "PCI parity error detected\n");
 		if (pci_cfg_stat & PCI_STATUS_SIG_TARGET_ABORT)
-			printk(KERN_ERR "%s: PCI target abort.\n",
-			       dev->name);
+			netdev_err(dev, "PCI target abort\n");
 		if (pci_cfg_stat & PCI_STATUS_REC_TARGET_ABORT)
-			printk(KERN_ERR "%s: PCI master acks target abort.\n",
-			       dev->name);
+			netdev_err(dev, "PCI master acks target abort\n");
 		if (pci_cfg_stat & PCI_STATUS_REC_MASTER_ABORT)
-			printk(KERN_ERR "%s: PCI master abort.\n",
-			       dev->name);
+			netdev_err(dev, "PCI master abort\n");
 		if (pci_cfg_stat & PCI_STATUS_SIG_SYSTEM_ERROR)
-			printk(KERN_ERR "%s: PCI system error SERR#.\n",
-			       dev->name);
+			netdev_err(dev, "PCI system error SERR#\n");
 		if (pci_cfg_stat & PCI_STATUS_DETECTED_PARITY)
-			printk(KERN_ERR "%s: PCI parity error.\n",
-			       dev->name);
+			netdev_err(dev, "PCI parity error\n");
 
 		/* Write the error bits back to clear them. */
 		pci_cfg_stat &= (PCI_STATUS_PARITY |
@@ -874,8 +855,7 @@ static int gem_rx(struct gem *gp, int work_to_do)
 	gp->rx_new = entry;
 
 	if (drops)
-		printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n",
-		       gp->dev->name);
+		netdev_info(gp->dev, "Memory squeeze, deferring packet\n");
 
 	return work_done;
 }
@@ -981,21 +961,19 @@ static void gem_tx_timeout(struct net_device *dev)
 {
 	struct gem *gp = netdev_priv(dev);
 
-	printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
+	netdev_err(dev, "transmit timed out, resetting\n");
 	if (!gp->running) {
-		printk("%s: hrm.. hw not running !\n", dev->name);
+		netdev_err(dev, "hrm.. hw not running !\n");
 		return;
 	}
-	printk(KERN_ERR "%s: TX_STATE[%08x:%08x:%08x]\n",
-	       dev->name,
-	       readl(gp->regs + TXDMA_CFG),
-	       readl(gp->regs + MAC_TXSTAT),
-	       readl(gp->regs + MAC_TXCFG));
-	printk(KERN_ERR "%s: RX_STATE[%08x:%08x:%08x]\n",
-	       dev->name,
-	       readl(gp->regs + RXDMA_CFG),
-	       readl(gp->regs + MAC_RXSTAT),
-	       readl(gp->regs + MAC_RXCFG));
+	netdev_err(dev, "TX_STATE[%08x:%08x:%08x]\n",
+		   readl(gp->regs + TXDMA_CFG),
+		   readl(gp->regs + MAC_TXSTAT),
+		   readl(gp->regs + MAC_TXCFG));
+	netdev_err(dev, "RX_STATE[%08x:%08x:%08x]\n",
+		   readl(gp->regs + RXDMA_CFG),
+		   readl(gp->regs + MAC_RXSTAT),
+		   readl(gp->regs + MAC_RXCFG));
 
 	spin_lock_irq(&gp->lock);
 	spin_lock(&gp->tx_lock);
@@ -1048,8 +1026,7 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb,
 	if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) {
 		netif_stop_queue(dev);
 		spin_unlock_irqrestore(&gp->tx_lock, flags);
-		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
-		       dev->name);
+		netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
 		return NETDEV_TX_BUSY;
 	}
 
@@ -1158,8 +1135,7 @@ static void gem_pcs_reset(struct gem *gp)
 			break;
 	}
 	if (limit < 0)
-		printk(KERN_WARNING "%s: PCS reset bit would not clear.\n",
-		       gp->dev->name);
+		netdev_warn(gp->dev, "PCS reset bit would not clear\n");
 }
 
 static void gem_pcs_reinit_adv(struct gem *gp)
@@ -1230,7 +1206,7 @@ static void gem_reset(struct gem *gp)
 	} while (val & (GREG_SWRST_TXRST | GREG_SWRST_RXRST));
 
 	if (limit < 0)
-		printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name);
+		netdev_err(gp->dev, "SW reset is ghetto\n");
 
 	if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes)
 		gem_pcs_reinit_adv(gp);
@@ -1395,9 +1371,8 @@ static int gem_set_link_modes(struct gem *gp)
 		speed = SPEED_1000;
 	}
 
-	if (netif_msg_link(gp))
-		printk(KERN_INFO "%s: Link is up at %d Mbps, %s-duplex.\n",
-			gp->dev->name, speed, (full_duplex ? "full" : "half"));
+	netif_info(gp, link, gp->dev, "Link is up at %d Mbps, %s-duplex\n",
+		   speed, (full_duplex ? "full" : "half"));
 
 	if (!gp->running)
 		return 0;
@@ -1451,15 +1426,13 @@ static int gem_set_link_modes(struct gem *gp)
 
 	if (netif_msg_link(gp)) {
 		if (pause) {
-			printk(KERN_INFO "%s: Pause is enabled "
-			       "(rxfifo: %d off: %d on: %d)\n",
-			       gp->dev->name,
-			       gp->rx_fifo_sz,
-			       gp->rx_pause_off,
-			       gp->rx_pause_on);
+			netdev_info(gp->dev,
+				    "Pause is enabled (rxfifo: %d off: %d on: %d)\n",
+				    gp->rx_fifo_sz,
+				    gp->rx_pause_off,
+				    gp->rx_pause_on);
 		} else {
-			printk(KERN_INFO "%s: Pause is disabled\n",
-			       gp->dev->name);
+			netdev_info(gp->dev, "Pause is disabled\n");
 		}
 	}
 
@@ -1484,9 +1457,8 @@ static int gem_mdio_link_not_up(struct gem *gp)
 {
 	switch (gp->lstate) {
 	case link_force_ret:
-		if (netif_msg_link(gp))
-			printk(KERN_INFO "%s: Autoneg failed again, keeping"
-				" forced mode\n", gp->dev->name);
+		netif_info(gp, link, gp->dev,
+			   "Autoneg failed again, keeping forced mode\n");
 		gp->phy_mii.def->ops->setup_forced(&gp->phy_mii,
 			gp->last_forced_speed, DUPLEX_HALF);
 		gp->timer_ticks = 5;
@@ -1499,9 +1471,7 @@ static int gem_mdio_link_not_up(struct gem *gp)
 		 */
 		if (gp->phy_mii.def->magic_aneg)
 			return 1;
-		if (netif_msg_link(gp))
-			printk(KERN_INFO "%s: switching to forced 100bt\n",
-				gp->dev->name);
+		netif_info(gp, link, gp->dev, "switching to forced 100bt\n");
 		/* Try forced modes. */
 		gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, SPEED_100,
 			DUPLEX_HALF);
@@ -1517,9 +1487,8 @@ static int gem_mdio_link_not_up(struct gem *gp)
 			gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, SPEED_10,
 				DUPLEX_HALF);
 			gp->timer_ticks = 5;
-			if (netif_msg_link(gp))
-				printk(KERN_INFO "%s: switching to forced 10bt\n",
-					gp->dev->name);
+			netif_info(gp, link, gp->dev,
+				   "switching to forced 10bt\n");
 			return 0;
 		} else
 			return 1;
@@ -1574,8 +1543,8 @@ static void gem_link_timer(unsigned long data)
 			gp->last_forced_speed = gp->phy_mii.speed;
 			gp->timer_ticks = 5;
 			if (netif_msg_link(gp))
-				printk(KERN_INFO "%s: Got link after fallback, retrying"
-					" autoneg once...\n", gp->dev->name);
+				netdev_info(gp->dev,
+					    "Got link after fallback, retrying autoneg once...\n");
 			gp->phy_mii.def->ops->setup_aneg(&gp->phy_mii, gp->phy_mii.advertising);
 		} else if (gp->lstate != link_up) {
 			gp->lstate = link_up;
@@ -1589,9 +1558,7 @@ static void gem_link_timer(unsigned long data)
 		 */
 		if (gp->lstate == link_up) {
 			gp->lstate = link_down;
-			if (netif_msg_link(gp))
-				printk(KERN_INFO "%s: Link down\n",
-					gp->dev->name);
+			netif_info(gp, link, gp->dev, "Link down\n");
 			netif_carrier_off(gp->dev);
 			gp->reset_task_pending = 1;
 			schedule_work(&gp->reset_task);
@@ -1746,8 +1713,7 @@ static void gem_init_phy(struct gem *gp)
 			if (phy_read(gp, MII_BMCR) != 0xffff)
 				break;
 			if (i == 2)
-				printk(KERN_WARNING "%s: GMAC PHY not responding !\n",
-				       gp->dev->name);
+				netdev_warn(gp->dev, "GMAC PHY not responding !\n");
 		}
 	}
 
@@ -2038,7 +2004,7 @@ static int gem_check_invariants(struct gem *gp)
 		 * as this chip has no gigabit PHY.
 		 */
 		if ((mif_cfg & (MIF_CFG_MDI0 | MIF_CFG_MDI1)) == 0) {
-			printk(KERN_ERR PFX "RIO GEM lacks MII phy, mif_cfg[%08x]\n",
+			pr_err("RIO GEM lacks MII phy, mif_cfg[%08x]\n",
 			       mif_cfg);
 			return -1;
 		}
@@ -2078,7 +2044,7 @@ static int gem_check_invariants(struct gem *gp)
 		}
 		if (i == 32) {
 			if (pdev->device != PCI_DEVICE_ID_SUN_GEM) {
-				printk(KERN_ERR PFX "RIO MII phy will not respond.\n");
+				pr_err("RIO MII phy will not respond\n");
 				return -1;
 			}
 			gp->phy_type = phy_serdes;
@@ -2093,7 +2059,7 @@ static int gem_check_invariants(struct gem *gp)
 		if (pdev->device == PCI_DEVICE_ID_SUN_GEM) {
 			if (gp->tx_fifo_sz != (9 * 1024) ||
 			    gp->rx_fifo_sz != (20 * 1024)) {
-				printk(KERN_ERR PFX "GEM has bogus fifo sizes tx(%d) rx(%d)\n",
+				pr_err("GEM has bogus fifo sizes tx(%d) rx(%d)\n",
 				       gp->tx_fifo_sz, gp->rx_fifo_sz);
 				return -1;
 			}
@@ -2101,7 +2067,7 @@ static int gem_check_invariants(struct gem *gp)
 		} else {
 			if (gp->tx_fifo_sz != (2 * 1024) ||
 			    gp->rx_fifo_sz != (2 * 1024)) {
-				printk(KERN_ERR PFX "RIO GEM has bogus fifo sizes tx(%d) rx(%d)\n",
+				pr_err("RIO GEM has bogus fifo sizes tx(%d) rx(%d)\n",
 				       gp->tx_fifo_sz, gp->rx_fifo_sz);
 				return -1;
 			}
@@ -2239,7 +2205,7 @@ static int gem_do_start(struct net_device *dev)
 
 	if (request_irq(gp->pdev->irq, gem_interrupt,
 				   IRQF_SHARED, dev->name, (void *)dev)) {
-		printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name);
+		netdev_err(dev, "failed to request irq !\n");
 
 		spin_lock_irqsave(&gp->lock, flags);
 		spin_lock(&gp->tx_lock);
@@ -2378,9 +2344,8 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
 
 	mutex_lock(&gp->pm_mutex);
 
-	printk(KERN_INFO "%s: suspending, WakeOnLan %s\n",
-	       dev->name,
-	       (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled");
+	netdev_info(dev, "suspending, WakeOnLan %s\n",
+		    (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled");
 
 	/* Keep the cell enabled during the entire operation */
 	spin_lock_irqsave(&gp->lock, flags);
@@ -2440,7 +2405,7 @@ static int gem_resume(struct pci_dev *pdev)
 	struct gem *gp = netdev_priv(dev);
 	unsigned long flags;
 
-	printk(KERN_INFO "%s: resuming\n", dev->name);
+	netdev_info(dev, "resuming\n");
 
 	mutex_lock(&gp->pm_mutex);
 
@@ -2452,8 +2417,7 @@ static int gem_resume(struct pci_dev *pdev)
 
 	/* Make sure PCI access and bus master are enabled */
 	if (pci_enable_device(gp->pdev)) {
-		printk(KERN_ERR "%s: Can't re-enable chip !\n",
-		       dev->name);
+		netdev_err(dev, "Can't re-enable chip !\n");
 		/* Put cell and forget it for now, it will be considered as
 		 * still asleep, a new sleep cycle may bring it back
 		 */
@@ -2938,7 +2902,7 @@ static int __devinit gem_get_device_address(struct gem *gp)
 		addr = idprom->id_ethaddr;
 #else
 		printk("\n");
-		printk(KERN_ERR "%s: can't get mac-address\n", dev->name);
+		pr_err("%s: can't get mac-address\n", dev->name);
 		return -1;
 #endif
 	}
@@ -3009,14 +2973,12 @@ static const struct net_device_ops gem_netdev_ops = {
 static int __devinit gem_init_one(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {
-	static int gem_version_printed = 0;
 	unsigned long gemreg_base, gemreg_len;
 	struct net_device *dev;
 	struct gem *gp;
 	int err, pci_using_dac;
 
-	if (gem_version_printed++ == 0)
-		printk(KERN_INFO "%s", version);
+	printk_once(KERN_INFO "%s", version);
 
 	/* Apple gmac note: during probe, the chip is powered up by
 	 * the arch code to allow the code below to work (and to let
@@ -3026,8 +2988,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 	 */
 	err = pci_enable_device(pdev);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot enable MMIO operation, "
-		       "aborting.\n");
+		pr_err("Cannot enable MMIO operation, aborting\n");
 		return err;
 	}
 	pci_set_master(pdev);
@@ -3048,8 +3009,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 	} else {
 		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
-			printk(KERN_ERR PFX "No usable DMA configuration, "
-			       "aborting.\n");
+			pr_err("No usable DMA configuration, aborting\n");
 			goto err_disable_device;
 		}
 		pci_using_dac = 0;
@@ -3059,15 +3019,14 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 	gemreg_len = pci_resource_len(pdev, 0);
 
 	if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) {
-		printk(KERN_ERR PFX "Cannot find proper PCI device "
-		       "base address, aborting.\n");
+		pr_err("Cannot find proper PCI device base address, aborting\n");
 		err = -ENODEV;
 		goto err_disable_device;
 	}
 
 	dev = alloc_etherdev(sizeof(*gp));
 	if (!dev) {
-		printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
+		pr_err("Etherdev alloc failed, aborting\n");
 		err = -ENOMEM;
 		goto err_disable_device;
 	}
@@ -3077,8 +3036,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 
 	err = pci_request_regions(pdev, DRV_NAME);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot obtain PCI resources, "
-		       "aborting.\n");
+		pr_err("Cannot obtain PCI resources, aborting\n");
 		goto err_out_free_netdev;
 	}
 
@@ -3104,8 +3062,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 
 	gp->regs = ioremap(gemreg_base, gemreg_len);
 	if (!gp->regs) {
-		printk(KERN_ERR PFX "Cannot map device registers, "
-		       "aborting.\n");
+		pr_err("Cannot map device registers, aborting\n");
 		err = -EIO;
 		goto err_out_free_res;
 	}
@@ -3150,8 +3107,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 		pci_alloc_consistent(pdev, sizeof(struct gem_init_block),
 				     &gp->gblock_dvma);
 	if (!gp->init_block) {
-		printk(KERN_ERR PFX "Cannot allocate init block, "
-		       "aborting.\n");
+		pr_err("Cannot allocate init block, aborting\n");
 		err = -ENOMEM;
 		goto err_out_iounmap;
 	}
@@ -3180,19 +3136,18 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 
 	/* Register with kernel */
 	if (register_netdev(dev)) {
-		printk(KERN_ERR PFX "Cannot register net device, "
-		       "aborting.\n");
+		pr_err("Cannot register net device, aborting\n");
 		err = -ENOMEM;
 		goto err_out_free_consistent;
 	}
 
-	printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet %pM\n",
-	       dev->name, dev->dev_addr);
+	netdev_info(dev, "Sun GEM (PCI) 10/100/1000BaseT Ethernet %pM\n",
+		    dev->dev_addr);
 
 	if (gp->phy_type == phy_mii_mdio0 ||
      	    gp->phy_type == phy_mii_mdio1)
-		printk(KERN_INFO "%s: Found %s PHY\n", dev->name,
-			gp->phy_mii.def ? gp->phy_mii.def->name : "no");
+		netdev_info(dev, "Found %s PHY\n",
+			    gp->phy_mii.def ? gp->phy_mii.def->name : "no");
 
 	/* GEM can do it all... */
 	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_LLTX;
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 78f8cee..4a4fac6 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -1175,7 +1175,8 @@ int mii_phy_probe(struct mii_phy *phy, int mii_id)
 
 	/* Read ID and find matching entry */
 	id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2));
-	printk(KERN_DEBUG "PHY ID: %x, addr: %x\n", id, mii_id);
+	printk(KERN_DEBUG KBUILD_MODNAME ": " "PHY ID: %x, addr: %x\n",
+	       id, mii_id);
 	for (i=0; (def = mii_phy_table[i]) != NULL; i++)
 		if ((id & def->phy_id_mask) == def->phy_id)
 			break;
-- 
1.7.2.19.g9a302


^ permalink raw reply related

* [PATCH net-next 2/2] drivers/net/sunvnet.c: Use pr_<level> and netdev_<level>
From: Joe Perches @ 2010-08-17 17:55 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel

Use the current message logging styles.

Signed-off-by: Joe Perches <joe@perches.com>
---
 drivers/net/sunvnet.c |   50 ++++++++++++++++++++----------------------------
 1 files changed, 21 insertions(+), 29 deletions(-)

diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c
index d281a7b..bf3c762 100644
--- a/drivers/net/sunvnet.c
+++ b/drivers/net/sunvnet.c
@@ -3,6 +3,8 @@
  * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -20,7 +22,6 @@
 #include "sunvnet.h"
 
 #define DRV_MODULE_NAME		"sunvnet"
-#define PFX DRV_MODULE_NAME	": "
 #define DRV_MODULE_VERSION	"1.0"
 #define DRV_MODULE_RELDATE	"June 25, 2007"
 
@@ -45,9 +46,9 @@ static int vnet_handle_unknown(struct vnet_port *port, void *arg)
 {
 	struct vio_msg_tag *pkt = arg;
 
-	printk(KERN_ERR PFX "Received unknown msg [%02x:%02x:%04x:%08x]\n",
+	pr_err("Received unknown msg [%02x:%02x:%04x:%08x]\n",
 	       pkt->type, pkt->stype, pkt->stype_env, pkt->sid);
-	printk(KERN_ERR PFX "Resetting connection.\n");
+	pr_err("Resetting connection\n");
 
 	ldc_disconnect(port->vio.lp);
 
@@ -400,8 +401,8 @@ static int vnet_rx(struct vnet_port *port, void *msgbuf)
 	if (unlikely(pkt->tag.stype_env != VIO_DRING_DATA))
 		return 0;
 	if (unlikely(pkt->seq != dr->rcv_nxt)) {
-		printk(KERN_ERR PFX "RX out of sequence seq[0x%llx] "
-		       "rcv_nxt[0x%llx]\n", pkt->seq, dr->rcv_nxt);
+		pr_err("RX out of sequence seq[0x%llx] rcv_nxt[0x%llx]\n",
+		       pkt->seq, dr->rcv_nxt);
 		return 0;
 	}
 
@@ -464,8 +465,7 @@ static int handle_mcast(struct vnet_port *port, void *msgbuf)
 	struct vio_net_mcast_info *pkt = msgbuf;
 
 	if (pkt->tag.stype != VIO_SUBTYPE_ACK)
-		printk(KERN_ERR PFX "%s: Got unexpected MCAST reply "
-		       "[%02x:%02x:%04x:%08x]\n",
+		pr_err("%s: Got unexpected MCAST reply [%02x:%02x:%04x:%08x]\n",
 		       port->vp->dev->name,
 		       pkt->tag.type,
 		       pkt->tag.stype,
@@ -520,7 +520,7 @@ static void vnet_event(void *arg, int event)
 	}
 
 	if (unlikely(event != LDC_EVENT_DATA_READY)) {
-		printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event);
+		pr_warning("Unexpected LDC event %d\n", event);
 		spin_unlock_irqrestore(&vio->lock, flags);
 		return;
 	}
@@ -662,8 +662,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			netif_stop_queue(dev);
 
 			/* This is a hard error, log it. */
-			printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
-			       "queue awake!\n", dev->name);
+			netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
 			dev->stats.tx_errors++;
 		}
 		spin_unlock_irqrestore(&port->vio.lock, flags);
@@ -696,8 +695,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	err = __vnet_tx_trigger(port);
 	if (unlikely(err < 0)) {
-		printk(KERN_INFO PFX "%s: TX trigger error %d\n",
-		       dev->name, err);
+		netdev_info(dev, "TX trigger error %d\n", err);
 		d->hdr.state = VIO_DESC_FREE;
 		dev->stats.tx_carrier_errors++;
 		goto out_dropped_unlock;
@@ -952,12 +950,12 @@ static int __devinit vnet_port_alloc_tx_bufs(struct vnet_port *port)
 
 		err = -ENOMEM;
 		if (!buf) {
-			printk(KERN_ERR "TX buffer allocation failure\n");
+			pr_err("TX buffer allocation failure\n");
 			goto err_out;
 		}
 		err = -EFAULT;
 		if ((unsigned long)buf & (8UL - 1)) {
-			printk(KERN_ERR "TX buffer misaligned\n");
+			pr_err("TX buffer misaligned\n");
 			kfree(buf);
 			goto err_out;
 		}
@@ -1030,7 +1028,7 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac)
 
 	dev = alloc_etherdev(sizeof(*vp));
 	if (!dev) {
-		printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
+		pr_err("Etherdev alloc failed, aborting\n");
 		return ERR_PTR(-ENOMEM);
 	}
 
@@ -1056,12 +1054,11 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac)
 
 	err = register_netdev(dev);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot register net device, "
-		       "aborting.\n");
+		pr_err("Cannot register net device, aborting\n");
 		goto err_out_free_dev;
 	}
 
-	printk(KERN_INFO "%s: Sun LDOM vnet %pM\n", dev->name, dev->dev_addr);
+	netdev_info(dev, "Sun LDOM vnet %pM\n", dev->dev_addr);
 
 	list_add(&vp->list, &vnet_list);
 
@@ -1133,10 +1130,7 @@ static struct vio_driver_ops vnet_vio_ops = {
 
 static void __devinit print_version(void)
 {
-	static int version_printed;
-
-	if (version_printed++ == 0)
-		printk(KERN_INFO "%s", version);
+	printk_once(KERN_INFO "%s", version);
 }
 
 const char *remote_macaddr_prop = "remote-mac-address";
@@ -1157,7 +1151,7 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
 
 	vp = vnet_find_parent(hp, vdev->mp);
 	if (IS_ERR(vp)) {
-		printk(KERN_ERR PFX "Cannot find port parent vnet.\n");
+		pr_err("Cannot find port parent vnet\n");
 		err = PTR_ERR(vp);
 		goto err_out_put_mdesc;
 	}
@@ -1165,15 +1159,14 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
 	rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len);
 	err = -ENODEV;
 	if (!rmac) {
-		printk(KERN_ERR PFX "Port lacks %s property.\n",
-		       remote_macaddr_prop);
+		pr_err("Port lacks %s property\n", remote_macaddr_prop);
 		goto err_out_put_mdesc;
 	}
 
 	port = kzalloc(sizeof(*port), GFP_KERNEL);
 	err = -ENOMEM;
 	if (!port) {
-		printk(KERN_ERR PFX "Cannot allocate vnet_port.\n");
+		pr_err("Cannot allocate vnet_port\n");
 		goto err_out_put_mdesc;
 	}
 
@@ -1214,9 +1207,8 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
 
 	dev_set_drvdata(&vdev->dev, port);
 
-	printk(KERN_INFO "%s: PORT ( remote-mac %pM%s )\n",
-	       vp->dev->name, port->raddr,
-	       switch_port ? " switch-port" : "");
+	pr_info("%s: PORT ( remote-mac %pM%s )\n",
+		vp->dev->name, port->raddr, switch_port ? " switch-port" : "");
 
 	vio_port_up(&port->vio);
 
-- 
1.7.2.19.g9a302


^ permalink raw reply related

* Re: BUG: IPv6 stops working after a while, needs ip ne del command to reset
From: Matt Carlson @ 2010-08-17 18:31 UTC (permalink / raw)
  To: Thomas Habets
  Cc: Matthew Carlson, Eric Dumazet, linux-kernel@vger.kernel.org,
	netdev, Michael Chan
In-Reply-To: <alpine.DEB.1.10.1008171928160.21857@red.crap.retrofitta.se>

On Tue, Aug 17, 2010 at 10:29:54AM -0700, Thomas Habets wrote:
> On Tue, 17 Aug 2010, Matt Carlson wrote:
> >>> But if problem remains even with "ifconfig eth0 allmulti" I suspect a
> >>> NIC firmware problem. (allmulti set to 1 all the 128 bits of filters)
> > Thomas, can you give me the output of 'ethtool -i eth0'?
> 
> $ sudo ethtool -i eth0
> driver: tg3
> version: 3.110
> firmware-version: 5715-v3.28, UMP 1.15
> bus-info: 0000:03:04.0

Thanks.  I put the question out to the firmware developer.  While we
wait, can you keep Eric's patch in place and give me the results along
with the output of 'ethtool -d eth0 | grep 0x047' after the problem
happens?

Eric's patch shows the hash registers at the time they are programmed.
I'm interested to see if the values change (by firmware) after the
failure.


^ permalink raw reply

* Re: [PATCH] ether1: Use net_device_stats from struct net_device
From: Dan Carpenter @ 2010-08-17 18:32 UTC (permalink / raw)
  To: Tobias Klauser
  Cc: David S. Miller, Russell King, netdev, linux-arm-kernel,
	kernel-janitors
In-Reply-To: <1282061719-19645-1-git-send-email-tklauser@distanz.ch>

On Tue, Aug 17, 2010 at 06:15:19PM +0200, Tobias Klauser wrote:
> struct net_device has its own struct net_device_stats member, so use
> this one instead of a private copy in the ether1_priv struct.
> 

You missed one in ether1_open().

        memset (&priv(dev)->stats, 0, sizeof (struct net_device_stats));

regards,
dan carpenter



^ permalink raw reply

* Re: [PATCH] ether1: Use net_device_stats from struct net_device
From: Tobias Klauser @ 2010-08-17 18:34 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: David S. Miller, Russell King, netdev, linux-arm-kernel,
	kernel-janitors
In-Reply-To: <20100817183205.GH645@bicker>

On 2010-08-17 at 20:32:05 +0200, Dan Carpenter <error27@gmail.com> wrote:
> On Tue, Aug 17, 2010 at 06:15:19PM +0200, Tobias Klauser wrote:
> > struct net_device has its own struct net_device_stats member, so use
> > this one instead of a private copy in the ether1_priv struct.
> > 
> 
> You missed one in ether1_open().
> 
>         memset (&priv(dev)->stats, 0, sizeof (struct net_device_stats));

Thanks. I'll send an updated patch.

Tobias

^ permalink raw reply

* Re: [PATCH] ether3: Use net_device_stats from struct net_device
From: Dan Carpenter @ 2010-08-17 18:35 UTC (permalink / raw)
  To: Tobias Klauser
  Cc: David S. Miller, Russell King, netdev, linux-arm-kernel,
	kernel-janitors
In-Reply-To: <1282061733-19700-1-git-send-email-tklauser@distanz.ch>

On Tue, Aug 17, 2010 at 06:15:33PM +0200, Tobias Klauser wrote:
> struct net_device has its own struct net_device_stats member, so use
> this one instead of a private copy in the ether1_priv struct.
> 

Two were missed, one from ether3_init_for_open()

	memset(&priv(dev)->stats, 0, sizeof(struct net_device_stats));

and another from ether3_rx().

	struct net_device_stats *stats = &priv(dev)->stats;

regards,
dan carpenter



^ permalink raw reply

* Inconsistent lock state in ipt_do_table
From: David Vrabel @ 2010-08-17 17:45 UTC (permalink / raw)
  To: netdev; +Cc: Changli Gao

Is this related to or fixed by

http://marc.info/?l=linux-netdev&m=128202731626693&w=2

[   15.676004] [ INFO: inconsistent lock state ]
[   15.676004] 2.6.36-rc1+ #4
[   15.676004] ---------------------------------
[   15.689917] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
[   15.696562] ypwhich/1939 [HC0[0]:SC1[2]:HE1:SE0] takes:
[   15.701742]  (&(&lock->lock)->rlock){+.?...}, at: [<f805578d>]
ipt_do_table+0
xad/0x570 [ip_tables]
[   15.701742] {SOFTIRQ-ON-W} state was registered at:
[   15.701742]   [<c016b1fb>] __lock_acquire+0x6cb/0xac0
[   15.701742]   [<c016b676>] lock_acquire+0x86/0x100
[   15.701742]   [<c03f6908>] _raw_spin_lock+0x38/0x50
[   15.701742]   [<f8054285>] get_counters+0xa5/0x110 [ip_tables]
[   15.701742]   [<f8055588>] do_ipt_get_ctl+0x2d8/0x430 [ip_tables]
[   15.701742]   [<c03820d5>] nf_sockopt+0x105/0x160
[   15.701742]   [<c0382159>] nf_getsockopt+0x29/0x30
[   15.701742]   [<c038e81a>] ip_getsockopt+0x15a/0x700
[   15.701742]   [<c03ab592>] raw_getsockopt+0x32/0xc0
[   15.701742]   [<c0351117>] sock_common_getsockopt+0x27/0x40
[   15.701742]   [<c034edb5>] sys_getsockopt+0x75/0xb0
[   15.701742]   [<c035080c>] sys_socketcall+0x13c/0x2d0
[   15.701742]   [<c0102bdc>] sysenter_do_call+0x12/0x38
[   15.701742] irq event stamp: 1802
[   15.701742] hardirqs last  enabled at (1802): [<c03f74ae>]
restore_all_notrac
e+0x0/0x18
[   15.701742] hardirqs last disabled at (1801): [<c03f7638>]
reschedule_interru
pt+0x28/0x40
[   15.701742] softirqs last  enabled at (1794): [<c0362e4b>]
dev_queue_xmit+0x2
0b/0x5c0
[   15.701742] softirqs last disabled at (1795): [<c013ea27>]
do_softirq+0x67/0x
70
[   15.701742]
[   15.701742] other info that might help us debug this:
[   15.701742] 3 locks held by ypwhich/1939:
[   15.701742]  #0:  (sk_lock-AF_INET){+.+.+.}, at: [<c03af340>]
udp_sendmsg+0x2
60/0x720
[   15.701742]  #1:  (rcu_read_lock){.+.+..}, at: [<c035d624>]
__netif_receive_s
kb+0x94/0x560
[   15.701742]  #2:  (rcu_read_lock){.+.+..}, at: [<c0381010>]
nf_hook_slow+0x0/
0x110
[   15.701742]
[   15.701742] stack backtrace:
[   15.701742] Pid: 1939, comm: ypwhich Not tainted 2.6.36-rc1+ #4
[   15.701742] Call Trace:
[   15.701742]  [<c0167c46>] print_usage_bug+0x166/0x1b0
[   15.701742]  [<c0168206>] mark_lock+0x576/0x5b0
[   15.701742]  [<c01694e0>] ? check_usage_forwards+0x0/0xd0
[   15.701742]  [<c016b1b8>] __lock_acquire+0x688/0xac0
[   15.701742]  [<c016b676>] lock_acquire+0x86/0x100
[   15.701742]  [<f805578d>] ? ipt_do_table+0xad/0x570 [ip_tables]
[   15.701742]  [<c03f6908>] _raw_spin_lock+0x38/0x50
[   15.701742]  [<f805578d>] ? ipt_do_table+0xad/0x570 [ip_tables]
[   15.701742]  [<f805578d>] ipt_do_table+0xad/0x570 [ip_tables]
[   15.701742]  [<c016ae28>] ? __lock_acquire+0x2f8/0xac0
[   15.701742]  [<f8557032>] iptable_filter_hook+0x32/0x70 [iptable_filter]
[   15.701742]  [<f8557000>] ? iptable_filter_hook+0x0/0x70 [iptable_filter]
[   15.701742]  [<c0380d23>] nf_iterate+0x53/0x80
[   15.701742]  [<c0388820>] ? ip_local_deliver_finish+0x0/0x2f0
[   15.701742]  [<c03810d8>] nf_hook_slow+0xc8/0x110
[   15.701742]  [<c0388820>] ? ip_local_deliver_finish+0x0/0x2f0
[   15.701742]  [<c038828c>] ip_local_deliver+0x6c/0xa0
[   15.701742]  [<c0388820>] ? ip_local_deliver_finish+0x0/0x2f0
[   15.701742]  [<c0388422>] ip_rcv_finish+0x162/0x560
[   15.701742]  [<c0388166>] ip_rcv+0x266/0x320
[   15.701742]  [<c0168295>] ? mark_held_locks+0x55/0x70
[   15.701742]  [<c0387f00>] ? ip_rcv+0x0/0x320
[   15.701742]  [<c035d849>] __netif_receive_skb+0x2b9/0x560
[   15.701742]  [<c035d624>] ? __netif_receive_skb+0x94/0x560
[   15.701742]  [<c016007b>] ? do_adjtimex+0x69b/0x790
[   15.701742]  [<c0362000>] process_backlog+0xb0/0x190
[   15.701742]  [<c0361d16>] net_rx_action+0xf6/0x1d0
[   15.701742]  [<c013e887>] __do_softirq+0xa7/0x1e0
[   15.701742]  [<c0336fd8>] ? loopback_xmit+0x58/0x90
[   15.701742]  [<c013ea27>] do_softirq+0x67/0x70
[   15.701742]  [<c0362e4b>] ? dev_queue_xmit+0x20b/0x5c0
[   15.701742]  [<c013f7fe>] local_bh_enable+0x9e/0xc0
[   15.701742]  [<c0362e4b>] dev_queue_xmit+0x20b/0x5c0
[   15.701742]  [<c0362c40>] ? dev_queue_xmit+0x0/0x5c0
[   15.701742]  [<c036ab6f>] ? neigh_resolve_output+0x1df/0x370
[   15.701742]  [<c036aa92>] neigh_resolve_output+0x102/0x370
[   15.701742]  [<c038e45c>] ip_finish_output+0x1fc/0x460
[   15.701742]  [<c038b2f0>] ? dst_output+0x0/0x60
[   15.701742]  [<c038d03f>] ip_output+0x8f/0x120
[   15.701742]  [<c038b2f0>] ? dst_output+0x0/0x60
[   15.701742]  [<c038c866>] ip_local_out+0x26/0x70
[   15.701742]  [<c038cb06>] ip_push_pending_frames+0x256/0x3a0
[   15.701742]  [<c03ad546>] udp_push_pending_frames+0x156/0x3e0
[   15.701742]  [<c03af40e>] udp_sendmsg+0x32e/0x720
[   15.701742]  [<c03af0e0>] ? udp_sendmsg+0x0/0x720
[   15.701742]  [<c03b66f6>] inet_sendmsg+0x96/0xe0
[   15.701742]  [<c03b6660>] ? inet_sendmsg+0x0/0xe0
[   15.701742]  [<c034ea2f>] sock_sendmsg+0xef/0x110
[   15.701742]  [<c01d90c0>] ? might_fault+0x50/0xa0
[   15.701742]  [<c02a8681>] ? _copy_from_user+0x41/0x70
[   15.701742]  [<c0350527>] sys_sendto+0xa7/0xd0
[   15.701742]  [<c016b773>] ? lock_release_non_nested+0x83/0x2b0
[   15.701742]  [<c01d90c0>] ? might_fault+0x50/0xa0
[   15.701742]  [<c01d90c0>] ? might_fault+0x50/0xa0
[   15.701742]  [<c03508a5>] sys_socketcall+0x1d5/0x2d0
[   15.701742]  [<c0102bdc>] sysenter_do_call+0x12/0x38

-- 
David Vrabel, Senior Software Engineer, Drivers
CSR, Churchill House, Cambridge Business Park,  Tel: +44 (0)1223 692562
Cowley Road, Cambridge, CB4 0WZ                 http://www.csr.com/


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom

^ permalink raw reply

* Re: BUG: IPv6 stops working after a while, needs ip ne del command to reset
From: Thomas Habets @ 2010-08-17 18:52 UTC (permalink / raw)
  To: Matt Carlson
  Cc: Thomas Habets, Eric Dumazet, linux-kernel@vger.kernel.org, netdev,
	Michael Chan
In-Reply-To: <20100817183112.GA4351@mcarlson.broadcom.com>

On Tue, 17 Aug 2010, Matt Carlson wrote:
> Thanks.  I put the question out to the firmware developer.  While we
> wait, can you keep Eric's patch in place and give me the results along
> with the output of 'ethtool -d eth0 | grep 0x047' after the problem
> happens?

Sure.

I think the problem occurs shortly after booting, or is triggered by it 
Linux getting a neighbor table entry for the router. The reason it took a 
while for everything to actually stop working is that the router was 
caching and presumably updating its neighbors cache when it saw traffic.

That is, maybe it only works if the router sets up its neigbor table 
first, and not otherwise.

The problem is there now. Last output in the kernel log about this is:

$ dmesg | egrep 'eth0|^add mc|^filters='
[...]
add mc_addr(ha->addr=33:33:00:00:00:01)
add mc_addr(ha->addr=01:00:5e:00:00:01)
add mc_addr(ha->addr=33:33:ff:5c:00:02)
add mc_addr(ha->addr=33:33:ff:a3:44:24)
filters=80020001 00000000 00000000 40000000

$ sudo ethtool -d eth0 | grep 0x047
0x0470	0x80020001
0x0474	0x00000000
0x0478	0x00000000
0x047c	0x40000000

> Eric's patch shows the hash registers at the time they are programmed.
> I'm interested to see if the values change (by firmware) after the
> failure.

Look the same.

But a strange thing is that if I delete the ipv6 neighbor on the Linux 
box (ip ne del 2a00:800:752:1::5c:1 dev eth0) it suddenly answers a ND 
solicitation. I tried it just now and it "wakes it up".

Nothing was written to the kernel log when I ran this command, and the 
ethtools -d output is the same afterwards as it was before. So unless 
there's another code path that changes the registers when I do "ip ne 
del" it may still be something else.

---------
typedef struct me_s {
   char name[]      = { "Thomas Habets" };
   char email[]     = { "thomas@habets.pp.se" };
   char kernel[]    = { "Linux" };
   char *pgpKey[]   = { "http://www.habets.pp.se/pubkey.txt" };
   char pgp[] = { "A8A3 D1DD 4AE0 8467 7FDE  0945 286A E90A AD48 E854" };
   char coolcmd[]   = { "echo '. ./_&. ./_'>_;. ./_" };
} me_t;

^ permalink raw reply

* Re: [PATCH] ether3: Use net_device_stats from struct net_device
From: Tobias Klauser @ 2010-08-17 18:53 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: David S. Miller, Russell King, netdev, linux-arm-kernel,
	kernel-janitors
In-Reply-To: <20100817183551.GI645@bicker>

On 2010-08-17 at 20:35:52 +0200, Dan Carpenter <error27@gmail.com> wrote:
> On Tue, Aug 17, 2010 at 06:15:33PM +0200, Tobias Klauser wrote:
> > struct net_device has its own struct net_device_stats member, so use
> > this one instead of a private copy in the ether1_priv struct.
> > 
> 
> Two were missed, one from ether3_init_for_open()
> 
> 	memset(&priv(dev)->stats, 0, sizeof(struct net_device_stats));
> 
> and another from ether3_rx().
> 
> 	struct net_device_stats *stats = &priv(dev)->stats;

Thanks a lot again. I'll send an updated patch. Please disregard this
one.

(I wasn't able to cross-compile-test the patch here, otherwise these
would hopefully have been caught by the compiler).

  Tobias

^ permalink raw reply

* [PATCH net-next-2.6] net: simplify flags for tx timestamping
From: Oliver Hartkopp @ 2010-08-17 18:59 UTC (permalink / raw)
  To: David Miller; +Cc: Patrick Ohly, Linux Netdev List

This patch removes the abstraction introduced by the union skb_shared_tx in
the shared skb data.

The access of the different union elements at several places led to some
confusion about accessing the shared tx_flags e.g. in skb_orphan_try().

    http://marc.info/?l=linux-netdev&m=128084897415886&w=2

Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>

---

diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt
index e8c8f4f..782d1fa 100644
--- a/Documentation/networking/timestamping.txt
+++ b/Documentation/networking/timestamping.txt
@@ -172,15 +172,19 @@ struct skb_shared_hwtstamps {
 };
 
 Time stamps for outgoing packets are to be generated as follows:
-- In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero.
-  If yes, then the driver is expected to do hardware time stamping.
+- In hard_start_xmit(), check if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+  is set no-zero. If yes, then the driver is expected to do hardware time
+  stamping.
 - If this is possible for the skb and requested, then declare
-  that the driver is doing the time stamping by setting the field
-  skb_tx(skb)->in_progress non-zero. You might want to keep a pointer
-  to the associated skb for the next step and not free the skb. A driver
-  not supporting hardware time stamping doesn't do that. A driver must
-  never touch sk_buff::tstamp! It is used to store software generated
-  time stamps by the network subsystem.
+  that the driver is doing the time stamping by setting the flag 
+  SKBTX_IN_PROGRESS in skb_shinfo(skb)->tx_flags , e.g. with
+ 
+      skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+
+  You might want to keep a pointer to the associated skb for the next step
+  and not free the skb. A driver not supporting hardware time stamping doesn't
+  do that. A driver must never touch sk_buff::tstamp! It is used to store
+  software generated time stamps by the network subsystem.
 - As soon as the driver has sent the packet and/or obtained a
   hardware time stamp for it, it passes the time stamp back by
   calling skb_hwtstamp_tx() with the original skb, the raw
@@ -191,6 +195,6 @@ Time stamps for outgoing packets are to be generated as follows:
   this would occur at a later time in the processing pipeline than other
   software time stamping and therefore could lead to unexpected deltas
   between time stamps.
-- If the driver did not call set skb_tx(skb)->in_progress, then
+- If the driver did not set the SKBTX_IN_PROGRESS flag (see above), then
   dev_hard_start_xmit() checks whether software time stamping
   is wanted as fallback and potentially generates the time stamp.
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 012613f..7a0e415 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -803,15 +803,14 @@ static void bfin_dump_hwtamp(char *s, ktime_t *hw, ktime_t *ts, struct timecompa
 static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
 {
 	struct bfin_mac_local *lp = netdev_priv(netdev);
-	union skb_shared_tx *shtx = skb_tx(skb);
 
-	if (shtx->hardware) {
+	if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
 		int timeout_cnt = MAX_TIMEOUT_CNT;
 
 		/* When doing time stamping, keep the connection to the socket
 		 * a while longer
 		 */
-		shtx->in_progress = 1;
+		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
 
 		/*
 		 * The timestamping is done at the EMAC module's MII/RMII interface
@@ -991,7 +990,6 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
 	struct bfin_mac_local *lp = netdev_priv(dev);
 	u16 *data;
 	u32 data_align = (unsigned long)(skb->data) & 0x3;
-	union skb_shared_tx *shtx = skb_tx(skb);
 
 	current_tx_ptr->skb = skb;
 
@@ -1005,7 +1003,7 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
 		 * of this field are the length of the packet payload in bytes and the higher
 		 * 4 bits are the timestamping enable field.
 		 */
-		if (shtx->hardware)
+		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
 			*data |= 0x1000;
 
 		current_tx_ptr->desc_a.start_addr = (u32)data;
@@ -1015,7 +1013,7 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
 	} else {
 		*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
 		/* enable timestamping for the sent packet */
-		if (shtx->hardware)
+		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
 			*((u16 *)(current_tx_ptr->packet)) |= 0x1000;
 		memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
 			skb->len);
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 3d9f958..e6048d6 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -2048,7 +2048,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	u32 bufaddr;
 	unsigned long flags;
 	unsigned int nr_frags, nr_txbds, length;
-	union skb_shared_tx *shtx;
 
 	/*
 	 * TOE=1 frames larger than 2500 bytes may see excess delays
@@ -2069,10 +2068,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	txq = netdev_get_tx_queue(dev, rq);
 	base = tx_queue->tx_bd_base;
 	regs = tx_queue->grp->regs;
-	shtx = skb_tx(skb);
 
 	/* check if time stamp should be generated */
-	if (unlikely(shtx->hardware && priv->hwts_tx_en))
+	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
+		     priv->hwts_tx_en))
 		do_tstamp = 1;
 
 	/* make space for additional header when fcb is needed */
@@ -2174,7 +2173,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* Setup tx hardware time stamping if requested */
 	if (unlikely(do_tstamp)) {
-		shtx->in_progress = 1;
+		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
 		if (fcb == NULL)
 			fcb = gfar_add_fcb(skb);
 		fcb->ptp = 1;
@@ -2446,7 +2445,6 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
 	int howmany = 0;
 	u32 lstatus;
 	size_t buflen;
-	union skb_shared_tx *shtx;
 
 	rx_queue = priv->rx_queue[tx_queue->qindex];
 	bdp = tx_queue->dirty_tx;
@@ -2461,8 +2459,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
 		 * When time stamping, one additional TxBD must be freed.
 		 * Also, we need to dma_unmap_single() the TxPAL.
 		 */
-		shtx = skb_tx(skb);
-		if (unlikely(shtx->in_progress))
+		if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
 			nr_txbds = frags + 2;
 		else
 			nr_txbds = frags + 1;
@@ -2476,7 +2473,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
 				(lstatus & BD_LENGTH_MASK))
 			break;
 
-		if (unlikely(shtx->in_progress)) {
+		if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
 			next = next_txbd(bdp, base, tx_ring_size);
 			buflen = next->length + GMAC_FCB_LEN;
 		} else
@@ -2485,7 +2482,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
 		dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr,
 				buflen, DMA_TO_DEVICE);
 
-		if (unlikely(shtx->in_progress)) {
+		if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
 			struct skb_shared_hwtstamps shhwtstamps;
 			u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7);
 			memset(&shhwtstamps, 0, sizeof(shhwtstamps));
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 6e63d9a..44e0ff1 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -143,7 +143,7 @@ struct igb_buffer {
 			u16 next_to_watch;
 			unsigned int bytecount;
 			u16 gso_segs;
-			union skb_shared_tx shtx;
+			u8 tx_flags;
 			u8 mapped_as_page;
 		};
 		/* RX */
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 9b4e589..985e37c 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3954,7 +3954,7 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb,
 	}
 
 	tx_ring->buffer_info[i].skb = skb;
-	tx_ring->buffer_info[i].shtx = skb_shinfo(skb)->tx_flags;
+	tx_ring->buffer_info[i].tx_flags = skb_shinfo(skb)->tx_flags;
 	/* multiply data chunks by size of headers */
 	tx_ring->buffer_info[i].bytecount = ((gso_segs - 1) * hlen) + skb->len;
 	tx_ring->buffer_info[i].gso_segs = gso_segs;
@@ -4088,7 +4088,6 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
 	u32 tx_flags = 0;
 	u16 first;
 	u8 hdr_len = 0;
-	union skb_shared_tx *shtx = skb_tx(skb);
 
 	/* need: 1 descriptor per page,
 	 *       + 2 desc gap to keep tail from touching head,
@@ -4100,8 +4099,8 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
 		return NETDEV_TX_BUSY;
 	}
 
-	if (unlikely(shtx->hardware)) {
-		shtx->in_progress = 1;
+	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
 		tx_flags |= IGB_TX_FLAGS_TSTAMP;
 	}
 
@@ -5319,7 +5318,7 @@ static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct igb_buffer *bu
 	u64 regval;
 
 	/* if skb does not support hw timestamp or TX stamp not valid exit */
-	if (likely(!buffer_info->shtx.hardware) ||
+	if (likely(!(buffer_info->tx_flags & SKBTX_HW_TSTAMP)) ||
 	    !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID))
 		return;
 
@@ -5500,7 +5499,7 @@ static void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr,
 	 * values must belong to this one here and therefore we don't need to
 	 * compare any of the additional attributes stored for it.
 	 *
-	 * If nothing went wrong, then it should have a skb_shared_tx that we
+	 * If nothing went wrong, then it should have a shared tx_flags that we
 	 * can turn into a skb_shared_hwtstamps.
 	 */
 	if (staterr & E1000_RXDADV_STAT_TSIP) {
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index d805038..f067c95 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -163,26 +163,19 @@ struct skb_shared_hwtstamps {
 	ktime_t	syststamp;
 };
 
-/**
- * struct skb_shared_tx - instructions for time stamping of outgoing packets
- * @hardware:		generate hardware time stamp
- * @software:		generate software time stamp
- * @in_progress:	device driver is going to provide
- *			hardware time stamp
- * @prevent_sk_orphan:	make sk reference available on driver level
- * @flags:		all shared_tx flags
- *
- * These flags are attached to packets as part of the
- * &skb_shared_info. Use skb_tx() to get a pointer.
- */
-union skb_shared_tx {
-	struct {
-		__u8	hardware:1,
-			software:1,
-			in_progress:1,
-			prevent_sk_orphan:1;
-	};
-	__u8 flags;
+/* Definitions for tx_flags in struct skb_shared_info */
+enum {
+	/* generate hardware time stamp */
+	SKBTX_HW_TSTAMP = 1 << 0,
+
+	/* generate software time stamp */
+	SKBTX_SW_TSTAMP = 1 << 1,
+
+	/* device driver is going to provide hardware time stamp */
+	SKBTX_IN_PROGRESS = 1 << 2,
+
+	/* ensure the originating sk reference is available on driver level */
+	SKBTX_DRV_NEEDS_SK_REF = 1 << 3,
 };
 
 /* This data is invariant across clones and lives at
@@ -195,7 +188,7 @@ struct skb_shared_info {
 	unsigned short	gso_segs;
 	unsigned short  gso_type;
 	__be32          ip6_frag_id;
-	union skb_shared_tx tx_flags;
+	__u8		tx_flags;
 	struct sk_buff	*frag_list;
 	struct skb_shared_hwtstamps hwtstamps;
 
@@ -587,11 +580,6 @@ static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb)
 	return &skb_shinfo(skb)->hwtstamps;
 }
 
-static inline union skb_shared_tx *skb_tx(struct sk_buff *skb)
-{
-	return &skb_shinfo(skb)->tx_flags;
-}
-
 /**
  *	skb_queue_empty - check if a queue is empty
  *	@list: queue head
@@ -1996,8 +1984,8 @@ extern void skb_tstamp_tx(struct sk_buff *orig_skb,
 
 static inline void sw_tx_timestamp(struct sk_buff *skb)
 {
-	union skb_shared_tx *shtx = skb_tx(skb);
-	if (shtx->software && !shtx->in_progress)
+	if (skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP &&
+	    !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
 		skb_tstamp_tx(skb, NULL);
 }
 
diff --git a/include/net/ip.h b/include/net/ip.h
index 890f972..7691aca 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -53,7 +53,7 @@ struct ipcm_cookie {
 	__be32			addr;
 	int			oif;
 	struct ip_options	*opt;
-	union skb_shared_tx	shtx;
+	__u8			tx_flags;
 };
 
 #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
diff --git a/include/net/sock.h b/include/net/sock.h
index ac53bfb..100e43b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1669,17 +1669,13 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
 
 /**
  * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped
- * @msg:	outgoing packet
  * @sk:		socket sending this packet
- * @shtx:	filled with instructions for time stamping
+ * @tx_flags:	filled with instructions for time stamping
  *
  * Currently only depends on SOCK_TIMESTAMPING* flags. Returns error code if
  * parameters are invalid.
  */
-extern int sock_tx_timestamp(struct msghdr *msg,
-			     struct sock *sk,
-			     union skb_shared_tx *shtx);
-
+extern int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags);
 
 /**
  * sk_eat_skb - Release a skb if it is no longer needed
diff --git a/net/can/raw.c b/net/can/raw.c
index a10e333..7d77e67 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -647,12 +647,12 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
 	err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
 	if (err < 0)
 		goto free_skb;
-	err = sock_tx_timestamp(msg, sk, skb_tx(skb));
+	err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
 	if (err < 0)
 		goto free_skb;
 
 	/* to be able to check the received tx sock reference in raw_rcv() */
-	skb_tx(skb)->prevent_sk_orphan = 1;
+	skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF;
 
 	skb->dev = dev;
 	skb->sk  = sk;
diff --git a/net/core/dev.c b/net/core/dev.c
index 586a11c..c1dc8a9 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1902,14 +1902,14 @@ static int dev_gso_segment(struct sk_buff *skb)
 
 /*
  * Try to orphan skb early, right before transmission by the device.
- * We cannot orphan skb if tx timestamp is requested, since
- * drivers need to call skb_tstamp_tx() to send the timestamp.
+ * We cannot orphan skb if tx timestamp is requested or the sk-reference
+ * is needed on driver level for other reasons, e.g. see net/can/raw.c
  */
 static inline void skb_orphan_try(struct sk_buff *skb)
 {
 	struct sock *sk = skb->sk;
 
-	if (sk && !skb_tx(skb)->flags) {
+	if (sk && !skb_shinfo(skb)->tx_flags) {
 		/* skb_tx_hash() wont be able to get sk.
 		 * We copy sk_hash into skb->rxhash
 		 */
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 3a2513f..99ef721 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3016,7 +3016,7 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,
 	} else {
 		/*
 		 * no hardware time stamps available,
-		 * so keep the skb_shared_tx and only
+		 * so keep the shared tx_flags and only
 		 * store software time stamp
 		 */
 		skb->tstamp = ktime_get_real();
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index a0d847c..96bc7f9 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -379,7 +379,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
 	inet->tos = ip_hdr(skb)->tos;
 	daddr = ipc.addr = rt->rt_src;
 	ipc.opt = NULL;
-	ipc.shtx.flags = 0;
+	ipc.tx_flags = 0;
 	if (icmp_param->replyopts.optlen) {
 		ipc.opt = &icmp_param->replyopts;
 		if (ipc.opt->srr)
@@ -538,7 +538,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
 	inet_sk(sk)->tos = tos;
 	ipc.addr = iph->saddr;
 	ipc.opt = &icmp_param.replyopts;
-	ipc.shtx.flags = 0;
+	ipc.tx_flags = 0;
 
 	{
 		struct flowi fl = {
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 04b6989..e807492 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -953,7 +953,7 @@ alloc_new_skb:
 				else
 					/* only the initial fragment is
 					   time stamped */
-					ipc->shtx.flags = 0;
+					ipc->tx_flags = 0;
 			}
 			if (skb == NULL)
 				goto error;
@@ -964,7 +964,7 @@ alloc_new_skb:
 			skb->ip_summed = csummode;
 			skb->csum = 0;
 			skb_reserve(skb, hh_len);
-			*skb_tx(skb) = ipc->shtx;
+			skb_shinfo(skb)->tx_flags = ipc->tx_flags;
 
 			/*
 			 *	Find where to start putting bytes.
@@ -1384,7 +1384,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
 
 	daddr = ipc.addr = rt->rt_src;
 	ipc.opt = NULL;
-	ipc.shtx.flags = 0;
+	ipc.tx_flags = 0;
 
 	if (replyopts.opt.optlen) {
 		ipc.opt = &replyopts.opt;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 009a7b2..1f85ef2 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -505,7 +505,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 
 	ipc.addr = inet->inet_saddr;
 	ipc.opt = NULL;
-	ipc.shtx.flags = 0;
+	ipc.tx_flags = 0;
 	ipc.oif = sk->sk_bound_dev_if;
 
 	if (msg->msg_controllen) {
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 32e0bef..86e757e 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -797,7 +797,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		return -EOPNOTSUPP;
 
 	ipc.opt = NULL;
-	ipc.shtx.flags = 0;
+	ipc.tx_flags = 0;
 
 	if (up->pending) {
 		/*
@@ -845,7 +845,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 	ipc.addr = inet->inet_saddr;
 
 	ipc.oif = sk->sk_bound_dev_if;
-	err = sock_tx_timestamp(msg, sk, &ipc.shtx);
+	err = sock_tx_timestamp(sk, &ipc.tx_flags);
 	if (err)
 		return err;
 	if (msg->msg_controllen) {
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 9a17f28..3616f27 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -488,7 +488,7 @@ retry:
 	skb->dev = dev;
 	skb->priority = sk->sk_priority;
 	skb->mark = sk->sk_mark;
-	err = sock_tx_timestamp(msg, sk, skb_tx(skb));
+	err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
 	if (err < 0)
 		goto out_unlock;
 
@@ -1209,7 +1209,7 @@ static int packet_snd(struct socket *sock,
 	err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len);
 	if (err)
 		goto out_free;
-	err = sock_tx_timestamp(msg, sk, skb_tx(skb));
+	err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
 	if (err < 0)
 		goto out_free;
 
diff --git a/net/socket.c b/net/socket.c
index 2270b94..7848d12 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -535,14 +535,13 @@ void sock_release(struct socket *sock)
 }
 EXPORT_SYMBOL(sock_release);
 
-int sock_tx_timestamp(struct msghdr *msg, struct sock *sk,
-		      union skb_shared_tx *shtx)
+int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags)
 {
-	shtx->flags = 0;
+	*tx_flags = 0;
 	if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE))
-		shtx->hardware = 1;
+		*tx_flags |= SKBTX_HW_TSTAMP;
 	if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE))
-		shtx->software = 1;
+		*tx_flags |= SKBTX_SW_TSTAMP;
 	return 0;
 }
 EXPORT_SYMBOL(sock_tx_timestamp);



^ permalink raw reply related

* [PATCH] ibmveth: Fix opps during MTU change on an active device
From: Robert Jennings @ 2010-08-17 19:15 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, Santiago Leon, Brian King, Rafael Camarda Silva Folco

This fixes the following opps which can occur when trying to deallocate
receive buffer pools when changing the MTU of an active ibmveth device.

Oops: Kernel access of bad area, sig: 11 [#1]
NIP: d000000004db00e8 LR: d000000004db00ac CTR: 0000000000591038
REGS: c00000007fff39d0 TRAP: 0300   Not tainted  (2.6.36-rc1)
MSR: 8000000000009032 <EE,ME,IR,DR>  CR: 22248244  XER: 00000002
DAR: 0000000000000488, DSISR: 0000000042000000
TASK = c00000007c463790[6531] 'netserver' THREAD: c00000007a154000 CPU: 0
GPR00: 0000000000000000 c00000007fff3c50 d000000004dbd360 0000000000000001 
GPR04: 0000000000000001 1fffffffffffffff 000000000000043c c00000007a8e9f60 
GPR08: c00000007a8e9e20 0000000000000245 0000000000000488 0000000000000000 
GPR12: 00000000000000c0 c000000006d70000 c00000007bfec098 c00000007bfebc2c 
GPR16: c00000007a157c78 0000000000000000 0000000000000001 0000000000000000 
GPR20: 0000000000000001 0000000000000010 c000000000b51180 c00000007a8e9d90 
GPR24: c00000007a8e9da0 c00000007a8e9580 00000000000005ea 00000000000002ff 
GPR28: 0000000000000004 0000000000000080 c000000000a946f8 c00000007a8e9d80 
NIP [d000000004db00e8] .ibmveth_remove_buffer_from_pool+0xe8/0x130 [ibmveth]
LR [d000000004db00ac] .ibmveth_remove_buffer_from_pool+0xac/0x130 [ibmveth]
Call Trace:
[c00000007fff3c50] [d000000004db00ac] .ibmveth_remove_buffer_from_pool+0xac/0x130 [ibmveth] (unreliable)
[c00000007fff3cf0] [d000000004db31dc] .ibmveth_poll+0x30c/0x460 [ibmveth]
[c00000007fff3dd0] [c00000000042c4b8] .net_rx_action+0x178/0x278
[c00000007fff3eb0] [c000000000093cf0] .__do_softirq+0x118/0x1f8
[c00000007fff3f90] [c00000000002ab3c] .call_do_softirq+0x14/0x24
[c00000007a157600] [c00000000000e3e4] .do_softirq+0xec/0x110
[c00000007a1576a0] [c000000000093394] .local_bh_enable_ip+0xb4/0xe0
[c00000007a157720] [c0000000004f0bac] ._raw_spin_unlock_bh+0x3c/0x50
[c00000007a157790] [c0000000004186e0] .release_sock+0x158/0x188
[c00000007a157840] [c000000000479660] .tcp_recvmsg+0x560/0x9b8
[c00000007a157970] [c0000000004a0d78] .inet_recvmsg+0x80/0xd8
[c00000007a157a00] [c000000000413e28] .sock_recvmsg+0x128/0x178
[c00000007a157bf0] [c0000000004164ac] .SyS_recvfrom+0xb4/0x148
[c00000007a157d70] [c000000000411f3c] .SyS_socketcall+0x274/0x360
[c00000007a157e30] [c0000000000085b4] syscall_exit+0x0/0x40

Reported-by: Rafael Camarda Silva Folco <rfolco@linux.vnet.ibm.com>
Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>

---
 drivers/net/ibmveth.c |   32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

Index: linux-2.6/drivers/net/ibmveth.c
===================================================================
--- linux-2.6.orig/drivers/net/ibmveth.c	2010-07-28 10:21:25.189339177 -0500
+++ linux-2.6/drivers/net/ibmveth.c	2010-08-12 08:46:33.378488391 -0500
@@ -1113,7 +1113,8 @@
 	struct ibmveth_adapter *adapter = netdev_priv(dev);
 	struct vio_dev *viodev = adapter->vdev;
 	int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH;
-	int i;
+	int i, rc;
+	int need_restart = 0;
 
 	if (new_mtu < IBMVETH_MAX_MTU)
 		return -EINVAL;
@@ -1127,35 +1128,32 @@
 
 	/* Deactivate all the buffer pools so that the next loop can activate
 	   only the buffer pools necessary to hold the new MTU */
-	for (i = 0; i < IbmVethNumBufferPools; i++)
-		if (adapter->rx_buff_pool[i].active) {
-			ibmveth_free_buffer_pool(adapter,
-						 &adapter->rx_buff_pool[i]);
-			adapter->rx_buff_pool[i].active = 0;
-		}
+	if (netif_running(adapter->netdev)) {
+		need_restart = 1;
+		adapter->pool_config = 1;
+		ibmveth_close(adapter->netdev);
+		adapter->pool_config = 0;
+	}
 
 	/* Look for an active buffer pool that can hold the new MTU */
 	for(i = 0; i<IbmVethNumBufferPools; i++) {
 		adapter->rx_buff_pool[i].active = 1;
 
 		if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) {
-			if (netif_running(adapter->netdev)) {
-				adapter->pool_config = 1;
-				ibmveth_close(adapter->netdev);
-				adapter->pool_config = 0;
-				dev->mtu = new_mtu;
-				vio_cmo_set_dev_desired(viodev,
-						ibmveth_get_desired_dma
-						(viodev));
-				return ibmveth_open(adapter->netdev);
-			}
 			dev->mtu = new_mtu;
 			vio_cmo_set_dev_desired(viodev,
 						ibmveth_get_desired_dma
 						(viodev));
+			if (need_restart) {
+				return ibmveth_open(adapter->netdev);
+			}
 			return 0;
 		}
 	}
+
+	if (need_restart && (rc = ibmveth_open(adapter->netdev)))
+		return rc;
+
 	return -EINVAL;
 }
 

^ permalink raw reply

* Re: sky2 driver fails to handle "rx length error: status 0x5d60100 length 2982" gracefully
From: Stephen Hemminger @ 2010-08-17 19:37 UTC (permalink / raw)
  To: Maciej Żenczykowski; +Cc: Stephen Hemminger, Linux NetDev
In-Reply-To: <AANLkTimWmJ5mTOswT8oJx7MXckzDWcSySZdAu6HZb6r7@mail.gmail.com>

On Thu, 12 Aug 2010 13:31:13 -0700
Maciej Żenczykowski <zenczykowski@gmail.com> wrote:

> > The status values indicate that the GMAC (frame parser) got a reasonable
> > size frame but the DMA merged frames together. This indicates a timing
> > problem. There are some bits which even with NDA programmers manual doesn't
> > help with. The Linux driver expects the BIOS or EEPROM to set them correctly
> > because different problems different settings.
> >
> > There is firmware in eeprom that configures internal state. On one motherboard
> > the vendor provided an update. There is no good way to update this from Linux,
> > you need to go system vendor and install firmware with their native OS (ie Windows
> > or MacOS).
> 
> Perfectly reasonable response.  If there was a firmware update fix,
> I'd apply it...
> That would presumably prevent this from ever happening in the first place.
> 
> But why doesn't the network driver reset the nic when it detects this
> 'rx length' error?
> 
> I'm not asking for the error to not happen (besides it happens very rarely)...
> 
> I'm asking, why does this error happening permanently hose the network driver.
> Once this happens the network card is not usable - traffic does not
> flow through it.
> You need to "ip link set down && ... up" to fix it.  Isn't this
> something the driver could and should do all by itself?

Also, the driver could schedule a reset (that is what the watchdog does),
but it looks like the receive DMA is walking past the end of the packet
and that is really dangerous since it could clobber random memory.

You might want to increase the size of rx DMA buffer and dump the
contents of the receive buffer to see if there is a memory corruption
risk. If the End Of Frame DMA hardware is not working, there is a real
danger if the driver silently continues.

-- 

^ permalink raw reply

* Re: sky2 driver fails to handle "rx length error: status 0x5d60100 length 2982" gracefully
From: Maciej Żenczykowski @ 2010-08-17 20:05 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Stephen Hemminger, Linux NetDev
In-Reply-To: <20100817123702.3d09a35b@nehalam>

> Also, the driver could schedule a reset (that is what the watchdog does),
> but it looks like the receive DMA is walking past the end of the packet
> and that is really dangerous since it could clobber random memory.

I'm not sure to what watchdog you are referring.
I'm not aware of this machine having a hw (or sw) watchdog.

> You might want to increase the size of rx DMA buffer and dump the
> contents of the receive buffer to see if there is a memory corruption

Is this something that is a userspace tweak (how? pointers please?),
or do you mean to modify the kernel source code and recompile.

> risk. If the End Of Frame DMA hardware is not working, there is a real
> danger if the driver silently continues.

Agreed, although that does seem to be what the driver is currently
doing... silently continuing.

---

BTW, I've run into the issue once more and I've verified that turning
off all acceleration options
doesn't fix the problem (ethtool -k eth0 rx off tx off sg off tso off
gso off [ufo/gro/lro already were off]), nor does trying to get
the network card to renegotiate the link speed (ethtool -s eth0 speed
10; sleep 5; ethtool -s eth0 speed 1000; sleep 5; ethtool -r eth0).

I am now testing to see if the problem ever occurs if all the
acceleration options are turned off.
Of late the occurrence rate seems to be pretty steady at about twice per week.

Maciej

^ permalink raw reply

* [PATCH 0/14 net-next] more TIPC fixes and updates
From: Paul Gortmaker @ 2010-08-17 21:00 UTC (permalink / raw)
  To: davem; +Cc: netdev, allan.stephens

With net-next reopened, here is another batch of TIPC patches primarily
from the out-of-kernel repo.  There is no real binding between any of the
commits aside from taking what appear to be stand-alone bits and migrating
them across and fixing up minor coding style things etc.  I believe there
will be a chance to get a lot more of this done in this dev window, so
hopefully this will be just one batch of several that I end up sending.

Basic runtime sanity test done on v2.6.36-rc1, and all patches git am
cleanly on the net-next of today as well.

Thanks,
Paul.


^ 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