aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/net/qeth_l2_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/net/qeth_l2_main.c')
-rw-r--r--drivers/s390/net/qeth_l2_main.c45
1 files changed, 14 insertions, 31 deletions
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index ada0fe782373..6fbaacb21943 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -202,17 +202,19 @@ static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac)
202 kfree(mc); 202 kfree(mc);
203} 203}
204 204
205static void qeth_l2_del_all_mc(struct qeth_card *card) 205static void qeth_l2_del_all_mc(struct qeth_card *card, int del)
206{ 206{
207 struct qeth_mc_mac *mc, *tmp; 207 struct qeth_mc_mac *mc, *tmp;
208 208
209 spin_lock_bh(&card->mclock); 209 spin_lock_bh(&card->mclock);
210 list_for_each_entry_safe(mc, tmp, &card->mc_list, list) { 210 list_for_each_entry_safe(mc, tmp, &card->mc_list, list) {
211 if (mc->is_vmac) 211 if (del) {
212 qeth_l2_send_setdelmac(card, mc->mc_addr, 212 if (mc->is_vmac)
213 qeth_l2_send_setdelmac(card, mc->mc_addr,
213 IPA_CMD_DELVMAC, NULL); 214 IPA_CMD_DELVMAC, NULL);
214 else 215 else
215 qeth_l2_send_delgroupmac(card, mc->mc_addr); 216 qeth_l2_send_delgroupmac(card, mc->mc_addr);
217 }
216 list_del(&mc->list); 218 list_del(&mc->list);
217 kfree(mc); 219 kfree(mc);
218 } 220 }
@@ -288,18 +290,13 @@ static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i,
288 qeth_l2_send_setdelvlan_cb, NULL); 290 qeth_l2_send_setdelvlan_cb, NULL);
289} 291}
290 292
291static void qeth_l2_process_vlans(struct qeth_card *card, int clear) 293static void qeth_l2_process_vlans(struct qeth_card *card)
292{ 294{
293 struct qeth_vlan_vid *id; 295 struct qeth_vlan_vid *id;
294 QETH_CARD_TEXT(card, 3, "L2prcvln"); 296 QETH_CARD_TEXT(card, 3, "L2prcvln");
295 spin_lock_bh(&card->vlanlock); 297 spin_lock_bh(&card->vlanlock);
296 list_for_each_entry(id, &card->vid_list, list) { 298 list_for_each_entry(id, &card->vid_list, list) {
297 if (clear) 299 qeth_l2_send_setdelvlan(card, id->vid, IPA_CMD_SETVLAN);
298 qeth_l2_send_setdelvlan(card, id->vid,
299 IPA_CMD_DELVLAN);
300 else
301 qeth_l2_send_setdelvlan(card, id->vid,
302 IPA_CMD_SETVLAN);
303 } 300 }
304 spin_unlock_bh(&card->vlanlock); 301 spin_unlock_bh(&card->vlanlock);
305} 302}
@@ -379,19 +376,11 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
379 dev_close(card->dev); 376 dev_close(card->dev);
380 rtnl_unlock(); 377 rtnl_unlock();
381 } 378 }
382 if (!card->use_hard_stop || 379 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
383 recovery_mode) {
384 __u8 *mac = &card->dev->dev_addr[0];
385 rc = qeth_l2_send_delmac(card, mac);
386 QETH_DBF_TEXT_(SETUP, 2, "Lerr%d", rc);
387 }
388 card->state = CARD_STATE_SOFTSETUP; 380 card->state = CARD_STATE_SOFTSETUP;
389 } 381 }
390 if (card->state == CARD_STATE_SOFTSETUP) { 382 if (card->state == CARD_STATE_SOFTSETUP) {
391 qeth_l2_process_vlans(card, 1); 383 qeth_l2_del_all_mc(card, 0);
392 if (!card->use_hard_stop ||
393 recovery_mode)
394 qeth_l2_del_all_mc(card);
395 qeth_clear_ipacmd_list(card); 384 qeth_clear_ipacmd_list(card);
396 card->state = CARD_STATE_HARDSETUP; 385 card->state = CARD_STATE_HARDSETUP;
397 } 386 }
@@ -405,7 +394,6 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
405 qeth_clear_cmd_buffers(&card->read); 394 qeth_clear_cmd_buffers(&card->read);
406 qeth_clear_cmd_buffers(&card->write); 395 qeth_clear_cmd_buffers(&card->write);
407 } 396 }
408 card->use_hard_stop = 0;
409 return rc; 397 return rc;
410} 398}
411 399
@@ -705,7 +693,7 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
705 if (qeth_threads_running(card, QETH_RECOVER_THREAD) && 693 if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
706 (card->state != CARD_STATE_UP)) 694 (card->state != CARD_STATE_UP))
707 return; 695 return;
708 qeth_l2_del_all_mc(card); 696 qeth_l2_del_all_mc(card, 1);
709 spin_lock_bh(&card->mclock); 697 spin_lock_bh(&card->mclock);
710 netdev_for_each_mc_addr(ha, dev) 698 netdev_for_each_mc_addr(ha, dev)
711 qeth_l2_add_mc(card, ha->addr, 0); 699 qeth_l2_add_mc(card, ha->addr, 0);
@@ -907,10 +895,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
907 qeth_set_allowed_threads(card, 0, 1); 895 qeth_set_allowed_threads(card, 0, 1);
908 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); 896 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
909 897
910 if (cgdev->state == CCWGROUP_ONLINE) { 898 if (cgdev->state == CCWGROUP_ONLINE)
911 card->use_hard_stop = 1;
912 qeth_l2_set_offline(cgdev); 899 qeth_l2_set_offline(cgdev);
913 }
914 900
915 if (card->dev) { 901 if (card->dev) {
916 unregister_netdev(card->dev); 902 unregister_netdev(card->dev);
@@ -1040,7 +1026,7 @@ contin:
1040 1026
1041 if (card->info.type != QETH_CARD_TYPE_OSN && 1027 if (card->info.type != QETH_CARD_TYPE_OSN &&
1042 card->info.type != QETH_CARD_TYPE_OSM) 1028 card->info.type != QETH_CARD_TYPE_OSM)
1043 qeth_l2_process_vlans(card, 0); 1029 qeth_l2_process_vlans(card);
1044 1030
1045 netif_tx_disable(card->dev); 1031 netif_tx_disable(card->dev);
1046 1032
@@ -1076,7 +1062,6 @@ contin:
1076 return 0; 1062 return 0;
1077 1063
1078out_remove: 1064out_remove:
1079 card->use_hard_stop = 1;
1080 qeth_l2_stop_card(card, 0); 1065 qeth_l2_stop_card(card, 0);
1081 ccw_device_set_offline(CARD_DDEV(card)); 1066 ccw_device_set_offline(CARD_DDEV(card));
1082 ccw_device_set_offline(CARD_WDEV(card)); 1067 ccw_device_set_offline(CARD_WDEV(card));
@@ -1144,7 +1129,6 @@ static int qeth_l2_recover(void *ptr)
1144 QETH_CARD_TEXT(card, 2, "recover2"); 1129 QETH_CARD_TEXT(card, 2, "recover2");
1145 dev_warn(&card->gdev->dev, 1130 dev_warn(&card->gdev->dev,
1146 "A recovery process has been started for the device\n"); 1131 "A recovery process has been started for the device\n");
1147 card->use_hard_stop = 1;
1148 __qeth_l2_set_offline(card->gdev, 1); 1132 __qeth_l2_set_offline(card->gdev, 1);
1149 rc = __qeth_l2_set_online(card->gdev, 1); 1133 rc = __qeth_l2_set_online(card->gdev, 1);
1150 if (!rc) 1134 if (!rc)
@@ -1191,7 +1175,6 @@ static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev)
1191 if (gdev->state == CCWGROUP_OFFLINE) 1175 if (gdev->state == CCWGROUP_OFFLINE)
1192 return 0; 1176 return 0;
1193 if (card->state == CARD_STATE_UP) { 1177 if (card->state == CARD_STATE_UP) {
1194 card->use_hard_stop = 1;
1195 __qeth_l2_set_offline(card->gdev, 1); 1178 __qeth_l2_set_offline(card->gdev, 1);
1196 } else 1179 } else
1197 __qeth_l2_set_offline(card->gdev, 0); 1180 __qeth_l2_set_offline(card->gdev, 0);