s390/qeth: fix initial operstate

Setting the carrier 'on' for an unregistered netdevice doesn't update
its operstate. Fix this by delaying the update until the netdevice has
been registered.

Fixes: 91cc98f51e ("s390/qeth: remove duplicated carrier state tracking")
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Julian Wiedmann 2018-11-02 19:04:11 +01:00 committed by David S. Miller
parent 30356d0815
commit 9fae5c3b60
4 changed files with 25 additions and 10 deletions

View File

@ -991,7 +991,7 @@ int qeth_wait_for_threads(struct qeth_card *, unsigned long);
int qeth_do_run_thread(struct qeth_card *, unsigned long); int qeth_do_run_thread(struct qeth_card *, unsigned long);
void qeth_clear_thread_start_bit(struct qeth_card *, unsigned long); void qeth_clear_thread_start_bit(struct qeth_card *, unsigned long);
void qeth_clear_thread_running_bit(struct qeth_card *, unsigned long); void qeth_clear_thread_running_bit(struct qeth_card *, unsigned long);
int qeth_core_hardsetup_card(struct qeth_card *); int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok);
void qeth_print_status_message(struct qeth_card *); void qeth_print_status_message(struct qeth_card *);
int qeth_init_qdio_queues(struct qeth_card *); int qeth_init_qdio_queues(struct qeth_card *);
int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,

View File

@ -5075,7 +5075,7 @@ static struct ccw_driver qeth_ccw_driver = {
.remove = ccwgroup_remove_ccwdev, .remove = ccwgroup_remove_ccwdev,
}; };
int qeth_core_hardsetup_card(struct qeth_card *card) int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok)
{ {
int retries = 3; int retries = 3;
int rc; int rc;
@ -5150,13 +5150,20 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
if (rc == IPA_RC_LAN_OFFLINE) { if (rc == IPA_RC_LAN_OFFLINE) {
dev_warn(&card->gdev->dev, dev_warn(&card->gdev->dev,
"The LAN is offline\n"); "The LAN is offline\n");
netif_carrier_off(card->dev); *carrier_ok = false;
} else { } else {
rc = -ENODEV; rc = -ENODEV;
goto out; goto out;
} }
} else { } else {
netif_carrier_on(card->dev); *carrier_ok = true;
}
if (qeth_netdev_is_registered(card->dev)) {
if (*carrier_ok)
netif_carrier_on(card->dev);
else
netif_carrier_off(card->dev);
} }
card->options.ipa4.supported_funcs = 0; card->options.ipa4.supported_funcs = 0;

View File

@ -863,7 +863,7 @@ static const struct net_device_ops qeth_l2_netdev_ops = {
.ndo_set_features = qeth_set_features .ndo_set_features = qeth_set_features
}; };
static int qeth_l2_setup_netdev(struct qeth_card *card) static int qeth_l2_setup_netdev(struct qeth_card *card, bool carrier_ok)
{ {
int rc; int rc;
@ -920,6 +920,9 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
qeth_l2_request_initial_mac(card); qeth_l2_request_initial_mac(card);
netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT); netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
rc = register_netdev(card->dev); rc = register_netdev(card->dev);
if (!rc && carrier_ok)
netif_carrier_on(card->dev);
if (rc) if (rc)
card->dev->netdev_ops = NULL; card->dev->netdev_ops = NULL;
return rc; return rc;
@ -950,6 +953,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct qeth_card *card = dev_get_drvdata(&gdev->dev);
int rc = 0; int rc = 0;
enum qeth_card_states recover_flag; enum qeth_card_states recover_flag;
bool carrier_ok;
mutex_lock(&card->discipline_mutex); mutex_lock(&card->discipline_mutex);
mutex_lock(&card->conf_mutex); mutex_lock(&card->conf_mutex);
@ -957,7 +961,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
recover_flag = card->state; recover_flag = card->state;
rc = qeth_core_hardsetup_card(card); rc = qeth_core_hardsetup_card(card, &carrier_ok);
if (rc) { if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc);
rc = -ENODEV; rc = -ENODEV;
@ -968,7 +972,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
dev_info(&card->gdev->dev, dev_info(&card->gdev->dev,
"The device represents a Bridge Capable Port\n"); "The device represents a Bridge Capable Port\n");
rc = qeth_l2_setup_netdev(card); rc = qeth_l2_setup_netdev(card, carrier_ok);
if (rc) if (rc)
goto out_remove; goto out_remove;

View File

@ -2351,7 +2351,7 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = {
.ndo_neigh_setup = qeth_l3_neigh_setup, .ndo_neigh_setup = qeth_l3_neigh_setup,
}; };
static int qeth_l3_setup_netdev(struct qeth_card *card) static int qeth_l3_setup_netdev(struct qeth_card *card, bool carrier_ok)
{ {
unsigned int headroom; unsigned int headroom;
int rc; int rc;
@ -2425,6 +2425,9 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT); netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
rc = register_netdev(card->dev); rc = register_netdev(card->dev);
if (!rc && carrier_ok)
netif_carrier_on(card->dev);
out: out:
if (rc) if (rc)
card->dev->netdev_ops = NULL; card->dev->netdev_ops = NULL;
@ -2476,6 +2479,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct qeth_card *card = dev_get_drvdata(&gdev->dev);
int rc = 0; int rc = 0;
enum qeth_card_states recover_flag; enum qeth_card_states recover_flag;
bool carrier_ok;
mutex_lock(&card->discipline_mutex); mutex_lock(&card->discipline_mutex);
mutex_lock(&card->conf_mutex); mutex_lock(&card->conf_mutex);
@ -2483,14 +2487,14 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
recover_flag = card->state; recover_flag = card->state;
rc = qeth_core_hardsetup_card(card); rc = qeth_core_hardsetup_card(card, &carrier_ok);
if (rc) { if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc);
rc = -ENODEV; rc = -ENODEV;
goto out_remove; goto out_remove;
} }
rc = qeth_l3_setup_netdev(card); rc = qeth_l3_setup_netdev(card, carrier_ok);
if (rc) if (rc)
goto out_remove; goto out_remove;