Skip to content

Commit d3d1b20

Browse files
julianwiedmanndavem330
authored andcommitted
s390/qeth: allocate netdevice early
Allocation of the netdevice is currently delayed until a qeth card first goes online. This complicates matters in several places, where we need to cache values instead of applying them straight to the netdevice. Improve on this by moving the allocation up to where the qeth card itself is created. This is also one step in direction of eventually placing the qeth card into netdev_priv(). In all subsequent code, remove the now redundant checks whether card->dev is valid. Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent addc5ee commit d3d1b20

File tree

6 files changed

+94
-88
lines changed

6 files changed

+94
-88
lines changed

drivers/s390/net/qeth_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,7 @@ extern struct qeth_card_list_struct qeth_core_card_list;
966966
extern struct kmem_cache *qeth_core_header_cache;
967967
extern struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS];
968968

969+
struct net_device *qeth_clone_netdev(struct net_device *orig);
969970
void qeth_set_recovery_task(struct qeth_card *);
970971
void qeth_clear_recovery_task(struct qeth_card *);
971972
void qeth_set_allowed_threads(struct qeth_card *, unsigned long , int);

drivers/s390/net/qeth_core_main.c

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -653,8 +653,7 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
653653
cmd->hdr.return_code, card);
654654
}
655655
card->lan_online = 0;
656-
if (card->dev)
657-
netif_carrier_off(card->dev);
656+
netif_carrier_off(card->dev);
658657
return NULL;
659658
case IPA_CMD_STARTLAN:
660659
dev_info(&card->gdev->dev,
@@ -2350,9 +2349,8 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
23502349
}
23512350
if (card->info.initial_mtu && (card->info.initial_mtu != mtu)) {
23522351
/* frame size has changed */
2353-
if (card->dev &&
2354-
((card->dev->mtu == card->info.initial_mtu) ||
2355-
(card->dev->mtu > mtu)))
2352+
if ((card->dev->mtu == card->info.initial_mtu) ||
2353+
(card->dev->mtu > mtu))
23562354
card->dev->mtu = mtu;
23572355
qeth_free_qdio_buffers(card);
23582356
}
@@ -3578,7 +3576,7 @@ static void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
35783576
{
35793577
struct qeth_card *card = (struct qeth_card *)card_ptr;
35803578

3581-
if (card->dev && (card->dev->flags & IFF_UP))
3579+
if (card->dev->flags & IFF_UP)
35823580
napi_schedule(&card->napi);
35833581
}
35843582

@@ -4794,9 +4792,6 @@ int qeth_vm_request_mac(struct qeth_card *card)
47944792

47954793
QETH_DBF_TEXT(SETUP, 2, "vmreqmac");
47964794

4797-
if (!card->dev)
4798-
return -ENODEV;
4799-
48004795
request = kzalloc(sizeof(*request), GFP_KERNEL | GFP_DMA);
48014796
response = kzalloc(sizeof(*response), GFP_KERNEL | GFP_DMA);
48024797
if (!request || !response) {
@@ -5676,6 +5671,44 @@ static void qeth_clear_dbf_list(void)
56765671
mutex_unlock(&qeth_dbf_list_mutex);
56775672
}
56785673

5674+
static struct net_device *qeth_alloc_netdev(struct qeth_card *card)
5675+
{
5676+
struct net_device *dev;
5677+
5678+
switch (card->info.type) {
5679+
case QETH_CARD_TYPE_IQD:
5680+
dev = alloc_netdev(0, "hsi%d", NET_NAME_UNKNOWN, ether_setup);
5681+
break;
5682+
case QETH_CARD_TYPE_OSN:
5683+
dev = alloc_netdev(0, "osn%d", NET_NAME_UNKNOWN, ether_setup);
5684+
break;
5685+
default:
5686+
dev = alloc_etherdev(0);
5687+
}
5688+
5689+
if (!dev)
5690+
return NULL;
5691+
5692+
dev->ml_priv = card;
5693+
dev->watchdog_timeo = QETH_TX_TIMEOUT;
5694+
dev->min_mtu = 64;
5695+
dev->max_mtu = ETH_MAX_MTU;
5696+
SET_NETDEV_DEV(dev, &card->gdev->dev);
5697+
netif_carrier_off(dev);
5698+
return dev;
5699+
}
5700+
5701+
struct net_device *qeth_clone_netdev(struct net_device *orig)
5702+
{
5703+
struct net_device *clone = qeth_alloc_netdev(orig->ml_priv);
5704+
5705+
if (!clone)
5706+
return NULL;
5707+
5708+
clone->dev_port = orig->dev_port;
5709+
return clone;
5710+
}
5711+
56795712
static int qeth_core_probe_device(struct ccwgroup_device *gdev)
56805713
{
56815714
struct qeth_card *card;
@@ -5725,6 +5758,10 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
57255758
goto err_card;
57265759
}
57275760

5761+
card->dev = qeth_alloc_netdev(card);
5762+
if (!card->dev)
5763+
goto err_card;
5764+
57285765
qeth_determine_capabilities(card);
57295766
enforced_disc = qeth_enforce_discipline(card);
57305767
switch (enforced_disc) {
@@ -5735,7 +5772,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
57355772
card->info.layer_enforced = true;
57365773
rc = qeth_core_load_discipline(card, enforced_disc);
57375774
if (rc)
5738-
goto err_card;
5775+
goto err_load;
57395776

57405777
gdev->dev.type = (card->info.type != QETH_CARD_TYPE_OSN)
57415778
? card->discipline->devtype
@@ -5753,6 +5790,8 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
57535790

57545791
err_disc:
57555792
qeth_core_free_discipline(card);
5793+
err_load:
5794+
free_netdev(card->dev);
57565795
err_card:
57575796
qeth_core_free_card(card);
57585797
err_dev:
@@ -5775,10 +5814,10 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
57755814
write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
57765815
list_del(&card->list);
57775816
write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
5817+
free_netdev(card->dev);
57785818
qeth_core_free_card(card);
57795819
dev_set_drvdata(&gdev->dev, NULL);
57805820
put_device(&gdev->dev);
5781-
return;
57825821
}
57835822

57845823
static int qeth_core_set_online(struct ccwgroup_device *gdev)

drivers/s390/net/qeth_core_sys.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,7 @@ static ssize_t qeth_dev_portno_store(struct device *dev,
144144
goto out;
145145
}
146146
card->info.portno = portno;
147-
if (card->dev)
148-
card->dev->dev_port = portno;
147+
card->dev->dev_port = portno;
149148
out:
150149
mutex_unlock(&card->conf_mutex);
151150
return rc ? rc : count;
@@ -388,6 +387,7 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
388387
struct device_attribute *attr, const char *buf, size_t count)
389388
{
390389
struct qeth_card *card = dev_get_drvdata(dev);
390+
struct net_device *ndev;
391391
char *tmp;
392392
int i, rc = 0;
393393
enum qeth_discipline_id newdis;
@@ -424,9 +424,19 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
424424

425425
card->info.mac_bits = 0;
426426
if (card->discipline) {
427+
/* start with a new, pristine netdevice: */
428+
ndev = qeth_clone_netdev(card->dev);
429+
if (!ndev) {
430+
rc = -ENOMEM;
431+
goto out;
432+
}
433+
427434
card->discipline->remove(card->gdev);
428435
qeth_core_free_discipline(card);
429436
card->options.layer2 = -1;
437+
438+
free_netdev(card->dev);
439+
card->dev = ndev;
430440
}
431441

432442
rc = qeth_core_load_discipline(card, newdis);

drivers/s390/net/qeth_l2_main.c

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -899,13 +899,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
899899

900900
if (cgdev->state == CCWGROUP_ONLINE)
901901
qeth_l2_set_offline(cgdev);
902-
903-
if (card->dev) {
904-
unregister_netdev(card->dev);
905-
free_netdev(card->dev);
906-
card->dev = NULL;
907-
}
908-
return;
902+
unregister_netdev(card->dev);
909903
}
910904

911905
static const struct ethtool_ops qeth_l2_ethtool_ops = {
@@ -944,29 +938,13 @@ static const struct net_device_ops qeth_l2_netdev_ops = {
944938

945939
static int qeth_l2_setup_netdev(struct qeth_card *card)
946940
{
947-
switch (card->info.type) {
948-
case QETH_CARD_TYPE_IQD:
949-
card->dev = alloc_netdev(0, "hsi%d", NET_NAME_UNKNOWN,
950-
ether_setup);
951-
break;
952-
case QETH_CARD_TYPE_OSN:
953-
card->dev = alloc_netdev(0, "osn%d", NET_NAME_UNKNOWN,
954-
ether_setup);
955-
break;
956-
default:
957-
card->dev = alloc_etherdev(0);
958-
}
941+
int rc;
959942

960-
if (!card->dev)
961-
return -ENODEV;
943+
if (card->dev->netdev_ops)
944+
return 0;
962945

963-
card->dev->ml_priv = card;
964946
card->dev->priv_flags |= IFF_UNICAST_FLT;
965-
card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
966947
card->dev->mtu = card->info.initial_mtu;
967-
card->dev->min_mtu = 64;
968-
card->dev->max_mtu = ETH_MAX_MTU;
969-
card->dev->dev_port = card->info.portno;
970948
card->dev->netdev_ops = &qeth_l2_netdev_ops;
971949
if (card->info.type == QETH_CARD_TYPE_OSN) {
972950
card->dev->ethtool_ops = &qeth_l2_osn_ops;
@@ -1006,12 +984,12 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
1006984
card->dev->vlan_features |= NETIF_F_RXCSUM;
1007985
}
1008986

1009-
card->info.broadcast_capable = 1;
1010987
qeth_l2_request_initial_mac(card);
1011-
SET_NETDEV_DEV(card->dev, &card->gdev->dev);
1012988
netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
1013-
netif_carrier_off(card->dev);
1014-
return register_netdev(card->dev);
989+
rc = register_netdev(card->dev);
990+
if (rc)
991+
card->dev->netdev_ops = NULL;
992+
return rc;
1015993
}
1016994

1017995
static int qeth_l2_start_ipassists(struct qeth_card *card)
@@ -1057,10 +1035,9 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
10571035
dev_info(&card->gdev->dev,
10581036
"The device represents a Bridge Capable Port\n");
10591037

1060-
if (!card->dev && qeth_l2_setup_netdev(card)) {
1061-
rc = -ENODEV;
1038+
rc = qeth_l2_setup_netdev(card);
1039+
if (rc)
10621040
goto out_remove;
1063-
}
10641041

10651042
if (card->info.type != QETH_CARD_TYPE_OSN &&
10661043
!qeth_l2_send_setmac(card, card->dev->dev_addr))
@@ -1163,8 +1140,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev,
11631140
QETH_DBF_TEXT(SETUP, 3, "setoffl");
11641141
QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *));
11651142

1166-
if (card->dev)
1167-
netif_carrier_off(card->dev);
1143+
netif_carrier_off(card->dev);
11681144
recover_flag = card->state;
11691145
if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
11701146
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
@@ -1237,8 +1213,7 @@ static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev)
12371213
{
12381214
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
12391215

1240-
if (card->dev)
1241-
netif_device_detach(card->dev);
1216+
netif_device_detach(card->dev);
12421217
qeth_set_allowed_threads(card, 0, 1);
12431218
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
12441219
if (gdev->state == CCWGROUP_OFFLINE)
@@ -1271,8 +1246,7 @@ static int qeth_l2_pm_resume(struct ccwgroup_device *gdev)
12711246
rc = __qeth_l2_set_online(card->gdev, 0);
12721247
out:
12731248
qeth_set_allowed_threads(card, 0xffffffff, 0);
1274-
if (card->dev)
1275-
netif_device_attach(card->dev);
1249+
netif_device_attach(card->dev);
12761250
if (rc)
12771251
dev_warn(&card->gdev->dev, "The qeth device driver "
12781252
"failed to recover an error on the device\n");

0 commit comments

Comments
 (0)