diff options
author | Jon Mason <jon.mason@exar.com> | 2010-11-10 23:25:54 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-11-11 12:30:19 -0500 |
commit | 4d2a5b406c02b224bd3f50992c8b02450c65a730 (patch) | |
tree | 624d968e9ae73e1ff14dcfbc4a26e0fbbe069124 /drivers/net/vxge/vxge-main.c | |
parent | 47f01db44b2470d9517848f6b73c75883ef5fda0 (diff) |
vxge: Wait for Rx to become idle before reseting or closing
Wait for the receive traffic to become idle before attempting to close
or reset the adapter. To enable the processing of packets while Receive
Idle, move the clearing of __VXGE_STATE_CARD_UP bit in vxge_close to
after it. Also, modify the return value of the ISR when the adapter is
down to IRQ_HANDLED. Otherwise there are unhandled interrupts for the
device.
Signed-off-by: Jon Mason <jon.mason@exar.com>
Signed-off-by: Ram Vepa <ram.vepa@exar.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/vxge/vxge-main.c')
-rw-r--r-- | drivers/net/vxge/vxge-main.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 2f26c377e5d9..53db6a4b9601 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c | |||
@@ -90,7 +90,6 @@ static int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac); | |||
90 | static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac); | 90 | static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac); |
91 | static enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath); | 91 | static enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath); |
92 | static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath); | 92 | static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath); |
93 | static enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev); | ||
94 | 93 | ||
95 | static inline int is_vxge_card_up(struct vxgedev *vdev) | 94 | static inline int is_vxge_card_up(struct vxgedev *vdev) |
96 | { | 95 | { |
@@ -1299,8 +1298,13 @@ static void vxge_vpath_intr_enable(struct vxgedev *vdev, int vp_id) | |||
1299 | static void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id) | 1298 | static void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id) |
1300 | { | 1299 | { |
1301 | struct vxge_vpath *vpath = &vdev->vpaths[vp_id]; | 1300 | struct vxge_vpath *vpath = &vdev->vpaths[vp_id]; |
1301 | struct __vxge_hw_device *hldev; | ||
1302 | int msix_id; | 1302 | int msix_id; |
1303 | 1303 | ||
1304 | hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); | ||
1305 | |||
1306 | vxge_hw_vpath_wait_receive_idle(hldev, vpath->device_id); | ||
1307 | |||
1304 | vxge_hw_vpath_intr_disable(vpath->handle); | 1308 | vxge_hw_vpath_intr_disable(vpath->handle); |
1305 | 1309 | ||
1306 | if (vdev->config.intr_type == INTA) | 1310 | if (vdev->config.intr_type == INTA) |
@@ -1430,6 +1434,7 @@ static int do_vxge_reset(struct vxgedev *vdev, int event) | |||
1430 | } | 1434 | } |
1431 | 1435 | ||
1432 | if (event == VXGE_LL_FULL_RESET) { | 1436 | if (event == VXGE_LL_FULL_RESET) { |
1437 | vxge_hw_device_wait_receive_idle(vdev->devh); | ||
1433 | vxge_hw_device_intr_disable(vdev->devh); | 1438 | vxge_hw_device_intr_disable(vdev->devh); |
1434 | 1439 | ||
1435 | switch (vdev->cric_err_event) { | 1440 | switch (vdev->cric_err_event) { |
@@ -1935,7 +1940,7 @@ static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath) | |||
1935 | } | 1940 | } |
1936 | 1941 | ||
1937 | /* reset vpaths */ | 1942 | /* reset vpaths */ |
1938 | static enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev) | 1943 | enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev) |
1939 | { | 1944 | { |
1940 | enum vxge_hw_status status = VXGE_HW_OK; | 1945 | enum vxge_hw_status status = VXGE_HW_OK; |
1941 | struct vxge_vpath *vpath; | 1946 | struct vxge_vpath *vpath; |
@@ -2080,7 +2085,7 @@ static irqreturn_t vxge_isr_napi(int irq, void *dev_id) | |||
2080 | return IRQ_NONE; | 2085 | return IRQ_NONE; |
2081 | 2086 | ||
2082 | if (unlikely(!is_vxge_card_up(vdev))) | 2087 | if (unlikely(!is_vxge_card_up(vdev))) |
2083 | return IRQ_NONE; | 2088 | return IRQ_HANDLED; |
2084 | 2089 | ||
2085 | status = vxge_hw_device_begin_irq(hldev, vdev->exec_mode, | 2090 | status = vxge_hw_device_begin_irq(hldev, vdev->exec_mode, |
2086 | &reason); | 2091 | &reason); |
@@ -2787,7 +2792,6 @@ static int do_vxge_close(struct net_device *dev, int do_io) | |||
2787 | while (test_and_set_bit(__VXGE_STATE_RESET_CARD, &vdev->state)) | 2792 | while (test_and_set_bit(__VXGE_STATE_RESET_CARD, &vdev->state)) |
2788 | msleep(50); | 2793 | msleep(50); |
2789 | 2794 | ||
2790 | clear_bit(__VXGE_STATE_CARD_UP, &vdev->state); | ||
2791 | if (do_io) { | 2795 | if (do_io) { |
2792 | /* Put the vpath back in normal mode */ | 2796 | /* Put the vpath back in normal mode */ |
2793 | vpath_vector = vxge_mBIT(vdev->vpaths[0].device_id); | 2797 | vpath_vector = vxge_mBIT(vdev->vpaths[0].device_id); |
@@ -2831,6 +2835,11 @@ static int do_vxge_close(struct net_device *dev, int do_io) | |||
2831 | 2835 | ||
2832 | del_timer_sync(&vdev->vp_reset_timer); | 2836 | del_timer_sync(&vdev->vp_reset_timer); |
2833 | 2837 | ||
2838 | if (do_io) | ||
2839 | vxge_hw_device_wait_receive_idle(hldev); | ||
2840 | |||
2841 | clear_bit(__VXGE_STATE_CARD_UP, &vdev->state); | ||
2842 | |||
2834 | /* Disable napi */ | 2843 | /* Disable napi */ |
2835 | if (vdev->config.intr_type != MSI_X) | 2844 | if (vdev->config.intr_type != MSI_X) |
2836 | napi_disable(&vdev->napi); | 2845 | napi_disable(&vdev->napi); |
@@ -2847,8 +2856,6 @@ static int do_vxge_close(struct net_device *dev, int do_io) | |||
2847 | if (do_io) | 2856 | if (do_io) |
2848 | vxge_hw_device_intr_disable(vdev->devh); | 2857 | vxge_hw_device_intr_disable(vdev->devh); |
2849 | 2858 | ||
2850 | mdelay(1000); | ||
2851 | |||
2852 | vxge_rem_isr(vdev); | 2859 | vxge_rem_isr(vdev); |
2853 | 2860 | ||
2854 | vxge_napi_del_all(vdev); | 2861 | vxge_napi_del_all(vdev); |