Skip to content

Commit

Permalink
s390/qeth: fix initial operstate
Browse files Browse the repository at this point in the history
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: 91cc98f ("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>
  • Loading branch information
Julian Wiedmann authored and David S. Miller committed Nov 3, 2018
1 parent 30356d0 commit 9fae5c3
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 10 deletions.
2 changes: 1 addition & 1 deletion drivers/s390/net/qeth_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,7 @@ int qeth_wait_for_threads(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_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 *);
int qeth_init_qdio_queues(struct qeth_card *);
int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
Expand Down
13 changes: 10 additions & 3 deletions drivers/s390/net/qeth_core_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5075,7 +5075,7 @@ static struct ccw_driver qeth_ccw_driver = {
.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 rc;
Expand Down Expand Up @@ -5150,13 +5150,20 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
if (rc == IPA_RC_LAN_OFFLINE) {
dev_warn(&card->gdev->dev,
"The LAN is offline\n");
netif_carrier_off(card->dev);
*carrier_ok = false;
} else {
rc = -ENODEV;
goto out;
}
} 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;
Expand Down
10 changes: 7 additions & 3 deletions drivers/s390/net/qeth_l2_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ static const struct net_device_ops qeth_l2_netdev_ops = {
.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;

Expand Down Expand Up @@ -920,6 +920,9 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
qeth_l2_request_initial_mac(card);
netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
rc = register_netdev(card->dev);
if (!rc && carrier_ok)
netif_carrier_on(card->dev);

if (rc)
card->dev->netdev_ops = NULL;
return rc;
Expand Down Expand Up @@ -950,14 +953,15 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
int rc = 0;
enum qeth_card_states recover_flag;
bool carrier_ok;

mutex_lock(&card->discipline_mutex);
mutex_lock(&card->conf_mutex);
QETH_DBF_TEXT(SETUP, 2, "setonlin");
QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));

recover_flag = card->state;
rc = qeth_core_hardsetup_card(card);
rc = qeth_core_hardsetup_card(card, &carrier_ok);
if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc);
rc = -ENODEV;
Expand All @@ -968,7 +972,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
dev_info(&card->gdev->dev,
"The device represents a Bridge Capable Port\n");

rc = qeth_l2_setup_netdev(card);
rc = qeth_l2_setup_netdev(card, carrier_ok);
if (rc)
goto out_remove;

Expand Down
10 changes: 7 additions & 3 deletions drivers/s390/net/qeth_l3_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2351,7 +2351,7 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = {
.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;
int rc;
Expand Down Expand Up @@ -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);
rc = register_netdev(card->dev);
if (!rc && carrier_ok)
netif_carrier_on(card->dev);

out:
if (rc)
card->dev->netdev_ops = NULL;
Expand Down Expand Up @@ -2476,21 +2479,22 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
int rc = 0;
enum qeth_card_states recover_flag;
bool carrier_ok;

mutex_lock(&card->discipline_mutex);
mutex_lock(&card->conf_mutex);
QETH_DBF_TEXT(SETUP, 2, "setonlin");
QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));

recover_flag = card->state;
rc = qeth_core_hardsetup_card(card);
rc = qeth_core_hardsetup_card(card, &carrier_ok);
if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc);
rc = -ENODEV;
goto out_remove;
}

rc = qeth_l3_setup_netdev(card);
rc = qeth_l3_setup_netdev(card, carrier_ok);
if (rc)
goto out_remove;

Expand Down

0 comments on commit 9fae5c3

Please sign in to comment.