diff options
author | Mark Rustad <mark.d.rustad@intel.com> | 2014-03-03 22:02:45 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2014-03-21 05:38:35 -0400 |
commit | 26597802b47c5b92e3a1e6d5bd7cceef9e611431 (patch) | |
tree | e6f4be3a33cb317a87a817df0626a364621c6b92 /drivers/net | |
parent | 984b0ee3e3bd1c2d6c955f9121d60bbfd96c399d (diff) |
ixgbevf: Additional adapter removal checks
Additional checks are needed for a detected removal not to cause
problems. Some involve simply avoiding a lot of stuff that can't
do anything good, and also cases where the phony return value can
cause problems. In addition, down the adapter when the removal is
sensed.
Signed-off-by: Mark Rustad <mark.d.rustad@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')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ethtool.c | 22 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 13 |
2 files changed, 35 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c index c769a8d364b6..b2d002394e5d 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c +++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c | |||
@@ -535,6 +535,10 @@ static bool reg_pattern_test(struct ixgbevf_adapter *adapter, u64 *data, | |||
535 | { | 535 | { |
536 | u32 pat, val, before; | 536 | u32 pat, val, before; |
537 | 537 | ||
538 | if (IXGBE_REMOVED(adapter->hw.hw_addr)) { | ||
539 | *data = 1; | ||
540 | return true; | ||
541 | } | ||
538 | for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { | 542 | for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { |
539 | before = ixgbe_read_reg(&adapter->hw, reg); | 543 | before = ixgbe_read_reg(&adapter->hw, reg); |
540 | ixgbe_write_reg(&adapter->hw, reg, | 544 | ixgbe_write_reg(&adapter->hw, reg, |
@@ -559,6 +563,10 @@ static bool reg_set_and_check(struct ixgbevf_adapter *adapter, u64 *data, | |||
559 | { | 563 | { |
560 | u32 val, before; | 564 | u32 val, before; |
561 | 565 | ||
566 | if (IXGBE_REMOVED(adapter->hw.hw_addr)) { | ||
567 | *data = 1; | ||
568 | return true; | ||
569 | } | ||
562 | before = ixgbe_read_reg(&adapter->hw, reg); | 570 | before = ixgbe_read_reg(&adapter->hw, reg); |
563 | ixgbe_write_reg(&adapter->hw, reg, write & mask); | 571 | ixgbe_write_reg(&adapter->hw, reg, write & mask); |
564 | val = ixgbe_read_reg(&adapter->hw, reg); | 572 | val = ixgbe_read_reg(&adapter->hw, reg); |
@@ -578,6 +586,12 @@ static int ixgbevf_reg_test(struct ixgbevf_adapter *adapter, u64 *data) | |||
578 | const struct ixgbevf_reg_test *test; | 586 | const struct ixgbevf_reg_test *test; |
579 | u32 i; | 587 | u32 i; |
580 | 588 | ||
589 | if (IXGBE_REMOVED(adapter->hw.hw_addr)) { | ||
590 | dev_err(&adapter->pdev->dev, | ||
591 | "Adapter removed - register test blocked\n"); | ||
592 | *data = 1; | ||
593 | return 1; | ||
594 | } | ||
581 | test = reg_test_vf; | 595 | test = reg_test_vf; |
582 | 596 | ||
583 | /* | 597 | /* |
@@ -641,6 +655,14 @@ static void ixgbevf_diag_test(struct net_device *netdev, | |||
641 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | 655 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); |
642 | bool if_running = netif_running(netdev); | 656 | bool if_running = netif_running(netdev); |
643 | 657 | ||
658 | if (IXGBE_REMOVED(adapter->hw.hw_addr)) { | ||
659 | dev_err(&adapter->pdev->dev, | ||
660 | "Adapter removed - test blocked\n"); | ||
661 | data[0] = 1; | ||
662 | data[1] = 1; | ||
663 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
664 | return; | ||
665 | } | ||
644 | set_bit(__IXGBEVF_TESTING, &adapter->state); | 666 | set_bit(__IXGBEVF_TESTING, &adapter->state); |
645 | if (eth_test->flags == ETH_TEST_FL_OFFLINE) { | 667 | if (eth_test->flags == ETH_TEST_FL_OFFLINE) { |
646 | /* Offline tests */ | 668 | /* Offline tests */ |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 37c4ebe97bda..a50e892a5d21 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
@@ -107,6 +107,7 @@ static void ixgbevf_remove_adapter(struct ixgbe_hw *hw) | |||
107 | return; | 107 | return; |
108 | hw->hw_addr = NULL; | 108 | hw->hw_addr = NULL; |
109 | dev_err(&adapter->pdev->dev, "Adapter removed\n"); | 109 | dev_err(&adapter->pdev->dev, "Adapter removed\n"); |
110 | schedule_work(&adapter->watchdog_task); | ||
110 | } | 111 | } |
111 | 112 | ||
112 | static void ixgbevf_check_remove(struct ixgbe_hw *hw, u32 reg) | 113 | static void ixgbevf_check_remove(struct ixgbe_hw *hw, u32 reg) |
@@ -1301,6 +1302,8 @@ static void ixgbevf_disable_rx_queue(struct ixgbevf_adapter *adapter, | |||
1301 | u32 rxdctl; | 1302 | u32 rxdctl; |
1302 | u8 reg_idx = ring->reg_idx; | 1303 | u8 reg_idx = ring->reg_idx; |
1303 | 1304 | ||
1305 | if (IXGBE_REMOVED(hw->hw_addr)) | ||
1306 | return; | ||
1304 | rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(reg_idx)); | 1307 | rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(reg_idx)); |
1305 | rxdctl &= ~IXGBE_RXDCTL_ENABLE; | 1308 | rxdctl &= ~IXGBE_RXDCTL_ENABLE; |
1306 | 1309 | ||
@@ -1326,6 +1329,8 @@ static void ixgbevf_rx_desc_queue_enable(struct ixgbevf_adapter *adapter, | |||
1326 | u32 rxdctl; | 1329 | u32 rxdctl; |
1327 | u8 reg_idx = ring->reg_idx; | 1330 | u8 reg_idx = ring->reg_idx; |
1328 | 1331 | ||
1332 | if (IXGBE_REMOVED(hw->hw_addr)) | ||
1333 | return; | ||
1329 | do { | 1334 | do { |
1330 | usleep_range(1000, 2000); | 1335 | usleep_range(1000, 2000); |
1331 | rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(reg_idx)); | 1336 | rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(reg_idx)); |
@@ -2399,6 +2404,14 @@ static void ixgbevf_watchdog_task(struct work_struct *work) | |||
2399 | bool link_up = adapter->link_up; | 2404 | bool link_up = adapter->link_up; |
2400 | s32 need_reset; | 2405 | s32 need_reset; |
2401 | 2406 | ||
2407 | if (IXGBE_REMOVED(hw->hw_addr)) { | ||
2408 | if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) { | ||
2409 | rtnl_lock(); | ||
2410 | ixgbevf_down(adapter); | ||
2411 | rtnl_unlock(); | ||
2412 | } | ||
2413 | return; | ||
2414 | } | ||
2402 | ixgbevf_queue_reset_subtask(adapter); | 2415 | ixgbevf_queue_reset_subtask(adapter); |
2403 | 2416 | ||
2404 | adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK; | 2417 | adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK; |