|
@@ -2536,6 +2536,9 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
|
|
|
{
|
|
|
int rc;
|
|
|
|
|
|
+ if (card->dev->netdev_ops)
|
|
|
+ return 0;
|
|
|
+
|
|
|
if (card->info.type == QETH_CARD_TYPE_OSD ||
|
|
|
card->info.type == QETH_CARD_TYPE_OSX) {
|
|
|
if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) ||
|
|
@@ -2544,9 +2547,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
- card->dev = alloc_etherdev(0);
|
|
|
- if (!card->dev)
|
|
|
- return -ENODEV;
|
|
|
card->dev->netdev_ops = &qeth_l3_osa_netdev_ops;
|
|
|
|
|
|
/*IPv6 address autoconfiguration stuff*/
|
|
@@ -2567,27 +2567,19 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
|
|
|
card->dev->vlan_features |= NETIF_F_IPV6_CSUM;
|
|
|
}
|
|
|
} else if (card->info.type == QETH_CARD_TYPE_IQD) {
|
|
|
- card->dev = alloc_netdev(0, "hsi%d", NET_NAME_UNKNOWN,
|
|
|
- ether_setup);
|
|
|
- if (!card->dev)
|
|
|
- return -ENODEV;
|
|
|
card->dev->flags |= IFF_NOARP;
|
|
|
card->dev->netdev_ops = &qeth_l3_netdev_ops;
|
|
|
|
|
|
rc = qeth_l3_iqd_read_initial_mac(card);
|
|
|
if (rc)
|
|
|
- return rc;
|
|
|
+ goto out;
|
|
|
+
|
|
|
if (card->options.hsuid[0])
|
|
|
memcpy(card->dev->perm_addr, card->options.hsuid, 9);
|
|
|
} else
|
|
|
return -ENODEV;
|
|
|
|
|
|
- card->dev->ml_priv = card;
|
|
|
- card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
|
|
|
card->dev->mtu = card->info.initial_mtu;
|
|
|
- card->dev->min_mtu = 64;
|
|
|
- card->dev->max_mtu = ETH_MAX_MTU;
|
|
|
- card->dev->dev_port = card->info.portno;
|
|
|
card->dev->ethtool_ops = &qeth_l3_ethtool_ops;
|
|
|
card->dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
|
|
card->dev->needed_headroom = sizeof(struct qeth_hdr) - ETH_HLEN;
|
|
@@ -2602,10 +2594,12 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
|
|
|
netif_set_gso_max_size(card->dev,
|
|
|
PAGE_SIZE * (QETH_MAX_BUFFER_ELEMENTS(card) - 1));
|
|
|
|
|
|
- SET_NETDEV_DEV(card->dev, &card->gdev->dev);
|
|
|
netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
|
|
|
- netif_carrier_off(card->dev);
|
|
|
- return register_netdev(card->dev);
|
|
|
+ rc = register_netdev(card->dev);
|
|
|
+out:
|
|
|
+ if (rc)
|
|
|
+ card->dev->netdev_ops = NULL;
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
static const struct device_type qeth_l3_devtype = {
|
|
@@ -2643,15 +2637,9 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
|
|
|
if (cgdev->state == CCWGROUP_ONLINE)
|
|
|
qeth_l3_set_offline(cgdev);
|
|
|
|
|
|
- if (card->dev) {
|
|
|
- unregister_netdev(card->dev);
|
|
|
- free_netdev(card->dev);
|
|
|
- card->dev = NULL;
|
|
|
- }
|
|
|
-
|
|
|
+ unregister_netdev(card->dev);
|
|
|
qeth_l3_clear_ip_htable(card, 0);
|
|
|
qeth_l3_clear_ipato_list(card);
|
|
|
- return;
|
|
|
}
|
|
|
|
|
|
static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
|
@@ -2673,10 +2661,9 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
|
|
goto out_remove;
|
|
|
}
|
|
|
|
|
|
- if (!card->dev && qeth_l3_setup_netdev(card)) {
|
|
|
- rc = -ENODEV;
|
|
|
+ rc = qeth_l3_setup_netdev(card);
|
|
|
+ if (rc)
|
|
|
goto out_remove;
|
|
|
- }
|
|
|
|
|
|
if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) {
|
|
|
if (card->info.hwtrap &&
|
|
@@ -2773,8 +2760,7 @@ 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 (card->dev)
|
|
|
- netif_carrier_off(card->dev);
|
|
|
+ netif_carrier_off(card->dev);
|
|
|
recover_flag = card->state;
|
|
|
if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
|
|
|
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
|
|
@@ -2842,8 +2828,7 @@ static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev)
|
|
|
{
|
|
|
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
|
|
|
|
|
|
- if (card->dev)
|
|
|
- netif_device_detach(card->dev);
|
|
|
+ netif_device_detach(card->dev);
|
|
|
qeth_set_allowed_threads(card, 0, 1);
|
|
|
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
|
|
|
if (gdev->state == CCWGROUP_OFFLINE)
|
|
@@ -2876,8 +2861,7 @@ static int qeth_l3_pm_resume(struct ccwgroup_device *gdev)
|
|
|
rc = __qeth_l3_set_online(card->gdev, 0);
|
|
|
out:
|
|
|
qeth_set_allowed_threads(card, 0xffffffff, 0);
|
|
|
- if (card->dev)
|
|
|
- netif_device_attach(card->dev);
|
|
|
+ netif_device_attach(card->dev);
|
|
|
if (rc)
|
|
|
dev_warn(&card->gdev->dev, "The qeth device driver "
|
|
|
"failed to recover an error on the device\n");
|