aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorStefan Raspl <raspl@linux.vnet.ibm.com>2013-01-20 21:30:20 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-21 13:51:14 -0500
commit0f54761d167f98dd93cb19a16edbc47bb6574a28 (patch)
tree8168f8df9a334bd636721f937d6a8c6fd959a7e8 /drivers/s390
parenteb3fb0baa2369595fa5cbfadc16f87f99a71ce4b (diff)
qeth: Support VEPA mode
The existing port isolation mode 'forward' will now verify that the adjacent switch port supports the required reflective relay (RR) mode. This patch adds the required error handling for the cases where enabling port isolation mode 'forward' can now fail. Furthermore, once established, we never fall back from one of the port isolation modes to a non-isolated mode without further user-interaction. This includes cases where the isolation mode was enabled successfully, but ceases to work e.g. due to configuration changes at the switch port. Finally, configuring an isolation mode with the device being offline will make onlining the device fail permanently upon errors encountered until either errors are resolved or the isolation mode is changed by the user to a different mode. Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com> Reviewed-by: Ursula Braun <ursula.braun@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/net/qeth_core.h5
-rw-r--r--drivers/s390/net/qeth_core_main.c135
-rw-r--r--drivers/s390/net/qeth_core_mpc.c1
-rw-r--r--drivers/s390/net/qeth_core_mpc.h5
-rw-r--r--drivers/s390/net/qeth_core_sys.c3
-rw-r--r--drivers/s390/net/qeth_l2_main.c16
-rw-r--r--drivers/s390/net/qeth_l3_main.c14
7 files changed, 112 insertions, 67 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 7f526bf1ecea..d690b33846cc 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -678,6 +678,7 @@ struct qeth_card_options {
678 int performance_stats; 678 int performance_stats;
679 int rx_sg_cb; 679 int rx_sg_cb;
680 enum qeth_ipa_isolation_modes isolation; 680 enum qeth_ipa_isolation_modes isolation;
681 enum qeth_ipa_isolation_modes prev_isolation;
681 int sniffer; 682 int sniffer;
682 enum qeth_cq cq; 683 enum qeth_cq cq;
683 char hsuid[9]; 684 char hsuid[9];
@@ -789,6 +790,7 @@ struct qeth_card {
789 struct qeth_rx rx; 790 struct qeth_rx rx;
790 struct delayed_work buffer_reclaim_work; 791 struct delayed_work buffer_reclaim_work;
791 int reclaim_index; 792 int reclaim_index;
793 struct work_struct close_dev_work;
792}; 794};
793 795
794struct qeth_card_list_struct { 796struct qeth_card_list_struct {
@@ -925,12 +927,13 @@ void qeth_core_get_strings(struct net_device *, u32, u8 *);
925void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); 927void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
926void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...); 928void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...);
927int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *); 929int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *);
928int qeth_set_access_ctrl_online(struct qeth_card *card); 930int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback);
929int qeth_hdr_chk_and_bounce(struct sk_buff *, int); 931int qeth_hdr_chk_and_bounce(struct sk_buff *, int);
930int qeth_configure_cq(struct qeth_card *, enum qeth_cq); 932int qeth_configure_cq(struct qeth_card *, enum qeth_cq);
931int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action); 933int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
932int qeth_query_ipassists(struct qeth_card *, enum qeth_prot_versions prot); 934int qeth_query_ipassists(struct qeth_card *, enum qeth_prot_versions prot);
933void qeth_trace_features(struct qeth_card *); 935void qeth_trace_features(struct qeth_card *);
936void qeth_close_dev(struct qeth_card *);
934 937
935/* exports for OSN */ 938/* exports for OSN */
936int qeth_osn_assist(struct net_device *, void *, int); 939int qeth_osn_assist(struct net_device *, void *, int);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index db077c48a8b7..1cccbad69cd4 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -68,6 +68,27 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
68 enum qeth_qdio_buffer_states newbufstate); 68 enum qeth_qdio_buffer_states newbufstate);
69static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int); 69static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int);
70 70
71static struct workqueue_struct *qeth_wq;
72
73static void qeth_close_dev_handler(struct work_struct *work)
74{
75 struct qeth_card *card;
76
77 card = container_of(work, struct qeth_card, close_dev_work);
78 QETH_CARD_TEXT(card, 2, "cldevhdl");
79 rtnl_lock();
80 dev_close(card->dev);
81 rtnl_unlock();
82 ccwgroup_set_offline(card->gdev);
83}
84
85void qeth_close_dev(struct qeth_card *card)
86{
87 QETH_CARD_TEXT(card, 2, "cldevsubm");
88 queue_work(qeth_wq, &card->close_dev_work);
89}
90EXPORT_SYMBOL_GPL(qeth_close_dev);
91
71static inline const char *qeth_get_cardname(struct qeth_card *card) 92static inline const char *qeth_get_cardname(struct qeth_card *card)
72{ 93{
73 if (card->info.guestlan) { 94 if (card->info.guestlan) {
@@ -542,11 +563,23 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
542 } else { 563 } else {
543 switch (cmd->hdr.command) { 564 switch (cmd->hdr.command) {
544 case IPA_CMD_STOPLAN: 565 case IPA_CMD_STOPLAN:
545 dev_warn(&card->gdev->dev, 566 if (cmd->hdr.return_code ==
567 IPA_RC_VEPA_TO_VEB_TRANSITION) {
568 dev_err(&card->gdev->dev,
569 "Interface %s is down because the "
570 "adjacent port is no longer in "
571 "reflective relay mode\n",
572 QETH_CARD_IFNAME(card));
573 qeth_close_dev(card);
574 } else {
575 dev_warn(&card->gdev->dev,
546 "The link for interface %s on CHPID" 576 "The link for interface %s on CHPID"
547 " 0x%X failed\n", 577 " 0x%X failed\n",
548 QETH_CARD_IFNAME(card), 578 QETH_CARD_IFNAME(card),
549 card->info.chpid); 579 card->info.chpid);
580 qeth_issue_ipa_msg(cmd,
581 cmd->hdr.return_code, card);
582 }
550 card->lan_online = 0; 583 card->lan_online = 0;
551 if (card->dev && netif_carrier_ok(card->dev)) 584 if (card->dev && netif_carrier_ok(card->dev))
552 netif_carrier_off(card->dev); 585 netif_carrier_off(card->dev);
@@ -1416,6 +1449,7 @@ static int qeth_setup_card(struct qeth_card *card)
1416 /* init QDIO stuff */ 1449 /* init QDIO stuff */
1417 qeth_init_qdio_info(card); 1450 qeth_init_qdio_info(card);
1418 INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work); 1451 INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work);
1452 INIT_WORK(&card->close_dev_work, qeth_close_dev_handler);
1419 return 0; 1453 return 0;
1420} 1454}
1421 1455
@@ -4057,6 +4091,7 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
4057{ 4091{
4058 struct qeth_ipa_cmd *cmd; 4092 struct qeth_ipa_cmd *cmd;
4059 struct qeth_set_access_ctrl *access_ctrl_req; 4093 struct qeth_set_access_ctrl *access_ctrl_req;
4094 int fallback = *(int *)reply->param;
4060 4095
4061 QETH_CARD_TEXT(card, 4, "setaccb"); 4096 QETH_CARD_TEXT(card, 4, "setaccb");
4062 4097
@@ -4066,12 +4101,14 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
4066 QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name); 4101 QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
4067 QETH_DBF_TEXT_(SETUP, 2, "rc=%d", 4102 QETH_DBF_TEXT_(SETUP, 2, "rc=%d",
4068 cmd->data.setadapterparms.hdr.return_code); 4103 cmd->data.setadapterparms.hdr.return_code);
4104 if (cmd->data.setadapterparms.hdr.return_code !=
4105 SET_ACCESS_CTRL_RC_SUCCESS)
4106 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%s,%d)==%d\n",
4107 card->gdev->dev.kobj.name,
4108 access_ctrl_req->subcmd_code,
4109 cmd->data.setadapterparms.hdr.return_code);
4069 switch (cmd->data.setadapterparms.hdr.return_code) { 4110 switch (cmd->data.setadapterparms.hdr.return_code) {
4070 case SET_ACCESS_CTRL_RC_SUCCESS: 4111 case SET_ACCESS_CTRL_RC_SUCCESS:
4071 case SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED:
4072 case SET_ACCESS_CTRL_RC_ALREADY_ISOLATED:
4073 {
4074 card->options.isolation = access_ctrl_req->subcmd_code;
4075 if (card->options.isolation == ISOLATION_MODE_NONE) { 4112 if (card->options.isolation == ISOLATION_MODE_NONE) {
4076 dev_info(&card->gdev->dev, 4113 dev_info(&card->gdev->dev,
4077 "QDIO data connection isolation is deactivated\n"); 4114 "QDIO data connection isolation is deactivated\n");
@@ -4079,72 +4116,64 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
4079 dev_info(&card->gdev->dev, 4116 dev_info(&card->gdev->dev,
4080 "QDIO data connection isolation is activated\n"); 4117 "QDIO data connection isolation is activated\n");
4081 } 4118 }
4082 QETH_DBF_MESSAGE(3, "OK:SET_ACCESS_CTRL(%s, %d)==%d\n",
4083 card->gdev->dev.kobj.name,
4084 access_ctrl_req->subcmd_code,
4085 cmd->data.setadapterparms.hdr.return_code);
4086 break; 4119 break;
4087 } 4120 case SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED:
4121 QETH_DBF_MESSAGE(2, "%s QDIO data connection isolation already "
4122 "deactivated\n", dev_name(&card->gdev->dev));
4123 if (fallback)
4124 card->options.isolation = card->options.prev_isolation;
4125 break;
4126 case SET_ACCESS_CTRL_RC_ALREADY_ISOLATED:
4127 QETH_DBF_MESSAGE(2, "%s QDIO data connection isolation already"
4128 " activated\n", dev_name(&card->gdev->dev));
4129 if (fallback)
4130 card->options.isolation = card->options.prev_isolation;
4131 break;
4088 case SET_ACCESS_CTRL_RC_NOT_SUPPORTED: 4132 case SET_ACCESS_CTRL_RC_NOT_SUPPORTED:
4089 {
4090 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%s,%d)==%d\n",
4091 card->gdev->dev.kobj.name,
4092 access_ctrl_req->subcmd_code,
4093 cmd->data.setadapterparms.hdr.return_code);
4094 dev_err(&card->gdev->dev, "Adapter does not " 4133 dev_err(&card->gdev->dev, "Adapter does not "
4095 "support QDIO data connection isolation\n"); 4134 "support QDIO data connection isolation\n");
4096
4097 /* ensure isolation mode is "none" */
4098 card->options.isolation = ISOLATION_MODE_NONE;
4099 break; 4135 break;
4100 }
4101 case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER: 4136 case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER:
4102 {
4103 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
4104 card->gdev->dev.kobj.name,
4105 access_ctrl_req->subcmd_code,
4106 cmd->data.setadapterparms.hdr.return_code);
4107 dev_err(&card->gdev->dev, 4137 dev_err(&card->gdev->dev,
4108 "Adapter is dedicated. " 4138 "Adapter is dedicated. "
4109 "QDIO data connection isolation not supported\n"); 4139 "QDIO data connection isolation not supported\n");
4110 4140 if (fallback)
4111 /* ensure isolation mode is "none" */ 4141 card->options.isolation = card->options.prev_isolation;
4112 card->options.isolation = ISOLATION_MODE_NONE;
4113 break; 4142 break;
4114 }
4115 case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF: 4143 case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF:
4116 {
4117 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
4118 card->gdev->dev.kobj.name,
4119 access_ctrl_req->subcmd_code,
4120 cmd->data.setadapterparms.hdr.return_code);
4121 dev_err(&card->gdev->dev, 4144 dev_err(&card->gdev->dev,
4122 "TSO does not permit QDIO data connection isolation\n"); 4145 "TSO does not permit QDIO data connection isolation\n");
4123 4146 if (fallback)
4124 /* ensure isolation mode is "none" */ 4147 card->options.isolation = card->options.prev_isolation;
4125 card->options.isolation = ISOLATION_MODE_NONE; 4148 break;
4149 case SET_ACCESS_CTRL_RC_REFLREL_UNSUPPORTED:
4150 dev_err(&card->gdev->dev, "The adjacent switch port does not "
4151 "support reflective relay mode\n");
4152 if (fallback)
4153 card->options.isolation = card->options.prev_isolation;
4154 break;
4155 case SET_ACCESS_CTRL_RC_REFLREL_FAILED:
4156 dev_err(&card->gdev->dev, "The reflective relay mode cannot be "
4157 "enabled at the adjacent switch port");
4158 if (fallback)
4159 card->options.isolation = card->options.prev_isolation;
4160 break;
4161 case SET_ACCESS_CTRL_RC_REFLREL_DEACT_FAILED:
4162 dev_warn(&card->gdev->dev, "Turning off reflective relay mode "
4163 "at the adjacent switch failed\n");
4126 break; 4164 break;
4127 }
4128 default: 4165 default:
4129 {
4130 /* this should never happen */ 4166 /* this should never happen */
4131 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d" 4167 if (fallback)
4132 "==UNKNOWN\n", 4168 card->options.isolation = card->options.prev_isolation;
4133 card->gdev->dev.kobj.name,
4134 access_ctrl_req->subcmd_code,
4135 cmd->data.setadapterparms.hdr.return_code);
4136
4137 /* ensure isolation mode is "none" */
4138 card->options.isolation = ISOLATION_MODE_NONE;
4139 break; 4169 break;
4140 } 4170 }
4141 }
4142 qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd); 4171 qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
4143 return 0; 4172 return 0;
4144} 4173}
4145 4174
4146static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card, 4175static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
4147 enum qeth_ipa_isolation_modes isolation) 4176 enum qeth_ipa_isolation_modes isolation, int fallback)
4148{ 4177{
4149 int rc; 4178 int rc;
4150 struct qeth_cmd_buffer *iob; 4179 struct qeth_cmd_buffer *iob;
@@ -4164,12 +4193,12 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
4164 access_ctrl_req->subcmd_code = isolation; 4193 access_ctrl_req->subcmd_code = isolation;
4165 4194
4166 rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_set_access_ctrl_cb, 4195 rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_set_access_ctrl_cb,
4167 NULL); 4196 &fallback);
4168 QETH_DBF_TEXT_(SETUP, 2, "rc=%d", rc); 4197 QETH_DBF_TEXT_(SETUP, 2, "rc=%d", rc);
4169 return rc; 4198 return rc;
4170} 4199}
4171 4200
4172int qeth_set_access_ctrl_online(struct qeth_card *card) 4201int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback)
4173{ 4202{
4174 int rc = 0; 4203 int rc = 0;
4175 4204
@@ -4179,12 +4208,13 @@ int qeth_set_access_ctrl_online(struct qeth_card *card)
4179 card->info.type == QETH_CARD_TYPE_OSX) && 4208 card->info.type == QETH_CARD_TYPE_OSX) &&
4180 qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) { 4209 qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) {
4181 rc = qeth_setadpparms_set_access_ctrl(card, 4210 rc = qeth_setadpparms_set_access_ctrl(card,
4182 card->options.isolation); 4211 card->options.isolation, fallback);
4183 if (rc) { 4212 if (rc) {
4184 QETH_DBF_MESSAGE(3, 4213 QETH_DBF_MESSAGE(3,
4185 "IPA(SET_ACCESS_CTRL,%s,%d) sent failed\n", 4214 "IPA(SET_ACCESS_CTRL,%s,%d) sent failed\n",
4186 card->gdev->dev.kobj.name, 4215 card->gdev->dev.kobj.name,
4187 rc); 4216 rc);
4217 rc = -EOPNOTSUPP;
4188 } 4218 }
4189 } else if (card->options.isolation != ISOLATION_MODE_NONE) { 4219 } else if (card->options.isolation != ISOLATION_MODE_NONE) {
4190 card->options.isolation = ISOLATION_MODE_NONE; 4220 card->options.isolation = ISOLATION_MODE_NONE;
@@ -5552,6 +5582,8 @@ static int __init qeth_core_init(void)
5552 rwlock_init(&qeth_core_card_list.rwlock); 5582 rwlock_init(&qeth_core_card_list.rwlock);
5553 mutex_init(&qeth_mod_mutex); 5583 mutex_init(&qeth_mod_mutex);
5554 5584
5585 qeth_wq = create_singlethread_workqueue("qeth_wq");
5586
5555 rc = qeth_register_dbf_views(); 5587 rc = qeth_register_dbf_views();
5556 if (rc) 5588 if (rc)
5557 goto out_err; 5589 goto out_err;
@@ -5598,6 +5630,7 @@ out_err:
5598 5630
5599static void __exit qeth_core_exit(void) 5631static void __exit qeth_core_exit(void)
5600{ 5632{
5633 destroy_workqueue(qeth_wq);
5601 ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); 5634 ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
5602 ccw_driver_unregister(&qeth_ccw_driver); 5635 ccw_driver_unregister(&qeth_ccw_driver);
5603 kmem_cache_destroy(qeth_qdio_outbuf_cache); 5636 kmem_cache_destroy(qeth_qdio_outbuf_cache);
diff --git a/drivers/s390/net/qeth_core_mpc.c b/drivers/s390/net/qeth_core_mpc.c
index 5cebfddb86bd..06c55780005e 100644
--- a/drivers/s390/net/qeth_core_mpc.c
+++ b/drivers/s390/net/qeth_core_mpc.c
@@ -204,6 +204,7 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
204 {IPA_RC_INVALID_SETRTG_INDICATOR, "Invalid SETRTG indicator"}, 204 {IPA_RC_INVALID_SETRTG_INDICATOR, "Invalid SETRTG indicator"},
205 {IPA_RC_MC_ADDR_ALREADY_DEFINED, "Multicast address already defined"}, 205 {IPA_RC_MC_ADDR_ALREADY_DEFINED, "Multicast address already defined"},
206 {IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"}, 206 {IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"},
207 {IPA_RC_VEPA_TO_VEB_TRANSITION, "Adj. switch disabled port mode RR"},
207 {IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"}, 208 {IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"},
208 {IPA_RC_ENOMEM, "Memory problem"}, 209 {IPA_RC_ENOMEM, "Memory problem"},
209 {IPA_RC_FFFF, "Unknown Error"} 210 {IPA_RC_FFFF, "Unknown Error"}
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index 3690bbf2cb3c..07085d55f9a1 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -177,6 +177,7 @@ enum qeth_ipa_return_codes {
177 IPA_RC_INVALID_SETRTG_INDICATOR = 0xe012, 177 IPA_RC_INVALID_SETRTG_INDICATOR = 0xe012,
178 IPA_RC_MC_ADDR_ALREADY_DEFINED = 0xe013, 178 IPA_RC_MC_ADDR_ALREADY_DEFINED = 0xe013,
179 IPA_RC_LAN_OFFLINE = 0xe080, 179 IPA_RC_LAN_OFFLINE = 0xe080,
180 IPA_RC_VEPA_TO_VEB_TRANSITION = 0xe090,
180 IPA_RC_INVALID_IP_VERSION2 = 0xf001, 181 IPA_RC_INVALID_IP_VERSION2 = 0xf001,
181 IPA_RC_ENOMEM = 0xfffe, 182 IPA_RC_ENOMEM = 0xfffe,
182 IPA_RC_FFFF = 0xffff 183 IPA_RC_FFFF = 0xffff
@@ -269,6 +270,9 @@ enum qeth_ipa_set_access_mode_rc {
269 SET_ACCESS_CTRL_RC_ALREADY_ISOLATED = 0x0010, 270 SET_ACCESS_CTRL_RC_ALREADY_ISOLATED = 0x0010,
270 SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER = 0x0014, 271 SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER = 0x0014,
271 SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF = 0x0018, 272 SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF = 0x0018,
273 SET_ACCESS_CTRL_RC_REFLREL_UNSUPPORTED = 0x0022,
274 SET_ACCESS_CTRL_RC_REFLREL_FAILED = 0x0024,
275 SET_ACCESS_CTRL_RC_REFLREL_DEACT_FAILED = 0x0028,
272}; 276};
273 277
274 278
@@ -386,6 +390,7 @@ struct qeth_snmp_ureq {
386/* SET_ACCESS_CONTROL: same format for request and reply */ 390/* SET_ACCESS_CONTROL: same format for request and reply */
387struct qeth_set_access_ctrl { 391struct qeth_set_access_ctrl {
388 __u32 subcmd_code; 392 __u32 subcmd_code;
393 __u8 reserved[8];
389} __attribute__((packed)); 394} __attribute__((packed));
390 395
391struct qeth_query_oat { 396struct qeth_query_oat {
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 9655dc0ea0ec..425c0ecf1f3b 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -513,10 +513,11 @@ static ssize_t qeth_dev_isolation_store(struct device *dev,
513 rc = count; 513 rc = count;
514 514
515 /* defer IP assist if device is offline (until discipline->set_online)*/ 515 /* defer IP assist if device is offline (until discipline->set_online)*/
516 card->options.prev_isolation = card->options.isolation;
516 card->options.isolation = isolation; 517 card->options.isolation = isolation;
517 if (card->state == CARD_STATE_SOFTSETUP || 518 if (card->state == CARD_STATE_SOFTSETUP ||
518 card->state == CARD_STATE_UP) { 519 card->state == CARD_STATE_UP) {
519 int ipa_rc = qeth_set_access_ctrl_online(card); 520 int ipa_rc = qeth_set_access_ctrl_online(card, 1);
520 if (ipa_rc != 0) 521 if (ipa_rc != 0)
521 rc = ipa_rc; 522 rc = ipa_rc;
522 } 523 }
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 73195553f84b..d690166efeaf 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1025,9 +1025,14 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
1025 1025
1026contin: 1026contin:
1027 if ((card->info.type == QETH_CARD_TYPE_OSD) || 1027 if ((card->info.type == QETH_CARD_TYPE_OSD) ||
1028 (card->info.type == QETH_CARD_TYPE_OSX)) 1028 (card->info.type == QETH_CARD_TYPE_OSX)) {
1029 /* configure isolation level */ 1029 /* configure isolation level */
1030 qeth_set_access_ctrl_online(card); 1030 rc = qeth_set_access_ctrl_online(card, 0);
1031 if (rc) {
1032 rc = -ENODEV;
1033 goto out_remove;
1034 }
1035 }
1031 1036
1032 if (card->info.type != QETH_CARD_TYPE_OSN && 1037 if (card->info.type != QETH_CARD_TYPE_OSN &&
1033 card->info.type != QETH_CARD_TYPE_OSM) 1038 card->info.type != QETH_CARD_TYPE_OSM)
@@ -1144,12 +1149,9 @@ static int qeth_l2_recover(void *ptr)
1144 dev_info(&card->gdev->dev, 1149 dev_info(&card->gdev->dev,
1145 "Device successfully recovered!\n"); 1150 "Device successfully recovered!\n");
1146 else { 1151 else {
1147 if (rtnl_trylock()) { 1152 qeth_close_dev(card);
1148 dev_close(card->dev); 1153 dev_warn(&card->gdev->dev, "The qeth device driver "
1149 rtnl_unlock();
1150 dev_warn(&card->gdev->dev, "The qeth device driver "
1151 "failed to recover an error on the device\n"); 1154 "failed to recover an error on the device\n");
1152 }
1153 } 1155 }
1154 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); 1156 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
1155 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); 1157 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 0749efe1c6d9..091ca0efa1c5 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1449,7 +1449,8 @@ static int qeth_l3_start_ipassists(struct qeth_card *card)
1449{ 1449{
1450 QETH_CARD_TEXT(card, 3, "strtipas"); 1450 QETH_CARD_TEXT(card, 3, "strtipas");
1451 1451
1452 qeth_set_access_ctrl_online(card); /* go on*/ 1452 if (qeth_set_access_ctrl_online(card, 0))
1453 return -EIO;
1453 qeth_l3_start_ipa_arp_processing(card); /* go on*/ 1454 qeth_l3_start_ipa_arp_processing(card); /* go on*/
1454 qeth_l3_start_ipa_ip_fragmentation(card); /* go on*/ 1455 qeth_l3_start_ipa_ip_fragmentation(card); /* go on*/
1455 qeth_l3_start_ipa_source_mac(card); /* go on*/ 1456 qeth_l3_start_ipa_source_mac(card); /* go on*/
@@ -3388,8 +3389,10 @@ contin:
3388 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); 3389 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
3389 if (!card->options.sniffer) { 3390 if (!card->options.sniffer) {
3390 rc = qeth_l3_start_ipassists(card); 3391 rc = qeth_l3_start_ipassists(card);
3391 if (rc) 3392 if (rc) {
3392 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); 3393 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
3394 goto out_remove;
3395 }
3393 rc = qeth_l3_setrouting_v4(card); 3396 rc = qeth_l3_setrouting_v4(card);
3394 if (rc) 3397 if (rc)
3395 QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); 3398 QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc);
@@ -3511,12 +3514,9 @@ static int qeth_l3_recover(void *ptr)
3511 dev_info(&card->gdev->dev, 3514 dev_info(&card->gdev->dev,
3512 "Device successfully recovered!\n"); 3515 "Device successfully recovered!\n");
3513 else { 3516 else {
3514 if (rtnl_trylock()) { 3517 qeth_close_dev(card);
3515 dev_close(card->dev); 3518 dev_warn(&card->gdev->dev, "The qeth device driver "
3516 rtnl_unlock();
3517 dev_warn(&card->gdev->dev, "The qeth device driver "
3518 "failed to recover an error on the device\n"); 3519 "failed to recover an error on the device\n");
3519 }
3520 } 3520 }
3521 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); 3521 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
3522 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); 3522 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);