extern struct kmem_cache *qeth_core_header_cache;
 extern struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS];
 
+struct net_device *qeth_clone_netdev(struct net_device *orig);
 void qeth_set_recovery_task(struct qeth_card *);
 void qeth_clear_recovery_task(struct qeth_card *);
 void qeth_set_allowed_threads(struct qeth_card *, unsigned long , int);
 
                                                cmd->hdr.return_code, card);
                                }
                                card->lan_online = 0;
-                               if (card->dev)
-                                       netif_carrier_off(card->dev);
+                               netif_carrier_off(card->dev);
                                return NULL;
                        case IPA_CMD_STARTLAN:
                                dev_info(&card->gdev->dev,
                }
                if (card->info.initial_mtu && (card->info.initial_mtu != mtu)) {
                        /* frame size has changed */
-                       if (card->dev &&
-                           ((card->dev->mtu == card->info.initial_mtu) ||
-                            (card->dev->mtu > mtu)))
+                       if ((card->dev->mtu == card->info.initial_mtu) ||
+                           (card->dev->mtu > mtu))
                                card->dev->mtu = mtu;
                        qeth_free_qdio_buffers(card);
                }
 {
        struct qeth_card *card = (struct qeth_card *)card_ptr;
 
-       if (card->dev && (card->dev->flags & IFF_UP))
+       if (card->dev->flags & IFF_UP)
                napi_schedule(&card->napi);
 }
 
 
        QETH_DBF_TEXT(SETUP, 2, "vmreqmac");
 
-       if (!card->dev)
-               return -ENODEV;
-
        request = kzalloc(sizeof(*request), GFP_KERNEL | GFP_DMA);
        response = kzalloc(sizeof(*response), GFP_KERNEL | GFP_DMA);
        if (!request || !response) {
        mutex_unlock(&qeth_dbf_list_mutex);
 }
 
+static struct net_device *qeth_alloc_netdev(struct qeth_card *card)
+{
+       struct net_device *dev;
+
+       switch (card->info.type) {
+       case QETH_CARD_TYPE_IQD:
+               dev = alloc_netdev(0, "hsi%d", NET_NAME_UNKNOWN, ether_setup);
+               break;
+       case QETH_CARD_TYPE_OSN:
+               dev = alloc_netdev(0, "osn%d", NET_NAME_UNKNOWN, ether_setup);
+               break;
+       default:
+               dev = alloc_etherdev(0);
+       }
+
+       if (!dev)
+               return NULL;
+
+       dev->ml_priv = card;
+       dev->watchdog_timeo = QETH_TX_TIMEOUT;
+       dev->min_mtu = 64;
+       dev->max_mtu = ETH_MAX_MTU;
+       SET_NETDEV_DEV(dev, &card->gdev->dev);
+       netif_carrier_off(dev);
+       return dev;
+}
+
+struct net_device *qeth_clone_netdev(struct net_device *orig)
+{
+       struct net_device *clone = qeth_alloc_netdev(orig->ml_priv);
+
+       if (!clone)
+               return NULL;
+
+       clone->dev_port = orig->dev_port;
+       return clone;
+}
+
 static int qeth_core_probe_device(struct ccwgroup_device *gdev)
 {
        struct qeth_card *card;
                goto err_card;
        }
 
+       card->dev = qeth_alloc_netdev(card);
+       if (!card->dev)
+               goto err_card;
+
        qeth_determine_capabilities(card);
        enforced_disc = qeth_enforce_discipline(card);
        switch (enforced_disc) {
                card->info.layer_enforced = true;
                rc = qeth_core_load_discipline(card, enforced_disc);
                if (rc)
-                       goto err_card;
+                       goto err_load;
 
                gdev->dev.type = (card->info.type != QETH_CARD_TYPE_OSN)
                                        ? card->discipline->devtype
 
 err_disc:
        qeth_core_free_discipline(card);
+err_load:
+       free_netdev(card->dev);
 err_card:
        qeth_core_free_card(card);
 err_dev:
        write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
        list_del(&card->list);
        write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
+       free_netdev(card->dev);
        qeth_core_free_card(card);
        dev_set_drvdata(&gdev->dev, NULL);
        put_device(&gdev->dev);
-       return;
 }
 
 static int qeth_core_set_online(struct ccwgroup_device *gdev)
 
                goto out;
        }
        card->info.portno = portno;
-       if (card->dev)
-               card->dev->dev_port = portno;
+       card->dev->dev_port = portno;
 out:
        mutex_unlock(&card->conf_mutex);
        return rc ? rc : count;
                struct device_attribute *attr, const char *buf, size_t count)
 {
        struct qeth_card *card = dev_get_drvdata(dev);
+       struct net_device *ndev;
        char *tmp;
        int i, rc = 0;
        enum qeth_discipline_id newdis;
 
        card->info.mac_bits = 0;
        if (card->discipline) {
+               /* start with a new, pristine netdevice: */
+               ndev = qeth_clone_netdev(card->dev);
+               if (!ndev) {
+                       rc = -ENOMEM;
+                       goto out;
+               }
+
                card->discipline->remove(card->gdev);
                qeth_core_free_discipline(card);
                card->options.layer2 = -1;
+
+               free_netdev(card->dev);
+               card->dev = ndev;
        }
 
        rc = qeth_core_load_discipline(card, newdis);
 
 
        if (cgdev->state == CCWGROUP_ONLINE)
                qeth_l2_set_offline(cgdev);
-
-       if (card->dev) {
-               unregister_netdev(card->dev);
-               free_netdev(card->dev);
-               card->dev = NULL;
-       }
-       return;
+       unregister_netdev(card->dev);
 }
 
 static const struct ethtool_ops qeth_l2_ethtool_ops = {
 
 static int qeth_l2_setup_netdev(struct qeth_card *card)
 {
-       switch (card->info.type) {
-       case QETH_CARD_TYPE_IQD:
-               card->dev = alloc_netdev(0, "hsi%d", NET_NAME_UNKNOWN,
-                                        ether_setup);
-               break;
-       case QETH_CARD_TYPE_OSN:
-               card->dev = alloc_netdev(0, "osn%d", NET_NAME_UNKNOWN,
-                                        ether_setup);
-               break;
-       default:
-               card->dev = alloc_etherdev(0);
-       }
+       int rc;
 
-       if (!card->dev)
-               return -ENODEV;
+       if (card->dev->netdev_ops)
+               return 0;
 
-       card->dev->ml_priv = card;
        card->dev->priv_flags |= IFF_UNICAST_FLT;
-       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->netdev_ops = &qeth_l2_netdev_ops;
        if (card->info.type == QETH_CARD_TYPE_OSN) {
                card->dev->ethtool_ops = &qeth_l2_osn_ops;
                card->dev->vlan_features |= NETIF_F_RXCSUM;
        }
 
-       card->info.broadcast_capable = 1;
        qeth_l2_request_initial_mac(card);
-       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);
+       if (rc)
+               card->dev->netdev_ops = NULL;
+       return rc;
 }
 
 static int qeth_l2_start_ipassists(struct qeth_card *card)
                dev_info(&card->gdev->dev,
                "The device represents a Bridge Capable Port\n");
 
-       if (!card->dev && qeth_l2_setup_netdev(card)) {
-               rc = -ENODEV;
+       rc = qeth_l2_setup_netdev(card);
+       if (rc)
                goto out_remove;
-       }
 
        if (card->info.type != QETH_CARD_TYPE_OSN &&
            !qeth_l2_send_setmac(card, card->dev->dev_addr))
        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);
 {
        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)
                rc = __qeth_l2_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");
 
 {
        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) ||
                        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*/
                        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;
                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 = {
        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)
                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 &&
        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);
 {
        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)
                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");
 
        if (strlen(tmp) == 0) {
                /* delete ip address only */
                card->options.hsuid[0] = '\0';
-               if (card->dev)
-                       memcpy(card->dev->perm_addr, card->options.hsuid, 9);
+               memcpy(card->dev->perm_addr, card->options.hsuid, 9);
                qeth_configure_cq(card, QETH_CQ_DISABLED);
                return count;
        }
        snprintf(card->options.hsuid, sizeof(card->options.hsuid),
                 "%-8s", tmp);
        ASCEBC(card->options.hsuid, 8);
-       if (card->dev)
-               memcpy(card->dev->perm_addr, card->options.hsuid, 9);
+       memcpy(card->dev->perm_addr, card->options.hsuid, 9);
 
        rc = qeth_l3_modify_hsuid(card, true);