Skip to content

Commit

Permalink
[PATCH] skge: use auto masking of irqs
Browse files Browse the repository at this point in the history
Improve performance of skge driver by not touching irq mask
register as much. Since the interrupt source auto-masks, the driver
can just leave it disabled until the end of the soft irq.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
  • Loading branch information
Stephen Hemminger authored and Jeff Garzik committed Mar 21, 2006
1 parent 00a6cae commit cfc3ed7
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 34 deletions.
54 changes: 21 additions & 33 deletions drivers/net/skge.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ static const int txqaddr[] = { Q_XA1, Q_XA2 };
static const int rxqaddr[] = { Q_R1, Q_R2 };
static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F };
static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F };
static const u32 portirqmask[] = { IS_PORT_1, IS_PORT_2 };

static int skge_get_regs_len(struct net_device *dev)
{
Expand Down Expand Up @@ -2184,12 +2183,6 @@ static int skge_up(struct net_device *dev)

skge->tx_avail = skge->tx_ring.count - 1;

/* Enable IRQ from port */
spin_lock_irq(&hw->hw_lock);
hw->intr_mask |= portirqmask[port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
spin_unlock_irq(&hw->hw_lock);

/* Initialize MAC */
spin_lock_bh(&hw->phy_lock);
if (hw->chip_id == CHIP_ID_GENESIS)
Expand Down Expand Up @@ -2246,11 +2239,6 @@ static int skge_down(struct net_device *dev)
else
yukon_stop(skge);

spin_lock_irq(&hw->hw_lock);
hw->intr_mask &= ~portirqmask[skge->port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
spin_unlock_irq(&hw->hw_lock);

/* Stop transmitter */
skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP);
skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
Expand Down Expand Up @@ -2734,11 +2722,9 @@ static int skge_poll(struct net_device *dev, int *budget)
if (work_done >= to_do)
return 1; /* not done */

spin_lock_irq(&hw->hw_lock);
__netif_rx_complete(dev);
hw->intr_mask |= portirqmask[skge->port];
netif_rx_complete(dev);
hw->intr_mask |= skge->port == 0 ? (IS_R1_F|IS_XA1_F) : (IS_R2_F|IS_XA2_F);
skge_write32(hw, B0_IMSK, hw->intr_mask);
spin_unlock_irq(&hw->hw_lock);

return 0;
}
Expand Down Expand Up @@ -2850,12 +2836,11 @@ static void skge_extirq(unsigned long data)
int port;

spin_lock(&hw->phy_lock);
for (port = 0; port < 2; port++) {
for (port = 0; port < hw->ports; port++) {
struct net_device *dev = hw->dev[port];
struct skge_port *skge = netdev_priv(dev);

if (dev && netif_running(dev)) {
struct skge_port *skge = netdev_priv(dev);

if (netif_running(dev)) {
if (hw->chip_id != CHIP_ID_GENESIS)
yukon_phy_intr(skge);
else
Expand All @@ -2864,21 +2849,25 @@ static void skge_extirq(unsigned long data)
}
spin_unlock(&hw->phy_lock);

spin_lock_irq(&hw->hw_lock);
hw->intr_mask |= IS_EXT_REG;
skge_write32(hw, B0_IMSK, hw->intr_mask);
spin_unlock_irq(&hw->hw_lock);
}

static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct skge_hw *hw = dev_id;
u32 status = skge_read32(hw, B0_SP_ISRC);
u32 status;

if (status == 0 || status == ~0) /* hotplug or shared irq */
/* Reading this register masks IRQ */
status = skge_read32(hw, B0_SP_ISRC);
if (status == 0)
return IRQ_NONE;

spin_lock(&hw->hw_lock);
if (status & IS_EXT_REG) {
hw->intr_mask &= ~IS_EXT_REG;
tasklet_schedule(&hw->ext_tasklet);
}

if (status & (IS_R1_F|IS_XA1_F)) {
skge_write8(hw, Q_ADDR(Q_R1, Q_CSR), CSR_IRQ_CL_F);
hw->intr_mask &= ~(IS_R1_F|IS_XA1_F);
Expand All @@ -2891,6 +2880,9 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
netif_rx_schedule(hw->dev[1]);
}

if (likely((status & hw->intr_mask) == 0))
return IRQ_HANDLED;

if (status & IS_PA_TO_RX1) {
struct skge_port *skge = netdev_priv(hw->dev[0]);
++skge->net_stats.rx_over_errors;
Expand Down Expand Up @@ -2918,13 +2910,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
if (status & IS_HW_ERR)
skge_error_irq(hw);

if (status & IS_EXT_REG) {
hw->intr_mask &= ~IS_EXT_REG;
tasklet_schedule(&hw->ext_tasklet);
}

skge_write32(hw, B0_IMSK, hw->intr_mask);
spin_unlock(&hw->hw_lock);

return IRQ_HANDLED;
}
Expand Down Expand Up @@ -3070,7 +3056,10 @@ static int skge_reset(struct skge_hw *hw)
else
hw->ram_size = t8 * 4096;

hw->intr_mask = IS_HW_ERR | IS_EXT_REG;
hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1;
if (hw->ports > 1)
hw->intr_mask |= IS_PORT_2;

if (hw->chip_id == CHIP_ID_GENESIS)
genesis_init(hw);
else {
Expand Down Expand Up @@ -3293,7 +3282,6 @@ static int __devinit skge_probe(struct pci_dev *pdev,

hw->pdev = pdev;
spin_lock_init(&hw->phy_lock);
spin_lock_init(&hw->hw_lock);
tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw);

hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
Expand Down
1 change: 0 additions & 1 deletion drivers/net/skge.h
Original file line number Diff line number Diff line change
Expand Up @@ -2402,7 +2402,6 @@ struct skge_hw {

struct tasklet_struct ext_tasklet;
spinlock_t phy_lock;
spinlock_t hw_lock;
};

enum {
Expand Down

0 comments on commit cfc3ed7

Please sign in to comment.