diff options
Diffstat (limited to 'drivers/s390/net/qeth_l2_main.c')
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 45 |
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 | ||
205 | static void qeth_l2_del_all_mc(struct qeth_card *card) | 205 | static 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 | ||
291 | static void qeth_l2_process_vlans(struct qeth_card *card, int clear) | 293 | static 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 | ||
1078 | out_remove: | 1064 | out_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); |