@@ -68,6 +68,27 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
68
68
enum qeth_qdio_buffer_states newbufstate );
69
69
static int qeth_init_qdio_out_buf (struct qeth_qdio_out_q * , int );
70
70
71
+ static struct workqueue_struct * qeth_wq ;
72
+
73
+ static 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
+
85
+ void 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
+ }
90
+ EXPORT_SYMBOL_GPL (qeth_close_dev );
91
+
71
92
static inline const char * qeth_get_cardname (struct qeth_card * card )
72
93
{
73
94
if (card -> info .guestlan ) {
@@ -542,11 +563,23 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
542
563
} else {
543
564
switch (cmd -> hdr .command ) {
544
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
576
"The link for interface %s on CHPID"
547
577
" 0x%X failed\n" ,
548
578
QETH_CARD_IFNAME (card ),
549
579
card -> info .chpid );
580
+ qeth_issue_ipa_msg (cmd ,
581
+ cmd -> hdr .return_code , card );
582
+ }
550
583
card -> lan_online = 0 ;
551
584
if (card -> dev && netif_carrier_ok (card -> dev ))
552
585
netif_carrier_off (card -> dev );
@@ -1416,6 +1449,7 @@ static int qeth_setup_card(struct qeth_card *card)
1416
1449
/* init QDIO stuff */
1417
1450
qeth_init_qdio_info (card );
1418
1451
INIT_DELAYED_WORK (& card -> buffer_reclaim_work , qeth_buffer_reclaim_work );
1452
+ INIT_WORK (& card -> close_dev_work , qeth_close_dev_handler );
1419
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
4092
struct qeth_ipa_cmd * cmd ;
4059
4093
struct qeth_set_access_ctrl * access_ctrl_req ;
4094
+ int fallback = * (int * )reply -> param ;
4060
4095
4061
4096
QETH_CARD_TEXT (card , 4 , "setaccb" );
4062
4097
@@ -4066,85 +4101,79 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
4066
4101
QETH_DBF_TEXT_ (SETUP , 2 , "%s" , card -> gdev -> dev .kobj .name );
4067
4102
QETH_DBF_TEXT_ (SETUP , 2 , "rc=%d" ,
4068
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
4110
switch (cmd -> data .setadapterparms .hdr .return_code ) {
4070
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
4112
if (card -> options .isolation == ISOLATION_MODE_NONE ) {
4076
4113
dev_info (& card -> gdev -> dev ,
4077
4114
"QDIO data connection isolation is deactivated\n" );
4078
4115
} else {
4079
4116
dev_info (& card -> gdev -> dev ,
4080
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
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
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
4133
dev_err (& card -> gdev -> dev , "Adapter does not "
4095
4134
"support QDIO data connection isolation\n" );
4096
-
4097
- /* ensure isolation mode is "none" */
4098
- card -> options .isolation = ISOLATION_MODE_NONE ;
4099
4135
break ;
4100
- }
4101
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
4137
dev_err (& card -> gdev -> dev ,
4108
4138
"Adapter is dedicated. "
4109
4139
"QDIO data connection isolation not supported\n" );
4110
-
4111
- /* ensure isolation mode is "none" */
4112
- card -> options .isolation = ISOLATION_MODE_NONE ;
4140
+ if (fallback )
4141
+ card -> options .isolation = card -> options .prev_isolation ;
4113
4142
break ;
4114
- }
4115
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
4144
dev_err (& card -> gdev -> dev ,
4122
4145
"TSO does not permit QDIO data connection isolation\n" );
4123
-
4124
- /* ensure isolation mode is "none" */
4125
- card -> options .isolation = ISOLATION_MODE_NONE ;
4146
+ if (fallback )
4147
+ card -> options .isolation = card -> options .prev_isolation ;
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
4164
break ;
4127
- }
4128
4165
default :
4129
- {
4130
4166
/* this should never happen */
4131
- QETH_DBF_MESSAGE (3 , "ERR:SET_ACCESS_MODE(%s,%d)==%d"
4132
- "==UNKNOWN\n" ,
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 ;
4167
+ if (fallback )
4168
+ card -> options .isolation = card -> options .prev_isolation ;
4139
4169
break ;
4140
4170
}
4141
- }
4142
4171
qeth_default_setadapterparms_cb (card , reply , (unsigned long ) cmd );
4143
4172
return 0 ;
4144
4173
}
4145
4174
4146
4175
static 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
4178
int rc ;
4150
4179
struct qeth_cmd_buffer * iob ;
@@ -4164,12 +4193,12 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
4164
4193
access_ctrl_req -> subcmd_code = isolation ;
4165
4194
4166
4195
rc = qeth_send_ipa_cmd (card , iob , qeth_setadpparms_set_access_ctrl_cb ,
4167
- NULL );
4196
+ & fallback );
4168
4197
QETH_DBF_TEXT_ (SETUP , 2 , "rc=%d" , rc );
4169
4198
return rc ;
4170
4199
}
4171
4200
4172
- int qeth_set_access_ctrl_online (struct qeth_card * card )
4201
+ int qeth_set_access_ctrl_online (struct qeth_card * card , int fallback )
4173
4202
{
4174
4203
int rc = 0 ;
4175
4204
@@ -4179,12 +4208,13 @@ int qeth_set_access_ctrl_online(struct qeth_card *card)
4179
4208
card -> info .type == QETH_CARD_TYPE_OSX ) &&
4180
4209
qeth_adp_supported (card , IPA_SETADP_SET_ACCESS_CONTROL )) {
4181
4210
rc = qeth_setadpparms_set_access_ctrl (card ,
4182
- card -> options .isolation );
4211
+ card -> options .isolation , fallback );
4183
4212
if (rc ) {
4184
4213
QETH_DBF_MESSAGE (3 ,
4185
4214
"IPA(SET_ACCESS_CTRL,%s,%d) sent failed\n" ,
4186
4215
card -> gdev -> dev .kobj .name ,
4187
4216
rc );
4217
+ rc = - EOPNOTSUPP ;
4188
4218
}
4189
4219
} else if (card -> options .isolation != ISOLATION_MODE_NONE ) {
4190
4220
card -> options .isolation = ISOLATION_MODE_NONE ;
@@ -5552,6 +5582,8 @@ static int __init qeth_core_init(void)
5552
5582
rwlock_init (& qeth_core_card_list .rwlock );
5553
5583
mutex_init (& qeth_mod_mutex );
5554
5584
5585
+ qeth_wq = create_singlethread_workqueue ("qeth_wq" );
5586
+
5555
5587
rc = qeth_register_dbf_views ();
5556
5588
if (rc )
5557
5589
goto out_err ;
@@ -5598,6 +5630,7 @@ static int __init qeth_core_init(void)
5598
5630
5599
5631
static void __exit qeth_core_exit (void )
5600
5632
{
5633
+ destroy_workqueue (qeth_wq );
5601
5634
ccwgroup_driver_unregister (& qeth_core_ccwgroup_driver );
5602
5635
ccw_driver_unregister (& qeth_ccw_driver );
5603
5636
kmem_cache_destroy (qeth_qdio_outbuf_cache );
0 commit comments