Skip to content

Commit b0483c8

Browse files
mdrustaddavem330
authored andcommitted
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 <[email protected]> Tested-by: Phil Schmitt <[email protected]> Signed-off-by: Aaron Brown <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b12babd commit b0483c8

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,10 @@ static bool reg_pattern_test(struct ixgbe_adapter *adapter, u64 *data, int reg,
13421342
static const u32 test_pattern[] = {
13431343
0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
13441344

1345+
if (ixgbe_removed(adapter->hw.hw_addr)) {
1346+
*data = 1;
1347+
return 1;
1348+
}
13451349
for (pat = 0; pat < ARRAY_SIZE(test_pattern); pat++) {
13461350
before = ixgbe_read_reg(&adapter->hw, reg);
13471351
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,
13641368
{
13651369
u32 val, before;
13661370

1371+
if (ixgbe_removed(adapter->hw.hw_addr)) {
1372+
*data = 1;
1373+
return 1;
1374+
}
13671375
before = ixgbe_read_reg(&adapter->hw, reg);
13681376
ixgbe_write_reg(&adapter->hw, reg, write & mask);
13691377
val = ixgbe_read_reg(&adapter->hw, reg);
@@ -1384,6 +1392,11 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
13841392
u32 value, before, after;
13851393
u32 i, toggle;
13861394

1395+
if (ixgbe_removed(adapter->hw.hw_addr)) {
1396+
e_err(drv, "Adapter removed - register test blocked\n");
1397+
*data = 1;
1398+
return 1;
1399+
}
13871400
switch (adapter->hw.mac.type) {
13881401
case ixgbe_mac_82598EB:
13891402
toggle = 0x7FFFF3FF;
@@ -1950,6 +1963,15 @@ static void ixgbe_diag_test(struct net_device *netdev,
19501963
struct ixgbe_adapter *adapter = netdev_priv(netdev);
19511964
bool if_running = netif_running(netdev);
19521965

1966+
if (ixgbe_removed(adapter->hw.hw_addr)) {
1967+
e_err(hw, "Adapter removed - test blocked\n");
1968+
data[0] = 1;
1969+
data[1] = 1;
1970+
data[2] = 1;
1971+
data[3] = 1;
1972+
eth_test->flags |= ETH_TEST_FL_FAILED;
1973+
return;
1974+
}
19531975
set_bit(__IXGBE_TESTING, &adapter->state);
19541976
if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
19551977
struct ixgbe_hw *hw = &adapter->hw;

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ static void ixgbe_remove_adapter(struct ixgbe_hw *hw)
291291
return;
292292
hw->hw_addr = NULL;
293293
e_dev_err("Adapter removed\n");
294+
ixgbe_service_event_schedule(adapter);
294295
}
295296

296297
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,
33383339
u32 rxdctl;
33393340
u8 reg_idx = ring->reg_idx;
33403341

3342+
if (ixgbe_removed(hw->hw_addr))
3343+
return;
33413344
/* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */
33423345
if (hw->mac.type == ixgbe_mac_82598EB &&
33433346
!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
@@ -3362,6 +3365,8 @@ void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter,
33623365
u32 rxdctl;
33633366
u8 reg_idx = ring->reg_idx;
33643367

3368+
if (ixgbe_removed(hw->hw_addr))
3369+
return;
33653370
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
33663371
rxdctl &= ~IXGBE_RXDCTL_ENABLE;
33673372

@@ -4687,6 +4692,8 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
46874692
struct ixgbe_hw *hw = &adapter->hw;
46884693
int err;
46894694

4695+
if (ixgbe_removed(hw->hw_addr))
4696+
return;
46904697
/* lock SFP init bit to prevent race conditions with the watchdog */
46914698
while (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
46924699
usleep_range(1000, 2000);
@@ -6397,6 +6404,15 @@ static void ixgbe_service_task(struct work_struct *work)
63976404
struct ixgbe_adapter *adapter = container_of(work,
63986405
struct ixgbe_adapter,
63996406
service_task);
6407+
if (ixgbe_removed(adapter->hw.hw_addr)) {
6408+
if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
6409+
rtnl_lock();
6410+
ixgbe_down(adapter);
6411+
rtnl_unlock();
6412+
}
6413+
ixgbe_service_event_complete(adapter);
6414+
return;
6415+
}
64006416
ixgbe_reset_subtask(adapter);
64016417
ixgbe_sfp_detection_subtask(adapter);
64026418
ixgbe_sfp_link_config_subtask(adapter);

0 commit comments

Comments
 (0)