aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/net/qeth_core.h2
-rw-r--r--drivers/s390/net/qeth_core_main.c151
-rw-r--r--drivers/s390/net/qeth_core_mpc.h45
-rw-r--r--drivers/s390/net/qeth_core_sys.c77
-rw-r--r--drivers/s390/net/qeth_l2_main.c2
-rw-r--r--drivers/s390/net/qeth_l3_main.c2
6 files changed, 267 insertions, 12 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index e8f72d715eba..4df5eaad6f94 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -648,6 +648,7 @@ struct qeth_card_options {
648 enum qeth_large_send_types large_send; 648 enum qeth_large_send_types large_send;
649 int performance_stats; 649 int performance_stats;
650 int rx_sg_cb; 650 int rx_sg_cb;
651 enum qeth_ipa_isolation_modes isolation;
651}; 652};
652 653
653/* 654/*
@@ -856,6 +857,7 @@ void qeth_core_get_strings(struct net_device *, u32, u8 *);
856void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); 857void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
857void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...); 858void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...);
858int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *); 859int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *);
860int qeth_set_access_ctrl_online(struct qeth_card *card);
859 861
860/* exports for OSN */ 862/* exports for OSN */
861int qeth_osn_assist(struct net_device *, void *, int); 863int 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 edee4dc6430c..2c71948c71a1 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -1079,6 +1079,7 @@ static void qeth_set_intial_options(struct qeth_card *card)
1079 card->options.add_hhlen = DEFAULT_ADD_HHLEN; 1079 card->options.add_hhlen = DEFAULT_ADD_HHLEN;
1080 card->options.performance_stats = 0; 1080 card->options.performance_stats = 0;
1081 card->options.rx_sg_cb = QETH_RX_SG_CB; 1081 card->options.rx_sg_cb = QETH_RX_SG_CB;
1082 card->options.isolation = ISOLATION_MODE_NONE;
1082} 1083}
1083 1084
1084static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread) 1085static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
@@ -3389,6 +3390,156 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card)
3389} 3390}
3390EXPORT_SYMBOL_GPL(qeth_setadpparms_change_macaddr); 3391EXPORT_SYMBOL_GPL(qeth_setadpparms_change_macaddr);
3391 3392
3393static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
3394 struct qeth_reply *reply, unsigned long data)
3395{
3396 struct qeth_ipa_cmd *cmd;
3397 struct qeth_set_access_ctrl *access_ctrl_req;
3398 int rc;
3399
3400 QETH_DBF_TEXT(TRACE, 4, "setaccb");
3401
3402 cmd = (struct qeth_ipa_cmd *) data;
3403 access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
3404 QETH_DBF_TEXT_(SETUP, 2, "setaccb");
3405 QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
3406 QETH_DBF_TEXT_(SETUP, 2, "rc=%d",
3407 cmd->data.setadapterparms.hdr.return_code);
3408 switch (cmd->data.setadapterparms.hdr.return_code) {
3409 case SET_ACCESS_CTRL_RC_SUCCESS:
3410 case SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED:
3411 case SET_ACCESS_CTRL_RC_ALREADY_ISOLATED:
3412 {
3413 card->options.isolation = access_ctrl_req->subcmd_code;
3414 if (card->options.isolation == ISOLATION_MODE_NONE) {
3415 dev_info(&card->gdev->dev,
3416 "QDIO data connection isolation is deactivated\n");
3417 } else {
3418 dev_info(&card->gdev->dev,
3419 "QDIO data connection isolation is activated\n");
3420 }
3421 QETH_DBF_MESSAGE(3, "OK:SET_ACCESS_CTRL(%s, %d)==%d\n",
3422 card->gdev->dev.kobj.name,
3423 access_ctrl_req->subcmd_code,
3424 cmd->data.setadapterparms.hdr.return_code);
3425 rc = 0;
3426 break;
3427 }
3428 case SET_ACCESS_CTRL_RC_NOT_SUPPORTED:
3429 {
3430 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%s,%d)==%d\n",
3431 card->gdev->dev.kobj.name,
3432 access_ctrl_req->subcmd_code,
3433 cmd->data.setadapterparms.hdr.return_code);
3434 dev_err(&card->gdev->dev, "Adapter does not "
3435 "support QDIO data connection isolation\n");
3436
3437 /* ensure isolation mode is "none" */
3438 card->options.isolation = ISOLATION_MODE_NONE;
3439 rc = -EOPNOTSUPP;
3440 break;
3441 }
3442 case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER:
3443 {
3444 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
3445 card->gdev->dev.kobj.name,
3446 access_ctrl_req->subcmd_code,
3447 cmd->data.setadapterparms.hdr.return_code);
3448 dev_err(&card->gdev->dev,
3449 "Adapter is dedicated. "
3450 "QDIO data connection isolation not supported\n");
3451
3452 /* ensure isolation mode is "none" */
3453 card->options.isolation = ISOLATION_MODE_NONE;
3454 rc = -EOPNOTSUPP;
3455 break;
3456 }
3457 case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF:
3458 {
3459 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
3460 card->gdev->dev.kobj.name,
3461 access_ctrl_req->subcmd_code,
3462 cmd->data.setadapterparms.hdr.return_code);
3463 dev_err(&card->gdev->dev,
3464 "TSO does not permit QDIO data connection isolation\n");
3465
3466 /* ensure isolation mode is "none" */
3467 card->options.isolation = ISOLATION_MODE_NONE;
3468 rc = -EPERM;
3469 break;
3470 }
3471 default:
3472 {
3473 /* this should never happen */
3474 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d"
3475 "==UNKNOWN\n",
3476 card->gdev->dev.kobj.name,
3477 access_ctrl_req->subcmd_code,
3478 cmd->data.setadapterparms.hdr.return_code);
3479
3480 /* ensure isolation mode is "none" */
3481 card->options.isolation = ISOLATION_MODE_NONE;
3482 rc = 0;
3483 break;
3484 }
3485 }
3486 qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
3487 return rc;
3488}
3489
3490static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
3491 enum qeth_ipa_isolation_modes isolation)
3492{
3493 int rc;
3494 struct qeth_cmd_buffer *iob;
3495 struct qeth_ipa_cmd *cmd;
3496 struct qeth_set_access_ctrl *access_ctrl_req;
3497
3498 QETH_DBF_TEXT(TRACE, 4, "setacctl");
3499
3500 QETH_DBF_TEXT_(SETUP, 2, "setacctl");
3501 QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
3502
3503 iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL,
3504 sizeof(struct qeth_ipacmd_setadpparms_hdr) +
3505 sizeof(struct qeth_set_access_ctrl));
3506 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
3507 access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
3508 access_ctrl_req->subcmd_code = isolation;
3509
3510 rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_set_access_ctrl_cb,
3511 NULL);
3512 QETH_DBF_TEXT_(SETUP, 2, "rc=%d", rc);
3513 return rc;
3514}
3515
3516int qeth_set_access_ctrl_online(struct qeth_card *card)
3517{
3518 int rc = 0;
3519
3520 QETH_DBF_TEXT(TRACE, 4, "setactlo");
3521
3522 if (card->info.type == QETH_CARD_TYPE_OSAE &&
3523 qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) {
3524 rc = qeth_setadpparms_set_access_ctrl(card,
3525 card->options.isolation);
3526 if (rc) {
3527 QETH_DBF_MESSAGE(3,
3528 "IPA(SET_ACCESS_CTRL,%s,%d) sent failed",
3529 card->gdev->dev.kobj.name,
3530 rc);
3531 }
3532 } else if (card->options.isolation != ISOLATION_MODE_NONE) {
3533 card->options.isolation = ISOLATION_MODE_NONE;
3534
3535 dev_err(&card->gdev->dev, "Adapter does not "
3536 "support QDIO data connection isolation\n");
3537 rc = -EOPNOTSUPP;
3538 }
3539 return rc;
3540}
3541EXPORT_SYMBOL_GPL(qeth_set_access_ctrl_online);
3542
3392void qeth_tx_timeout(struct net_device *dev) 3543void qeth_tx_timeout(struct net_device *dev)
3393{ 3544{
3394 struct qeth_card *card; 3545 struct qeth_card *card;
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index eecb2ee62e85..52c03438dbec 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -234,18 +234,19 @@ enum qeth_ipa_setdelip_flags {
234 234
235/* SETADAPTER IPA Command: ****************************************************/ 235/* SETADAPTER IPA Command: ****************************************************/
236enum qeth_ipa_setadp_cmd { 236enum qeth_ipa_setadp_cmd {
237 IPA_SETADP_QUERY_COMMANDS_SUPPORTED = 0x0001, 237 IPA_SETADP_QUERY_COMMANDS_SUPPORTED = 0x00000001L,
238 IPA_SETADP_ALTER_MAC_ADDRESS = 0x0002, 238 IPA_SETADP_ALTER_MAC_ADDRESS = 0x00000002L,
239 IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x0004, 239 IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x00000004L,
240 IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x0008, 240 IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x00000008L,
241 IPA_SETADP_SET_ADDRESSING_MODE = 0x0010, 241 IPA_SETADP_SET_ADDRESSING_MODE = 0x00000010L,
242 IPA_SETADP_SET_CONFIG_PARMS = 0x0020, 242 IPA_SETADP_SET_CONFIG_PARMS = 0x00000020L,
243 IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x0040, 243 IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x00000040L,
244 IPA_SETADP_SET_BROADCAST_MODE = 0x0080, 244 IPA_SETADP_SET_BROADCAST_MODE = 0x00000080L,
245 IPA_SETADP_SEND_OSA_MESSAGE = 0x0100, 245 IPA_SETADP_SEND_OSA_MESSAGE = 0x00000100L,
246 IPA_SETADP_SET_SNMP_CONTROL = 0x0200, 246 IPA_SETADP_SET_SNMP_CONTROL = 0x00000200L,
247 IPA_SETADP_QUERY_CARD_INFO = 0x0400, 247 IPA_SETADP_QUERY_CARD_INFO = 0x00000400L,
248 IPA_SETADP_SET_PROMISC_MODE = 0x0800, 248 IPA_SETADP_SET_PROMISC_MODE = 0x00000800L,
249 IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L,
249}; 250};
250enum qeth_ipa_mac_ops { 251enum qeth_ipa_mac_ops {
251 CHANGE_ADDR_READ_MAC = 0, 252 CHANGE_ADDR_READ_MAC = 0,
@@ -264,6 +265,20 @@ enum qeth_ipa_promisc_modes {
264 SET_PROMISC_MODE_OFF = 0, 265 SET_PROMISC_MODE_OFF = 0,
265 SET_PROMISC_MODE_ON = 1, 266 SET_PROMISC_MODE_ON = 1,
266}; 267};
268enum qeth_ipa_isolation_modes {
269 ISOLATION_MODE_NONE = 0x00000000L,
270 ISOLATION_MODE_FWD = 0x00000001L,
271 ISOLATION_MODE_DROP = 0x00000002L,
272};
273enum qeth_ipa_set_access_mode_rc {
274 SET_ACCESS_CTRL_RC_SUCCESS = 0x0000,
275 SET_ACCESS_CTRL_RC_NOT_SUPPORTED = 0x0004,
276 SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED = 0x0008,
277 SET_ACCESS_CTRL_RC_ALREADY_ISOLATED = 0x0010,
278 SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER = 0x0014,
279 SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF = 0x0018,
280};
281
267 282
268/* (SET)DELIP(M) IPA stuff ***************************************************/ 283/* (SET)DELIP(M) IPA stuff ***************************************************/
269struct qeth_ipacmd_setdelip4 { 284struct qeth_ipacmd_setdelip4 {
@@ -376,6 +391,11 @@ struct qeth_snmp_ureq {
376 struct qeth_snmp_cmd cmd; 391 struct qeth_snmp_cmd cmd;
377} __attribute__((packed)); 392} __attribute__((packed));
378 393
394/* SET_ACCESS_CONTROL: same format for request and reply */
395struct qeth_set_access_ctrl {
396 __u32 subcmd_code;
397} __attribute__((packed));
398
379struct qeth_ipacmd_setadpparms_hdr { 399struct qeth_ipacmd_setadpparms_hdr {
380 __u32 supp_hw_cmds; 400 __u32 supp_hw_cmds;
381 __u32 reserved1; 401 __u32 reserved1;
@@ -394,6 +414,7 @@ struct qeth_ipacmd_setadpparms {
394 struct qeth_query_cmds_supp query_cmds_supp; 414 struct qeth_query_cmds_supp query_cmds_supp;
395 struct qeth_change_addr change_addr; 415 struct qeth_change_addr change_addr;
396 struct qeth_snmp_cmd snmp; 416 struct qeth_snmp_cmd snmp;
417 struct qeth_set_access_ctrl set_access_ctrl;
397 __u32 mode; 418 __u32 mode;
398 } data; 419 } data;
399} __attribute__ ((packed)); 420} __attribute__ ((packed));
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 33505c2a0e3a..f2358a75ed0c 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -463,6 +463,82 @@ static ssize_t qeth_dev_large_send_store(struct device *dev,
463static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show, 463static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show,
464 qeth_dev_large_send_store); 464 qeth_dev_large_send_store);
465 465
466#define ATTR_QETH_ISOLATION_NONE ("none")
467#define ATTR_QETH_ISOLATION_FWD ("forward")
468#define ATTR_QETH_ISOLATION_DROP ("drop")
469
470static ssize_t qeth_dev_isolation_show(struct device *dev,
471 struct device_attribute *attr, char *buf)
472{
473 struct qeth_card *card = dev_get_drvdata(dev);
474
475 if (!card)
476 return -EINVAL;
477
478 switch (card->options.isolation) {
479 case ISOLATION_MODE_NONE:
480 return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_NONE);
481 case ISOLATION_MODE_FWD:
482 return snprintf(buf, 9, "%s\n", ATTR_QETH_ISOLATION_FWD);
483 case ISOLATION_MODE_DROP:
484 return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_DROP);
485 default:
486 return snprintf(buf, 5, "%s\n", "N/A");
487 }
488}
489
490static ssize_t qeth_dev_isolation_store(struct device *dev,
491 struct device_attribute *attr, const char *buf, size_t count)
492{
493 struct qeth_card *card = dev_get_drvdata(dev);
494 enum qeth_ipa_isolation_modes isolation;
495 int rc = 0;
496 char *tmp, *curtoken;
497 curtoken = (char *) buf;
498
499 if (!card) {
500 rc = -EINVAL;
501 goto out;
502 }
503
504 /* check for unknown, too, in case we do not yet know who we are */
505 if (card->info.type != QETH_CARD_TYPE_OSAE &&
506 card->info.type != QETH_CARD_TYPE_UNKNOWN) {
507 rc = -EOPNOTSUPP;
508 dev_err(&card->gdev->dev, "Adapter does not "
509 "support QDIO data connection isolation\n");
510 goto out;
511 }
512
513 /* parse input into isolation mode */
514 tmp = strsep(&curtoken, "\n");
515 if (!strcmp(tmp, ATTR_QETH_ISOLATION_NONE)) {
516 isolation = ISOLATION_MODE_NONE;
517 } else if (!strcmp(tmp, ATTR_QETH_ISOLATION_FWD)) {
518 isolation = ISOLATION_MODE_FWD;
519 } else if (!strcmp(tmp, ATTR_QETH_ISOLATION_DROP)) {
520 isolation = ISOLATION_MODE_DROP;
521 } else {
522 rc = -EINVAL;
523 goto out;
524 }
525 rc = count;
526
527 /* defer IP assist if device is offline (until discipline->set_online)*/
528 card->options.isolation = isolation;
529 if (card->state == CARD_STATE_SOFTSETUP ||
530 card->state == CARD_STATE_UP) {
531 int ipa_rc = qeth_set_access_ctrl_online(card);
532 if (ipa_rc != 0)
533 rc = ipa_rc;
534 }
535out:
536 return rc;
537}
538
539static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
540 qeth_dev_isolation_store);
541
466static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value) 542static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
467{ 543{
468 544
@@ -583,6 +659,7 @@ static struct attribute *qeth_device_attrs[] = {
583 &dev_attr_performance_stats.attr, 659 &dev_attr_performance_stats.attr,
584 &dev_attr_layer2.attr, 660 &dev_attr_layer2.attr,
585 &dev_attr_large_send.attr, 661 &dev_attr_large_send.attr,
662 &dev_attr_isolation.attr,
586 NULL, 663 NULL,
587}; 664};
588 665
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index b61d5c723c50..a63a3dfcdf63 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -988,6 +988,8 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
988 card->lan_online = 1; 988 card->lan_online = 1;
989 989
990 if (card->info.type != QETH_CARD_TYPE_OSN) { 990 if (card->info.type != QETH_CARD_TYPE_OSN) {
991 /* configure isolation level */
992 qeth_set_access_ctrl_online(card);
991 qeth_set_large_send(card, card->options.large_send); 993 qeth_set_large_send(card, card->options.large_send);
992 qeth_l2_process_vlans(card, 0); 994 qeth_l2_process_vlans(card, 0);
993 } 995 }
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 4ca28c16ca83..dd6766672a00 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1506,6 +1506,8 @@ static int qeth_l3_start_ipa_tso(struct qeth_card *card)
1506static int qeth_l3_start_ipassists(struct qeth_card *card) 1506static int qeth_l3_start_ipassists(struct qeth_card *card)
1507{ 1507{
1508 QETH_DBF_TEXT(TRACE, 3, "strtipas"); 1508 QETH_DBF_TEXT(TRACE, 3, "strtipas");
1509
1510 qeth_set_access_ctrl_online(card); /* go on*/
1509 qeth_l3_start_ipa_arp_processing(card); /* go on*/ 1511 qeth_l3_start_ipa_arp_processing(card); /* go on*/
1510 qeth_l3_start_ipa_ip_fragmentation(card); /* go on*/ 1512 qeth_l3_start_ipa_ip_fragmentation(card); /* go on*/
1511 qeth_l3_start_ipa_source_mac(card); /* go on*/ 1513 qeth_l3_start_ipa_source_mac(card); /* go on*/