diff options
Diffstat (limited to 'drivers/net/vxge')
-rw-r--r-- | drivers/net/vxge/vxge-config.c | 86 | ||||
-rw-r--r-- | drivers/net/vxge/vxge-config.h | 7 | ||||
-rw-r--r-- | drivers/net/vxge/vxge-main.c | 19 | ||||
-rw-r--r-- | drivers/net/vxge/vxge-main.h | 2 | ||||
-rw-r--r-- | drivers/net/vxge/vxge-reg.h | 1 |
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 | ||
196 | static void | ||
197 | vxge_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 | */ | ||
212 | int 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 | */ | ||
264 | void 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 | |||
1169 | enum vxge_hw_status vxge_hw_device_setpause_data(struct __vxge_hw_device *hldev, | 1250 | enum 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 | */ |
1414 | static enum vxge_hw_status | 1494 | static 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 | ||
2052 | enum vxge_hw_status | 2052 | enum 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 | |||
2058 | int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id); | ||
2059 | |||
2060 | void 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); | |||
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); |
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 | ||
399 | extern void vxge_initialize_ethtool_ops(struct net_device *ndev); | 399 | extern void vxge_initialize_ethtool_ops(struct net_device *ndev); |
400 | enum 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) |