diff options
author | Sivakumar Subramani <Sivakumar.Subramani@neterion.com> | 2007-09-06 06:51:14 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:51:10 -0400 |
commit | 92b84437a6cddf5dc00ab179e38d2baa2264d46a (patch) | |
tree | f59ff1584115efce91c535adc3c8e28dd9099fd5 | |
parent | eaae7f72304f2cd095e68ab39629c0f32815dcf2 (diff) |
S2io: Check for device state before handling traffic
- Added check to return from the traffic handling function, if the card status
is DOWN.
- Implemented Jeff's comments on incorrect return value in s2io_poll function.
Signed-off-by: Sivakumar Subramani <sivakumar.subramani@neterion.com>
Signed-off-by: Santosh Rastapur <santosh.rastapur@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/net/s2io.c | 56 | ||||
-rw-r--r-- | drivers/net/s2io.h | 12 |
2 files changed, 46 insertions, 22 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 2ee2a2b4b272..d167bc0ae951 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -130,6 +130,11 @@ static inline int rx_buffer_level(struct s2io_nic * sp, int rxb_size, int ring) | |||
130 | return 0; | 130 | return 0; |
131 | } | 131 | } |
132 | 132 | ||
133 | static inline int is_s2io_card_up(const struct s2io_nic * sp) | ||
134 | { | ||
135 | return test_bit(__S2IO_STATE_CARD_UP, &sp->state); | ||
136 | } | ||
137 | |||
133 | /* Ethtool related variables and Macros. */ | 138 | /* Ethtool related variables and Macros. */ |
134 | static char s2io_gstrings[][ETH_GSTRING_LEN] = { | 139 | static char s2io_gstrings[][ETH_GSTRING_LEN] = { |
135 | "Register test\t(offline)", | 140 | "Register test\t(offline)", |
@@ -2711,6 +2716,12 @@ static int s2io_poll(struct napi_struct *napi, int budget) | |||
2711 | int i; | 2716 | int i; |
2712 | 2717 | ||
2713 | atomic_inc(&nic->isr_cnt); | 2718 | atomic_inc(&nic->isr_cnt); |
2719 | |||
2720 | if (!is_s2io_card_up(nic)) { | ||
2721 | atomic_dec(&nic->isr_cnt); | ||
2722 | return 0; | ||
2723 | } | ||
2724 | |||
2714 | mac_control = &nic->mac_control; | 2725 | mac_control = &nic->mac_control; |
2715 | config = &nic->config; | 2726 | config = &nic->config; |
2716 | 2727 | ||
@@ -2837,12 +2848,6 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
2837 | struct RxD3* rxdp3; | 2848 | struct RxD3* rxdp3; |
2838 | 2849 | ||
2839 | spin_lock(&nic->rx_lock); | 2850 | spin_lock(&nic->rx_lock); |
2840 | if (atomic_read(&nic->card_state) == CARD_DOWN) { | ||
2841 | DBG_PRINT(INTR_DBG, "%s: %s going down for reset\n", | ||
2842 | __FUNCTION__, dev->name); | ||
2843 | spin_unlock(&nic->rx_lock); | ||
2844 | return; | ||
2845 | } | ||
2846 | 2851 | ||
2847 | get_info = ring_data->rx_curr_get_info; | 2852 | get_info = ring_data->rx_curr_get_info; |
2848 | get_block = get_info.block_index; | 2853 | get_block = get_info.block_index; |
@@ -3990,7 +3995,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3990 | } | 3995 | } |
3991 | 3996 | ||
3992 | spin_lock_irqsave(&sp->tx_lock, flags); | 3997 | spin_lock_irqsave(&sp->tx_lock, flags); |
3993 | if (atomic_read(&sp->card_state) == CARD_DOWN) { | 3998 | if (!is_s2io_card_up(sp)) { |
3994 | DBG_PRINT(TX_DBG, "%s: Card going down for reset\n", | 3999 | DBG_PRINT(TX_DBG, "%s: Card going down for reset\n", |
3995 | dev->name); | 4000 | dev->name); |
3996 | spin_unlock_irqrestore(&sp->tx_lock, flags); | 4001 | spin_unlock_irqrestore(&sp->tx_lock, flags); |
@@ -4184,6 +4189,11 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) | |||
4184 | 4189 | ||
4185 | atomic_inc(&sp->isr_cnt); | 4190 | atomic_inc(&sp->isr_cnt); |
4186 | 4191 | ||
4192 | if (!is_s2io_card_up(sp)) { | ||
4193 | atomic_dec(&sp->isr_cnt); | ||
4194 | return IRQ_HANDLED; | ||
4195 | } | ||
4196 | |||
4187 | rx_intr_handler(ring); | 4197 | rx_intr_handler(ring); |
4188 | s2io_chk_rx_buffers(sp, ring->ring_no); | 4198 | s2io_chk_rx_buffers(sp, ring->ring_no); |
4189 | 4199 | ||
@@ -4197,6 +4207,12 @@ static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) | |||
4197 | struct s2io_nic *sp = fifo->nic; | 4207 | struct s2io_nic *sp = fifo->nic; |
4198 | 4208 | ||
4199 | atomic_inc(&sp->isr_cnt); | 4209 | atomic_inc(&sp->isr_cnt); |
4210 | |||
4211 | if (!is_s2io_card_up(sp)) { | ||
4212 | atomic_dec(&sp->isr_cnt); | ||
4213 | return IRQ_HANDLED; | ||
4214 | } | ||
4215 | |||
4200 | tx_intr_handler(fifo); | 4216 | tx_intr_handler(fifo); |
4201 | atomic_dec(&sp->isr_cnt); | 4217 | atomic_dec(&sp->isr_cnt); |
4202 | return IRQ_HANDLED; | 4218 | return IRQ_HANDLED; |
@@ -4305,7 +4321,7 @@ static void s2io_handle_errors(void * dev_id) | |||
4305 | struct swStat *sw_stat = &sp->mac_control.stats_info->sw_stat; | 4321 | struct swStat *sw_stat = &sp->mac_control.stats_info->sw_stat; |
4306 | struct xpakStat *stats = &sp->mac_control.stats_info->xpak_stat; | 4322 | struct xpakStat *stats = &sp->mac_control.stats_info->xpak_stat; |
4307 | 4323 | ||
4308 | if (unlikely(atomic_read(&sp->card_state) == CARD_DOWN)) | 4324 | if (!is_s2io_card_up(sp)) |
4309 | return; | 4325 | return; |
4310 | 4326 | ||
4311 | if (pci_channel_offline(sp->pdev)) | 4327 | if (pci_channel_offline(sp->pdev)) |
@@ -4576,6 +4592,12 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) | |||
4576 | return IRQ_NONE; | 4592 | return IRQ_NONE; |
4577 | 4593 | ||
4578 | atomic_inc(&sp->isr_cnt); | 4594 | atomic_inc(&sp->isr_cnt); |
4595 | |||
4596 | if (!is_s2io_card_up(sp)) { | ||
4597 | atomic_dec(&sp->isr_cnt); | ||
4598 | return IRQ_NONE; | ||
4599 | } | ||
4600 | |||
4579 | mac_control = &sp->mac_control; | 4601 | mac_control = &sp->mac_control; |
4580 | config = &sp->config; | 4602 | config = &sp->config; |
4581 | 4603 | ||
@@ -4664,7 +4686,7 @@ static void s2io_updt_stats(struct s2io_nic *sp) | |||
4664 | u64 val64; | 4686 | u64 val64; |
4665 | int cnt = 0; | 4687 | int cnt = 0; |
4666 | 4688 | ||
4667 | if (atomic_read(&sp->card_state) == CARD_UP) { | 4689 | if (is_s2io_card_up(sp)) { |
4668 | /* Apprx 30us on a 133 MHz bus */ | 4690 | /* Apprx 30us on a 133 MHz bus */ |
4669 | val64 = SET_UPDT_CLICKS(10) | | 4691 | val64 = SET_UPDT_CLICKS(10) | |
4670 | STAT_CFG_ONE_SHOT_EN | STAT_CFG_STAT_EN; | 4692 | STAT_CFG_ONE_SHOT_EN | STAT_CFG_STAT_EN; |
@@ -6460,7 +6482,7 @@ static void s2io_set_link(struct work_struct *work) | |||
6460 | if (!netif_running(dev)) | 6482 | if (!netif_running(dev)) |
6461 | goto out_unlock; | 6483 | goto out_unlock; |
6462 | 6484 | ||
6463 | if (test_and_set_bit(0, &(nic->link_state))) { | 6485 | if (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(nic->state))) { |
6464 | /* The card is being reset, no point doing anything */ | 6486 | /* The card is being reset, no point doing anything */ |
6465 | goto out_unlock; | 6487 | goto out_unlock; |
6466 | } | 6488 | } |
@@ -6516,7 +6538,7 @@ static void s2io_set_link(struct work_struct *work) | |||
6516 | writeq(val64, &bar0->adapter_control); | 6538 | writeq(val64, &bar0->adapter_control); |
6517 | s2io_link(nic, LINK_DOWN); | 6539 | s2io_link(nic, LINK_DOWN); |
6518 | } | 6540 | } |
6519 | clear_bit(0, &(nic->link_state)); | 6541 | clear_bit(__S2IO_STATE_LINK_TASK, &(nic->state)); |
6520 | 6542 | ||
6521 | out_unlock: | 6543 | out_unlock: |
6522 | rtnl_unlock(); | 6544 | rtnl_unlock(); |
@@ -6825,10 +6847,10 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) | |||
6825 | 6847 | ||
6826 | del_timer_sync(&sp->alarm_timer); | 6848 | del_timer_sync(&sp->alarm_timer); |
6827 | /* If s2io_set_link task is executing, wait till it completes. */ | 6849 | /* If s2io_set_link task is executing, wait till it completes. */ |
6828 | while (test_and_set_bit(0, &(sp->link_state))) { | 6850 | while (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(sp->state))) { |
6829 | msleep(50); | 6851 | msleep(50); |
6830 | } | 6852 | } |
6831 | atomic_set(&sp->card_state, CARD_DOWN); | 6853 | clear_bit(__S2IO_STATE_CARD_UP, &sp->state); |
6832 | 6854 | ||
6833 | /* disable Tx and Rx traffic on the NIC */ | 6855 | /* disable Tx and Rx traffic on the NIC */ |
6834 | if (do_io) | 6856 | if (do_io) |
@@ -6879,7 +6901,7 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) | |||
6879 | free_rx_buffers(sp); | 6901 | free_rx_buffers(sp); |
6880 | spin_unlock_irqrestore(&sp->rx_lock, flags); | 6902 | spin_unlock_irqrestore(&sp->rx_lock, flags); |
6881 | 6903 | ||
6882 | clear_bit(0, &(sp->link_state)); | 6904 | clear_bit(__S2IO_STATE_LINK_TASK, &(sp->state)); |
6883 | } | 6905 | } |
6884 | 6906 | ||
6885 | static void s2io_card_down(struct s2io_nic * sp) | 6907 | static void s2io_card_down(struct s2io_nic * sp) |
@@ -6972,8 +6994,7 @@ static int s2io_card_up(struct s2io_nic * sp) | |||
6972 | en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS); | 6994 | en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS); |
6973 | } | 6995 | } |
6974 | 6996 | ||
6975 | 6997 | set_bit(__S2IO_STATE_CARD_UP, &sp->state); | |
6976 | atomic_set(&sp->card_state, CARD_UP); | ||
6977 | return 0; | 6998 | return 0; |
6978 | } | 6999 | } |
6979 | 7000 | ||
@@ -7701,9 +7722,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7701 | * Initialize the tasklet status and link state flags | 7722 | * Initialize the tasklet status and link state flags |
7702 | * and the card state parameter | 7723 | * and the card state parameter |
7703 | */ | 7724 | */ |
7704 | atomic_set(&(sp->card_state), 0); | ||
7705 | sp->tasklet_status = 0; | 7725 | sp->tasklet_status = 0; |
7706 | sp->link_state = 0; | 7726 | sp->state = 0; |
7707 | 7727 | ||
7708 | /* Initialize spinlocks */ | 7728 | /* Initialize spinlocks */ |
7709 | spin_lock_init(&sp->tx_lock); | 7729 | spin_lock_init(&sp->tx_lock); |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index c01abc1d89af..33e812ea7d18 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -802,6 +802,13 @@ struct lro { | |||
802 | u8 saw_ts; | 802 | u8 saw_ts; |
803 | }; | 803 | }; |
804 | 804 | ||
805 | /* These flags represent the devices temporary state */ | ||
806 | enum s2io_device_state_t | ||
807 | { | ||
808 | __S2IO_STATE_LINK_TASK=0, | ||
809 | __S2IO_STATE_CARD_UP | ||
810 | }; | ||
811 | |||
805 | /* Structure representing one instance of the NIC */ | 812 | /* Structure representing one instance of the NIC */ |
806 | struct s2io_nic { | 813 | struct s2io_nic { |
807 | int rxd_mode; | 814 | int rxd_mode; |
@@ -880,10 +887,6 @@ struct s2io_nic { | |||
880 | 887 | ||
881 | int task_flag; | 888 | int task_flag; |
882 | unsigned long long start_time; | 889 | unsigned long long start_time; |
883 | #define CARD_DOWN 1 | ||
884 | #define CARD_UP 2 | ||
885 | atomic_t card_state; | ||
886 | volatile unsigned long link_state; | ||
887 | struct vlan_group *vlgrp; | 890 | struct vlan_group *vlgrp; |
888 | #define MSIX_FLG 0xA5 | 891 | #define MSIX_FLG 0xA5 |
889 | struct msix_entry *entries; | 892 | struct msix_entry *entries; |
@@ -906,6 +909,7 @@ struct s2io_nic { | |||
906 | unsigned long sending_both; | 909 | unsigned long sending_both; |
907 | u8 lro; | 910 | u8 lro; |
908 | u16 lro_max_aggr_per_sess; | 911 | u16 lro_max_aggr_per_sess; |
912 | volatile unsigned long state; | ||
909 | spinlock_t rx_lock; | 913 | spinlock_t rx_lock; |
910 | atomic_t isr_cnt; | 914 | atomic_t isr_cnt; |
911 | u64 general_int_mask; | 915 | u64 general_int_mask; |