>From fb5fdae345e4099a8e543401ba36e7588c7c8e4c Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: <269c60147b6e7e7ad46b36e7dd1c91bb0c1b0274.1338938527.git.romieu@fr.zoreil.com> References: <269c60147b6e7e7ad46b36e7dd1c91bb0c1b0274.1338938527.git.romieu@fr.zoreil.com> From: Francois Romieu Date: Sat, 2 Jun 2012 11:21:58 +0200 Subject: [PATCH 2/2] r8169: irq debug stuff. X-Organisation: Land of Sunshine Inc. Signed-off-by: Francois Romieu --- drivers/net/ethernet/realtek/r8169.c | 59 ++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index abb028a..4a05b68 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -782,6 +782,15 @@ struct rtl8169_private { #ifdef CONFIG_R8169_DEBUGFS struct dentry *debugfs; + +#define RTL_DEBUG_EVENT_RING_SIZE 1024 + struct rtl_event_ring { + struct rtl_event { + u16 ts; + u16 evt; + } evts[RTL_DEBUG_EVENT_RING_SIZE]; + int used; + } event_ring; #endif }; @@ -5849,6 +5858,31 @@ process_pkt: return count; } +#ifdef CONFIG_R8169_DEBUGFS +static void rtl_trace_event(struct rtl8169_private *tp, u16 status) +{ + struct rtl_event_ring *evr = &tp->event_ring; + int used = evr->used; + struct rtl_event *e = evr->evts + used; + + if (used >= RTL_DEBUG_EVENT_RING_SIZE) { + if (net_ratelimit()) + netif_err(tp, drv, tp->dev, "event ring full.\n"); + return; + } + + /* ms. Well, almost. */ + e->ts = ((local_clock() / 100000) % 100000) >> 1; + e->evt = status; + evr->used = used + 1; +} + +#else /* !CONFIG_R8169_DEBUGFS */ + +#define rtl_trace_event(tp, status) do { } while (0) + +#endif /* !CONFIG_R8169_DEBUGFS */ + static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) { struct net_device *dev = dev_instance; @@ -5858,6 +5892,8 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) status = rtl_get_events(tp); if (status && status != 0xffff) { + rtl_trace_event(tp, status); + status &= RTL_EVENT_NAPI | tp->event_slow; if (status) { handled = 1; @@ -6776,6 +6812,28 @@ static int rtl_debug_open_tx(struct inode *inode, struct file *file) DECLARE_RTL_DEBUG_FOPS(tx); +static int rtl_debug_show_irq(struct seq_file *seq, void *v) +{ + struct rtl8169_private *tp = seq->private; + struct rtl_event_ring *evr = &tp->event_ring; + int i; + + for (i = 0; i < min(evr->used, RTL_DEBUG_EVENT_RING_SIZE); i++) { + struct rtl_event *e = evr->evts + i; + + seq_printf(seq, "[%05d] %04x\n", e->ts << 1, e->evt); + } + + return 0; +} + +static int rtl_debug_open_irq(struct inode *inode, struct file *file) +{ + return single_open(file, rtl_debug_show_irq, inode->i_private); +} + +DECLARE_RTL_DEBUG_FOPS(irq); + static void rtl_debug_create_tree(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -6786,6 +6844,7 @@ static void rtl_debug_create_tree(struct net_device *dev) } ent[] = { { &rtl_debug_fops_rx, "rx" }, { &rtl_debug_fops_tx, "tx" }, + { &rtl_debug_fops_irq, "irq" }, { NULL, } }; int i; -- 1.7.10.2