Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 7/7] unix_diag: Fixup RQLEN extension report
From: David Miller @ 2011-12-30 21:47 UTC (permalink / raw)
  To: xemul; +Cc: netdev
In-Reply-To: <4EFD986F.4030808@parallels.com>

From: Pavel Emelyanov <xemul@parallels.com>
Date: Fri, 30 Dec 2011 14:54:39 +0400

> While it's not too late fix the recently added RQLEN diag extension
> to report rqlen and wqlen in the same way as TCP does.
> 
> I.e. for listening sockets the ack backlog length (which is the input
> queue length for socket) in rqlen and the max ack backlog length in
> wqlen, and what the CINQ/OUTQ ioctls do for established.
> 
> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

Applied.

^ permalink raw reply

* Re: [PATCH 6/7] af_unix: Move CINQ/COUTQ code to helpers
From: David Miller @ 2011-12-30 21:47 UTC (permalink / raw)
  To: xemul; +Cc: netdev
In-Reply-To: <4EFD9853.7090601@parallels.com>

From: Pavel Emelyanov <xemul@parallels.com>
Date: Fri, 30 Dec 2011 14:54:11 +0400

> Currently tcp diag reports rqlen and wqlen values similar to how
> the CINQ/COUTQ iotcls do. To make unix diag report these values 
> in the same way move the respective code into helpers.
> 
> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

Applied with some minor indentation fixes, thanks.

^ permalink raw reply

* Re: [PATCH 5/7] unix_diag: Add the MEMINFO extension
From: David Miller @ 2011-12-30 21:47 UTC (permalink / raw)
  To: xemul; +Cc: netdev
In-Reply-To: <4EFE10AF.8010308@parallels.com>

From: Pavel Emelyanov <xemul@parallels.com>
Date: Fri, 30 Dec 2011 23:27:43 +0400

> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

Applied with some minor indentation fixes, thanks.

^ permalink raw reply

* Re: [PATCH 4/7] inet_diag: Add the SKMEMINFO extension
From: David Miller @ 2011-12-30 21:47 UTC (permalink / raw)
  To: xemul; +Cc: netdev
In-Reply-To: <4EFD982C.8080801@parallels.com>

From: Pavel Emelyanov <xemul@parallels.com>
Date: Fri, 30 Dec 2011 14:53:32 +0400

> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

Applied.

^ permalink raw reply

* Re: [PATCH 3/7] sock_diag: Introduce the meminfo nla core (v2)
From: David Miller @ 2011-12-30 21:47 UTC (permalink / raw)
  To: xemul; +Cc: netdev
In-Reply-To: <4EFD9819.1060701@parallels.com>

From: Pavel Emelyanov <xemul@parallels.com>
Date: Fri, 30 Dec 2011 14:53:13 +0400

> Add a routine that dumps memory-related values of a socket.
> It's made as an array to make it possible to add more stuff
> here later without breaking compatibility.
> 
> Since v1: The SK_MEMINFO_ constants are in userspace
> visible part of sock_diag.h, the rest is under __KERNEL__.
> 
> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

Applied.

^ permalink raw reply

* Re: [PATCH 2/7] unix_diag: Include unix_diag.h into header-y target
From: David Miller @ 2011-12-30 21:46 UTC (permalink / raw)
  To: xemul; +Cc: netdev
In-Reply-To: <4EFD9803.3040106@parallels.com>

From: Pavel Emelyanov <xemul@parallels.com>
Date: Fri, 30 Dec 2011 14:52:51 +0400

> The headers check complains it should include the linux/types.h
> withing, thus add this one.
> 
> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

Applied.

^ permalink raw reply

* Re: [PATCH 1/7] sock_diag: Arrange sock_diag.h such that it is exportable to userspace
From: David Miller @ 2011-12-30 21:46 UTC (permalink / raw)
  To: xemul; +Cc: netdev
In-Reply-To: <4EFD97E5.6080701@parallels.com>

From: Pavel Emelyanov <xemul@parallels.com>
Date: Fri, 30 Dec 2011 14:52:21 +0400

> Properly toss existing components around the ifdef __KERNEL__
> and include the header into the header-y target.
> 
> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

Applied.

^ permalink raw reply

* Re: [PATCH 1/1] via-rhine: Fix hanging with high CPU load on low-end broads.
From: Bjarke Istrup Pedersen @ 2011-12-30 20:38 UTC (permalink / raw)
  To: Francois Romieu
  Cc: David Miller, shemminger, bhutchings, linux-kernel, netdev, rl
In-Reply-To: <20111230180347.GA3647@electric-eye.fr.zoreil.com>

2011/12/30 Francois Romieu <romieu@fr.zoreil.com>:
> Bjarke Istrup Pedersen <gurligebis@gentoo.org> :
> [...]
>> Great, let me know when there is more to test :)
>
> It's done. I have removed linux-kernel from the Cc: where patches are sent
> since there is netdev.
>
> If you don't crash trivially, feel free to :
> 1. loop ip link up / down + module removal / insertion under traffic
> 2. loop ethtool / vlan commands under traffic
> 3. do the same as above and perform suspend / resume

Hey,

Going to test it later tonight.
Just applied it to HEAD of net-next, and got the following compiler warning:
drivers/net/ethernet/via/via-rhine.c:2182:13: warning:
'rhine_task_enable' defined but not used

Just so you know that too :)

/Bjarke

> --
> Ueimor
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* [PATCH 5/7] unix_diag: Add the MEMINFO extension
From: Pavel Emelyanov @ 2011-12-30 19:27 UTC (permalink / raw)
  To: David Miller, Linux Netdev List

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---
 include/linux/unix_diag.h |    2 ++
 net/unix/diag.c           |    4 ++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/include/linux/unix_diag.h b/include/linux/unix_diag.h
index a5ce0f3..93fdb78 100644
--- a/include/linux/unix_diag.h
+++ b/include/linux/unix_diag.h
@@ -18,6 +18,7 @@ struct unix_diag_req {
 #define UDIAG_SHOW_PEER		0x00000004	/* show peer socket info */
 #define UDIAG_SHOW_ICONS	0x00000008	/* show pending connections */
 #define UDIAG_SHOW_RQLEN	0x00000010	/* show skb receive queue len */
+#define UDIAG_SHOW_MEMINFO	0x00000020	/* show memory info of a socket */
 
 struct unix_diag_msg {
 	__u8	udiag_family;
@@ -35,6 +36,7 @@ enum {
 	UNIX_DIAG_PEER,
 	UNIX_DIAG_ICONS,
 	UNIX_DIAG_RQLEN,
+	UNIX_DIAG_MEMINFO,
 
 	UNIX_DIAG_MAX,
 };
diff --git a/net/unix/diag.c b/net/unix/diag.c
index c5bdbcb..9517bdd 100644
--- a/net/unix/diag.c
+++ b/net/unix/diag.c
@@ -146,6 +146,10 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
 			sk_diag_show_rqlen(sk, skb))
 		goto nlmsg_failure;
 
+	if ((req->udiag_show & UDIAG_SHOW_MEMINFO) &&
+			sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO))
+		goto nlmsg_failure;
+
 	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
 	return skb->len;
 
-- 
1.5.5.6

^ permalink raw reply related

* Re: [PATCH net-next 0/8] tipc: add tipc_ prefix to various structs
From: David Miller @ 2011-12-30 18:53 UTC (permalink / raw)
  To: paul.gortmaker; +Cc: netdev, allan.stephens, ying.xue
In-Reply-To: <1325216937-5856-1-git-send-email-paul.gortmaker@windriver.com>

From: Paul Gortmaker <paul.gortmaker@windriver.com>
Date: Thu, 29 Dec 2011 22:48:49 -0500

> Here is the addition of the tipc_ prefix that you requested earlier
> this week.  I left the changes as separate commits since it makes it
> easier at a glance to review them and make sure my regex foo did
> the right thing in each case.  The last commit intentionally adds
> an "s" [i.e. name --> names] since that better describes what the
> struct actually contains.
> 
> I didn't redo runtime testing, but it is compile tested as a sanity
> check.  Long lines caused by the addition of the prefix have been
> wrapped so the patches are (as usual) checkpatch clean.

Pulled, thanks a lot.

> Happy New Year!

Same to you!

^ permalink raw reply

* Re: [PATCH 1/1] via-rhine: Fix hanging with high CPU load on low-end broads.
From: Bjarke Istrup Pedersen @ 2011-12-30 18:45 UTC (permalink / raw)
  To: Francois Romieu
  Cc: David Miller, shemminger, bhutchings, linux-kernel, netdev, rl
In-Reply-To: <20111230180347.GA3647@electric-eye.fr.zoreil.com>

2011/12/30 Francois Romieu <romieu@fr.zoreil.com>:
> Bjarke Istrup Pedersen <gurligebis@gentoo.org> :
> [...]
>> Great, let me know when there is more to test :)
>
> It's done. I have removed linux-kernel from the Cc: where patches are sent
> since there is netdev.
>
> If you don't crash trivially, feel free to :
> 1. loop ip link up / down + module removal / insertion under traffic
> 2. loop ethtool / vlan commands under traffic
> 3. do the same as above and perform suspend / resume

I can try and do some ip link up and down. - the kernel is built
without module support, to make it as compact as possible.
I can also try ethtool and see if that breaks anything.
It's a headless router, so it doesn't have support for suspend and resume :)

/Bjarke

> --
> Ueimor
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* Serious relationship
From: dale @ 2011-12-30 18:22 UTC (permalink / raw)
  To: Curt

Aloha
If only I could have come up with the right words to express the depth of
the beautiful feeling that I have in my heart http://alllovelove.in/?idAff=243
The best thing I can do is to show you my deepest dreams and hopes about
love, about our happy relationship and sweetest memories that we can create
together with my soul mate. Find me, I need you as an air.
The best of luck
Veronyka

^ permalink raw reply

* [PATCH net-next 3/3] via-rhine: move work from irq handler to softirq and beyond.
From: Francois Romieu @ 2011-12-30 18:04 UTC (permalink / raw)
  To: Bjarke Istrup Pedersen; +Cc: David Miller, shemminger, bhutchings, netdev, rl

- Tx processing is moved from the irq handler to NAPI poll
- link events and obscure event processing is moved to its proper work queue

Locking rules undergo some changes through the driver.

- the driver offers the usual lock-free Tx path
- besides the IRQ handler, the link event task schedules the napi handler.
  The driver thus adds some internal locking to prevent a loop when both
  must be disabled.
- the reset task keeps being scheduled from the Tx watchdog handler, thus
  with implicit Tx queue disabling. It does not need to care about irq,
  only napi softirq and competing task.
- it is not worth to add a dedicated lock between {g, s}et_wol and
  rhine_shutdown. It should not hurt no narrow it down a bit though.
- rhine_reset_task must keep its huge spin_lock_bh protected section due
  to :
  - races for the CAM registers (see rhine_vlan_rx_{add, kill}_vid)
  - implicit use of napi_enable (see init_registers)
  - use of the same lock for stats read / update exclusion between
    napi rx processing and rhine_get_stats
- rhine_resume requires a softirq disabled section for the same reason
  as rhine_reset_task
- {free, request}_irq have been replaced with IntrEnable actions in
  rhine_{suspend, resume}. It is hidden behind init_registers for the
  latter.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
 drivers/net/ethernet/via/via-rhine.c |  406 +++++++++++++++++++---------------
 1 files changed, 223 insertions(+), 183 deletions(-)

diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 716fd42..c57e1da 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -42,7 +42,8 @@
 
 #define DEBUG
 static int debug = 1;	/* 1 normal messages, 0 quiet .. 7 verbose. */
-static int max_interrupt_work = 20;
+#define RHINE_MSG_DEFAULT \
+        (0x0000)
 
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
    Setting to > 1518 effectively disables this feature. */
@@ -128,11 +129,9 @@ MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("VIA Rhine PCI Fast Ethernet driver");
 MODULE_LICENSE("GPL");
 
-module_param(max_interrupt_work, int, 0);
 module_param(debug, int, 0);
 module_param(rx_copybreak, int, 0);
 module_param(avoid_D3, bool, 0);
-MODULE_PARM_DESC(max_interrupt_work, "VIA Rhine maximum events handled per interrupt");
 MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)");
 MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)");
@@ -351,16 +350,25 @@ static const int mmio_verify_registers[] = {
 
 /* Bits in the interrupt status/mask registers. */
 enum intr_status_bits {
-	IntrRxDone=0x0001, IntrRxErr=0x0004, IntrRxEmpty=0x0020,
-	IntrTxDone=0x0002, IntrTxError=0x0008, IntrTxUnderrun=0x0210,
-	IntrPCIErr=0x0040,
-	IntrStatsMax=0x0080, IntrRxEarly=0x0100,
-	IntrRxOverflow=0x0400, IntrRxDropped=0x0800, IntrRxNoBuf=0x1000,
-	IntrTxAborted=0x2000, IntrLinkChange=0x4000,
-	IntrRxWakeUp=0x8000,
-	IntrNormalSummary=0x0003, IntrAbnormalSummary=0xC260,
-	IntrTxDescRace=0x080000,	/* mapped from IntrStatus2 */
-	IntrTxErrSummary=0x082218,
+	IntrRxDone	= 0x0001,
+	IntrTxDone	= 0x0002,
+	IntrRxErr	= 0x0004,
+	IntrTxError	= 0x0008,
+	IntrRxEmpty	= 0x0020,
+	IntrPCIErr	= 0x0040,
+	IntrStatsMax	= 0x0080,
+	IntrRxEarly	= 0x0100,
+	IntrTxUnderrun	= 0x0210,
+	IntrRxOverflow	= 0x0400,
+	IntrRxDropped	= 0x0800,
+	IntrRxNoBuf	= 0x1000,
+	IntrTxAborted	= 0x2000,
+	IntrLinkChange	= 0x4000,
+	IntrRxWakeUp	= 0x8000,
+	IntrTxDescRace		= 0x080000,	/* mapped from IntrStatus2 */
+	IntrNormalSummary	= IntrRxDone | IntrTxDone,
+	IntrTxErrSummary	= IntrTxDescRace | IntrTxAborted | IntrTxError |
+				  IntrTxUnderrun,
 };
 
 /* Bits in WOLcrSet/WOLcrClr and PwrcsrSet/PwrcsrClr */
@@ -439,8 +447,13 @@ struct rhine_private {
 	struct net_device *dev;
 	struct napi_struct napi;
 	spinlock_t lock;
+	struct mutex task_lock;
+	bool task_enable;
+	struct work_struct slow_event_task;
 	struct work_struct reset_task;
 
+	u32 msg_enable;
+
 	/* Frequently used values: keep some adjacent for cache effect. */
 	u32 quirks;
 	struct rx_desc *rx_head_desc;
@@ -476,13 +489,13 @@ static int  mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
 static int  rhine_open(struct net_device *dev);
 static void rhine_reset_task(struct work_struct *work);
+static void rhine_slow_event_task(struct work_struct *work);
 static void rhine_tx_timeout(struct net_device *dev);
 static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
 				  struct net_device *dev);
 static irqreturn_t rhine_interrupt(int irq, void *dev_instance);
 static void rhine_tx(struct net_device *dev);
 static int rhine_rx(struct net_device *dev, int limit);
-static void rhine_error(struct net_device *dev, int intr_status);
 static void rhine_set_rx_mode(struct net_device *dev);
 static struct net_device_stats *rhine_get_stats(struct net_device *dev);
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -491,12 +504,7 @@ static int  rhine_close(struct net_device *dev);
 static void rhine_shutdown (struct pci_dev *pdev);
 static int rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid);
 static int rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
-static void rhine_set_cam(void __iomem *ioaddr, int idx, u8 *addr);
-static void rhine_set_vlan_cam(void __iomem *ioaddr, int idx, u8 *addr);
-static void rhine_set_cam_mask(void __iomem *ioaddr, u32 mask);
-static void rhine_set_vlan_cam_mask(void __iomem *ioaddr, u32 mask);
-static void rhine_init_cam_filter(struct net_device *dev);
-static void rhine_update_vcam(struct net_device *dev);
+static void rhine_restart_tx(struct net_device *dev);
 
 #define RHINE_WAIT_FOR(condition)				\
 do {								\
@@ -527,7 +535,7 @@ static void rhine_ack_events(struct rhine_private *rp, u32 mask)
 	if (rp->quirks & rqStatusWBRace)
 		iowrite8(mask >> 16, ioaddr + IntrStatus2);
 	iowrite16(mask, ioaddr + IntrStatus);
-	IOSYNC;
+	mmiowb();
 }
 
 /*
@@ -676,23 +684,117 @@ static void rhine_kick_tx_threshold(struct rhine_private *rp)
 	}
 }
 
+static void rhine_tx_err(struct rhine_private *rp, u32 status)
+{
+	struct net_device *dev = rp->dev;
+
+	if (status & IntrTxAborted) {
+		netif_info(rp, tx_err, dev,
+			   "Abort %08x, frame dropped\n", status);
+	}
+
+	if (status & IntrTxUnderrun) {
+		rhine_kick_tx_threshold(rp);
+		netif_info(rp, tx_err ,dev, "Transmitter underrun, "
+			   "Tx threshold now %02x\n", rp->tx_thresh);
+	}
+
+	if (status & IntrTxDescRace)
+		netif_info(rp, tx_err, dev, "Tx descriptor write-back race\n");
+
+	if ((status & IntrTxError) &&
+	    (status & (IntrTxAborted | IntrTxUnderrun | IntrTxDescRace)) == 0) {
+		rhine_kick_tx_threshold(rp);
+		netif_info(rp, tx_err, dev, "Unspecified error. "
+			   "Tx threshold now %02x\n", rp->tx_thresh);
+	}
+
+	rhine_restart_tx(dev);
+}
+
+static void rhine_update_rx_crc_and_missed_errord(struct rhine_private *rp)
+{
+	void __iomem *ioaddr = rp->base;
+	struct net_device_stats *stats = &rp->dev->stats;
+
+	stats->rx_crc_errors    += ioread16(ioaddr + RxCRCErrs);
+	stats->rx_missed_errors += ioread16(ioaddr + RxMissed);
+
+	/*
+	 * Clears the "tally counters" for CRC errors and missed frames(?).
+	 * It has been reported that some chips need a write of 0 to clear
+	 * these, for others the counters are set to 1 when written to and
+	 * instead cleared when read. So we clear them both ways ...
+	 */
+	iowrite32(0, ioaddr + RxMissed);
+	ioread16(ioaddr + RxCRCErrs);
+	ioread16(ioaddr + RxMissed);
+}
+
+#define RHINE_EVENT_NAPI_RX	(IntrRxDone | \
+				 IntrRxErr | \
+				 IntrRxEmpty | \
+				 IntrRxOverflow	| \
+				 IntrRxDropped | \
+				 IntrRxNoBuf | \
+				 IntrRxWakeUp)
+
+#define RHINE_EVENT_NAPI_TX_ERR	(IntrTxError | \
+				 IntrTxAborted | \
+				 IntrTxUnderrun | \
+				 IntrTxDescRace)
+#define RHINE_EVENT_NAPI_TX	(IntrTxDone | RHINE_EVENT_NAPI_TX_ERR)
+
+#define RHINE_EVENT_NAPI	(RHINE_EVENT_NAPI_RX | \
+				 RHINE_EVENT_NAPI_TX | \
+				 IntrStatsMax)
+#define RHINE_EVENT_SLOW	(IntrPCIErr | IntrLinkChange)
+#define RHINE_EVENT		(RHINE_EVENT_NAPI | RHINE_EVENT_SLOW)
+
 static int rhine_napipoll(struct napi_struct *napi, int budget)
 {
 	struct rhine_private *rp = container_of(napi, struct rhine_private, napi);
 	struct net_device *dev = rp->dev;
 	void __iomem *ioaddr = rp->base;
-	int work_done;
+	u16 enable_mask = RHINE_EVENT & 0xffff;
+	int work_done = 0;
+	u32 status;
+
+	status = rhine_get_events(rp);
+	rhine_ack_events(rp, status & ~RHINE_EVENT_SLOW);
+
+	if (status & RHINE_EVENT_NAPI_RX)
+		work_done += rhine_rx(dev, budget);
+
+	if (status & RHINE_EVENT_NAPI_TX) {
+		if (status & RHINE_EVENT_NAPI_TX_ERR) {
+			/* Avoid scavenging before Tx engine turned off */
+			RHINE_WAIT_FOR(!(ioread8(ioaddr + ChipCmd) & CmdTxOn));
+			if (ioread8(ioaddr + ChipCmd) & CmdTxOn)
+				netif_warn(rp, tx_err, dev, "Tx still on\n");
+		}
 
-	work_done = rhine_rx(dev, budget);
+		rhine_tx(dev);
+
+		if (status & RHINE_EVENT_NAPI_TX_ERR)
+			rhine_tx_err(rp, status);
+	}
+
+	if (status & IntrStatsMax) {
+		spin_lock(&rp->lock);
+		rhine_update_rx_crc_and_missed_errord(rp);
+		spin_unlock(&rp->lock);
+	}
+
+	if (status & RHINE_EVENT_SLOW) {
+		enable_mask &= ~RHINE_EVENT_SLOW;
+		schedule_work(&rp->slow_event_task);
+	}
 
 	if (work_done < budget) {
 		napi_complete(napi);
-
-		iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
-			  IntrRxDropped | IntrRxNoBuf | IntrTxAborted |
-			  IntrTxDone | IntrTxError | IntrTxUnderrun |
-			  IntrPCIErr | IntrStatsMax | IntrLinkChange,
-			  ioaddr + IntrEnable);
+		iowrite16(enable_mask, ioaddr + IntrEnable);
+		mmiowb();
 	}
 	return work_done;
 }
@@ -816,6 +918,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
 	rp->quirks = quirks;
 	rp->pioaddr = pioaddr;
 	rp->pdev = pdev;
+	rp->msg_enable = netif_msg_init(-1, RHINE_MSG_DEFAULT);
 
 	rc = pci_request_regions(pdev, DRV_NAME);
 	if (rc)
@@ -875,7 +978,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
 	dev->irq = pdev->irq;
 
 	spin_lock_init(&rp->lock);
+	mutex_init(&rp->task_lock);
 	INIT_WORK(&rp->reset_task, rhine_reset_task);
+	INIT_WORK(&rp->slow_event_task, rhine_slow_event_task);
 
 	rp->mii_if.dev = dev;
 	rp->mii_if.mdio_read = mdio_read;
@@ -1285,10 +1390,10 @@ static int rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
 {
 	struct rhine_private *rp = netdev_priv(dev);
 
-	spin_lock_irq(&rp->lock);
+	spin_lock_bh(&rp->lock);
 	set_bit(vid, rp->active_vlans);
 	rhine_update_vcam(dev);
-	spin_unlock_irq(&rp->lock);
+	spin_unlock_bh(&rp->lock);
 	return 0;
 }
 
@@ -1296,10 +1401,10 @@ static int rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
 {
 	struct rhine_private *rp = netdev_priv(dev);
 
-	spin_lock_irq(&rp->lock);
+	spin_lock_bh(&rp->lock);
 	clear_bit(vid, rp->active_vlans);
 	rhine_update_vcam(dev);
-	spin_unlock_irq(&rp->lock);
+	spin_unlock_bh(&rp->lock);
 	return 0;
 }
 
@@ -1329,12 +1434,7 @@ static void init_registers(struct net_device *dev)
 
 	napi_enable(&rp->napi);
 
-	/* Enable interrupts by setting the interrupt mask. */
-	iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
-	       IntrRxDropped | IntrRxNoBuf | IntrTxAborted |
-	       IntrTxDone | IntrTxError | IntrTxUnderrun |
-	       IntrPCIErr | IntrStatsMax | IntrLinkChange,
-	       ioaddr + IntrEnable);
+	iowrite16(RHINE_EVENT & 0xffff, ioaddr + IntrEnable);
 
 	iowrite16(CmdStart | CmdTxOn | CmdRxOn | (Cmd1NoTxPoll << 8),
 	       ioaddr + ChipCmd);
@@ -1453,11 +1553,12 @@ static void rhine_reset_task(struct work_struct *work)
 						reset_task);
 	struct net_device *dev = rp->dev;
 
-	/* protect against concurrent rx interrupts */
-	disable_irq(rp->pdev->irq);
+	mutex_lock(&rp->task_lock);
 
-	napi_disable(&rp->napi);
+	if (!rp->task_enable)
+		goto out_unlock;
 
+	napi_disable(&rp->napi);
 	spin_lock_bh(&rp->lock);
 
 	/* clear all descriptors */
@@ -1471,11 +1572,13 @@ static void rhine_reset_task(struct work_struct *work)
 	init_registers(dev);
 
 	spin_unlock_bh(&rp->lock);
-	enable_irq(rp->pdev->irq);
 
 	dev->trans_start = jiffies; /* prevent tx timeout */
 	dev->stats.tx_errors++;
 	netif_wake_queue(dev);
+
+out_unlock:
+	mutex_unlock(&rp->task_lock);
 }
 
 static void rhine_tx_timeout(struct net_device *dev)
@@ -1496,7 +1599,6 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
 	struct rhine_private *rp = netdev_priv(dev);
 	void __iomem *ioaddr = rp->base;
 	unsigned entry;
-	unsigned long flags;
 
 	/* Caution: the write order is important here, set the field
 	   with the "ownership" bits last. */
@@ -1548,7 +1650,6 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
 		rp->tx_ring[entry].tx_status = 0;
 
 	/* lock eth irq */
-	spin_lock_irqsave(&rp->lock, flags);
 	wmb();
 	rp->tx_ring[entry].tx_status |= cpu_to_le32(DescOwn);
 	wmb();
@@ -1569,8 +1670,6 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
 	if (rp->cur_tx == rp->dirty_tx + TX_QUEUE_LEN)
 		netif_stop_queue(dev);
 
-	spin_unlock_irqrestore(&rp->lock, flags);
-
 	if (debug > 4) {
 		netdev_dbg(dev, "Transmit frame #%d queued in slot %d\n",
 			   rp->cur_tx-1, entry);
@@ -1578,66 +1677,37 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
 	return NETDEV_TX_OK;
 }
 
+static void rhine_irq_disable(struct rhine_private *rp)
+{
+	iowrite16(0x0000, rp->base + IntrEnable);
+	mmiowb();
+}
+
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
 static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
 {
 	struct net_device *dev = dev_instance;
 	struct rhine_private *rp = netdev_priv(dev);
-	void __iomem *ioaddr = rp->base;
-	u32 intr_status;
-	int boguscnt = max_interrupt_work;
+	u32 status;
 	int handled = 0;
 
-	while ((intr_status = rhine_get_events(rp))) {
-		handled = 1;
-
-		/* Acknowledge all of the current interrupt sources ASAP. */
-		rhine_ack_events(rp, intr_status);
-
-		if (debug > 4)
-			netdev_dbg(dev, "Interrupt, status %08x\n",
-				   intr_status);
-
-		if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped |
-				   IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) {
-			iowrite16(IntrTxAborted |
-				  IntrTxDone | IntrTxError | IntrTxUnderrun |
-				  IntrPCIErr | IntrStatsMax | IntrLinkChange,
-				  ioaddr + IntrEnable);
+	status = rhine_get_events(rp);
 
-			napi_schedule(&rp->napi);
-		}
+	netif_dbg(rp, intr, dev, "Interrupt, status %08x\n", status);
 
-		if (intr_status & (IntrTxErrSummary | IntrTxDone)) {
-			if (intr_status & IntrTxErrSummary) {
-				/* Avoid scavenging before Tx engine turned off */
-				RHINE_WAIT_FOR(!(ioread8(ioaddr+ChipCmd) & CmdTxOn));
-				if (debug > 2 &&
-				    ioread8(ioaddr+ChipCmd) & CmdTxOn)
-					netdev_warn(dev,
-						    "%s: Tx engine still on\n",
-						    __func__);
-			}
-			rhine_tx(dev);
-		}
+	if (status & RHINE_EVENT) {
+		handled = 1;
 
-		/* Abnormal error summary/uncommon events handlers. */
-		if (intr_status & (IntrPCIErr | IntrLinkChange |
-				   IntrStatsMax | IntrTxError | IntrTxAborted |
-				   IntrTxUnderrun | IntrTxDescRace))
-			rhine_error(dev, intr_status);
+		rhine_irq_disable(rp);
+		napi_schedule(&rp->napi);
+	}
 
-		if (--boguscnt < 0) {
-			netdev_warn(dev, "Too much work at interrupt, status=%#08x\n",
-				    intr_status);
-			break;
-		}
+	if (status & ~(IntrLinkChange | IntrStatsMax | RHINE_EVENT_NAPI)) {
+		netif_err(rp, intr, dev, "Something Wicked happened! %08x\n",
+			  status);
 	}
 
-	if (debug > 3)
-		netdev_dbg(dev, "exiting interrupt, status=%08x\n",
-			   ioread16(ioaddr + IntrStatus));
 	return IRQ_RETVAL(handled);
 }
 
@@ -1648,8 +1718,6 @@ static void rhine_tx(struct net_device *dev)
 	struct rhine_private *rp = netdev_priv(dev);
 	int txstatus = 0, entry = rp->dirty_tx % TX_RING_SIZE;
 
-	spin_lock(&rp->lock);
-
 	/* find and cleanup dirty tx descriptors */
 	while (rp->dirty_tx != rp->cur_tx) {
 		txstatus = le32_to_cpu(rp->tx_ring[entry].tx_status);
@@ -1703,8 +1771,6 @@ static void rhine_tx(struct net_device *dev)
 	}
 	if ((rp->cur_tx - rp->dirty_tx) < TX_QUEUE_LEN - 4)
 		netif_wake_queue(dev);
-
-	spin_unlock(&rp->lock);
 }
 
 /**
@@ -1855,19 +1921,6 @@ static int rhine_rx(struct net_device *dev, int limit)
 	return count;
 }
 
-/*
- * Clears the "tally counters" for CRC errors and missed frames(?).
- * It has been reported that some chips need a write of 0 to clear
- * these, for others the counters are set to 1 when written to and
- * instead cleared when read. So we clear them both ways ...
- */
-static inline void clear_tally_counters(void __iomem *ioaddr)
-{
-	iowrite32(0, ioaddr + RxMissed);
-	ioread16(ioaddr + RxCRCErrs);
-	ioread16(ioaddr + RxMissed);
-}
-
 static void rhine_restart_tx(struct net_device *dev) {
 	struct rhine_private *rp = netdev_priv(dev);
 	void __iomem *ioaddr = rp->base;
@@ -1906,69 +1959,45 @@ static void rhine_restart_tx(struct net_device *dev) {
 
 }
 
-static void rhine_error(struct net_device *dev, int intr_status)
+static void rhine_slow_event_task(struct work_struct *work)
 {
-	struct rhine_private *rp = netdev_priv(dev);
-	void __iomem *ioaddr = rp->base;
+	struct rhine_private *rp =
+		container_of(work, struct rhine_private, slow_event_task);
+	struct net_device *dev = rp->dev;
+	u32 intr_status;
 
-	spin_lock(&rp->lock);
+	mutex_lock(&rp->task_lock);
+
+	if (!rp->task_enable)
+		goto out_unlock;
+
+	intr_status = rhine_get_events(rp);
+	rhine_ack_events(rp, intr_status & RHINE_EVENT_SLOW);
 
 	if (intr_status & IntrLinkChange)
 		rhine_check_media(dev, 0);
-	if (intr_status & IntrStatsMax) {
-		dev->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
-		dev->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
-		clear_tally_counters(ioaddr);
-	}
-	if (intr_status & IntrTxAborted) {
-		if (debug > 1)
-			netdev_info(dev, "Abort %08x, frame dropped\n",
-				    intr_status);
-	}
-	if (intr_status & IntrTxUnderrun) {
-		rhine_kick_tx_threshold(rp);
-		if (debug > 1)
-			netdev_info(dev, "Transmitter underrun, Tx threshold now %02x\n",
-				    rp->tx_thresh);
-	}
-	if (intr_status & IntrTxDescRace) {
-		if (debug > 2)
-			netdev_info(dev, "Tx descriptor write-back race\n");
-	}
-	if ((intr_status & IntrTxError) &&
-	    (intr_status & (IntrTxAborted |
-	     IntrTxUnderrun | IntrTxDescRace)) == 0) {
-		rhine_kick_tx_threshold(rp);
-		if (debug > 1)
-			netdev_info(dev, "Unspecified error. Tx threshold now %02x\n",
-				    rp->tx_thresh);
-	}
-	if (intr_status & (IntrTxAborted | IntrTxUnderrun | IntrTxDescRace |
-			   IntrTxError))
-		rhine_restart_tx(dev);
 
-	if (intr_status & ~(IntrLinkChange | IntrStatsMax | IntrTxUnderrun |
-			    IntrTxError | IntrTxAborted | IntrNormalSummary |
-			    IntrTxDescRace)) {
-		if (debug > 1)
-			netdev_err(dev, "Something Wicked happened! %08x\n",
-				   intr_status);
-	}
+	/* FIXME: ignore ? */
+	if (intr_status & IntrPCIErr)
+		netif_warn(rp, hw, dev, "PCI error\n");
 
-	spin_unlock(&rp->lock);
+	napi_disable(&rp->napi);
+	rhine_irq_disable(rp);
+	/* Slow and safe. Consider __napi_schedule as a replacement ? */
+	napi_enable(&rp->napi);
+	napi_schedule(&rp->napi);
+
+out_unlock:
+	mutex_unlock(&rp->task_lock);
 }
 
 static struct net_device_stats *rhine_get_stats(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
-	void __iomem *ioaddr = rp->base;
-	unsigned long flags;
 
-	spin_lock_irqsave(&rp->lock, flags);
-	dev->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
-	dev->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
-	clear_tally_counters(ioaddr);
-	spin_unlock_irqrestore(&rp->lock, flags);
+	spin_lock_bh(&rp->lock);
+	rhine_update_rx_crc_and_missed_errord(rp);
+	spin_unlock_bh(&rp->lock);
 
 	return &dev->stats;
 }
@@ -2035,9 +2064,9 @@ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	struct rhine_private *rp = netdev_priv(dev);
 	int rc;
 
-	spin_lock_irq(&rp->lock);
+	mutex_lock(&rp->task_lock);
 	rc = mii_ethtool_gset(&rp->mii_if, cmd);
-	spin_unlock_irq(&rp->lock);
+	mutex_unlock(&rp->task_lock);
 
 	return rc;
 }
@@ -2047,10 +2076,10 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	struct rhine_private *rp = netdev_priv(dev);
 	int rc;
 
-	spin_lock_irq(&rp->lock);
+	mutex_lock(&rp->task_lock);
 	rc = mii_ethtool_sset(&rp->mii_if, cmd);
-	spin_unlock_irq(&rp->lock);
 	rhine_set_carrier(&rp->mii_if);
+	mutex_unlock(&rp->task_lock);
 
 	return rc;
 }
@@ -2132,25 +2161,40 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	if (!netif_running(dev))
 		return -EINVAL;
 
-	spin_lock_irq(&rp->lock);
+	mutex_lock(&rp->task_lock);
 	rc = generic_mii_ioctl(&rp->mii_if, if_mii(rq), cmd, NULL);
-	spin_unlock_irq(&rp->lock);
 	rhine_set_carrier(&rp->mii_if);
+	mutex_unlock(&rp->task_lock);
 
 	return rc;
 }
 
+static void rhine_task_disable(struct rhine_private *rp)
+{
+	mutex_lock(&rp->task_lock);
+	rp->task_enable = false;
+	mutex_unlock(&rp->task_lock);
+
+	cancel_work_sync(&rp->slow_event_task);
+	cancel_work_sync(&rp->reset_task);
+}
+
+static void rhine_task_enable(struct rhine_private *rp)
+{
+	mutex_lock(&rp->task_lock);
+	rp->task_enable = true;
+	mutex_unlock(&rp->task_lock);
+}
+
 static int rhine_close(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
 	void __iomem *ioaddr = rp->base;
 
+	rhine_task_disable(rp);
 	napi_disable(&rp->napi);
-	cancel_work_sync(&rp->reset_task);
 	netif_stop_queue(dev);
 
-	spin_lock_irq(&rp->lock);
-
 	if (debug > 1)
 		netdev_dbg(dev, "Shutting down ethercard, status was %04x\n",
 			   ioread16(ioaddr + ChipCmd));
@@ -2158,14 +2202,11 @@ static int rhine_close(struct net_device *dev)
 	/* Switch to loopback mode to avoid hardware races. */
 	iowrite8(rp->tx_thresh | 0x02, ioaddr + TxConfig);
 
-	/* Disable interrupts by clearing the interrupt mask. */
-	iowrite16(0x0000, ioaddr + IntrEnable);
+	rhine_irq_disable(rp);
 
 	/* Stop the chip's Tx and Rx processes. */
 	iowrite16(CmdStop, ioaddr + ChipCmd);
 
-	spin_unlock_irq(&rp->lock);
-
 	free_irq(rp->pdev->irq, dev);
 	free_rbufs(dev);
 	free_tbufs(dev);
@@ -2205,6 +2246,8 @@ static void rhine_shutdown (struct pci_dev *pdev)
 	if (rp->quirks & rq6patterns)
 		iowrite8(0x04, ioaddr + WOLcgClr);
 
+	spin_lock(&rp->lock);
+
 	if (rp->wolopts & WAKE_MAGIC) {
 		iowrite8(WOLmagic, ioaddr + WOLcrSet);
 		/*
@@ -2229,6 +2272,8 @@ static void rhine_shutdown (struct pci_dev *pdev)
 		iowrite8(ioread8(ioaddr + StickyHW) | 0x04, ioaddr + StickyHW);
 	}
 
+	spin_unlock(&rp->lock);
+
 	/* Hit power state D3 (sleep) */
 	if (!avoid_D3)
 		iowrite8(ioread8(ioaddr + StickyHW) | 0x03, ioaddr + StickyHW);
@@ -2242,21 +2287,19 @@ static int rhine_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rhine_private *rp = netdev_priv(dev);
-	unsigned long flags;
 
 	if (!netif_running(dev))
 		return 0;
 
+	rhine_task_disable(rp);
+	rhine_irq_disable(rp);
 	napi_disable(&rp->napi);
 
 	netif_device_detach(dev);
 	pci_save_state(pdev);
 
-	spin_lock_irqsave(&rp->lock, flags);
 	rhine_shutdown(pdev);
-	spin_unlock_irqrestore(&rp->lock, flags);
 
-	free_irq(dev->irq, dev);
 	return 0;
 }
 
@@ -2264,15 +2307,11 @@ static int rhine_resume(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rhine_private *rp = netdev_priv(dev);
-	unsigned long flags;
 	int ret;
 
 	if (!netif_running(dev))
 		return 0;
 
-	if (request_irq(dev->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev))
-		netdev_err(dev, "request_irq failed\n");
-
 	ret = pci_set_power_state(pdev, PCI_D0);
 	if (debug > 1)
 		netdev_info(dev, "Entering power state D0 %s (%d)\n",
@@ -2280,7 +2319,6 @@ static int rhine_resume(struct pci_dev *pdev)
 
 	pci_restore_state(pdev);
 
-	spin_lock_irqsave(&rp->lock, flags);
 #ifdef USE_MMIO
 	enable_mmio(rp->pioaddr, rp->quirks);
 #endif
@@ -2289,8 +2327,10 @@ static int rhine_resume(struct pci_dev *pdev)
 	free_rbufs(dev);
 	alloc_tbufs(dev);
 	alloc_rbufs(dev);
+	rhine_task_enable(rp);
+	spin_lock_bh(&rp->lock);
 	init_registers(dev);
-	spin_unlock_irqrestore(&rp->lock, flags);
+	spin_unlock_bh(&rp->lock);
 
 	netif_device_attach(dev);
 
-- 
1.7.6.4

^ permalink raw reply related

* [PATCH net-next 2/3] via-rhine: balance interrupt acknowledge and events retrieval.
From: Francois Romieu @ 2011-12-30 18:04 UTC (permalink / raw)
  To: Bjarke Istrup Pedersen; +Cc: David Miller, shemminger, bhutchings, netdev, rl

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
 drivers/net/ethernet/via/via-rhine.c |   22 ++++++++++++++--------
 1 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 93987e8..716fd42 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -508,9 +508,8 @@ do {								\
 			1024 - i, __func__, __LINE__);		\
 } while (0)
 
-static inline u32 get_intr_status(struct net_device *dev)
+static u32 rhine_get_events(struct rhine_private *rp)
 {
-	struct rhine_private *rp = netdev_priv(dev);
 	void __iomem *ioaddr = rp->base;
 	u32 intr_status;
 
@@ -521,6 +520,16 @@ static inline u32 get_intr_status(struct net_device *dev)
 	return intr_status;
 }
 
+static void rhine_ack_events(struct rhine_private *rp, u32 mask)
+{
+	void __iomem *ioaddr = rp->base;
+
+	if (rp->quirks & rqStatusWBRace)
+		iowrite8(mask >> 16, ioaddr + IntrStatus2);
+	iowrite16(mask, ioaddr + IntrStatus);
+	IOSYNC;
+}
+
 /*
  * Get power related registers into sane state.
  * Notify user about past WOL event.
@@ -1580,14 +1589,11 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
 	int boguscnt = max_interrupt_work;
 	int handled = 0;
 
-	while ((intr_status = get_intr_status(dev))) {
+	while ((intr_status = rhine_get_events(rp))) {
 		handled = 1;
 
 		/* Acknowledge all of the current interrupt sources ASAP. */
-		if (intr_status & IntrTxDescRace)
-			iowrite8(0x08, ioaddr + IntrStatus2);
-		iowrite16(intr_status & 0xffff, ioaddr + IntrStatus);
-		IOSYNC;
+		rhine_ack_events(rp, intr_status);
 
 		if (debug > 4)
 			netdev_dbg(dev, "Interrupt, status %08x\n",
@@ -1872,7 +1878,7 @@ static void rhine_restart_tx(struct net_device *dev) {
 	 * If new errors occurred, we need to sort them out before doing Tx.
 	 * In that case the ISR will be back here RSN anyway.
 	 */
-	intr_status = get_intr_status(dev);
+	intr_status = rhine_get_events(rp);
 
 	if ((intr_status & IntrTxErrSummary) == 0) {
 
-- 
1.7.6.4

^ permalink raw reply related

* [PATCH net-next 1/3] via-rhine: factor out tx_thresh handling
From: Francois Romieu @ 2011-12-30 18:03 UTC (permalink / raw)
  To: Bjarke Istrup Pedersen; +Cc: David Miller, shemminger, bhutchings, netdev, rl

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
 drivers/net/ethernet/via/via-rhine.c |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 5c4983b..93987e8 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -657,6 +657,16 @@ static void rhine_poll(struct net_device *dev)
 }
 #endif
 
+static void rhine_kick_tx_threshold(struct rhine_private *rp)
+{
+	if (rp->tx_thresh < 0xe0) {
+		void __iomem *ioaddr = rp->base;
+
+		rp->tx_thresh += 0x20;
+		BYTE_REG_BITS_SET(rp->tx_thresh, 0x80, ioaddr + TxConfig);
+	}
+}
+
 static int rhine_napipoll(struct napi_struct *napi, int budget)
 {
 	struct rhine_private *rp = container_of(napi, struct rhine_private, napi);
@@ -1910,8 +1920,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
 				    intr_status);
 	}
 	if (intr_status & IntrTxUnderrun) {
-		if (rp->tx_thresh < 0xE0)
-			BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig);
+		rhine_kick_tx_threshold(rp);
 		if (debug > 1)
 			netdev_info(dev, "Transmitter underrun, Tx threshold now %02x\n",
 				    rp->tx_thresh);
@@ -1923,9 +1932,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
 	if ((intr_status & IntrTxError) &&
 	    (intr_status & (IntrTxAborted |
 	     IntrTxUnderrun | IntrTxDescRace)) == 0) {
-		if (rp->tx_thresh < 0xE0) {
-			BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig);
-		}
+		rhine_kick_tx_threshold(rp);
 		if (debug > 1)
 			netdev_info(dev, "Unspecified error. Tx threshold now %02x\n",
 				    rp->tx_thresh);
-- 
1.7.6.4

^ permalink raw reply related

* Re: [PATCH 1/1] via-rhine: Fix hanging with high CPU load on low-end broads.
From: Francois Romieu @ 2011-12-30 18:03 UTC (permalink / raw)
  To: Bjarke Istrup Pedersen
  Cc: David Miller, shemminger, bhutchings, linux-kernel, netdev, rl
In-Reply-To: <CACPM=kVBxcL1_Z9zVvnEEdEgAc0rbAAbzkcocz4OYWQ2xn6VmQ@mail.gmail.com>

Bjarke Istrup Pedersen <gurligebis@gentoo.org> :
[...]
> Great, let me know when there is more to test :)

It's done. I have removed linux-kernel from the Cc: where patches are sent
since there is netdev.

If you don't crash trivially, feel free to :
1. loop ip link up / down + module removal / insertion under traffic
2. loop ethtool / vlan commands under traffic
3. do the same as above and perform suspend / resume

-- 
Ueimor

^ permalink raw reply

* Re: A pure virtual nic
From: Ben Greear @ 2011-12-30 15:44 UTC (permalink / raw)
  To: Li, Zhen-Hua; +Cc: Michał Mirosław, Linux NetDev
In-Reply-To: <CAEk7JKY6xtBm4DraqRMYEnmZZhsOZoZG-MSgrq+W4n2eCCz1Sg@mail.gmail.com>

On 12/29/2011 05:51 PM, Li, Zhen-Hua wrote:
> I plan to add some protocols to it. For example, HTTP Proxy packet
> analysis. So user-space programs can use an NIC in common way in a
> proxy needed environment.

When a program transmits a packet on your virtual NIC, where does the
packet go?  When it receives a packet, where did the packet come from?

Thanks,
Ben

>
>
>
> 2011/12/29 Michał Mirosław<mirqus@gmail.com>:
>> 2011/12/29 Zhen-Hua Li<lizhenhua.dev@gmail.com>:
>>> I have opened a project in SourceForge, it provides a pure virtual
>>> ethernet adapter.  If you are interested to join it, please mail me.
>>
>> Is veth or tap (both in vanilla kernel) not enough for you? What are
>> the differences?
>>
>> Best Regards,
>> Michał Mirosław
> --
> 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


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply

* [PATCH] netfilter: ctnetlink: fix timeout calculation
From: Xi Wang @ 2011-12-30 15:40 UTC (permalink / raw)
  To: Pablo Neira Ayuso, Patrick McHardy, David S. Miller
  Cc: netfilter-devel, netdev, Xi Wang

The sanity check (timeout < 0) never works; the dividend is unsigned
and so is the division, which should have been a signed division.

	long timeout = (ct->timeout.expires - jiffies) / HZ;
	if (timeout < 0)
		timeout = 0;

This patch converts the time values to signed for the division.

Signed-off-by: Xi Wang <xi.wang@gmail.com>
---
 net/netfilter/nf_conntrack_netlink.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index b697777..257e772 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -135,7 +135,7 @@ nla_put_failure:
 static inline int
 ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct)
 {
-	long timeout = (ct->timeout.expires - jiffies) / HZ;
+	long timeout = ((long)ct->timeout.expires - (long)jiffies) / HZ;
 
 	if (timeout < 0)
 		timeout = 0;
@@ -1641,7 +1641,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
 			  const struct nf_conntrack_expect *exp)
 {
 	struct nf_conn *master = exp->master;
-	long timeout = (exp->timeout.expires - jiffies) / HZ;
+	long timeout = ((long)exp->timeout.expires - (long)jiffies) / HZ;
 	struct nf_conn_help *help;
 
 	if (timeout < 0)
-- 
1.7.5.4


^ permalink raw reply related

* Re: [PATCH 1/1] via-rhine: Fix hanging with high CPU load on low-end broads.
From: Bjarke Istrup Pedersen @ 2011-12-30 13:51 UTC (permalink / raw)
  To: Francois Romieu
  Cc: David Miller, shemminger, bhutchings, linux-kernel, netdev, rl
In-Reply-To: <20111230125655.GA32031@electric-eye.fr.zoreil.com>

2011/12/30 Francois Romieu <romieu@fr.zoreil.com>:
> Bjarke Istrup Pedersen <gurligebis@gentoo.org> :
> [...]
>> Sorry for asking a probably obvious question, but whats next to get it
>> fixed and ready for inclusion?
>
> It should be there for testing and deeper review within a pair of hours.
> I ended up vandalizing most of the locking. From a testing viewpoint it
> means some amount of work (not mine :o) ) to get a decent coverage.

Great, let me know when there is more to test :)

/Bjarke

> Once it is known tested and reviewed - it may need a few iterations - it
> can be formally submitted for inclusion.
>
> --
> Ueimor
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* Re: [BUG] SIOCSIFFLAGS returns -EIO on SMSC LAN911x
From: Ben Hutchings @ 2011-12-30 13:15 UTC (permalink / raw)
  To: Javier Martinez Canillas; +Cc: netdev, Enric Balletbo i Serra
In-Reply-To: <CAAwP0s0Y329AAXpHW9muOECt5DpgpDm6kefXR7uE1233A1LGWg@mail.gmail.com>

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

On Fri, 2011-12-30 at 13:58 +0100, Javier Martinez Canillas wrote:
> On Fri, Dec 30, 2011 at 11:56 AM, Ben Hutchings <ben@decadent.org.uk> wrote:
> > On Fri, 2011-12-30 at 10:44 +0100, Javier Martinez Canillas wrote:
[...]
> >> Did anyone have the same problem?
> >>
> >> The problem is really strange to me, especially since we are sure that
> >> all the requirements to software reset the device are meet in both
> >> cases (with SMSC_PHY compiled built-in and without it)
> >
> > I don't know about that.  smsc_phy_config_init() attempts to enable
> > power-saving on the PHY, but it is writing to a bit that is reserved
> > according to the data sheet for the combined MAC/PHY chip.  dwein
> 
> Since the PHY chip is a lan8700, the power-saving seems to be correct.

But the feature may not be supported in the combined chip, the 9221i.  I
would tend to believe the more specific data sheet.

> But the problem is when latter in the open handler a software reset is
> attempt.
> 
> Probably I can protect the software reset and only try to reset the
> device if the PHY is now in a low power mode. But if we don't reset
> the device at interface bringing up, when should we do a the reset?

You may have to change the order of initialisation of the PHY and MAC so
that reset works properly.

> I'm not that familiarized with the networking layer, if someone can
> give me some light I can fix the issue and send a patch.

This really doesn't have much to do with general networking, only phylib
and the specifics of the SMSC hardware and drivers.  The smsc911x driver
is responsible for calling phylib functions and so the hardware
initialisation is very much under its control.

Ben.

-- 
Ben Hutchings
Beware of programmers who carry screwdrivers. - Leonard Brandwein

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: [PATCH 1/1] via-rhine: Fix hanging with high CPU load on low-end broads.
From: Francois Romieu @ 2011-12-30 12:56 UTC (permalink / raw)
  To: Bjarke Istrup Pedersen
  Cc: David Miller, shemminger, bhutchings, linux-kernel, netdev, rl
In-Reply-To: <CACPM=kXTqY1kVWrEMB-Z0Lqy6t+rXvMzixcSUy7fAz6g_ajV9g@mail.gmail.com>

Bjarke Istrup Pedersen <gurligebis@gentoo.org> :
[...]
> Sorry for asking a probably obvious question, but whats next to get it
> fixed and ready for inclusion?

It should be there for testing and deeper review within a pair of hours.
I ended up vandalizing most of the locking. From a testing viewpoint it
means some amount of work (not mine :o) ) to get a decent coverage.

Once it is known tested and reviewed - it may need a few iterations - it
can be formally submitted for inclusion.

-- 
Ueimor

^ permalink raw reply

* Re: [BUG] SIOCSIFFLAGS returns -EIO on SMSC LAN911x
From: Javier Martinez Canillas @ 2011-12-30 12:58 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: netdev, Enric Balletbo i Serra
In-Reply-To: <1325242573.13595.71.camel@deadeye>

On Fri, Dec 30, 2011 at 11:56 AM, Ben Hutchings <ben@decadent.org.uk> wrote:
> On Fri, 2011-12-30 at 10:44 +0100, Javier Martinez Canillas wrote:
>> Hello,
>>
>> We have an issue with the SMSC LAN911x driver with today linux-2.6 [1]
>> executing on an IGEPv2 [2] board using omap2plus_defconfig.
>>
>> When I try to bring up the network interface, the ioctl set interface
>> flags command (SIOCSIFFLAGS)  fails returning -EIO:
> [...]
>> By doing a git bisect we found that this strange behavior exists when
>> the Kconfig tristate compilation condition SMSC_PHY has the value yes
>> to be compiled built-in:
>>
>> SMSC_PHY=y
>>
>> If this config symbol has the value module (m) or not build at all,
>> then bringing up the network interface never fails.
>
> So the PHY driver is doing something that interferes with soft reset.
>

We have more information about the issue. It seems that the LAN9221i
network device has inside a lan8700 phy chip. When we compile with
SMSC_PHY and the smsc.c driver is included the lan8700 phy_driver
enable the energy detect mode for the transceiver.

> The data sheet for this part
> <http://www.smsc.com/media/Downloads_Public/Data_Sheets/9221.pdf> says
> that soft reset does not work if the PHY is in certain states.  Also, it
> doesn't seem to specify a maximum time for soft reset to complete,
> though it does say that PHY reset takes 100 us.
>

One of the states that prevents software reseting the chip is when the
phy is in low power mode. So the reset fails in the ndo_open handler
(ifconfig ethx up).

>> Did anyone have the same problem?
>>
>> The problem is really strange to me, especially since we are sure that
>> all the requirements to software reset the device are meet in both
>> cases (with SMSC_PHY compiled built-in and without it)
>
> I don't know about that.  smsc_phy_config_init() attempts to enable
> power-saving on the PHY, but it is writing to a bit that is reserved
> according to the data sheet for the combined MAC/PHY chip.  dwein

Since the PHY chip is a lan8700, the power-saving seems to be correct.
But the problem is when latter in the open handler a software reset is
attempt.

Probably I can protect the software reset and only try to reset the
device if the PHY is now in a low power mode. But if we don't reset
the device at interface bringing up, when should we do a the reset?

I'm not that familiarized with the networking layer, if someone can
give me some light I can fix the issue and send a patch.

Thanks a lot and best regards,

-- 
Javier Martínez Canillas
(+34) 682 39 81 69
Barcelona, Spain

^ permalink raw reply

* Darlehen anbieten
From: CARSON FINANCIAL SERVICE @ 2011-12-30 11:05 UTC (permalink / raw)


CARSON FINANCIAL SERVICE LTD ist die Lösung für alle Ihrefinanziellen
Möglichkeiten, für schnelle und einfache Kredit bei 3% Zinssatz kontaktieren Sie
uns unter (carsonfinance11@admin.in.th).

KREDITNEHMER DATEN BILDEN

VOLLSTÄNDIGER NAME:
ALTER:
GESCHLECHT:
LAND:
TELEFONNUMMER:
KREDITBETRAG IN USD:
DAUER DER AUSLEIHE:
MONATSEINKOMMEN:
BERUF:
ZWECK DES DARLEHENS:

nach Erhalt der oben möchten wir Sie mit einem gut berechneten Bedingungen und
den Zustandder von der benötigten Menge zu kontaktieren.Dank, wie ich Ihre
schnelle Antwort erwarten so schnell wie möglich.

Bitte richten Sie alle Antwort auf diese
E-Mail: carsonfinance11@admin.in.th


Was
CARSON FINANCIAL SERVICE LTD
Anthony Williams (Darlehen Regisseur)

^ permalink raw reply

* RE: bonding device in balance-alb mode shows packet loss in kernel 3.2-rc6
From: Narendra_K @ 2011-12-30 12:22 UTC (permalink / raw)
  To: fubar; +Cc: netdev, Surya_Prabhakar, Shyam_Iyer
In-Reply-To: <27384.1325102910@death>

> -----Original Message-----
> From: Jay Vosburgh [mailto:fubar@us.ibm.com]
> Sent: Thursday, December 29, 2011 1:39 AM
> To: K, Narendra
> Cc: netdev@vger.kernel.org
> Subject: Re: bonding device in balance-alb mode shows packet loss in kernel
> 3.2-rc6
> 
> <Narendra_K@Dell.com> wrote:
> 
> >By observing the packets on remote HOST2, the sequence is
> >
> >1. 'bond0' broadcasts an ARP request with source MAC equal to 'bond0'
> >MAC address and receives a ARP response to the same.
> >Next few packets are received.
> 
> 	In this case, it means the peer has been assigned to the "em2"
> slave.
> 
> >2. After some, there are 2 ARP replies from 'bond0' to HOST2 with
> >source MAC equal to 'inactive slave' MAC id. Now HOST2 sends ICMP
> >response with destnation MAC equal to inactive slave MAC id and these
> >packets are dropped.
> 
> 	This part is not unusual for the balance-alb mode; the traffic is
> periodically rebalanced, and in this case the peer HOST2 was likely assigned
> to a different slave that it was previously.  I'm not sure why the packets don't
> reach their destination, but they shouldn't be dropped due to the slave being
> "inactive," as I explained above.
> 
> >The wireshark protocol trace is attached to this note.
> >
> >3. The behavior was independent of the Network adapters models.
> >
> >4. Also, I had few prints in 'eth_type_trans' and it seemed like the 'inactive
> slave'
> >was not receiving any frames destined to it (00:21:9b:9d:a5:74) except ARP
> broadcasts.
> >Setting the 'inactive slave' in 'promisc' mode made bond0 see the responses.
> 
> 	This seems very strange, since the MAC information shown later
> suggests that the slaves all are using their original MAC addresses, so the
> packets ought to be delivered.
> 
> 	I'm out of the office until next week, so I won't have an opportunity
> to try and reproduce this myself until then.  I wonder if something in the
> rx_handler changes over the last few months has broken this, although a
> look at the code suggests that it should be doing the right things.

Hi Jay, thanks for looking into this. I am out of office next week.
I am copying Surya if additional information is required.
(Please keep Surya in CC).

It was strange that 'eth_type_trans' showed only ARP broadcasts for
em3 and em4. Interestingly when i set the perm HW address of em3 manually
by

ifconfig em3 hw ether 00:21:9b:9d:a5:74

packet drops stopped and 'eth_type_trans' showed unicast frames
destined to 00:21:9b:9d:a5:74.

I put few debug prints in 'bnx2_set_mac_addr' to see what MAC ids are
getting set in the hardware. When i stopped and started the bond0,
all the slaves seemed to have the same MAC id 
(of em2 and bond0 00:21:9b:9d:a5:72). 

Also, the following change made the packet drops stop and prints in
'bnx2_set_mac_addr' seemed to indicate that all slaves got unique
mac id set in hardware.

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 7f87568..e717267 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1620,7 +1620,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
         */
        memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN);

-       if (!bond->params.fail_over_mac) {
+       if (!bond->params.fail_over_mac && !bond_is_lb(bond)) {
                /*
                 * Set slave to master's mac address.  The application already
                 * set the master's mac address to that of the first slave


With regards,
Narendra K
 

^ permalink raw reply related

* Re: [BUG] SIOCSIFFLAGS returns -EIO on SMSC LAN911x
From: Javier Martinez Canillas @ 2011-12-30 12:04 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: netdev, Enric Balletbo i Serra
In-Reply-To: <1325242573.13595.71.camel@deadeye>

On Fri, Dec 30, 2011 at 11:56 AM, Ben Hutchings <ben@decadent.org.uk> wrote:
> On Fri, 2011-12-30 at 10:44 +0100, Javier Martinez Canillas wrote:
>> Hello,
>>
>> We have an issue with the SMSC LAN911x driver with today linux-2.6 [1]
>> executing on an IGEPv2 [2] board using omap2plus_defconfig.
>>
>> When I try to bring up the network interface, the ioctl set interface
>> flags command (SIOCSIFFLAGS)  fails returning -EIO:
> [...]
>> By doing a git bisect we found that this strange behavior exists when
>> the Kconfig tristate compilation condition SMSC_PHY has the value yes
>> to be compiled built-in:
>>
>> SMSC_PHY=y
>>
>> If this config symbol has the value module (m) or not build at all,
>> then bringing up the network interface never fails.
>

Hello Ben, thanks for answering.

> So the PHY driver is doing something that interferes with soft reset.
>
> The data sheet for this part
> <http://www.smsc.com/media/Downloads_Public/Data_Sheets/9221.pdf> says
> that soft reset does not work if the PHY is in certain states.  Also, it
> doesn't seem to specify a maximum time for soft reset to complete,
> though it does say that PHY reset takes 100 us.
>

Yes, it seems that the PHY driver is the responsible of that.

Something I forgot to mention, the ethernet chip we are using is a
SMSC LAN 9221i.

>> Did anyone have the same problem?
>>
>> The problem is really strange to me, especially since we are sure that
>> all the requirements to software reset the device are meet in both
>> cases (with SMSC_PHY compiled built-in and without it)
>
> I don't know about that.  smsc_phy_config_init() attempts to enable
> power-saving on the PHY, but it is writing to a bit that is reserved
> according to the data sheet for the combined MAC/PHY chip.  You might
> want to try reverting:
>
> commit 698244ace8b63896565022143ab19f141bc48993
> Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> Date:   Wed Jan 6 20:35:14 2010 -0800
>
>    phy: SMSC device Energy Detect power-down mode
>
> Ben.

Thanks a lot, reverting that patch solves the issue.

I've looked at that patch before but since we are using the smsc911x
and that patch made an exception for the lan911x phy_driver I thought
it wasn't the responsible for this:

+static int lan911x_config_init(struct phy_device *phydev)
+{
+       return smsc_phy_ack_interrupt(phydev);
+}

@@ -147,7 +164,7 @@ static struct phy_driver lan911x_int_driver = {
        /* basic functions */
        .config_aneg    = genphy_config_aneg,
        .read_status    = genphy_read_status,
-       .config_init    = smsc_phy_config_init,
+       .config_init    = lan911x_config_init,

But now I realized that the lan911x phy driver is not being used but
the lan8700_driver phy_driver, and the modified smsc_phy_config_init
was executed.

thanks a lot and best regards,

-- 
Javier Martínez Canillas
(+34) 682 39 81 69
Barcelona, Spain

^ 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