From: Jeff Garzik <jgarzik@pobox.com>
To: "David S. Miller" <davem@redhat.com>
Cc: Manish Lachwani <manish@Zambeel.com>, netdev@oss.sgi.com
Subject: [PATCH] tg3 intr masking update
Date: Sat, 21 Dec 2002 15:31:58 -0500 [thread overview]
Message-ID: <3E04CFBE.2060909@pobox.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1539 bytes --]
Here is a better patch, after I mulled it over on the trip to Atlanta.
It is based on the premise, derived from the chip documentation, that
1) intr-mbox-0 register usage is used to indicate to the NIC that the
driver is "in interrupt handler".
2) (intr-mbox-0 = 1) == pci-inta-mask + pci-inta-clear + stuff
3) the docs seem to be saying "just use intr-mbox-0 and ignore
pci-inta-mask"
Based on these three observations, the attached patch updates tg3 for
the following changes:
1) Mask ints in tg3_interrupt and unmask in tg3_poll. We not only
eliminate several MMIO writes/reads, but we also eliminate all usage of
functions tg3_[un]mask_ints(), which bit-bangs the
MISC_HOST_CTRL_MASK_PCI_INT bit in the TG3PCI_MISC_HOST_CTRL register.
2) If tg3_main_interrupt_work() returns no-work-exists, we [obviously
must] unmask ints in tg3_interrupt. But this is an unlikely case.
3) Simply call netif_rx_schedule(dev) in tg3_interrupt_main_work().
This was a change previously discussed. Eliminates the "poll already
scheduled" message which was often actually a bogus message.
4) Because of #2, tg3_interrupt_main_work returns boolean 'work_exists' now.
5) There are some Bugzilla bug reports for tg3 1.2, where NMI watchdog
triggers in tg3_timer. I did s/spin_lock_irq/spin_lock_irqsave/ in
tg3_poll for safety, because we might be locking against a timer not
only an interrupt handler. And just for general paranoia and safety as
an "obviously more safe" change.
Comments/feedback/corrections/flames requested :)
[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 2960 bytes --]
===== drivers/net/tg3.c 1.40 vs edited =====
--- 1.40/drivers/net/tg3.c Mon Dec 9 21:32:02 2002
+++ edited/drivers/net/tg3.c Sat Dec 21 15:06:34 2002
@@ -217,22 +217,6 @@
tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
}
-static inline void tg3_mask_ints(struct tg3 *tp)
-{
- tw32(TG3PCI_MISC_HOST_CTRL,
- (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
-}
-
-static inline void tg3_unmask_ints(struct tg3 *tp)
-{
- tw32(TG3PCI_MISC_HOST_CTRL,
- (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
- if (tp->hw_status->status & SD_STATUS_UPDATED) {
- tw32(GRC_LOCAL_CTRL,
- tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
- }
-}
-
static void tg3_switch_clocks(struct tg3 *tp)
{
if (tr32(TG3PCI_CLOCK_CTRL) & CLOCK_CTRL_44MHZ_CORE) {
@@ -2014,8 +1998,9 @@
struct tg3 *tp = netdev->priv;
struct tg3_hw_status *sblk = tp->hw_status;
int done;
+ unsigned long flags;
- spin_lock_irq(&tp->lock);
+ spin_lock_irqsave(&tp->lock, flags);
if (!(tp->tg3_flags &
(TG3_FLAG_USE_LINKCHG_REG |
@@ -2052,15 +2037,18 @@
if (done) {
netif_rx_complete(netdev);
- tg3_unmask_ints(tp);
+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+ 0x00000000);
+ /* don't care about flushing this write immediately */
}
- spin_unlock_irq(&tp->lock);
+ spin_unlock_irqrestore(&tp->lock, flags);
return (done ? 0 : 1);
}
-static __inline__ void tg3_interrupt_main_work(struct net_device *dev, struct tg3 *tp)
+static inline unsigned int tg3_interrupt_main_work(struct net_device *dev,
+ struct tg3 *tp)
{
struct tg3_hw_status *sblk = tp->hw_status;
int work_exists = 0;
@@ -2075,19 +2063,10 @@
sblk->idx[0].rx_producer != tp->rx_rcb_ptr)
work_exists = 1;
- if (!work_exists)
- return;
+ if (work_exists)
+ netif_rx_schedule(dev);
- if (netif_rx_schedule_prep(dev)) {
- /* NOTE: These writes are posted by the readback of
- * the mailbox register done by our caller.
- */
- tg3_mask_ints(tp);
- __netif_rx_schedule(dev);
- } else {
- printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
- dev->name);
- }
+ return work_exists;
}
static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -2102,13 +2081,16 @@
if (sblk->status & SD_STATUS_UPDATED) {
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
0x00000001);
+ /* flush the intr clear-and-mask before updating status block */
+ tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
sblk->status &= ~SD_STATUS_UPDATED;
- tg3_interrupt_main_work(dev, tp);
-
- tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
- 0x00000000);
- tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
+ if (!tg3_interrupt_main_work(dev, tp)) {
+ /* if work doesn't exist... */
+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+ 0x00000000);
+ tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
+ }
}
spin_unlock_irqrestore(&tp->lock, flags);
next reply other threads:[~2002-12-21 20:31 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-12-21 20:31 Jeff Garzik [this message]
2002-12-21 20:38 ` [PATCH] tg3 intr masking update Jeff Garzik
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3E04CFBE.2060909@pobox.com \
--to=jgarzik@pobox.com \
--cc=davem@redhat.com \
--cc=manish@Zambeel.com \
--cc=netdev@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.