aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMark Rustad <mark.d.rustad@intel.com>2014-03-03 22:02:45 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-03-21 05:38:35 -0400
commit26597802b47c5b92e3a1e6d5bd7cceef9e611431 (patch)
treee6f4be3a33cb317a87a817df0626a364621c6b92 /drivers/net
parent984b0ee3e3bd1c2d6c955f9121d60bbfd96c399d (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.c22
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c13
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
112static void ixgbevf_check_remove(struct ixgbe_hw *hw, u32 reg) 113static 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;