From d7d543f252994387571462096ec646f5f335c4ee Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 28 Feb 2019 18:59:36 +0100 Subject: [PATCH 1/9] s390/qeth: remove RECOVER state The offline code uses a specific RECOVER state to indicate that the interface should be brought up when a qeth device is set online again. Rather than having a specific card-state for this, just put it in an internal flag bit and set the state to DOWN. When working with the card's state transitions, this reduces the complexity quite a bit. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 2 +- drivers/s390/net/qeth_core_main.c | 6 ++---- drivers/s390/net/qeth_core_sys.c | 14 ++++---------- drivers/s390/net/qeth_l2_main.c | 19 +++++++------------ drivers/s390/net/qeth_l3_main.c | 19 +++++++------------ drivers/s390/net/qeth_l3_sys.c | 12 ++++-------- 6 files changed, 25 insertions(+), 47 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index c0c46be0b2517..79de890010c70 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -553,7 +553,6 @@ enum qeth_card_states { CARD_STATE_HARDSETUP, CARD_STATE_SOFTSETUP, CARD_STATE_UP, - CARD_STATE_RECOVER, }; /** @@ -665,6 +664,7 @@ struct qeth_card_info { unsigned short chpid; __u16 func_level; char mcl_level[QETH_MCL_LENGTH + 1]; + u8 open_when_online:1; int guestlan; int mac_bits; enum qeth_card_types type; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 4708df39f1293..a69e31e9bdf1d 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -265,8 +265,7 @@ int qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt) { QETH_CARD_TEXT(card, 2, "realcbp"); - if ((card->state != CARD_STATE_DOWN) && - (card->state != CARD_STATE_RECOVER)) + if (card->state != CARD_STATE_DOWN) return -EPERM; /* TODO: steel/add buffers from/to a running card's buffer pool (?) */ @@ -3479,8 +3478,7 @@ int qeth_configure_cq(struct qeth_card *card, enum qeth_cq cq) goto out; } - if (card->state != CARD_STATE_DOWN && - card->state != CARD_STATE_RECOVER) { + if (card->state != CARD_STATE_DOWN) { rc = -1; goto out; } diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 8b223cc2c19b4..e24d204b780ad 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c @@ -34,8 +34,6 @@ static ssize_t qeth_dev_state_show(struct device *dev, return sprintf(buf, "UP (LAN %s)\n", netif_carrier_ok(card->dev) ? "ONLINE" : "OFFLINE"); - case CARD_STATE_RECOVER: - return sprintf(buf, "RECOVER\n"); default: return sprintf(buf, "UNKNOWN\n"); } @@ -126,8 +124,7 @@ static ssize_t qeth_dev_portno_store(struct device *dev, return -EINVAL; mutex_lock(&card->conf_mutex); - if ((card->state != CARD_STATE_DOWN) && - (card->state != CARD_STATE_RECOVER)) { + if (card->state != CARD_STATE_DOWN) { rc = -EPERM; goto out; } @@ -202,8 +199,7 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev, return -EINVAL; mutex_lock(&card->conf_mutex); - if ((card->state != CARD_STATE_DOWN) && - (card->state != CARD_STATE_RECOVER)) { + if (card->state != CARD_STATE_DOWN) { rc = -EPERM; goto out; } @@ -285,8 +281,7 @@ static ssize_t qeth_dev_bufcnt_store(struct device *dev, return -EINVAL; mutex_lock(&card->conf_mutex); - if ((card->state != CARD_STATE_DOWN) && - (card->state != CARD_STATE_RECOVER)) { + if (card->state != CARD_STATE_DOWN) { rc = -EPERM; goto out; } @@ -634,8 +629,7 @@ static ssize_t qeth_dev_blkt_store(struct qeth_card *card, return -EINVAL; mutex_lock(&card->conf_mutex); - if ((card->state != CARD_STATE_DOWN) && - (card->state != CARD_STATE_RECOVER)) { + if (card->state != CARD_STATE_DOWN) { rc = -EPERM; goto out; } diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 2c97142157750..f621656f9ea79 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -807,7 +807,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct net_device *dev = card->dev; int rc = 0; - enum qeth_card_states recover_flag; bool carrier_ok; mutex_lock(&card->discipline_mutex); @@ -815,7 +814,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) QETH_DBF_TEXT(SETUP, 2, "setonlin"); QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); - recover_flag = card->state; rc = qeth_core_hardsetup_card(card, &carrier_ok); if (rc) { QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); @@ -881,7 +879,8 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) netif_device_attach(dev); qeth_enable_hw_features(dev); - if (recover_flag == CARD_STATE_RECOVER) { + if (card->info.open_when_online) { + card->info.open_when_online = 0; if (recovery_mode && !IS_OSN(card)) { if (!qeth_l2_validate_addr(dev)) { qeth_open(dev); @@ -905,10 +904,8 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) ccw_device_set_offline(CARD_WDEV(card)); ccw_device_set_offline(CARD_RDEV(card)); qdio_free(CARD_DDEV(card)); - if (recover_flag == CARD_STATE_RECOVER) - card->state = CARD_STATE_RECOVER; - else - card->state = CARD_STATE_DOWN; + card->state = CARD_STATE_DOWN; + mutex_unlock(&card->conf_mutex); mutex_unlock(&card->discipline_mutex); return rc; @@ -924,7 +921,6 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, { struct qeth_card *card = dev_get_drvdata(&cgdev->dev); int rc = 0, rc2 = 0, rc3 = 0; - enum qeth_card_states recover_flag; mutex_lock(&card->discipline_mutex); mutex_lock(&card->conf_mutex); @@ -932,11 +928,11 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); rtnl_lock(); + card->info.open_when_online = card->dev->flags & IFF_UP; netif_device_detach(card->dev); netif_carrier_off(card->dev); rtnl_unlock(); - recover_flag = card->state; if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) { qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); card->info.hwtrap = 1; @@ -950,8 +946,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, if (rc) QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); qdio_free(CARD_DDEV(card)); - if (recover_flag == CARD_STATE_UP) - card->state = CARD_STATE_RECOVER; + /* let user_space know that device is offline */ kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); mutex_unlock(&card->conf_mutex); @@ -1024,7 +1019,7 @@ static int qeth_l2_pm_resume(struct ccwgroup_device *gdev) struct qeth_card *card = dev_get_drvdata(&gdev->dev); int rc = 0; - if (card->state == CARD_STATE_RECOVER) { + if (card->info.open_when_online) { rc = __qeth_l2_set_online(card->gdev, 1); if (rc) { rtnl_lock(); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 07c3149e228c6..fe6b9a82f69ef 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2304,7 +2304,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct net_device *dev = card->dev; int rc = 0; - enum qeth_card_states recover_flag; bool carrier_ok; mutex_lock(&card->discipline_mutex); @@ -2312,7 +2311,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) QETH_DBF_TEXT(SETUP, 2, "setonlin"); QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); - recover_flag = card->state; rc = qeth_core_hardsetup_card(card, &carrier_ok); if (rc) { QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); @@ -2375,7 +2373,8 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) netif_device_attach(dev); qeth_enable_hw_features(dev); - if (recover_flag == CARD_STATE_RECOVER) { + if (card->info.open_when_online) { + card->info.open_when_online = 0; if (recovery_mode) { qeth_open(dev); qeth_l3_set_rx_mode(dev); @@ -2397,10 +2396,8 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) ccw_device_set_offline(CARD_WDEV(card)); ccw_device_set_offline(CARD_RDEV(card)); qdio_free(CARD_DDEV(card)); - if (recover_flag == CARD_STATE_RECOVER) - card->state = CARD_STATE_RECOVER; - else - card->state = CARD_STATE_DOWN; + card->state = CARD_STATE_DOWN; + mutex_unlock(&card->conf_mutex); mutex_unlock(&card->discipline_mutex); return rc; @@ -2416,7 +2413,6 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, { struct qeth_card *card = dev_get_drvdata(&cgdev->dev); int rc = 0, rc2 = 0, rc3 = 0; - enum qeth_card_states recover_flag; mutex_lock(&card->discipline_mutex); mutex_lock(&card->conf_mutex); @@ -2424,11 +2420,11 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); rtnl_lock(); + card->info.open_when_online = card->dev->flags & IFF_UP; netif_device_detach(card->dev); netif_carrier_off(card->dev); rtnl_unlock(); - recover_flag = card->state; if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) { qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); card->info.hwtrap = 1; @@ -2447,8 +2443,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, if (rc) QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); qdio_free(CARD_DDEV(card)); - if (recover_flag == CARD_STATE_UP) - card->state = CARD_STATE_RECOVER; + /* let user_space know that device is offline */ kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); mutex_unlock(&card->conf_mutex); @@ -2511,7 +2506,7 @@ static int qeth_l3_pm_resume(struct ccwgroup_device *gdev) struct qeth_card *card = dev_get_drvdata(&gdev->dev); int rc = 0; - if (card->state == CARD_STATE_RECOVER) { + if (card->info.open_when_online) { rc = __qeth_l3_set_online(card->gdev, 1); if (rc) { rtnl_lock(); diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 45ac6d8705c69..cff518b0f9043 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c @@ -167,8 +167,7 @@ static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev, return -EINVAL; mutex_lock(&card->conf_mutex); - if ((card->state != CARD_STATE_DOWN) && - (card->state != CARD_STATE_RECOVER)) { + if (card->state != CARD_STATE_DOWN) { rc = -EPERM; goto out; } @@ -213,8 +212,7 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev, return -EPERM; mutex_lock(&card->conf_mutex); - if ((card->state != CARD_STATE_DOWN) && - (card->state != CARD_STATE_RECOVER)) { + if (card->state != CARD_STATE_DOWN) { rc = -EPERM; goto out; } @@ -280,8 +278,7 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev, if (card->info.type != QETH_CARD_TYPE_IQD) return -EPERM; - if (card->state != CARD_STATE_DOWN && - card->state != CARD_STATE_RECOVER) + if (card->state != CARD_STATE_DOWN) return -EPERM; if (card->options.sniffer) return -EPERM; @@ -356,8 +353,7 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, return -EINVAL; mutex_lock(&card->conf_mutex); - if ((card->state != CARD_STATE_DOWN) && - (card->state != CARD_STATE_RECOVER)) { + if (card->state != CARD_STATE_DOWN) { rc = -EPERM; goto out; } From d7ef489f8261208b8a21b3c563e4d3d40b674e01 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 28 Feb 2019 18:59:37 +0100 Subject: [PATCH 2/9] s390/qeth: enable/disable the HW trap a little earlier When setting a L2 qeth device online, enable the HW trap as soon as the control plane is available. This allows us to catch any error that occurs during the very first commands. In the same spirit, the offline code should disable the HW trap as the very first step of its processing. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l2_main.c | 22 ++++++++++++---------- drivers/s390/net/qeth_l3_main.c | 9 +++++---- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index f621656f9ea79..72e6d08444a74 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -820,12 +820,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) rc = -ENODEV; goto out_remove; } - qeth_bridgeport_query_support(card); - if (card->options.sbp.supported_funcs) - dev_info(&card->gdev->dev, - "The device represents a Bridge Capable Port\n"); - - qeth_l2_register_dev_addr(card); if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) { if (card->info.hwtrap && @@ -834,6 +828,13 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) } else card->info.hwtrap = 0; + qeth_bridgeport_query_support(card); + if (card->options.sbp.supported_funcs) + dev_info(&card->gdev->dev, + "The device represents a Bridge Capable Port\n"); + + qeth_l2_register_dev_addr(card); + /* for the rx_bcast characteristic, init VNICC after setmac */ qeth_l2_vnicc_init(card); @@ -927,16 +928,17 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, QETH_DBF_TEXT(SETUP, 3, "setoffl"); QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); + if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) { + qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); + card->info.hwtrap = 1; + } + rtnl_lock(); card->info.open_when_online = card->dev->flags & IFF_UP; netif_device_detach(card->dev); netif_carrier_off(card->dev); rtnl_unlock(); - if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) { - qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); - card->info.hwtrap = 1; - } qeth_l2_stop_card(card, recovery_mode); rc = ccw_device_set_offline(CARD_DDEV(card)); rc2 = ccw_device_set_offline(CARD_WDEV(card)); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index fe6b9a82f69ef..c299e84cf5d19 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2419,16 +2419,17 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, QETH_DBF_TEXT(SETUP, 3, "setoffl"); QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); + if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) { + qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); + card->info.hwtrap = 1; + } + rtnl_lock(); card->info.open_when_online = card->dev->flags & IFF_UP; netif_device_detach(card->dev); netif_carrier_off(card->dev); rtnl_unlock(); - if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) { - qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); - card->info.hwtrap = 1; - } qeth_l3_stop_card(card, recovery_mode); if ((card->options.cq == QETH_CQ_ENABLED) && card->dev) { rtnl_lock(); From 7bd2275c974f9dd7789ee957a0d1837c4114a910 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 28 Feb 2019 18:59:38 +0100 Subject: [PATCH 3/9] s390/qeth: unconditionally clear MAC_REGISTERED flag In its attempt to run only the minimal amount of tear down steps, qeth_l2_stop_card() fails to reset the "is dev_addr registered?" flag in some rare scenarios. But a future change to the tear down sequence would cause us to _always_ hit this issue, so patch it up before that code lands. Fix it by unconditionally clearing the flag bit. This also allows us to remove the additional cleanup step in qeth_dev_layer2_store(). Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_sys.c | 1 - drivers/s390/net/qeth_l2_main.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index e24d204b780ad..fa575549d2885 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c @@ -416,7 +416,6 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, goto out; } - card->info.mac_bits = 0; if (card->discipline) { /* start with a new, pristine netdevice: */ ndev = qeth_clone_netdev(card->dev); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 72e6d08444a74..f71d45ea30dae 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -301,7 +301,6 @@ static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) dev_close(card->dev); rtnl_unlock(); } - card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; card->state = CARD_STATE_SOFTSETUP; } if (card->state == CARD_STATE_SOFTSETUP) { @@ -321,6 +320,7 @@ static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) } flush_workqueue(card->event_wq); + card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; } static int qeth_l2_process_inbound_buffer(struct qeth_card *card, From d4560150cb47daba50b0d080550ca4bbe80cf3c3 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 28 Feb 2019 18:59:39 +0100 Subject: [PATCH 4/9] s390/qeth: call dev_close() during recovery When resetting an interface ("recovery"), qeth currently attempts to elide the call to dev_close(). We initially only call .ndo_close to quiesce the data path, and then offline & online the ccwgroup device. If the reset succeeded, a call to .ndo_open then resumes the data path along with some internal setup (dev_addr validation, RX modeset) that dev_open() would have usually triggered. dev_close() only gets called (via the close_dev worker) if the reset action fails. It's unclear whether this was initially done due to locking concerns, or rather to execute the reset transparently. Either way, temporarily closing the interface without dev_close() is fragile, and means we're susceptible to various races and unexpected behaviour. For instance: - Bypassing dev_deactivate_many() means that the qdiscs are not set to __QDISC_STATE_DEACTIVATED. Consequently any intermittent TX completion can wake up the txq, resulting in calls to .ndo_start_xmit while the data path is down. We have custom state checking to detect this case and drop such packets. - Because the IFF_UP flag doesn't reflect the interface's actual state during a reset, we have custom state checking in .ndo_open and .ndo_close to guard against invalid calls. - Considering that the reset might take a considerable amount of time (in particular if an IO fails and we end up waiting for its timeout), we _do_ want NETDEV_GOING_DOWN and NETDEV_DOWN events so that components like bonding, team, bridge, macvlan, vlan, ... can take appropriate action. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 3 -- drivers/s390/net/qeth_l2_main.c | 47 +++++++------------------------ drivers/s390/net/qeth_l3_main.c | 45 +++++++---------------------- 3 files changed, 20 insertions(+), 75 deletions(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index a69e31e9bdf1d..a1a66467b06b9 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -89,9 +89,6 @@ static void qeth_close_dev_handler(struct work_struct *work) card = container_of(work, struct qeth_card, close_dev_work); QETH_CARD_TEXT(card, 2, "cldevhdl"); - rtnl_lock(); - dev_close(card->dev); - rtnl_unlock(); ccwgroup_set_offline(card->gdev); } diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index f71d45ea30dae..a42285b1daa30 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -285,7 +285,7 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev, return qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN); } -static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) +static void qeth_l2_stop_card(struct qeth_card *card) { QETH_DBF_TEXT(SETUP , 2, "stopcard"); QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); @@ -293,16 +293,8 @@ static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) qeth_set_allowed_threads(card, 0, 1); if (card->read.state == CH_STATE_UP && card->write.state == CH_STATE_UP && - (card->state == CARD_STATE_UP)) { - if (recovery_mode && !IS_OSN(card)) { - qeth_stop(card->dev); - } else { - rtnl_lock(); - dev_close(card->dev); - rtnl_unlock(); - } + card->state == CARD_STATE_UP) card->state = CARD_STATE_SOFTSETUP; - } if (card->state == CARD_STATE_SOFTSETUP) { qeth_l2_del_all_macs(card); qeth_clear_ipacmd_list(card); @@ -802,7 +794,7 @@ static void qeth_l2_trace_features(struct qeth_card *card) sizeof(card->options.vnicc.sup_chars)); } -static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) +static int qeth_l2_set_online(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct net_device *dev = card->dev; @@ -882,14 +874,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) if (card->info.open_when_online) { card->info.open_when_online = 0; - if (recovery_mode && !IS_OSN(card)) { - if (!qeth_l2_validate_addr(dev)) { - qeth_open(dev); - qeth_l2_set_rx_mode(dev); - } - } else { - dev_open(dev, NULL); - } + dev_open(dev, NULL); } rtnl_unlock(); } @@ -900,7 +885,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) return 0; out_remove: - qeth_l2_stop_card(card, 0); + qeth_l2_stop_card(card); ccw_device_set_offline(CARD_DDEV(card)); ccw_device_set_offline(CARD_WDEV(card)); ccw_device_set_offline(CARD_RDEV(card)); @@ -912,11 +897,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) return rc; } -static int qeth_l2_set_online(struct ccwgroup_device *gdev) -{ - return __qeth_l2_set_online(gdev, 0); -} - static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) { @@ -935,11 +915,12 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, rtnl_lock(); card->info.open_when_online = card->dev->flags & IFF_UP; + dev_close(card->dev); netif_device_detach(card->dev); netif_carrier_off(card->dev); rtnl_unlock(); - qeth_l2_stop_card(card, recovery_mode); + qeth_l2_stop_card(card); rc = ccw_device_set_offline(CARD_DDEV(card)); rc2 = ccw_device_set_offline(CARD_WDEV(card)); rc3 = ccw_device_set_offline(CARD_RDEV(card)); @@ -974,7 +955,7 @@ static int qeth_l2_recover(void *ptr) dev_warn(&card->gdev->dev, "A recovery process has been started for the device\n"); __qeth_l2_set_offline(card->gdev, 1); - rc = __qeth_l2_set_online(card->gdev, 1); + rc = qeth_l2_set_online(card->gdev); if (!rc) dev_info(&card->gdev->dev, "Device successfully recovered!\n"); @@ -1019,17 +1000,9 @@ static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev) static int qeth_l2_pm_resume(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - int rc = 0; + int rc; - if (card->info.open_when_online) { - rc = __qeth_l2_set_online(card->gdev, 1); - if (rc) { - rtnl_lock(); - dev_close(card->dev); - rtnl_unlock(); - } - } else - rc = __qeth_l2_set_online(card->gdev, 0); + rc = qeth_l2_set_online(gdev); qeth_set_allowed_threads(card, 0xffffffff, 0); if (rc) diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index c299e84cf5d19..1381e7e312cd0 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1406,7 +1406,7 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card, return work_done; } -static void qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) +static void qeth_l3_stop_card(struct qeth_card *card) { QETH_DBF_TEXT(SETUP, 2, "stopcard"); QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); @@ -1417,16 +1417,8 @@ static void qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE); if (card->read.state == CH_STATE_UP && card->write.state == CH_STATE_UP && - (card->state == CARD_STATE_UP)) { - if (recovery_mode) - qeth_stop(card->dev); - else { - rtnl_lock(); - dev_close(card->dev); - rtnl_unlock(); - } + card->state == CARD_STATE_UP) card->state = CARD_STATE_SOFTSETUP; - } if (card->state == CARD_STATE_SOFTSETUP) { qeth_l3_clear_ip_htable(card, 1); qeth_clear_ipacmd_list(card); @@ -2299,7 +2291,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) qeth_l3_clear_ipato_list(card); } -static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) +static int qeth_l3_set_online(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct net_device *dev = card->dev; @@ -2375,12 +2367,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) if (card->info.open_when_online) { card->info.open_when_online = 0; - if (recovery_mode) { - qeth_open(dev); - qeth_l3_set_rx_mode(dev); - } else { - dev_open(dev, NULL); - } + dev_open(dev, NULL); } rtnl_unlock(); } @@ -2391,7 +2378,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) mutex_unlock(&card->discipline_mutex); return 0; out_remove: - qeth_l3_stop_card(card, 0); + qeth_l3_stop_card(card); ccw_device_set_offline(CARD_DDEV(card)); ccw_device_set_offline(CARD_WDEV(card)); ccw_device_set_offline(CARD_RDEV(card)); @@ -2403,11 +2390,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) return rc; } -static int qeth_l3_set_online(struct ccwgroup_device *gdev) -{ - return __qeth_l3_set_online(gdev, 0); -} - static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) { @@ -2426,11 +2408,12 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, rtnl_lock(); card->info.open_when_online = card->dev->flags & IFF_UP; + dev_close(card->dev); netif_device_detach(card->dev); netif_carrier_off(card->dev); rtnl_unlock(); - qeth_l3_stop_card(card, recovery_mode); + qeth_l3_stop_card(card); if ((card->options.cq == QETH_CQ_ENABLED) && card->dev) { rtnl_lock(); call_netdevice_notifiers(NETDEV_REBOOT, card->dev); @@ -2471,7 +2454,7 @@ static int qeth_l3_recover(void *ptr) dev_warn(&card->gdev->dev, "A recovery process has been started for the device\n"); __qeth_l3_set_offline(card->gdev, 1); - rc = __qeth_l3_set_online(card->gdev, 1); + rc = qeth_l3_set_online(card->gdev); if (!rc) dev_info(&card->gdev->dev, "Device successfully recovered!\n"); @@ -2505,17 +2488,9 @@ static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev) static int qeth_l3_pm_resume(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - int rc = 0; + int rc; - if (card->info.open_when_online) { - rc = __qeth_l3_set_online(card->gdev, 1); - if (rc) { - rtnl_lock(); - dev_close(card->dev); - rtnl_unlock(); - } - } else - rc = __qeth_l3_set_online(card->gdev, 0); + rc = qeth_l3_set_online(gdev); qeth_set_allowed_threads(card, 0xffffffff, 0); if (rc) From 464e86dafcca14e5f7a7157fc567c58654ec80b3 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 28 Feb 2019 18:59:40 +0100 Subject: [PATCH 5/9] s390/qeth: remove a redundant check for card->dev smatch complains that __qeth_l3_set_offline() first accesses card->dev, and then later checks whether the pointer is valid. Since commit d3d1b205e89f ("s390/qeth: allocate netdevice early"), the pointer is _always_ valid - that patch merely missed to remove this one check. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l3_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 1381e7e312cd0..13d77957404c3 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2414,7 +2414,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, rtnl_unlock(); qeth_l3_stop_card(card); - if ((card->options.cq == QETH_CQ_ENABLED) && card->dev) { + if (card->options.cq == QETH_CQ_ENABLED) { rtnl_lock(); call_netdevice_notifiers(NETDEV_REBOOT, card->dev); rtnl_unlock(); From bf42d40b1254afe26015ebdb09d137fb15250fa4 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 28 Feb 2019 18:59:41 +0100 Subject: [PATCH 6/9] s390/qeth: don't defer close_dev work during recovery The recovery code already runs in a kthread, we don't have to defer the offlining further. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 1 - drivers/s390/net/qeth_core_main.c | 3 +-- drivers/s390/net/qeth_l2_main.c | 2 +- drivers/s390/net/qeth_l3_main.c | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 79de890010c70..8c354cdc86c07 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -1002,7 +1002,6 @@ int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback); int qeth_configure_cq(struct qeth_card *, enum qeth_cq); int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action); void qeth_trace_features(struct qeth_card *); -void qeth_close_dev(struct qeth_card *); int qeth_setassparms_cb(struct qeth_card *, struct qeth_reply *, unsigned long); struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *, enum qeth_ipa_funcs, diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index a1a66467b06b9..6c2540e3247b9 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -92,12 +92,11 @@ static void qeth_close_dev_handler(struct work_struct *work) ccwgroup_set_offline(card->gdev); } -void qeth_close_dev(struct qeth_card *card) +static void qeth_close_dev(struct qeth_card *card) { QETH_CARD_TEXT(card, 2, "cldevsubm"); queue_work(qeth_wq, &card->close_dev_work); } -EXPORT_SYMBOL_GPL(qeth_close_dev); static const char *qeth_get_cardname(struct qeth_card *card) { diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index a42285b1daa30..f34fe983012c2 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -960,7 +960,7 @@ static int qeth_l2_recover(void *ptr) dev_info(&card->gdev->dev, "Device successfully recovered!\n"); else { - qeth_close_dev(card); + ccwgroup_set_offline(card->gdev); dev_warn(&card->gdev->dev, "The qeth device driver " "failed to recover an error on the device\n"); } diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 13d77957404c3..d424a6704811a 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2459,7 +2459,7 @@ static int qeth_l3_recover(void *ptr) dev_info(&card->gdev->dev, "Device successfully recovered!\n"); else { - qeth_close_dev(card); + ccwgroup_set_offline(card->gdev); dev_warn(&card->gdev->dev, "The qeth device driver " "failed to recover an error on the device\n"); } From dcef5cad639e0c24dd562e777b31533f5c97baa1 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 28 Feb 2019 18:59:42 +0100 Subject: [PATCH 7/9] s390/qeth: remove driver-wide workqueue The qeth-wide workqueue is now only used by a single caller to schedule close_dev work. Just put it on a system queue instead. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 6c2540e3247b9..4dcb4f91b9c0c 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -74,8 +74,6 @@ static void qeth_notify_skbs(struct qeth_qdio_out_q *queue, static void qeth_release_skbs(struct qeth_qdio_out_buffer *buf); static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int); -static struct workqueue_struct *qeth_wq; - int qeth_card_hw_is_reachable(struct qeth_card *card) { return (card->state == CARD_STATE_SOFTSETUP) || @@ -92,12 +90,6 @@ static void qeth_close_dev_handler(struct work_struct *work) ccwgroup_set_offline(card->gdev); } -static void qeth_close_dev(struct qeth_card *card) -{ - QETH_CARD_TEXT(card, 2, "cldevsubm"); - queue_work(qeth_wq, &card->close_dev_work); -} - static const char *qeth_get_cardname(struct qeth_card *card) { if (card->info.guestlan) { @@ -634,7 +626,7 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card, dev_err(&card->gdev->dev, "Interface %s is down because the adjacent port is no longer in reflective relay mode\n", QETH_CARD_IFNAME(card)); - qeth_close_dev(card); + schedule_work(&card->close_dev_work); } else { dev_warn(&card->gdev->dev, "The link for interface %s on CHPID 0x%X failed\n", @@ -6265,12 +6257,6 @@ static int __init qeth_core_init(void) pr_info("loading core functions\n"); - qeth_wq = create_singlethread_workqueue("qeth_wq"); - if (!qeth_wq) { - rc = -ENOMEM; - goto out_err; - } - rc = qeth_register_dbf_views(); if (rc) goto dbf_err; @@ -6312,8 +6298,6 @@ static int __init qeth_core_init(void) register_err: qeth_unregister_dbf_views(); dbf_err: - destroy_workqueue(qeth_wq); -out_err: pr_err("Initializing the qeth device driver failed\n"); return rc; } @@ -6321,7 +6305,6 @@ static int __init qeth_core_init(void) static void __exit qeth_core_exit(void) { qeth_clear_dbf_list(); - destroy_workqueue(qeth_wq); ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); ccw_driver_unregister(&qeth_ccw_driver); kmem_cache_destroy(qeth_qdio_outbuf_cache); From 62ca98d475d1839f90d209bb47cc0192dc3db946 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 28 Feb 2019 18:59:43 +0100 Subject: [PATCH 8/9] s390/qeth: don't special-case HW trap during suspend It makes no difference whether we 1. manually disarm the HW trap and call the offline code with recovery_mode == 1, or 2. call the offline code with recovery_mode == 0, and let it disarm the HW trap for us. So consolidate the two code paths in the suspend callback. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l2_main.c | 8 ++------ drivers/s390/net/qeth_l3_main.c | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index f34fe983012c2..6380d29c10f7c 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -988,12 +988,8 @@ static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev) wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); if (gdev->state == CCWGROUP_OFFLINE) return 0; - if (card->state == CARD_STATE_UP) { - if (card->info.hwtrap) - qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); - __qeth_l2_set_offline(card->gdev, 1); - } else - __qeth_l2_set_offline(card->gdev, 0); + + qeth_l2_set_offline(gdev); return 0; } diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index d424a6704811a..375ad03ea4c58 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2476,12 +2476,8 @@ static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev) wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); if (gdev->state == CCWGROUP_OFFLINE) return 0; - if (card->state == CARD_STATE_UP) { - if (card->info.hwtrap) - qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); - __qeth_l3_set_offline(card->gdev, 1); - } else - __qeth_l3_set_offline(card->gdev, 0); + + qeth_l3_set_offline(gdev); return 0; } From 0f7aedbdf2bb92cf1a3462561b3ff4c3a42bfe7d Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 28 Feb 2019 18:59:44 +0100 Subject: [PATCH 9/9] s390/qeth: drop redundant state checking Now that qeth always uses dev_close() to shutdown the interface, we can trust the locking and remove some custom state checks. qeth_l?_stop_card() is no longer called for a card in UP state, so remove the checks there too. This basically makes the UP state obsolete, so rip out the whole thing (except for the sysfs-visible string). Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 8 +++++--- drivers/s390/net/qeth_core_main.c | 18 +----------------- drivers/s390/net/qeth_core_sys.c | 8 ++++---- drivers/s390/net/qeth_l2_main.c | 11 +---------- drivers/s390/net/qeth_l3_main.c | 11 ++--------- 5 files changed, 13 insertions(+), 43 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 8c354cdc86c07..c851cf6e01c43 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -483,7 +483,6 @@ struct qeth_out_q_stats { u64 tx_bytes; u64 tx_errors; u64 tx_dropped; - u64 tx_carrier_errors; }; struct qeth_qdio_out_q { @@ -552,7 +551,6 @@ enum qeth_card_states { CARD_STATE_DOWN, CARD_STATE_HARDSETUP, CARD_STATE_SOFTSETUP, - CARD_STATE_UP, }; /** @@ -808,6 +806,11 @@ struct qeth_card { struct work_struct close_dev_work; }; +static inline bool qeth_card_hw_is_reachable(struct qeth_card *card) +{ + return card->state == CARD_STATE_SOFTSETUP; +} + struct qeth_trap_id { __u16 lparnr; char vmname[8]; @@ -942,7 +945,6 @@ extern const struct attribute_group qeth_device_attr_group; extern const struct attribute_group qeth_device_blkt_group; extern const struct device_type qeth_generic_devtype; -int qeth_card_hw_is_reachable(struct qeth_card *); const char *qeth_get_cardname_short(struct qeth_card *); int qeth_realloc_buffer_pool(struct qeth_card *, int); int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 4dcb4f91b9c0c..a44a4e0d2b191 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -74,13 +74,6 @@ static void qeth_notify_skbs(struct qeth_qdio_out_q *queue, static void qeth_release_skbs(struct qeth_qdio_out_buffer *buf); static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int); -int qeth_card_hw_is_reachable(struct qeth_card *card) -{ - return (card->state == CARD_STATE_SOFTSETUP) || - (card->state == CARD_STATE_UP); -} -EXPORT_SYMBOL_GPL(qeth_card_hw_is_reachable); - static void qeth_close_dev_handler(struct work_struct *work) { struct qeth_card *card; @@ -6206,7 +6199,6 @@ void qeth_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) stats->tx_bytes += queue->stats.tx_bytes; stats->tx_errors += queue->stats.tx_errors; stats->tx_dropped += queue->stats.tx_dropped; - stats->tx_carrier_errors += queue->stats.tx_carrier_errors; } } EXPORT_SYMBOL_GPL(qeth_get_stats64); @@ -6216,16 +6208,11 @@ int qeth_open(struct net_device *dev) struct qeth_card *card = dev->ml_priv; QETH_CARD_TEXT(card, 4, "qethopen"); - if (card->state == CARD_STATE_UP) - return 0; - if (card->state != CARD_STATE_SOFTSETUP) - return -ENODEV; if (qdio_stop_irq(CARD_DDEV(card), 0) < 0) return -EIO; card->data.state = CH_STATE_UP; - card->state = CARD_STATE_UP; netif_start_queue(dev); napi_enable(&card->napi); @@ -6243,10 +6230,7 @@ int qeth_stop(struct net_device *dev) QETH_CARD_TEXT(card, 4, "qethstop"); netif_tx_disable(dev); - if (card->state == CARD_STATE_UP) { - card->state = CARD_STATE_SOFTSETUP; - napi_disable(&card->napi); - } + napi_disable(&card->napi); return 0; } EXPORT_SYMBOL_GPL(qeth_stop); diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index fa575549d2885..56deeb6f7bc07 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c @@ -29,11 +29,11 @@ static ssize_t qeth_dev_state_show(struct device *dev, case CARD_STATE_HARDSETUP: return sprintf(buf, "HARDSETUP\n"); case CARD_STATE_SOFTSETUP: + if (card->dev->flags & IFF_UP) + return sprintf(buf, "UP (LAN %s)\n", + netif_carrier_ok(card->dev) ? "ONLINE" : + "OFFLINE"); return sprintf(buf, "SOFTSETUP\n"); - case CARD_STATE_UP: - return sprintf(buf, "UP (LAN %s)\n", - netif_carrier_ok(card->dev) ? "ONLINE" : - "OFFLINE"); default: return sprintf(buf, "UNKNOWN\n"); } diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 6380d29c10f7c..8efb2e8ff8f46 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -291,10 +291,7 @@ static void qeth_l2_stop_card(struct qeth_card *card) QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); qeth_set_allowed_threads(card, 0, 1); - if (card->read.state == CH_STATE_UP && - card->write.state == CH_STATE_UP && - card->state == CARD_STATE_UP) - card->state = CARD_STATE_SOFTSETUP; + if (card->state == CARD_STATE_SOFTSETUP) { qeth_l2_del_all_macs(card); qeth_clear_ipacmd_list(card); @@ -614,11 +611,6 @@ static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb, queue = qeth_get_tx_queue(card, skb, ipv, cast_type); - if (card->state != CARD_STATE_UP) { - QETH_TXQ_STAT_INC(queue, tx_carrier_errors); - goto tx_drop; - } - netif_stop_queue(dev); if (IS_OSN(card)) @@ -636,7 +628,6 @@ static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb, return NETDEV_TX_BUSY; } /* else fall through */ -tx_drop: QETH_TXQ_STAT_INC(queue, tx_dropped); QETH_TXQ_STAT_INC(queue, tx_errors); dev_kfree_skb_any(skb); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 375ad03ea4c58..7e68d9d16859d 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1412,13 +1412,11 @@ static void qeth_l3_stop_card(struct qeth_card *card) QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); qeth_set_allowed_threads(card, 0, 1); + if (card->options.sniffer && (card->info.promisc_mode == SET_PROMISC_MODE_ON)) qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE); - if (card->read.state == CH_STATE_UP && - card->write.state == CH_STATE_UP && - card->state == CARD_STATE_UP) - card->state = CARD_STATE_SOFTSETUP; + if (card->state == CARD_STATE_SOFTSETUP) { qeth_l3_clear_ip_htable(card, 1); qeth_clear_ipacmd_list(card); @@ -2076,11 +2074,6 @@ static netdev_tx_t qeth_l3_hard_start_xmit(struct sk_buff *skb, goto tx_drop; } - if (card->state != CARD_STATE_UP) { - QETH_TXQ_STAT_INC(queue, tx_carrier_errors); - goto tx_drop; - } - if (cast_type == RTN_BROADCAST && !card->info.broadcast_capable) goto tx_drop;