mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-13 01:08:50 +00:00
ixgbe: 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: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b12babd4d0
commit
b0483c8f36
@ -1342,6 +1342,10 @@ static bool reg_pattern_test(struct ixgbe_adapter *adapter, u64 *data, int reg,
|
||||
static const u32 test_pattern[] = {
|
||||
0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
|
||||
|
||||
if (ixgbe_removed(adapter->hw.hw_addr)) {
|
||||
*data = 1;
|
||||
return 1;
|
||||
}
|
||||
for (pat = 0; pat < ARRAY_SIZE(test_pattern); pat++) {
|
||||
before = ixgbe_read_reg(&adapter->hw, reg);
|
||||
ixgbe_write_reg(&adapter->hw, reg, test_pattern[pat] & write);
|
||||
@ -1364,6 +1368,10 @@ static bool reg_set_and_check(struct ixgbe_adapter *adapter, u64 *data, int reg,
|
||||
{
|
||||
u32 val, before;
|
||||
|
||||
if (ixgbe_removed(adapter->hw.hw_addr)) {
|
||||
*data = 1;
|
||||
return 1;
|
||||
}
|
||||
before = ixgbe_read_reg(&adapter->hw, reg);
|
||||
ixgbe_write_reg(&adapter->hw, reg, write & mask);
|
||||
val = ixgbe_read_reg(&adapter->hw, reg);
|
||||
@ -1384,6 +1392,11 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
|
||||
u32 value, before, after;
|
||||
u32 i, toggle;
|
||||
|
||||
if (ixgbe_removed(adapter->hw.hw_addr)) {
|
||||
e_err(drv, "Adapter removed - register test blocked\n");
|
||||
*data = 1;
|
||||
return 1;
|
||||
}
|
||||
switch (adapter->hw.mac.type) {
|
||||
case ixgbe_mac_82598EB:
|
||||
toggle = 0x7FFFF3FF;
|
||||
@ -1950,6 +1963,15 @@ static void ixgbe_diag_test(struct net_device *netdev,
|
||||
struct ixgbe_adapter *adapter = netdev_priv(netdev);
|
||||
bool if_running = netif_running(netdev);
|
||||
|
||||
if (ixgbe_removed(adapter->hw.hw_addr)) {
|
||||
e_err(hw, "Adapter removed - test blocked\n");
|
||||
data[0] = 1;
|
||||
data[1] = 1;
|
||||
data[2] = 1;
|
||||
data[3] = 1;
|
||||
eth_test->flags |= ETH_TEST_FL_FAILED;
|
||||
return;
|
||||
}
|
||||
set_bit(__IXGBE_TESTING, &adapter->state);
|
||||
if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
|
@ -291,6 +291,7 @@ static void ixgbe_remove_adapter(struct ixgbe_hw *hw)
|
||||
return;
|
||||
hw->hw_addr = NULL;
|
||||
e_dev_err("Adapter removed\n");
|
||||
ixgbe_service_event_schedule(adapter);
|
||||
}
|
||||
|
||||
void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
|
||||
@ -3338,6 +3339,8 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
|
||||
u32 rxdctl;
|
||||
u8 reg_idx = ring->reg_idx;
|
||||
|
||||
if (ixgbe_removed(hw->hw_addr))
|
||||
return;
|
||||
/* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */
|
||||
if (hw->mac.type == ixgbe_mac_82598EB &&
|
||||
!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
|
||||
@ -3362,6 +3365,8 @@ void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter,
|
||||
u32 rxdctl;
|
||||
u8 reg_idx = ring->reg_idx;
|
||||
|
||||
if (ixgbe_removed(hw->hw_addr))
|
||||
return;
|
||||
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
|
||||
rxdctl &= ~IXGBE_RXDCTL_ENABLE;
|
||||
|
||||
@ -4687,6 +4692,8 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
int err;
|
||||
|
||||
if (ixgbe_removed(hw->hw_addr))
|
||||
return;
|
||||
/* lock SFP init bit to prevent race conditions with the watchdog */
|
||||
while (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
|
||||
usleep_range(1000, 2000);
|
||||
@ -6397,6 +6404,15 @@ static void ixgbe_service_task(struct work_struct *work)
|
||||
struct ixgbe_adapter *adapter = container_of(work,
|
||||
struct ixgbe_adapter,
|
||||
service_task);
|
||||
if (ixgbe_removed(adapter->hw.hw_addr)) {
|
||||
if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
|
||||
rtnl_lock();
|
||||
ixgbe_down(adapter);
|
||||
rtnl_unlock();
|
||||
}
|
||||
ixgbe_service_event_complete(adapter);
|
||||
return;
|
||||
}
|
||||
ixgbe_reset_subtask(adapter);
|
||||
ixgbe_sfp_detection_subtask(adapter);
|
||||
ixgbe_sfp_link_config_subtask(adapter);
|
||||
|
Loading…
x
Reference in New Issue
Block a user