diff options
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 157 |
1 files changed, 61 insertions, 96 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index d167bc0ae951..ac6b9b93c025 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -84,7 +84,7 @@ | |||
84 | #include "s2io.h" | 84 | #include "s2io.h" |
85 | #include "s2io-regs.h" | 85 | #include "s2io-regs.h" |
86 | 86 | ||
87 | #define DRV_VERSION "2.0.26.1" | 87 | #define DRV_VERSION "2.0.26.2" |
88 | 88 | ||
89 | /* S2io Driver name & version. */ | 89 | /* S2io Driver name & version. */ |
90 | static char s2io_driver_name[] = "Neterion"; | 90 | static char s2io_driver_name[] = "Neterion"; |
@@ -2715,12 +2715,8 @@ static int s2io_poll(struct napi_struct *napi, int budget) | |||
2715 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 2715 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
2716 | int i; | 2716 | int i; |
2717 | 2717 | ||
2718 | atomic_inc(&nic->isr_cnt); | 2718 | if (!is_s2io_card_up(nic)) |
2719 | |||
2720 | if (!is_s2io_card_up(nic)) { | ||
2721 | atomic_dec(&nic->isr_cnt); | ||
2722 | return 0; | 2719 | return 0; |
2723 | } | ||
2724 | 2720 | ||
2725 | mac_control = &nic->mac_control; | 2721 | mac_control = &nic->mac_control; |
2726 | config = &nic->config; | 2722 | config = &nic->config; |
@@ -2752,7 +2748,6 @@ static int s2io_poll(struct napi_struct *napi, int budget) | |||
2752 | /* Re enable the Rx interrupts. */ | 2748 | /* Re enable the Rx interrupts. */ |
2753 | writeq(0x0, &bar0->rx_traffic_mask); | 2749 | writeq(0x0, &bar0->rx_traffic_mask); |
2754 | readl(&bar0->rx_traffic_mask); | 2750 | readl(&bar0->rx_traffic_mask); |
2755 | atomic_dec(&nic->isr_cnt); | ||
2756 | return pkt_cnt; | 2751 | return pkt_cnt; |
2757 | 2752 | ||
2758 | no_rx: | 2753 | no_rx: |
@@ -2763,7 +2758,6 @@ no_rx: | |||
2763 | break; | 2758 | break; |
2764 | } | 2759 | } |
2765 | } | 2760 | } |
2766 | atomic_dec(&nic->isr_cnt); | ||
2767 | return pkt_cnt; | 2761 | return pkt_cnt; |
2768 | } | 2762 | } |
2769 | 2763 | ||
@@ -2791,7 +2785,6 @@ static void s2io_netpoll(struct net_device *dev) | |||
2791 | 2785 | ||
2792 | disable_irq(dev->irq); | 2786 | disable_irq(dev->irq); |
2793 | 2787 | ||
2794 | atomic_inc(&nic->isr_cnt); | ||
2795 | mac_control = &nic->mac_control; | 2788 | mac_control = &nic->mac_control; |
2796 | config = &nic->config; | 2789 | config = &nic->config; |
2797 | 2790 | ||
@@ -2816,7 +2809,6 @@ static void s2io_netpoll(struct net_device *dev) | |||
2816 | break; | 2809 | break; |
2817 | } | 2810 | } |
2818 | } | 2811 | } |
2819 | atomic_dec(&nic->isr_cnt); | ||
2820 | enable_irq(dev->irq); | 2812 | enable_irq(dev->irq); |
2821 | return; | 2813 | return; |
2822 | } | 2814 | } |
@@ -4187,17 +4179,12 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) | |||
4187 | struct ring_info *ring = (struct ring_info *)dev_id; | 4179 | struct ring_info *ring = (struct ring_info *)dev_id; |
4188 | struct s2io_nic *sp = ring->nic; | 4180 | struct s2io_nic *sp = ring->nic; |
4189 | 4181 | ||
4190 | atomic_inc(&sp->isr_cnt); | 4182 | if (!is_s2io_card_up(sp)) |
4191 | |||
4192 | if (!is_s2io_card_up(sp)) { | ||
4193 | atomic_dec(&sp->isr_cnt); | ||
4194 | return IRQ_HANDLED; | 4183 | return IRQ_HANDLED; |
4195 | } | ||
4196 | 4184 | ||
4197 | rx_intr_handler(ring); | 4185 | rx_intr_handler(ring); |
4198 | s2io_chk_rx_buffers(sp, ring->ring_no); | 4186 | s2io_chk_rx_buffers(sp, ring->ring_no); |
4199 | 4187 | ||
4200 | atomic_dec(&sp->isr_cnt); | ||
4201 | return IRQ_HANDLED; | 4188 | return IRQ_HANDLED; |
4202 | } | 4189 | } |
4203 | 4190 | ||
@@ -4206,15 +4193,10 @@ static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) | |||
4206 | struct fifo_info *fifo = (struct fifo_info *)dev_id; | 4193 | struct fifo_info *fifo = (struct fifo_info *)dev_id; |
4207 | struct s2io_nic *sp = fifo->nic; | 4194 | struct s2io_nic *sp = fifo->nic; |
4208 | 4195 | ||
4209 | atomic_inc(&sp->isr_cnt); | 4196 | if (!is_s2io_card_up(sp)) |
4210 | |||
4211 | if (!is_s2io_card_up(sp)) { | ||
4212 | atomic_dec(&sp->isr_cnt); | ||
4213 | return IRQ_HANDLED; | 4197 | return IRQ_HANDLED; |
4214 | } | ||
4215 | 4198 | ||
4216 | tx_intr_handler(fifo); | 4199 | tx_intr_handler(fifo); |
4217 | atomic_dec(&sp->isr_cnt); | ||
4218 | return IRQ_HANDLED; | 4200 | return IRQ_HANDLED; |
4219 | } | 4201 | } |
4220 | static void s2io_txpic_intr_handle(struct s2io_nic *sp) | 4202 | static void s2io_txpic_intr_handle(struct s2io_nic *sp) |
@@ -4591,12 +4573,8 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) | |||
4591 | if (pci_channel_offline(sp->pdev)) | 4573 | if (pci_channel_offline(sp->pdev)) |
4592 | return IRQ_NONE; | 4574 | return IRQ_NONE; |
4593 | 4575 | ||
4594 | atomic_inc(&sp->isr_cnt); | 4576 | if (!is_s2io_card_up(sp)) |
4595 | |||
4596 | if (!is_s2io_card_up(sp)) { | ||
4597 | atomic_dec(&sp->isr_cnt); | ||
4598 | return IRQ_NONE; | 4577 | return IRQ_NONE; |
4599 | } | ||
4600 | 4578 | ||
4601 | mac_control = &sp->mac_control; | 4579 | mac_control = &sp->mac_control; |
4602 | config = &sp->config; | 4580 | config = &sp->config; |
@@ -4607,73 +4585,75 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) | |||
4607 | * 1. Rx of packet. | 4585 | * 1. Rx of packet. |
4608 | * 2. Tx complete. | 4586 | * 2. Tx complete. |
4609 | * 3. Link down. | 4587 | * 3. Link down. |
4610 | * 4. Error in any functional blocks of the NIC. | ||
4611 | */ | 4588 | */ |
4612 | reason = readq(&bar0->general_int_status); | 4589 | reason = readq(&bar0->general_int_status); |
4613 | 4590 | ||
4614 | if (!reason) { | 4591 | if (unlikely(reason == S2IO_MINUS_ONE) ) { |
4615 | /* The interrupt was not raised by us. */ | 4592 | /* Nothing much can be done. Get out */ |
4616 | atomic_dec(&sp->isr_cnt); | 4593 | return IRQ_HANDLED; |
4617 | return IRQ_NONE; | ||
4618 | } | ||
4619 | else if (unlikely(reason == S2IO_MINUS_ONE) ) { | ||
4620 | /* Disable device and get out */ | ||
4621 | atomic_dec(&sp->isr_cnt); | ||
4622 | return IRQ_NONE; | ||
4623 | } | 4594 | } |
4624 | 4595 | ||
4625 | if (napi) { | 4596 | if (reason & (GEN_INTR_RXTRAFFIC | |
4626 | if (reason & GEN_INTR_RXTRAFFIC) { | 4597 | GEN_INTR_TXTRAFFIC | GEN_INTR_TXPIC)) |
4627 | if (likely (netif_rx_schedule_prep(dev, &sp->napi))) { | 4598 | { |
4628 | __netif_rx_schedule(dev, &sp->napi); | 4599 | writeq(S2IO_MINUS_ONE, &bar0->general_int_mask); |
4629 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask); | 4600 | |
4601 | if (config->napi) { | ||
4602 | if (reason & GEN_INTR_RXTRAFFIC) { | ||
4603 | if (likely(netif_rx_schedule_prep(dev, | ||
4604 | &sp->napi))) { | ||
4605 | __netif_rx_schedule(dev, &sp->napi); | ||
4606 | writeq(S2IO_MINUS_ONE, | ||
4607 | &bar0->rx_traffic_mask); | ||
4608 | } else | ||
4609 | writeq(S2IO_MINUS_ONE, | ||
4610 | &bar0->rx_traffic_int); | ||
4630 | } | 4611 | } |
4631 | else | 4612 | } else { |
4613 | /* | ||
4614 | * rx_traffic_int reg is an R1 register, writing all 1's | ||
4615 | * will ensure that the actual interrupt causing bit | ||
4616 | * get's cleared and hence a read can be avoided. | ||
4617 | */ | ||
4618 | if (reason & GEN_INTR_RXTRAFFIC) | ||
4632 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); | 4619 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); |
4620 | |||
4621 | for (i = 0; i < config->rx_ring_num; i++) | ||
4622 | rx_intr_handler(&mac_control->rings[i]); | ||
4633 | } | 4623 | } |
4634 | } else { | 4624 | |
4635 | /* | 4625 | /* |
4636 | * Rx handler is called by default, without checking for the | 4626 | * tx_traffic_int reg is an R1 register, writing all 1's |
4637 | * cause of interrupt. | ||
4638 | * rx_traffic_int reg is an R1 register, writing all 1's | ||
4639 | * will ensure that the actual interrupt causing bit get's | 4627 | * will ensure that the actual interrupt causing bit get's |
4640 | * cleared and hence a read can be avoided. | 4628 | * cleared and hence a read can be avoided. |
4641 | */ | 4629 | */ |
4642 | if (reason & GEN_INTR_RXTRAFFIC) | 4630 | if (reason & GEN_INTR_TXTRAFFIC) |
4643 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); | 4631 | writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); |
4644 | 4632 | ||
4645 | for (i = 0; i < config->rx_ring_num; i++) { | 4633 | for (i = 0; i < config->tx_fifo_num; i++) |
4646 | rx_intr_handler(&mac_control->rings[i]); | 4634 | tx_intr_handler(&mac_control->fifos[i]); |
4647 | } | ||
4648 | } | ||
4649 | 4635 | ||
4650 | /* | 4636 | if (reason & GEN_INTR_TXPIC) |
4651 | * tx_traffic_int reg is an R1 register, writing all 1's | 4637 | s2io_txpic_intr_handle(sp); |
4652 | * will ensure that the actual interrupt causing bit get's | ||
4653 | * cleared and hence a read can be avoided. | ||
4654 | */ | ||
4655 | if (reason & GEN_INTR_TXTRAFFIC) | ||
4656 | writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); | ||
4657 | 4638 | ||
4658 | for (i = 0; i < config->tx_fifo_num; i++) | 4639 | /* |
4659 | tx_intr_handler(&mac_control->fifos[i]); | 4640 | * Reallocate the buffers from the interrupt handler itself. |
4641 | */ | ||
4642 | if (!config->napi) { | ||
4643 | for (i = 0; i < config->rx_ring_num; i++) | ||
4644 | s2io_chk_rx_buffers(sp, i); | ||
4645 | } | ||
4646 | writeq(sp->general_int_mask, &bar0->general_int_mask); | ||
4647 | readl(&bar0->general_int_status); | ||
4660 | 4648 | ||
4661 | if (reason & GEN_INTR_TXPIC) | 4649 | return IRQ_HANDLED; |
4662 | s2io_txpic_intr_handle(sp); | ||
4663 | /* | ||
4664 | * If the Rx buffer count is below the panic threshold then | ||
4665 | * reallocate the buffers from the interrupt handler itself, | ||
4666 | * else schedule a tasklet to reallocate the buffers. | ||
4667 | */ | ||
4668 | if (!napi) { | ||
4669 | for (i = 0; i < config->rx_ring_num; i++) | ||
4670 | s2io_chk_rx_buffers(sp, i); | ||
4671 | } | ||
4672 | 4650 | ||
4673 | writeq(0, &bar0->general_int_mask); | 4651 | } |
4674 | readl(&bar0->general_int_status); | 4652 | else if (!reason) { |
4653 | /* The interrupt was not raised by us */ | ||
4654 | return IRQ_NONE; | ||
4655 | } | ||
4675 | 4656 | ||
4676 | atomic_dec(&sp->isr_cnt); | ||
4677 | return IRQ_HANDLED; | 4657 | return IRQ_HANDLED; |
4678 | } | 4658 | } |
4679 | 4659 | ||
@@ -6795,7 +6775,6 @@ static int s2io_add_isr(struct s2io_nic * sp) | |||
6795 | } | 6775 | } |
6796 | static void s2io_rem_isr(struct s2io_nic * sp) | 6776 | static void s2io_rem_isr(struct s2io_nic * sp) |
6797 | { | 6777 | { |
6798 | int cnt = 0; | ||
6799 | struct net_device *dev = sp->dev; | 6778 | struct net_device *dev = sp->dev; |
6800 | struct swStat *stats = &sp->mac_control.stats_info->sw_stat; | 6779 | struct swStat *stats = &sp->mac_control.stats_info->sw_stat; |
6801 | 6780 | ||
@@ -6808,6 +6787,7 @@ static void s2io_rem_isr(struct s2io_nic * sp) | |||
6808 | int vector = sp->entries[i].vector; | 6787 | int vector = sp->entries[i].vector; |
6809 | void *arg = sp->s2io_entries[i].arg; | 6788 | void *arg = sp->s2io_entries[i].arg; |
6810 | 6789 | ||
6790 | synchronize_irq(vector); | ||
6811 | free_irq(vector, arg); | 6791 | free_irq(vector, arg); |
6812 | } | 6792 | } |
6813 | 6793 | ||
@@ -6826,16 +6806,9 @@ static void s2io_rem_isr(struct s2io_nic * sp) | |||
6826 | 6806 | ||
6827 | pci_disable_msix(sp->pdev); | 6807 | pci_disable_msix(sp->pdev); |
6828 | } else { | 6808 | } else { |
6809 | synchronize_irq(sp->pdev->irq); | ||
6829 | free_irq(sp->pdev->irq, dev); | 6810 | free_irq(sp->pdev->irq, dev); |
6830 | } | 6811 | } |
6831 | /* Waiting till all Interrupt handlers are complete */ | ||
6832 | cnt = 0; | ||
6833 | do { | ||
6834 | msleep(10); | ||
6835 | if (!atomic_read(&sp->isr_cnt)) | ||
6836 | break; | ||
6837 | cnt++; | ||
6838 | } while(cnt < 5); | ||
6839 | } | 6812 | } |
6840 | 6813 | ||
6841 | static void do_s2io_card_down(struct s2io_nic * sp, int do_io) | 6814 | static void do_s2io_card_down(struct s2io_nic * sp, int do_io) |
@@ -7365,19 +7338,12 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) | |||
7365 | if (*dev_intr_type != INTA) | 7338 | if (*dev_intr_type != INTA) |
7366 | napi = 0; | 7339 | napi = 0; |
7367 | 7340 | ||
7368 | #ifndef CONFIG_PCI_MSI | ||
7369 | if (*dev_intr_type != INTA) { | ||
7370 | DBG_PRINT(ERR_DBG, "s2io: This kernel does not support" | ||
7371 | "MSI/MSI-X. Defaulting to INTA\n"); | ||
7372 | *dev_intr_type = INTA; | ||
7373 | } | ||
7374 | #else | ||
7375 | if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { | 7341 | if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { |
7376 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " | 7342 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " |
7377 | "Defaulting to INTA\n"); | 7343 | "Defaulting to INTA\n"); |
7378 | *dev_intr_type = INTA; | 7344 | *dev_intr_type = INTA; |
7379 | } | 7345 | } |
7380 | #endif | 7346 | |
7381 | if ((*dev_intr_type == MSI_X) && | 7347 | if ((*dev_intr_type == MSI_X) && |
7382 | ((pdev->device != PCI_DEVICE_ID_HERC_WIN) && | 7348 | ((pdev->device != PCI_DEVICE_ID_HERC_WIN) && |
7383 | (pdev->device != PCI_DEVICE_ID_HERC_UNI))) { | 7349 | (pdev->device != PCI_DEVICE_ID_HERC_UNI))) { |
@@ -7535,6 +7501,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7535 | mac_control = &sp->mac_control; | 7501 | mac_control = &sp->mac_control; |
7536 | config = &sp->config; | 7502 | config = &sp->config; |
7537 | 7503 | ||
7504 | config->napi = napi; | ||
7505 | |||
7538 | /* Tx side parameters. */ | 7506 | /* Tx side parameters. */ |
7539 | config->tx_fifo_num = tx_fifo_num; | 7507 | config->tx_fifo_num = tx_fifo_num; |
7540 | for (i = 0; i < MAX_TX_FIFOS; i++) { | 7508 | for (i = 0; i < MAX_TX_FIFOS; i++) { |
@@ -7582,9 +7550,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7582 | for (i = 0; i < config->rx_ring_num; i++) | 7550 | for (i = 0; i < config->rx_ring_num; i++) |
7583 | atomic_set(&sp->rx_bufs_left[i], 0); | 7551 | atomic_set(&sp->rx_bufs_left[i], 0); |
7584 | 7552 | ||
7585 | /* Initialize the number of ISRs currently running */ | ||
7586 | atomic_set(&sp->isr_cnt, 0); | ||
7587 | |||
7588 | /* initialize the shared memory used by the NIC and the host */ | 7553 | /* initialize the shared memory used by the NIC and the host */ |
7589 | if (init_shared_mem(sp)) { | 7554 | if (init_shared_mem(sp)) { |
7590 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", | 7555 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", |