aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Mason <jon.mason@exar.com>2010-11-10 23:25:54 -0500
committerDavid S. Miller <davem@davemloft.net>2010-11-11 12:30:19 -0500
commit4d2a5b406c02b224bd3f50992c8b02450c65a730 (patch)
tree624d968e9ae73e1ff14dcfbc4a26e0fbbe069124
parent47f01db44b2470d9517848f6b73c75883ef5fda0 (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>
-rw-r--r--drivers/net/vxge/vxge-config.c86
-rw-r--r--drivers/net/vxge/vxge-config.h7
-rw-r--r--drivers/net/vxge/vxge-main.c19
-rw-r--r--drivers/net/vxge/vxge-main.h2
-rw-r--r--drivers/net/vxge/vxge-reg.h1
5 files changed, 106 insertions, 9 deletions
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c
index 0a35ab1ee2e1..212e301bdd68 100644
--- a/drivers/net/vxge/vxge-config.c
+++ b/drivers/net/vxge/vxge-config.c
@@ -193,6 +193,88 @@ static enum vxge_hw_status
193__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath, 193__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath,
194 struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats); 194 struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats);
195 195
196static void
197vxge_hw_vpath_set_zero_rx_frm_len(struct vxge_hw_vpath_reg __iomem *vp_reg)
198{
199 u64 val64;
200
201 val64 = readq(&vp_reg->rxmac_vcfg0);
202 val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
203 writeq(val64, &vp_reg->rxmac_vcfg0);
204 val64 = readq(&vp_reg->rxmac_vcfg0);
205
206 return;
207}
208
209/*
210 * vxge_hw_vpath_wait_receive_idle - Wait for Rx to become idle
211 */
212int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id)
213{
214 struct vxge_hw_vpath_reg __iomem *vp_reg;
215 struct __vxge_hw_virtualpath *vpath;
216 u64 val64, rxd_count, rxd_spat;
217 int count = 0, total_count = 0;
218
219 vpath = &hldev->virtual_paths[vp_id];
220 vp_reg = vpath->vp_reg;
221
222 vxge_hw_vpath_set_zero_rx_frm_len(vp_reg);
223
224 /* Check that the ring controller for this vpath has enough free RxDs
225 * to send frames to the host. This is done by reading the
226 * PRC_RXD_DOORBELL_VPn register and comparing the read value to the
227 * RXD_SPAT value for the vpath.
228 */
229 val64 = readq(&vp_reg->prc_cfg6);
230 rxd_spat = VXGE_HW_PRC_CFG6_GET_RXD_SPAT(val64) + 1;
231 /* Use a factor of 2 when comparing rxd_count against rxd_spat for some
232 * leg room.
233 */
234 rxd_spat *= 2;
235
236 do {
237 mdelay(1);
238
239 rxd_count = readq(&vp_reg->prc_rxd_doorbell);
240
241 /* Check that the ring controller for this vpath does
242 * not have any frame in its pipeline.
243 */
244 val64 = readq(&vp_reg->frm_in_progress_cnt);
245 if ((rxd_count <= rxd_spat) || (val64 > 0))
246 count = 0;
247 else
248 count++;
249 total_count++;
250 } while ((count < VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT) &&
251 (total_count < VXGE_HW_MAX_POLLING_COUNT));
252
253 if (total_count >= VXGE_HW_MAX_POLLING_COUNT)
254 printk(KERN_ALERT "%s: Still Receiving traffic. Abort wait\n",
255 __func__);
256
257 return total_count;
258}
259
260/* vxge_hw_device_wait_receive_idle - This function waits until all frames
261 * stored in the frame buffer for each vpath assigned to the given
262 * function (hldev) have been sent to the host.
263 */
264void vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev)
265{
266 int i, total_count = 0;
267
268 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
269 if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
270 continue;
271
272 total_count += vxge_hw_vpath_wait_receive_idle(hldev, i);
273 if (total_count >= VXGE_HW_MAX_POLLING_COUNT)
274 break;
275 }
276}
277
196/* 278/*
197 * __vxge_hw_channel_allocate - Allocate memory for channel 279 * __vxge_hw_channel_allocate - Allocate memory for channel
198 * This function allocates required memory for the channel and various arrays 280 * This function allocates required memory for the channel and various arrays
@@ -390,7 +472,7 @@ __vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis)
390 return ret; 472 return ret;
391} 473}
392 474
393 /* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset 475/* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset
394 * in progress 476 * in progress
395 * This routine checks the vpath reset in progress register is turned zero 477 * This routine checks the vpath reset in progress register is turned zero
396 */ 478 */
@@ -1165,7 +1247,6 @@ exit:
1165 * It can be used to set or reset Pause frame generation or reception 1247 * It can be used to set or reset Pause frame generation or reception
1166 * support of the NIC. 1248 * support of the NIC.
1167 */ 1249 */
1168
1169enum vxge_hw_status vxge_hw_device_setpause_data(struct __vxge_hw_device *hldev, 1250enum vxge_hw_status vxge_hw_device_setpause_data(struct __vxge_hw_device *hldev,
1170 u32 port, u32 tx, u32 rx) 1251 u32 port, u32 tx, u32 rx)
1171{ 1252{
@@ -1409,7 +1490,6 @@ exit:
1409/* 1490/*
1410 * __vxge_hw_ring_create - Create a Ring 1491 * __vxge_hw_ring_create - Create a Ring
1411 * This function creates Ring and initializes it. 1492 * This function creates Ring and initializes it.
1412 *
1413 */ 1493 */
1414static enum vxge_hw_status 1494static enum vxge_hw_status
1415__vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp, 1495__vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp,
diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h
index 5d7790558f44..95e7021f88d8 100644
--- a/drivers/net/vxge/vxge-config.h
+++ b/drivers/net/vxge/vxge-config.h
@@ -2051,4 +2051,11 @@ enum vxge_hw_status vxge_hw_vpath_rts_rth_set(
2051 2051
2052enum vxge_hw_status 2052enum vxge_hw_status
2053__vxge_hw_device_is_privilaged(u32 host_type, u32 func_id); 2053__vxge_hw_device_is_privilaged(u32 host_type, u32 func_id);
2054
2055#define VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT 5
2056#define VXGE_HW_MAX_POLLING_COUNT 100
2057
2058int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id);
2059
2060void vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev);
2054#endif 2061#endif
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);
90static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac); 90static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac);
91static enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath); 91static enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath);
92static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath); 92static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath);
93static enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev);
94 93
95static inline int is_vxge_card_up(struct vxgedev *vdev) 94static 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)
1299static void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id) 1298static 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 */
1938static enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev) 1943enum 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);
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
index a4f6d864fc8e..54989d07af34 100644
--- a/drivers/net/vxge/vxge-main.h
+++ b/drivers/net/vxge/vxge-main.h
@@ -397,6 +397,8 @@ struct vxge_tx_priv {
397 } while (0); 397 } while (0);
398 398
399extern void vxge_initialize_ethtool_ops(struct net_device *ndev); 399extern void vxge_initialize_ethtool_ops(struct net_device *ndev);
400enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev);
401
400/** 402/**
401 * #define VXGE_DEBUG_INIT: debug for initialization functions 403 * #define VXGE_DEBUG_INIT: debug for initialization functions
402 * #define VXGE_DEBUG_TX : debug transmit related functions 404 * #define VXGE_DEBUG_TX : debug transmit related functions
diff --git a/drivers/net/vxge/vxge-reg.h b/drivers/net/vxge/vxge-reg.h
index 3dd5c9615ef9..93fd752187bc 100644
--- a/drivers/net/vxge/vxge-reg.h
+++ b/drivers/net/vxge/vxge-reg.h
@@ -3998,6 +3998,7 @@ struct vxge_hw_vpath_reg {
3998#define VXGE_HW_PRC_CFG6_L4_CPC_TRSFR_CODE_EN vxge_mBIT(9) 3998#define VXGE_HW_PRC_CFG6_L4_CPC_TRSFR_CODE_EN vxge_mBIT(9)
3999#define VXGE_HW_PRC_CFG6_RXD_CRXDT(val) vxge_vBIT(val, 23, 9) 3999#define VXGE_HW_PRC_CFG6_RXD_CRXDT(val) vxge_vBIT(val, 23, 9)
4000#define VXGE_HW_PRC_CFG6_RXD_SPAT(val) vxge_vBIT(val, 36, 9) 4000#define VXGE_HW_PRC_CFG6_RXD_SPAT(val) vxge_vBIT(val, 36, 9)
4001#define VXGE_HW_PRC_CFG6_GET_RXD_SPAT(val) vxge_bVALn(val, 36, 9)
4001/*0x00a78*/ u64 prc_cfg7; 4002/*0x00a78*/ u64 prc_cfg7;
4002#define VXGE_HW_PRC_CFG7_SCATTER_MODE(val) vxge_vBIT(val, 6, 2) 4003#define VXGE_HW_PRC_CFG7_SCATTER_MODE(val) vxge_vBIT(val, 6, 2)
4003#define VXGE_HW_PRC_CFG7_SMART_SCAT_EN vxge_mBIT(11) 4004#define VXGE_HW_PRC_CFG7_SMART_SCAT_EN vxge_mBIT(11)