aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ixgbevf
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2012-08-01 21:16:59 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-09-24 03:21:51 -0400
commit4b2cd27f834e526f933aa63ce91964b7581271f4 (patch)
treee1bcbe1e3b19396049ba82462c547a1da356c53d /drivers/net/ethernet/intel/ixgbevf
parentc9d2ea96ca3bbc85264803ff6bd66eb3bbefdb77 (diff)
ixgbevf: Fix code for handling timeout
The VF driver was not designed to correctly handle a message timeout. As a result it is possible for one bad message to invalidate all messages following it until the part is reset. Instead we should copy the example in igbvf of how to handle a mailbox event and message timeout. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbevf')
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c46
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/mbx.c15
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/vf.c49
3 files changed, 58 insertions, 52 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index c5ffe1dd3fcd..7aa31eebc356 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -716,40 +716,15 @@ static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector)
716 } 716 }
717} 717}
718 718
719static irqreturn_t ixgbevf_msix_mbx(int irq, void *data) 719static irqreturn_t ixgbevf_msix_other(int irq, void *data)
720{ 720{
721 struct ixgbevf_adapter *adapter = data; 721 struct ixgbevf_adapter *adapter = data;
722 struct ixgbe_hw *hw = &adapter->hw; 722 struct ixgbe_hw *hw = &adapter->hw;
723 u32 msg;
724 bool got_ack = false;
725 723
726 if (!hw->mbx.ops.check_for_ack(hw)) 724 hw->mac.get_link_status = 1;
727 got_ack = true;
728 725
729 if (!hw->mbx.ops.check_for_msg(hw)) { 726 if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
730 hw->mbx.ops.read(hw, &msg, 1); 727 mod_timer(&adapter->watchdog_timer, jiffies);
731
732 if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG)
733 mod_timer(&adapter->watchdog_timer,
734 round_jiffies(jiffies + 1));
735
736 if (msg & IXGBE_VT_MSGTYPE_NACK)
737 pr_warn("Last Request of type %2.2x to PF Nacked\n",
738 msg & 0xFF);
739 /*
740 * Restore the PFSTS bit in case someone is polling for a
741 * return message from the PF
742 */
743 hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFSTS;
744 }
745
746 /*
747 * checking for the ack clears the PFACK bit. Place
748 * it back in the v2p_mailbox cache so that anyone
749 * polling for an ack will not miss it
750 */
751 if (got_ack)
752 hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
753 728
754 IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, adapter->eims_other); 729 IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, adapter->eims_other);
755 730
@@ -899,10 +874,10 @@ static int ixgbevf_request_msix_irqs(struct ixgbevf_adapter *adapter)
899 } 874 }
900 875
901 err = request_irq(adapter->msix_entries[vector].vector, 876 err = request_irq(adapter->msix_entries[vector].vector,
902 &ixgbevf_msix_mbx, 0, netdev->name, adapter); 877 &ixgbevf_msix_other, 0, netdev->name, adapter);
903 if (err) { 878 if (err) {
904 hw_dbg(&adapter->hw, 879 hw_dbg(&adapter->hw,
905 "request_irq for msix_mbx failed: %d\n", err); 880 "request_irq for msix_other failed: %d\n", err);
906 goto free_queue_irqs; 881 goto free_queue_irqs;
907 } 882 }
908 883
@@ -1411,6 +1386,7 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
1411 ixgbevf_save_reset_stats(adapter); 1386 ixgbevf_save_reset_stats(adapter);
1412 ixgbevf_init_last_counter_stats(adapter); 1387 ixgbevf_init_last_counter_stats(adapter);
1413 1388
1389 hw->mac.get_link_status = 1;
1414 mod_timer(&adapter->watchdog_timer, jiffies); 1390 mod_timer(&adapter->watchdog_timer, jiffies);
1415} 1391}
1416 1392
@@ -1589,8 +1565,6 @@ void ixgbevf_down(struct ixgbevf_adapter *adapter)
1589 1565
1590void ixgbevf_reinit_locked(struct ixgbevf_adapter *adapter) 1566void ixgbevf_reinit_locked(struct ixgbevf_adapter *adapter)
1591{ 1567{
1592 struct ixgbe_hw *hw = &adapter->hw;
1593
1594 WARN_ON(in_interrupt()); 1568 WARN_ON(in_interrupt());
1595 1569
1596 while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state)) 1570 while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state))
@@ -1603,10 +1577,8 @@ void ixgbevf_reinit_locked(struct ixgbevf_adapter *adapter)
1603 * watchdog task will continue to schedule reset tasks until 1577 * watchdog task will continue to schedule reset tasks until
1604 * the PF is up and running. 1578 * the PF is up and running.
1605 */ 1579 */
1606 if (!hw->mac.ops.reset_hw(hw)) { 1580 ixgbevf_down(adapter);
1607 ixgbevf_down(adapter); 1581 ixgbevf_up(adapter);
1608 ixgbevf_up(adapter);
1609 }
1610 1582
1611 clear_bit(__IXGBEVF_RESETTING, &adapter->state); 1583 clear_bit(__IXGBEVF_RESETTING, &adapter->state);
1612} 1584}
diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.c b/drivers/net/ethernet/intel/ixgbevf/mbx.c
index 9c955900fe64..d5028ddf4b31 100644
--- a/drivers/net/ethernet/intel/ixgbevf/mbx.c
+++ b/drivers/net/ethernet/intel/ixgbevf/mbx.c
@@ -86,14 +86,17 @@ static s32 ixgbevf_poll_for_ack(struct ixgbe_hw *hw)
86static s32 ixgbevf_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size) 86static s32 ixgbevf_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
87{ 87{
88 struct ixgbe_mbx_info *mbx = &hw->mbx; 88 struct ixgbe_mbx_info *mbx = &hw->mbx;
89 s32 ret_val = IXGBE_ERR_MBX; 89 s32 ret_val = -IXGBE_ERR_MBX;
90
91 if (!mbx->ops.read)
92 goto out;
90 93
91 ret_val = ixgbevf_poll_for_msg(hw); 94 ret_val = ixgbevf_poll_for_msg(hw);
92 95
93 /* if ack received read message, otherwise we timed out */ 96 /* if ack received read message, otherwise we timed out */
94 if (!ret_val) 97 if (!ret_val)
95 ret_val = mbx->ops.read(hw, msg, size); 98 ret_val = mbx->ops.read(hw, msg, size);
96 99out:
97 return ret_val; 100 return ret_val;
98} 101}
99 102
@@ -109,7 +112,11 @@ static s32 ixgbevf_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
109static s32 ixgbevf_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size) 112static s32 ixgbevf_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
110{ 113{
111 struct ixgbe_mbx_info *mbx = &hw->mbx; 114 struct ixgbe_mbx_info *mbx = &hw->mbx;
112 s32 ret_val; 115 s32 ret_val = -IXGBE_ERR_MBX;
116
117 /* exit if either we can't write or there isn't a defined timeout */
118 if (!mbx->ops.write || !mbx->timeout)
119 goto out;
113 120
114 /* send msg */ 121 /* send msg */
115 ret_val = mbx->ops.write(hw, msg, size); 122 ret_val = mbx->ops.write(hw, msg, size);
@@ -117,7 +124,7 @@ static s32 ixgbevf_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
117 /* if msg sent wait until we receive an ack */ 124 /* if msg sent wait until we receive an ack */
118 if (!ret_val) 125 if (!ret_val)
119 ret_val = ixgbevf_poll_for_ack(hw); 126 ret_val = ixgbevf_poll_for_ack(hw);
120 127out:
121 return ret_val; 128 return ret_val;
122} 129}
123 130
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c
index 87b3f3bf1c1f..a5e66c79f632 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.c
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.c
@@ -392,20 +392,23 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
392 bool *link_up, 392 bool *link_up,
393 bool autoneg_wait_to_complete) 393 bool autoneg_wait_to_complete)
394{ 394{
395 struct ixgbe_mbx_info *mbx = &hw->mbx;
396 struct ixgbe_mac_info *mac = &hw->mac;
397 s32 ret_val = 0;
395 u32 links_reg; 398 u32 links_reg;
399 u32 in_msg = 0;
396 400
397 if (!(hw->mbx.ops.check_for_rst(hw))) { 401 /* If we were hit with a reset drop the link */
398 *link_up = false; 402 if (!mbx->ops.check_for_rst(hw) || !mbx->timeout)
399 *speed = 0; 403 mac->get_link_status = true;
400 return -1;
401 }
402 404
403 links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS); 405 if (!mac->get_link_status)
406 goto out;
404 407
405 if (links_reg & IXGBE_LINKS_UP) 408 /* if link status is down no point in checking to see if pf is up */
406 *link_up = true; 409 links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
407 else 410 if (!(links_reg & IXGBE_LINKS_UP))
408 *link_up = false; 411 goto out;
409 412
410 switch (links_reg & IXGBE_LINKS_SPEED_82599) { 413 switch (links_reg & IXGBE_LINKS_SPEED_82599) {
411 case IXGBE_LINKS_SPEED_10G_82599: 414 case IXGBE_LINKS_SPEED_10G_82599:
@@ -419,7 +422,31 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
419 break; 422 break;
420 } 423 }
421 424
422 return 0; 425 /* if the read failed it could just be a mailbox collision, best wait
426 * until we are called again and don't report an error */
427 if (mbx->ops.read(hw, &in_msg, 1))
428 goto out;
429
430 if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) {
431 /* msg is not CTS and is NACK we must have lost CTS status */
432 if (in_msg & IXGBE_VT_MSGTYPE_NACK)
433 ret_val = -1;
434 goto out;
435 }
436
437 /* the pf is talking, if we timed out in the past we reinit */
438 if (!mbx->timeout) {
439 ret_val = -1;
440 goto out;
441 }
442
443 /* if we passed all the tests above then the link is up and we no
444 * longer need to check for link */
445 mac->get_link_status = false;
446
447out:
448 *link_up = !mac->get_link_status;
449 return ret_val;
423} 450}
424 451
425/** 452/**