- Optimized interrupt routine fast path. Signed-off-by: Sivakumar Subramani <[EMAIL PROTECTED]> Signed-off-by: Santosh Rastapur <[EMAIL PROTECTED]> Signed-off-by: Ramkrishna Vepa <[EMAIL PROTECTED]> --- diff -Nurp patch4/drivers/net/s2io.c patch5/drivers/net/s2io.c --- patch4/drivers/net/s2io.c 2007-08-15 08:42:14.000000000 -0700 +++ patch5/drivers/net/s2io.c 2007-08-15 08:42:51.000000000 -0700 @@ -84,7 +84,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.26.1" +#define DRV_VERSION "2.0.26.2" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; @@ -4917,71 +4917,76 @@ static irqreturn_t s2io_isr(int irq, voi * 1. Rx of packet. * 2. Tx complete. * 3. Link down. - * 4. Error in any functional blocks of the NIC. */ reason = readq(&bar0->general_int_status); - if (!reason) { - /* The interrupt was not raised by us. */ + if (unlikely(reason == S2IO_MINUS_ONE) ) { + /* Nothing much can be done. Get out */ atomic_dec(&sp->isr_cnt); - return IRQ_NONE; - } - else if (unlikely(reason == S2IO_MINUS_ONE) ) { - /* Disable device and get out */ - atomic_dec(&sp->isr_cnt); - return IRQ_NONE; + return IRQ_HANDLED; } - if (napi) { - if (reason & GEN_INTR_RXTRAFFIC) { - if ( likely ( netif_rx_schedule_prep(dev)) ) { - __netif_rx_schedule(dev); - writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask); + if (reason & (GEN_INTR_RXTRAFFIC | + GEN_INTR_TXTRAFFIC | GEN_INTR_TXPIC)) + { + writeq(S2IO_MINUS_ONE, &bar0->general_int_mask); + + if (config->napi) { + if (reason & GEN_INTR_RXTRAFFIC) { + if ( likely (netif_rx_schedule_prep(dev)) ) { + __netif_rx_schedule(dev); + writeq(S2IO_MINUS_ONE, + &bar0->rx_traffic_mask); + } else + writeq(S2IO_MINUS_ONE, + &bar0->rx_traffic_int); } - else + } else { + /* + * rx_traffic_int reg is an R1 register, writing all 1's + * will ensure that the actual interrupt causing bit + * get's cleared and hence a read can be avoided. + */ + if (reason & GEN_INTR_RXTRAFFIC) writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); + + for (i = 0; i < config->rx_ring_num; i++) + rx_intr_handler(&mac_control->rings[i]); } - } else { + /* - * Rx handler is called by default, without checking for the - * cause of interrupt. - * rx_traffic_int reg is an R1 register, writing all 1's + * tx_traffic_int reg is an R1 register, writing all 1's * will ensure that the actual interrupt causing bit get's * cleared and hence a read can be avoided. */ - if (reason & GEN_INTR_RXTRAFFIC) - writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); + if (reason & GEN_INTR_TXTRAFFIC) + writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); - for (i = 0; i < config->rx_ring_num; i++) { - rx_intr_handler(&mac_control->rings[i]); - } - } + for (i = 0; i < config->tx_fifo_num; i++) + tx_intr_handler(&mac_control->fifos[i]); - /* - * tx_traffic_int reg is an R1 register, writing all 1's - * will ensure that the actual interrupt causing bit get's - * cleared and hence a read can be avoided. - */ - if (reason & GEN_INTR_TXTRAFFIC) - writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); + if (reason & GEN_INTR_TXPIC) + s2io_txpic_intr_handle(sp); - for (i = 0; i < config->tx_fifo_num; i++) - tx_intr_handler(&mac_control->fifos[i]); + /* + * Reallocate the buffers from the interrupt handler itself. + */ + if (!config->napi) { + for (i = 0; i < config->rx_ring_num; i++) + s2io_chk_rx_buffers(sp, i); + } + writeq(sp->general_int_mask, &bar0->general_int_mask); + readl(&bar0->general_int_status); - if (reason & GEN_INTR_TXPIC) - s2io_txpic_intr_handle(sp); - /* - * If the Rx buffer count is below the panic threshold then - * reallocate the buffers from the interrupt handler itself, - * else schedule a tasklet to reallocate the buffers. - */ - if (!napi) { - for (i = 0; i < config->rx_ring_num; i++) - s2io_chk_rx_buffers(sp, i); - } + atomic_dec(&sp->isr_cnt); + return IRQ_HANDLED; - writeq(0, &bar0->general_int_mask); - readl(&bar0->general_int_status); + } + else if (!reason) { + /* The interrupt was not raised by us */ + atomic_dec(&sp->isr_cnt); + return IRQ_NONE; + } atomic_dec(&sp->isr_cnt); return IRQ_HANDLED; @@ -7109,6 +7114,14 @@ static void s2io_rem_isr(struct s2io_nic struct net_device *dev = sp->dev; struct swStat *stats = &sp->mac_control.stats_info->sw_stat; + /* Waiting till all Interrupt handlers are complete */ + do { + if (!atomic_read(&sp->isr_cnt)) + break; + msleep(10); + cnt++; + } while(cnt < 5); + if (sp->config.intr_type == MSI_X) { int i; u16 msi_control; @@ -7138,14 +7151,6 @@ static void s2io_rem_isr(struct s2io_nic } else { free_irq(sp->pdev->irq, dev); } - /* Waiting till all Interrupt handlers are complete */ - cnt = 0; - do { - msleep(10); - if (!atomic_read(&sp->isr_cnt)) - break; - cnt++; - } while(cnt < 5); } static void do_s2io_card_down(struct s2io_nic * sp, int do_io) @@ -7676,19 +7681,12 @@ static int s2io_verify_parm(struct pci_d if (*dev_intr_type != INTA) napi = 0; -#ifndef CONFIG_PCI_MSI - if (*dev_intr_type != INTA) { - DBG_PRINT(ERR_DBG, "s2io: This kernel does not support" - "MSI/MSI-X. Defaulting to INTA\n"); - *dev_intr_type = INTA; - } -#else if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " "Defaulting to INTA\n"); *dev_intr_type = INTA; } -#endif + if ((*dev_intr_type == MSI_X) && ((pdev->device != PCI_DEVICE_ID_HERC_WIN) && (pdev->device != PCI_DEVICE_ID_HERC_UNI))) { @@ -7846,6 +7844,8 @@ s2io_init_nic(struct pci_dev *pdev, cons mac_control = &sp->mac_control; config = &sp->config; + config->napi = napi; + /* Tx side parameters. */ config->tx_fifo_num = tx_fifo_num; for (i = 0; i < MAX_TX_FIFOS; i++) {
- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html