aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/net')
-rw-r--r--drivers/s390/net/Kconfig10
-rw-r--r--drivers/s390/net/Makefile7
-rw-r--r--drivers/s390/net/claw.c82
-rw-r--r--drivers/s390/net/claw.h12
-rw-r--r--drivers/s390/net/ctcm_dbug.c1
-rw-r--r--drivers/s390/net/ctcm_fsms.c1
-rw-r--r--drivers/s390/net/ctcm_fsms.h1
-rw-r--r--drivers/s390/net/ctcm_main.c168
-rw-r--r--drivers/s390/net/ctcm_main.h20
-rw-r--r--drivers/s390/net/ctcm_mpc.c1
-rw-r--r--drivers/s390/net/ctcm_sysfs.c12
-rw-r--r--drivers/s390/net/cu3088.c148
-rw-r--r--drivers/s390/net/cu3088.h41
-rw-r--r--drivers/s390/net/fsm.c2
-rw-r--r--drivers/s390/net/fsm.h2
-rw-r--r--drivers/s390/net/lcs.c116
-rw-r--r--drivers/s390/net/lcs.h18
-rw-r--r--drivers/s390/net/netiucv.c14
-rw-r--r--drivers/s390/net/qeth_core.h16
-rw-r--r--drivers/s390/net/qeth_core_main.c403
-rw-r--r--drivers/s390/net/qeth_core_mpc.h91
-rw-r--r--drivers/s390/net/qeth_core_sys.c100
-rw-r--r--drivers/s390/net/qeth_l2_main.c80
-rw-r--r--drivers/s390/net/qeth_l3.h4
-rw-r--r--drivers/s390/net/qeth_l3_main.c343
-rw-r--r--drivers/s390/net/qeth_l3_sys.c125
-rw-r--r--drivers/s390/net/smsgiucv.c18
-rw-r--r--drivers/s390/net/smsgiucv.h8
-rw-r--r--drivers/s390/net/smsgiucv_app.c212
29 files changed, 1452 insertions, 604 deletions
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index cb909a5b5047..977bb4d4ed15 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -43,6 +43,16 @@ config SMSGIUCV
43 Select this option if you want to be able to receive SMSG messages 43 Select this option if you want to be able to receive SMSG messages
44 from other VM guest systems. 44 from other VM guest systems.
45 45
46config SMSGIUCV_EVENT
47 tristate "Deliver IUCV special messages as uevents (VM only)"
48 depends on SMSGIUCV
49 help
50 Select this option to deliver CP special messages (SMSGs) as
51 uevents. The driver handles only those special messages that
52 start with "APP".
53
54 To compile as a module, choose M. The module name is "smsgiucv_app".
55
46config CLAW 56config CLAW
47 tristate "CLAW device support" 57 tristate "CLAW device support"
48 depends on CCW && NETDEVICES 58 depends on CCW && NETDEVICES
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index 96eddb3b1d08..4dfe8c1092da 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -3,11 +3,12 @@
3# 3#
4 4
5ctcm-y += ctcm_main.o ctcm_fsms.o ctcm_mpc.o ctcm_sysfs.o ctcm_dbug.o 5ctcm-y += ctcm_main.o ctcm_fsms.o ctcm_mpc.o ctcm_sysfs.o ctcm_dbug.o
6obj-$(CONFIG_CTCM) += ctcm.o fsm.o cu3088.o 6obj-$(CONFIG_CTCM) += ctcm.o fsm.o
7obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o 7obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
8obj-$(CONFIG_SMSGIUCV) += smsgiucv.o 8obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
9obj-$(CONFIG_LCS) += lcs.o cu3088.o 9obj-$(CONFIG_SMSGIUCV_EVENT) += smsgiucv_app.o
10obj-$(CONFIG_CLAW) += claw.o cu3088.o 10obj-$(CONFIG_LCS) += lcs.o
11obj-$(CONFIG_CLAW) += claw.o
11qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o 12qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o
12obj-$(CONFIG_QETH) += qeth.o 13obj-$(CONFIG_QETH) += qeth.o
13qeth_l2-y += qeth_l2_main.o 14qeth_l2-y += qeth_l2_main.o
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index c63babefb698..147bb1a69aba 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -90,7 +90,6 @@
90#include <linux/timer.h> 90#include <linux/timer.h>
91#include <linux/types.h> 91#include <linux/types.h>
92 92
93#include "cu3088.h"
94#include "claw.h" 93#include "claw.h"
95 94
96/* 95/*
@@ -258,6 +257,9 @@ static int claw_pm_prepare(struct ccwgroup_device *gdev)
258 return -EPERM; 257 return -EPERM;
259} 258}
260 259
260/* the root device for claw group devices */
261static struct device *claw_root_dev;
262
261/* ccwgroup table */ 263/* ccwgroup table */
262 264
263static struct ccwgroup_driver claw_group_driver = { 265static struct ccwgroup_driver claw_group_driver = {
@@ -272,6 +274,47 @@ static struct ccwgroup_driver claw_group_driver = {
272 .prepare = claw_pm_prepare, 274 .prepare = claw_pm_prepare,
273}; 275};
274 276
277static struct ccw_device_id claw_ids[] = {
278 {CCW_DEVICE(0x3088, 0x61), .driver_info = claw_channel_type_claw},
279 {},
280};
281MODULE_DEVICE_TABLE(ccw, claw_ids);
282
283static struct ccw_driver claw_ccw_driver = {
284 .owner = THIS_MODULE,
285 .name = "claw",
286 .ids = claw_ids,
287 .probe = ccwgroup_probe_ccwdev,
288 .remove = ccwgroup_remove_ccwdev,
289};
290
291static ssize_t
292claw_driver_group_store(struct device_driver *ddrv, const char *buf,
293 size_t count)
294{
295 int err;
296 err = ccwgroup_create_from_string(claw_root_dev,
297 claw_group_driver.driver_id,
298 &claw_ccw_driver, 3, buf);
299 return err ? err : count;
300}
301
302static DRIVER_ATTR(group, 0200, NULL, claw_driver_group_store);
303
304static struct attribute *claw_group_attrs[] = {
305 &driver_attr_group.attr,
306 NULL,
307};
308
309static struct attribute_group claw_group_attr_group = {
310 .attrs = claw_group_attrs,
311};
312
313static const struct attribute_group *claw_group_attr_groups[] = {
314 &claw_group_attr_group,
315 NULL,
316};
317
275/* 318/*
276* Key functions 319* Key functions
277*/ 320*/
@@ -3326,7 +3369,11 @@ claw_remove_files(struct device *dev)
3326static void __exit 3369static void __exit
3327claw_cleanup(void) 3370claw_cleanup(void)
3328{ 3371{
3329 unregister_cu3088_discipline(&claw_group_driver); 3372 driver_remove_file(&claw_group_driver.driver,
3373 &driver_attr_group);
3374 ccwgroup_driver_unregister(&claw_group_driver);
3375 ccw_driver_unregister(&claw_ccw_driver);
3376 root_device_unregister(claw_root_dev);
3330 claw_unregister_debug_facility(); 3377 claw_unregister_debug_facility();
3331 pr_info("Driver unloaded\n"); 3378 pr_info("Driver unloaded\n");
3332 3379
@@ -3348,16 +3395,31 @@ claw_init(void)
3348 if (ret) { 3395 if (ret) {
3349 pr_err("Registering with the S/390 debug feature" 3396 pr_err("Registering with the S/390 debug feature"
3350 " failed with error code %d\n", ret); 3397 " failed with error code %d\n", ret);
3351 return ret; 3398 goto out_err;
3352 } 3399 }
3353 CLAW_DBF_TEXT(2, setup, "init_mod"); 3400 CLAW_DBF_TEXT(2, setup, "init_mod");
3354 ret = register_cu3088_discipline(&claw_group_driver); 3401 claw_root_dev = root_device_register("claw");
3355 if (ret) { 3402 ret = IS_ERR(claw_root_dev) ? PTR_ERR(claw_root_dev) : 0;
3356 CLAW_DBF_TEXT(2, setup, "init_bad"); 3403 if (ret)
3357 claw_unregister_debug_facility(); 3404 goto register_err;
3358 pr_err("Registering with the cu3088 device driver failed " 3405 ret = ccw_driver_register(&claw_ccw_driver);
3359 "with error code %d\n", ret); 3406 if (ret)
3360 } 3407 goto ccw_err;
3408 claw_group_driver.driver.groups = claw_group_attr_groups;
3409 ret = ccwgroup_driver_register(&claw_group_driver);
3410 if (ret)
3411 goto ccwgroup_err;
3412 return 0;
3413
3414ccwgroup_err:
3415 ccw_driver_unregister(&claw_ccw_driver);
3416ccw_err:
3417 root_device_unregister(claw_root_dev);
3418register_err:
3419 CLAW_DBF_TEXT(2, setup, "init_bad");
3420 claw_unregister_debug_facility();
3421out_err:
3422 pr_err("Initializing the claw device driver failed\n");
3361 return ret; 3423 return ret;
3362} 3424}
3363 3425
diff --git a/drivers/s390/net/claw.h b/drivers/s390/net/claw.h
index 005072c420d3..46d59a13db12 100644
--- a/drivers/s390/net/claw.h
+++ b/drivers/s390/net/claw.h
@@ -129,6 +129,18 @@ static inline int claw_dbf_passes(debug_info_t *dbf_grp, int level)
129 } \ 129 } \
130 } while (0) 130 } while (0)
131 131
132/**
133 * Enum for classifying detected devices.
134 */
135enum claw_channel_types {
136 /* Device is not a channel */
137 claw_channel_type_none,
138
139 /* Device is a CLAW channel device */
140 claw_channel_type_claw
141};
142
143
132/******************************************************* 144/*******************************************************
133* Define Control Blocks * 145* Define Control Blocks *
134* * 146* *
diff --git a/drivers/s390/net/ctcm_dbug.c b/drivers/s390/net/ctcm_dbug.c
index 1ca58f153470..d962fd741a23 100644
--- a/drivers/s390/net/ctcm_dbug.c
+++ b/drivers/s390/net/ctcm_dbug.c
@@ -10,7 +10,6 @@
10#include <linux/string.h> 10#include <linux/string.h>
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/slab.h>
14#include <linux/ctype.h> 13#include <linux/ctype.h>
15#include <linux/sysctl.h> 14#include <linux/sysctl.h>
16#include <linux/module.h> 15#include <linux/module.h>
diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c
index 4ded9ac2c5ef..70eb7f138414 100644
--- a/drivers/s390/net/ctcm_fsms.c
+++ b/drivers/s390/net/ctcm_fsms.c
@@ -44,7 +44,6 @@
44#include <asm/idals.h> 44#include <asm/idals.h>
45 45
46#include "fsm.h" 46#include "fsm.h"
47#include "cu3088.h"
48 47
49#include "ctcm_dbug.h" 48#include "ctcm_dbug.h"
50#include "ctcm_main.h" 49#include "ctcm_main.h"
diff --git a/drivers/s390/net/ctcm_fsms.h b/drivers/s390/net/ctcm_fsms.h
index 2326aba9807a..046d077fabbb 100644
--- a/drivers/s390/net/ctcm_fsms.h
+++ b/drivers/s390/net/ctcm_fsms.h
@@ -39,7 +39,6 @@
39#include <asm/idals.h> 39#include <asm/idals.h>
40 40
41#include "fsm.h" 41#include "fsm.h"
42#include "cu3088.h"
43#include "ctcm_main.h" 42#include "ctcm_main.h"
44 43
45/* 44/*
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index c5b83874500c..e35713dd0504 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -51,12 +51,16 @@
51 51
52#include <asm/idals.h> 52#include <asm/idals.h>
53 53
54#include "cu3088.h"
55#include "ctcm_fsms.h" 54#include "ctcm_fsms.h"
56#include "ctcm_main.h" 55#include "ctcm_main.h"
57 56
58/* Some common global variables */ 57/* Some common global variables */
59 58
59/**
60 * The root device for ctcm group devices
61 */
62static struct device *ctcm_root_dev;
63
60/* 64/*
61 * Linked list of all detected channels. 65 * Linked list of all detected channels.
62 */ 66 */
@@ -246,7 +250,7 @@ static void channel_remove(struct channel *ch)
246 * 250 *
247 * returns Pointer to a channel or NULL if no matching channel available. 251 * returns Pointer to a channel or NULL if no matching channel available.
248 */ 252 */
249static struct channel *channel_get(enum channel_types type, 253static struct channel *channel_get(enum ctcm_channel_types type,
250 char *id, int direction) 254 char *id, int direction)
251{ 255{
252 struct channel *ch = channels; 256 struct channel *ch = channels;
@@ -1342,7 +1346,7 @@ static int ctcm_probe_device(struct ccwgroup_device *cgdev)
1342 * 1346 *
1343 * returns 0 on success, !0 on error. 1347 * returns 0 on success, !0 on error.
1344 */ 1348 */
1345static int add_channel(struct ccw_device *cdev, enum channel_types type, 1349static int add_channel(struct ccw_device *cdev, enum ctcm_channel_types type,
1346 struct ctcm_priv *priv) 1350 struct ctcm_priv *priv)
1347{ 1351{
1348 struct channel **c = &channels; 1352 struct channel **c = &channels;
@@ -1501,13 +1505,13 @@ free_return: /* note that all channel pointers are 0 or valid */
1501/* 1505/*
1502 * Return type of a detected device. 1506 * Return type of a detected device.
1503 */ 1507 */
1504static enum channel_types get_channel_type(struct ccw_device_id *id) 1508static enum ctcm_channel_types get_channel_type(struct ccw_device_id *id)
1505{ 1509{
1506 enum channel_types type; 1510 enum ctcm_channel_types type;
1507 type = (enum channel_types)id->driver_info; 1511 type = (enum ctcm_channel_types)id->driver_info;
1508 1512
1509 if (type == channel_type_ficon) 1513 if (type == ctcm_channel_type_ficon)
1510 type = channel_type_escon; 1514 type = ctcm_channel_type_escon;
1511 1515
1512 return type; 1516 return type;
1513} 1517}
@@ -1525,16 +1529,21 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
1525 char read_id[CTCM_ID_SIZE]; 1529 char read_id[CTCM_ID_SIZE];
1526 char write_id[CTCM_ID_SIZE]; 1530 char write_id[CTCM_ID_SIZE];
1527 int direction; 1531 int direction;
1528 enum channel_types type; 1532 enum ctcm_channel_types type;
1529 struct ctcm_priv *priv; 1533 struct ctcm_priv *priv;
1530 struct net_device *dev; 1534 struct net_device *dev;
1531 struct ccw_device *cdev0; 1535 struct ccw_device *cdev0;
1532 struct ccw_device *cdev1; 1536 struct ccw_device *cdev1;
1537 struct channel *readc;
1538 struct channel *writec;
1533 int ret; 1539 int ret;
1540 int result;
1534 1541
1535 priv = dev_get_drvdata(&cgdev->dev); 1542 priv = dev_get_drvdata(&cgdev->dev);
1536 if (!priv) 1543 if (!priv) {
1537 return -ENODEV; 1544 result = -ENODEV;
1545 goto out_err_result;
1546 }
1538 1547
1539 cdev0 = cgdev->cdev[0]; 1548 cdev0 = cgdev->cdev[0];
1540 cdev1 = cgdev->cdev[1]; 1549 cdev1 = cgdev->cdev[1];
@@ -1545,31 +1554,40 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
1545 snprintf(write_id, CTCM_ID_SIZE, "ch-%s", dev_name(&cdev1->dev)); 1554 snprintf(write_id, CTCM_ID_SIZE, "ch-%s", dev_name(&cdev1->dev));
1546 1555
1547 ret = add_channel(cdev0, type, priv); 1556 ret = add_channel(cdev0, type, priv);
1548 if (ret) 1557 if (ret) {
1549 return ret; 1558 result = ret;
1559 goto out_err_result;
1560 }
1550 ret = add_channel(cdev1, type, priv); 1561 ret = add_channel(cdev1, type, priv);
1551 if (ret) 1562 if (ret) {
1552 return ret; 1563 result = ret;
1564 goto out_remove_channel1;
1565 }
1553 1566
1554 ret = ccw_device_set_online(cdev0); 1567 ret = ccw_device_set_online(cdev0);
1555 if (ret != 0) { 1568 if (ret != 0) {
1556 /* may be ok to fail now - can be done later */
1557 CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE, 1569 CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
1558 "%s(%s) set_online rc=%d", 1570 "%s(%s) set_online rc=%d",
1559 CTCM_FUNTAIL, read_id, ret); 1571 CTCM_FUNTAIL, read_id, ret);
1572 result = -EIO;
1573 goto out_remove_channel2;
1560 } 1574 }
1561 1575
1562 ret = ccw_device_set_online(cdev1); 1576 ret = ccw_device_set_online(cdev1);
1563 if (ret != 0) { 1577 if (ret != 0) {
1564 /* may be ok to fail now - can be done later */
1565 CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE, 1578 CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
1566 "%s(%s) set_online rc=%d", 1579 "%s(%s) set_online rc=%d",
1567 CTCM_FUNTAIL, write_id, ret); 1580 CTCM_FUNTAIL, write_id, ret);
1581
1582 result = -EIO;
1583 goto out_ccw1;
1568 } 1584 }
1569 1585
1570 dev = ctcm_init_netdevice(priv); 1586 dev = ctcm_init_netdevice(priv);
1571 if (dev == NULL) 1587 if (dev == NULL) {
1572 goto out; 1588 result = -ENODEV;
1589 goto out_ccw2;
1590 }
1573 1591
1574 for (direction = READ; direction <= WRITE; direction++) { 1592 for (direction = READ; direction <= WRITE; direction++) {
1575 priv->channel[direction] = 1593 priv->channel[direction] =
@@ -1587,12 +1605,14 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
1587 /* sysfs magic */ 1605 /* sysfs magic */
1588 SET_NETDEV_DEV(dev, &cgdev->dev); 1606 SET_NETDEV_DEV(dev, &cgdev->dev);
1589 1607
1590 if (register_netdev(dev)) 1608 if (register_netdev(dev)) {
1591 goto out_dev; 1609 result = -ENODEV;
1610 goto out_dev;
1611 }
1592 1612
1593 if (ctcm_add_attributes(&cgdev->dev)) { 1613 if (ctcm_add_attributes(&cgdev->dev)) {
1594 unregister_netdev(dev); 1614 result = -ENODEV;
1595 goto out_dev; 1615 goto out_unregister;
1596 } 1616 }
1597 1617
1598 strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name)); 1618 strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name));
@@ -1608,13 +1628,22 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
1608 priv->channel[WRITE]->id, priv->protocol); 1628 priv->channel[WRITE]->id, priv->protocol);
1609 1629
1610 return 0; 1630 return 0;
1631out_unregister:
1632 unregister_netdev(dev);
1611out_dev: 1633out_dev:
1612 ctcm_free_netdevice(dev); 1634 ctcm_free_netdevice(dev);
1613out: 1635out_ccw2:
1614 ccw_device_set_offline(cgdev->cdev[1]); 1636 ccw_device_set_offline(cgdev->cdev[1]);
1637out_ccw1:
1615 ccw_device_set_offline(cgdev->cdev[0]); 1638 ccw_device_set_offline(cgdev->cdev[0]);
1616 1639out_remove_channel2:
1617 return -ENODEV; 1640 readc = channel_get(type, read_id, READ);
1641 channel_remove(readc);
1642out_remove_channel1:
1643 writec = channel_get(type, write_id, WRITE);
1644 channel_remove(writec);
1645out_err_result:
1646 return result;
1618} 1647}
1619 1648
1620/** 1649/**
@@ -1695,6 +1724,11 @@ static int ctcm_pm_suspend(struct ccwgroup_device *gdev)
1695 return 0; 1724 return 0;
1696 netif_device_detach(priv->channel[READ]->netdev); 1725 netif_device_detach(priv->channel[READ]->netdev);
1697 ctcm_close(priv->channel[READ]->netdev); 1726 ctcm_close(priv->channel[READ]->netdev);
1727 if (!wait_event_timeout(priv->fsm->wait_q,
1728 fsm_getstate(priv->fsm) == DEV_STATE_STOPPED, CTCM_TIME_5_SEC)) {
1729 netif_device_attach(priv->channel[READ]->netdev);
1730 return -EBUSY;
1731 }
1698 ccw_device_set_offline(gdev->cdev[1]); 1732 ccw_device_set_offline(gdev->cdev[1]);
1699 ccw_device_set_offline(gdev->cdev[0]); 1733 ccw_device_set_offline(gdev->cdev[0]);
1700 return 0; 1734 return 0;
@@ -1719,6 +1753,22 @@ err_out:
1719 return rc; 1753 return rc;
1720} 1754}
1721 1755
1756static struct ccw_device_id ctcm_ids[] = {
1757 {CCW_DEVICE(0x3088, 0x08), .driver_info = ctcm_channel_type_parallel},
1758 {CCW_DEVICE(0x3088, 0x1e), .driver_info = ctcm_channel_type_ficon},
1759 {CCW_DEVICE(0x3088, 0x1f), .driver_info = ctcm_channel_type_escon},
1760 {},
1761};
1762MODULE_DEVICE_TABLE(ccw, ctcm_ids);
1763
1764static struct ccw_driver ctcm_ccw_driver = {
1765 .owner = THIS_MODULE,
1766 .name = "ctcm",
1767 .ids = ctcm_ids,
1768 .probe = ccwgroup_probe_ccwdev,
1769 .remove = ccwgroup_remove_ccwdev,
1770};
1771
1722static struct ccwgroup_driver ctcm_group_driver = { 1772static struct ccwgroup_driver ctcm_group_driver = {
1723 .owner = THIS_MODULE, 1773 .owner = THIS_MODULE,
1724 .name = CTC_DRIVER_NAME, 1774 .name = CTC_DRIVER_NAME,
@@ -1733,6 +1783,33 @@ static struct ccwgroup_driver ctcm_group_driver = {
1733 .restore = ctcm_pm_resume, 1783 .restore = ctcm_pm_resume,
1734}; 1784};
1735 1785
1786static ssize_t
1787ctcm_driver_group_store(struct device_driver *ddrv, const char *buf,
1788 size_t count)
1789{
1790 int err;
1791
1792 err = ccwgroup_create_from_string(ctcm_root_dev,
1793 ctcm_group_driver.driver_id,
1794 &ctcm_ccw_driver, 2, buf);
1795 return err ? err : count;
1796}
1797
1798static DRIVER_ATTR(group, 0200, NULL, ctcm_driver_group_store);
1799
1800static struct attribute *ctcm_group_attrs[] = {
1801 &driver_attr_group.attr,
1802 NULL,
1803};
1804
1805static struct attribute_group ctcm_group_attr_group = {
1806 .attrs = ctcm_group_attrs,
1807};
1808
1809static const struct attribute_group *ctcm_group_attr_groups[] = {
1810 &ctcm_group_attr_group,
1811 NULL,
1812};
1736 1813
1737/* 1814/*
1738 * Module related routines 1815 * Module related routines
@@ -1746,7 +1823,10 @@ static struct ccwgroup_driver ctcm_group_driver = {
1746 */ 1823 */
1747static void __exit ctcm_exit(void) 1824static void __exit ctcm_exit(void)
1748{ 1825{
1749 unregister_cu3088_discipline(&ctcm_group_driver); 1826 driver_remove_file(&ctcm_group_driver.driver, &driver_attr_group);
1827 ccwgroup_driver_unregister(&ctcm_group_driver);
1828 ccw_driver_unregister(&ctcm_ccw_driver);
1829 root_device_unregister(ctcm_root_dev);
1750 ctcm_unregister_dbf_views(); 1830 ctcm_unregister_dbf_views();
1751 pr_info("CTCM driver unloaded\n"); 1831 pr_info("CTCM driver unloaded\n");
1752} 1832}
@@ -1772,17 +1852,31 @@ static int __init ctcm_init(void)
1772 channels = NULL; 1852 channels = NULL;
1773 1853
1774 ret = ctcm_register_dbf_views(); 1854 ret = ctcm_register_dbf_views();
1775 if (ret) { 1855 if (ret)
1776 return ret; 1856 goto out_err;
1777 } 1857 ctcm_root_dev = root_device_register("ctcm");
1778 ret = register_cu3088_discipline(&ctcm_group_driver); 1858 ret = IS_ERR(ctcm_root_dev) ? PTR_ERR(ctcm_root_dev) : 0;
1779 if (ret) { 1859 if (ret)
1780 ctcm_unregister_dbf_views(); 1860 goto register_err;
1781 pr_err("%s / register_cu3088_discipline failed, ret = %d\n", 1861 ret = ccw_driver_register(&ctcm_ccw_driver);
1782 __func__, ret); 1862 if (ret)
1783 return ret; 1863 goto ccw_err;
1784 } 1864 ctcm_group_driver.driver.groups = ctcm_group_attr_groups;
1865 ret = ccwgroup_driver_register(&ctcm_group_driver);
1866 if (ret)
1867 goto ccwgroup_err;
1785 print_banner(); 1868 print_banner();
1869 return 0;
1870
1871ccwgroup_err:
1872 ccw_driver_unregister(&ctcm_ccw_driver);
1873ccw_err:
1874 root_device_unregister(ctcm_root_dev);
1875register_err:
1876 ctcm_unregister_dbf_views();
1877out_err:
1878 pr_err("%s / Initializing the ctcm device driver failed, ret = %d\n",
1879 __func__, ret);
1786 return ret; 1880 return ret;
1787} 1881}
1788 1882
diff --git a/drivers/s390/net/ctcm_main.h b/drivers/s390/net/ctcm_main.h
index d925e732b7d8..d34fa14f44e7 100644
--- a/drivers/s390/net/ctcm_main.h
+++ b/drivers/s390/net/ctcm_main.h
@@ -16,7 +16,6 @@
16#include <linux/netdevice.h> 16#include <linux/netdevice.h>
17 17
18#include "fsm.h" 18#include "fsm.h"
19#include "cu3088.h"
20#include "ctcm_dbug.h" 19#include "ctcm_dbug.h"
21#include "ctcm_mpc.h" 20#include "ctcm_mpc.h"
22 21
@@ -66,6 +65,23 @@
66 ctcmpc_dumpit(buf, len); \ 65 ctcmpc_dumpit(buf, len); \
67 } while (0) 66 } while (0)
68 67
68/**
69 * Enum for classifying detected devices
70 */
71enum ctcm_channel_types {
72 /* Device is not a channel */
73 ctcm_channel_type_none,
74
75 /* Device is a CTC/A */
76 ctcm_channel_type_parallel,
77
78 /* Device is a FICON channel */
79 ctcm_channel_type_ficon,
80
81 /* Device is a ESCON channel */
82 ctcm_channel_type_escon
83};
84
69/* 85/*
70 * CCW commands, used in this driver. 86 * CCW commands, used in this driver.
71 */ 87 */
@@ -121,7 +137,7 @@ struct channel {
121 * Type of this channel. 137 * Type of this channel.
122 * CTC/A or Escon for valid channels. 138 * CTC/A or Escon for valid channels.
123 */ 139 */
124 enum channel_types type; 140 enum ctcm_channel_types type;
125 /* 141 /*
126 * Misc. flags. See CHANNEL_FLAGS_... below 142 * Misc. flags. See CHANNEL_FLAGS_... below
127 */ 143 */
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
index 781e18be7e8f..5978b390153f 100644
--- a/drivers/s390/net/ctcm_mpc.c
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -53,7 +53,6 @@
53#include <linux/moduleparam.h> 53#include <linux/moduleparam.h>
54#include <asm/idals.h> 54#include <asm/idals.h>
55 55
56#include "cu3088.h"
57#include "ctcm_mpc.h" 56#include "ctcm_mpc.h"
58#include "ctcm_main.h" 57#include "ctcm_main.h"
59#include "ctcm_fsms.h" 58#include "ctcm_fsms.h"
diff --git a/drivers/s390/net/ctcm_sysfs.c b/drivers/s390/net/ctcm_sysfs.c
index 8452bb052d68..2b24550e865e 100644
--- a/drivers/s390/net/ctcm_sysfs.c
+++ b/drivers/s390/net/ctcm_sysfs.c
@@ -14,6 +14,7 @@
14#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 14#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
15 15
16#include <linux/sysfs.h> 16#include <linux/sysfs.h>
17#include <linux/slab.h>
17#include "ctcm_main.h" 18#include "ctcm_main.h"
18 19
19/* 20/*
@@ -158,6 +159,15 @@ static ssize_t ctcm_proto_store(struct device *dev,
158 return count; 159 return count;
159} 160}
160 161
162const char *ctcm_type[] = {
163 "not a channel",
164 "CTC/A",
165 "FICON channel",
166 "ESCON channel",
167 "unknown channel type",
168 "unsupported channel type",
169};
170
161static ssize_t ctcm_type_show(struct device *dev, 171static ssize_t ctcm_type_show(struct device *dev,
162 struct device_attribute *attr, char *buf) 172 struct device_attribute *attr, char *buf)
163{ 173{
@@ -168,7 +178,7 @@ static ssize_t ctcm_type_show(struct device *dev,
168 return -ENODEV; 178 return -ENODEV;
169 179
170 return sprintf(buf, "%s\n", 180 return sprintf(buf, "%s\n",
171 cu3088_type[cgdev->cdev[0]->id.driver_info]); 181 ctcm_type[cgdev->cdev[0]->id.driver_info]);
172} 182}
173 183
174static DEVICE_ATTR(buffer, 0644, ctcm_buffer_show, ctcm_buffer_write); 184static DEVICE_ATTR(buffer, 0644, ctcm_buffer_show, ctcm_buffer_write);
diff --git a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c
deleted file mode 100644
index 48383459e99b..000000000000
--- a/drivers/s390/net/cu3088.c
+++ /dev/null
@@ -1,148 +0,0 @@
1/*
2 * CTC / LCS ccw_device driver
3 *
4 * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
5 * Author(s): Arnd Bergmann <arndb@de.ibm.com>
6 * Cornelia Huck <cornelia.huck@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/err.h>
27
28#include <asm/ccwdev.h>
29#include <asm/ccwgroup.h>
30
31#include "cu3088.h"
32
33const char *cu3088_type[] = {
34 "not a channel",
35 "CTC/A",
36 "ESCON channel",
37 "FICON channel",
38 "OSA LCS card",
39 "CLAW channel device",
40 "unknown channel type",
41 "unsupported channel type",
42};
43
44/* static definitions */
45
46static struct ccw_device_id cu3088_ids[] = {
47 { CCW_DEVICE(0x3088, 0x08), .driver_info = channel_type_parallel },
48 { CCW_DEVICE(0x3088, 0x1f), .driver_info = channel_type_escon },
49 { CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon },
50 { CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 },
51 { CCW_DEVICE(0x3088, 0x61), .driver_info = channel_type_claw },
52 { /* end of list */ }
53};
54
55static struct ccw_driver cu3088_driver;
56
57static struct device *cu3088_root_dev;
58
59static ssize_t
60group_write(struct device_driver *drv, const char *buf, size_t count)
61{
62 int ret;
63 struct ccwgroup_driver *cdrv;
64
65 cdrv = to_ccwgroupdrv(drv);
66 if (!cdrv)
67 return -EINVAL;
68 ret = ccwgroup_create_from_string(cu3088_root_dev, cdrv->driver_id,
69 &cu3088_driver, 2, buf);
70
71 return (ret == 0) ? count : ret;
72}
73
74static DRIVER_ATTR(group, 0200, NULL, group_write);
75
76/* Register-unregister for ctc&lcs */
77int
78register_cu3088_discipline(struct ccwgroup_driver *dcp)
79{
80 int rc;
81
82 if (!dcp)
83 return -EINVAL;
84
85 /* Register discipline.*/
86 rc = ccwgroup_driver_register(dcp);
87 if (rc)
88 return rc;
89
90 rc = driver_create_file(&dcp->driver, &driver_attr_group);
91 if (rc)
92 ccwgroup_driver_unregister(dcp);
93
94 return rc;
95
96}
97
98void
99unregister_cu3088_discipline(struct ccwgroup_driver *dcp)
100{
101 if (!dcp)
102 return;
103
104 driver_remove_file(&dcp->driver, &driver_attr_group);
105 ccwgroup_driver_unregister(dcp);
106}
107
108static struct ccw_driver cu3088_driver = {
109 .owner = THIS_MODULE,
110 .ids = cu3088_ids,
111 .name = "cu3088",
112 .probe = ccwgroup_probe_ccwdev,
113 .remove = ccwgroup_remove_ccwdev,
114};
115
116/* module setup */
117static int __init
118cu3088_init (void)
119{
120 int rc;
121
122 cu3088_root_dev = root_device_register("cu3088");
123 if (IS_ERR(cu3088_root_dev))
124 return PTR_ERR(cu3088_root_dev);
125 rc = ccw_driver_register(&cu3088_driver);
126 if (rc)
127 root_device_unregister(cu3088_root_dev);
128
129 return rc;
130}
131
132static void __exit
133cu3088_exit (void)
134{
135 ccw_driver_unregister(&cu3088_driver);
136 root_device_unregister(cu3088_root_dev);
137}
138
139MODULE_DEVICE_TABLE(ccw,cu3088_ids);
140MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
141MODULE_LICENSE("GPL");
142
143module_init(cu3088_init);
144module_exit(cu3088_exit);
145
146EXPORT_SYMBOL_GPL(cu3088_type);
147EXPORT_SYMBOL_GPL(register_cu3088_discipline);
148EXPORT_SYMBOL_GPL(unregister_cu3088_discipline);
diff --git a/drivers/s390/net/cu3088.h b/drivers/s390/net/cu3088.h
deleted file mode 100644
index d8558a7105a5..000000000000
--- a/drivers/s390/net/cu3088.h
+++ /dev/null
@@ -1,41 +0,0 @@
1#ifndef _CU3088_H
2#define _CU3088_H
3
4/**
5 * Enum for classifying detected devices.
6 */
7enum channel_types {
8 /* Device is not a channel */
9 channel_type_none,
10
11 /* Device is a CTC/A */
12 channel_type_parallel,
13
14 /* Device is a ESCON channel */
15 channel_type_escon,
16
17 /* Device is a FICON channel */
18 channel_type_ficon,
19
20 /* Device is a OSA2 card */
21 channel_type_osa2,
22
23 /* Device is a CLAW channel device */
24 channel_type_claw,
25
26 /* Device is a channel, but we don't know
27 * anything about it */
28 channel_type_unknown,
29
30 /* Device is an unsupported model */
31 channel_type_unsupported,
32
33 /* number of type entries */
34 num_channel_types
35};
36
37extern const char *cu3088_type[num_channel_types];
38extern int register_cu3088_discipline(struct ccwgroup_driver *);
39extern void unregister_cu3088_discipline(struct ccwgroup_driver *);
40
41#endif
diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c
index 2c1db8036b7c..e5dea67f902e 100644
--- a/drivers/s390/net/fsm.c
+++ b/drivers/s390/net/fsm.c
@@ -5,6 +5,7 @@
5 5
6#include "fsm.h" 6#include "fsm.h"
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/slab.h>
8#include <linux/timer.h> 9#include <linux/timer.h>
9 10
10MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)"); 11MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
@@ -27,6 +28,7 @@ init_fsm(char *name, const char **state_names, const char **event_names, int nr_
27 return NULL; 28 return NULL;
28 } 29 }
29 strlcpy(this->name, name, sizeof(this->name)); 30 strlcpy(this->name, name, sizeof(this->name));
31 init_waitqueue_head(&this->wait_q);
30 32
31 f = kzalloc(sizeof(fsm), order); 33 f = kzalloc(sizeof(fsm), order);
32 if (f == NULL) { 34 if (f == NULL) {
diff --git a/drivers/s390/net/fsm.h b/drivers/s390/net/fsm.h
index af679c10f1bd..1e8b235d95b5 100644
--- a/drivers/s390/net/fsm.h
+++ b/drivers/s390/net/fsm.h
@@ -66,6 +66,7 @@ typedef struct fsm_instance_t {
66 char name[16]; 66 char name[16];
67 void *userdata; 67 void *userdata;
68 int userint; 68 int userint;
69 wait_queue_head_t wait_q;
69#if FSM_DEBUG_HISTORY 70#if FSM_DEBUG_HISTORY
70 int history_index; 71 int history_index;
71 int history_size; 72 int history_size;
@@ -197,6 +198,7 @@ fsm_newstate(fsm_instance *fi, int newstate)
197 printk(KERN_DEBUG "fsm(%s): New state %s\n", fi->name, 198 printk(KERN_DEBUG "fsm(%s): New state %s\n", fi->name,
198 fi->f->state_names[newstate]); 199 fi->f->state_names[newstate]);
199#endif 200#endif
201 wake_up(&fi->wait_q);
200} 202}
201 203
202/** 204/**
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index a70de9b4bf29..9b19ea13b4d8 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -37,6 +37,7 @@
37#include <linux/igmp.h> 37#include <linux/igmp.h>
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/kthread.h> 39#include <linux/kthread.h>
40#include <linux/slab.h>
40#include <net/arp.h> 41#include <net/arp.h>
41#include <net/ip.h> 42#include <net/ip.h>
42 43
@@ -47,7 +48,6 @@
47#include <asm/ccwgroup.h> 48#include <asm/ccwgroup.h>
48 49
49#include "lcs.h" 50#include "lcs.h"
50#include "cu3088.h"
51 51
52 52
53#if !defined(CONFIG_NET_ETHERNET) && \ 53#if !defined(CONFIG_NET_ETHERNET) && \
@@ -60,7 +60,11 @@
60 */ 60 */
61 61
62static char version[] __initdata = "LCS driver"; 62static char version[] __initdata = "LCS driver";
63static char debug_buffer[255]; 63
64/**
65 * the root device for lcs group devices
66 */
67static struct device *lcs_root_dev;
64 68
65/** 69/**
66 * Some prototypes. 70 * Some prototypes.
@@ -76,6 +80,7 @@ static int lcs_recovery(void *ptr);
76/** 80/**
77 * Debug Facility Stuff 81 * Debug Facility Stuff
78 */ 82 */
83static char debug_buffer[255];
79static debug_info_t *lcs_dbf_setup; 84static debug_info_t *lcs_dbf_setup;
80static debug_info_t *lcs_dbf_trace; 85static debug_info_t *lcs_dbf_trace;
81 86
@@ -889,7 +894,7 @@ lcs_send_lancmd(struct lcs_card *card, struct lcs_buffer *buffer,
889 rc = lcs_ready_buffer(&card->write, buffer); 894 rc = lcs_ready_buffer(&card->write, buffer);
890 if (rc) 895 if (rc)
891 return rc; 896 return rc;
892 init_timer(&timer); 897 init_timer_on_stack(&timer);
893 timer.function = lcs_lancmd_timeout; 898 timer.function = lcs_lancmd_timeout;
894 timer.data = (unsigned long) reply; 899 timer.data = (unsigned long) reply;
895 timer.expires = jiffies + HZ*card->lancmd_timeout; 900 timer.expires = jiffies + HZ*card->lancmd_timeout;
@@ -1968,6 +1973,15 @@ lcs_portno_store (struct device *dev, struct device_attribute *attr, const char
1968 1973
1969static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store); 1974static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store);
1970 1975
1976const char *lcs_type[] = {
1977 "not a channel",
1978 "2216 parallel",
1979 "2216 channel",
1980 "OSA LCS card",
1981 "unknown channel type",
1982 "unsupported channel type",
1983};
1984
1971static ssize_t 1985static ssize_t
1972lcs_type_show(struct device *dev, struct device_attribute *attr, char *buf) 1986lcs_type_show(struct device *dev, struct device_attribute *attr, char *buf)
1973{ 1987{
@@ -1977,7 +1991,7 @@ lcs_type_show(struct device *dev, struct device_attribute *attr, char *buf)
1977 if (!cgdev) 1991 if (!cgdev)
1978 return -ENODEV; 1992 return -ENODEV;
1979 1993
1980 return sprintf(buf, "%s\n", cu3088_type[cgdev->cdev[0]->id.driver_info]); 1994 return sprintf(buf, "%s\n", lcs_type[cgdev->cdev[0]->id.driver_info]);
1981} 1995}
1982 1996
1983static DEVICE_ATTR(type, 0444, lcs_type_show, NULL); 1997static DEVICE_ATTR(type, 0444, lcs_type_show, NULL);
@@ -2130,8 +2144,12 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
2130 card->write.ccwdev = ccwgdev->cdev[1]; 2144 card->write.ccwdev = ccwgdev->cdev[1];
2131 2145
2132 recover_state = card->state; 2146 recover_state = card->state;
2133 ccw_device_set_online(card->read.ccwdev); 2147 rc = ccw_device_set_online(card->read.ccwdev);
2134 ccw_device_set_online(card->write.ccwdev); 2148 if (rc)
2149 goto out_err;
2150 rc = ccw_device_set_online(card->write.ccwdev);
2151 if (rc)
2152 goto out_werr;
2135 2153
2136 LCS_DBF_TEXT(3, setup, "lcsnewdv"); 2154 LCS_DBF_TEXT(3, setup, "lcsnewdv");
2137 2155
@@ -2210,8 +2228,10 @@ netdev_out:
2210 return 0; 2228 return 0;
2211out: 2229out:
2212 2230
2213 ccw_device_set_offline(card->read.ccwdev);
2214 ccw_device_set_offline(card->write.ccwdev); 2231 ccw_device_set_offline(card->write.ccwdev);
2232out_werr:
2233 ccw_device_set_offline(card->read.ccwdev);
2234out_err:
2215 return -ENODEV; 2235 return -ENODEV;
2216} 2236}
2217 2237
@@ -2364,6 +2384,22 @@ static int lcs_restore(struct ccwgroup_device *gdev)
2364 return lcs_pm_resume(card); 2384 return lcs_pm_resume(card);
2365} 2385}
2366 2386
2387static struct ccw_device_id lcs_ids[] = {
2388 {CCW_DEVICE(0x3088, 0x08), .driver_info = lcs_channel_type_parallel},
2389 {CCW_DEVICE(0x3088, 0x1f), .driver_info = lcs_channel_type_2216},
2390 {CCW_DEVICE(0x3088, 0x60), .driver_info = lcs_channel_type_osa2},
2391 {},
2392};
2393MODULE_DEVICE_TABLE(ccw, lcs_ids);
2394
2395static struct ccw_driver lcs_ccw_driver = {
2396 .owner = THIS_MODULE,
2397 .name = "lcs",
2398 .ids = lcs_ids,
2399 .probe = ccwgroup_probe_ccwdev,
2400 .remove = ccwgroup_remove_ccwdev,
2401};
2402
2367/** 2403/**
2368 * LCS ccwgroup driver registration 2404 * LCS ccwgroup driver registration
2369 */ 2405 */
@@ -2383,6 +2419,33 @@ static struct ccwgroup_driver lcs_group_driver = {
2383 .restore = lcs_restore, 2419 .restore = lcs_restore,
2384}; 2420};
2385 2421
2422static ssize_t
2423lcs_driver_group_store(struct device_driver *ddrv, const char *buf,
2424 size_t count)
2425{
2426 int err;
2427 err = ccwgroup_create_from_string(lcs_root_dev,
2428 lcs_group_driver.driver_id,
2429 &lcs_ccw_driver, 2, buf);
2430 return err ? err : count;
2431}
2432
2433static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store);
2434
2435static struct attribute *lcs_group_attrs[] = {
2436 &driver_attr_group.attr,
2437 NULL,
2438};
2439
2440static struct attribute_group lcs_group_attr_group = {
2441 .attrs = lcs_group_attrs,
2442};
2443
2444static const struct attribute_group *lcs_group_attr_groups[] = {
2445 &lcs_group_attr_group,
2446 NULL,
2447};
2448
2386/** 2449/**
2387 * LCS Module/Kernel initialization function 2450 * LCS Module/Kernel initialization function
2388 */ 2451 */
@@ -2394,17 +2457,30 @@ __init lcs_init_module(void)
2394 pr_info("Loading %s\n", version); 2457 pr_info("Loading %s\n", version);
2395 rc = lcs_register_debug_facility(); 2458 rc = lcs_register_debug_facility();
2396 LCS_DBF_TEXT(0, setup, "lcsinit"); 2459 LCS_DBF_TEXT(0, setup, "lcsinit");
2397 if (rc) { 2460 if (rc)
2398 pr_err("Initialization failed\n"); 2461 goto out_err;
2399 return rc; 2462 lcs_root_dev = root_device_register("lcs");
2400 } 2463 rc = IS_ERR(lcs_root_dev) ? PTR_ERR(lcs_root_dev) : 0;
2401 2464 if (rc)
2402 rc = register_cu3088_discipline(&lcs_group_driver); 2465 goto register_err;
2403 if (rc) { 2466 rc = ccw_driver_register(&lcs_ccw_driver);
2404 pr_err("Initialization failed\n"); 2467 if (rc)
2405 return rc; 2468 goto ccw_err;
2406 } 2469 lcs_group_driver.driver.groups = lcs_group_attr_groups;
2470 rc = ccwgroup_driver_register(&lcs_group_driver);
2471 if (rc)
2472 goto ccwgroup_err;
2407 return 0; 2473 return 0;
2474
2475ccwgroup_err:
2476 ccw_driver_unregister(&lcs_ccw_driver);
2477ccw_err:
2478 root_device_unregister(lcs_root_dev);
2479register_err:
2480 lcs_unregister_debug_facility();
2481out_err:
2482 pr_err("Initializing the lcs device driver failed\n");
2483 return rc;
2408} 2484}
2409 2485
2410 2486
@@ -2416,7 +2492,11 @@ __exit lcs_cleanup_module(void)
2416{ 2492{
2417 pr_info("Terminating lcs module.\n"); 2493 pr_info("Terminating lcs module.\n");
2418 LCS_DBF_TEXT(0, trace, "cleanup"); 2494 LCS_DBF_TEXT(0, trace, "cleanup");
2419 unregister_cu3088_discipline(&lcs_group_driver); 2495 driver_remove_file(&lcs_group_driver.driver,
2496 &driver_attr_group);
2497 ccwgroup_driver_unregister(&lcs_group_driver);
2498 ccw_driver_unregister(&lcs_ccw_driver);
2499 root_device_unregister(lcs_root_dev);
2420 lcs_unregister_debug_facility(); 2500 lcs_unregister_debug_facility();
2421} 2501}
2422 2502
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h
index 6d668642af27..8c03392ac833 100644
--- a/drivers/s390/net/lcs.h
+++ b/drivers/s390/net/lcs.h
@@ -36,6 +36,24 @@ static inline int lcs_dbf_passes(debug_info_t *dbf_grp, int level)
36#define CARD_FROM_DEV(cdev) \ 36#define CARD_FROM_DEV(cdev) \
37 (struct lcs_card *) dev_get_drvdata( \ 37 (struct lcs_card *) dev_get_drvdata( \
38 &((struct ccwgroup_device *)dev_get_drvdata(&cdev->dev))->dev); 38 &((struct ccwgroup_device *)dev_get_drvdata(&cdev->dev))->dev);
39
40/**
41 * Enum for classifying detected devices.
42 */
43enum lcs_channel_types {
44 /* Device is not a channel */
45 lcs_channel_type_none,
46
47 /* Device is a 2216 channel */
48 lcs_channel_type_parallel,
49
50 /* Device is a 2216 channel */
51 lcs_channel_type_2216,
52
53 /* Device is a OSA2 card */
54 lcs_channel_type_osa2
55};
56
39/** 57/**
40 * CCW commands used in this driver 58 * CCW commands used in this driver
41 */ 59 */
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index c84eadd3602a..65ebee0a3266 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -113,11 +113,9 @@ static inline int iucv_dbf_passes(debug_info_t *dbf_grp, int level)
113#define IUCV_DBF_TEXT_(name, level, text...) \ 113#define IUCV_DBF_TEXT_(name, level, text...) \
114 do { \ 114 do { \
115 if (iucv_dbf_passes(iucv_dbf_##name, level)) { \ 115 if (iucv_dbf_passes(iucv_dbf_##name, level)) { \
116 char* iucv_dbf_txt_buf = \ 116 char* __buf = get_cpu_var(iucv_dbf_txt_buf); \
117 get_cpu_var(iucv_dbf_txt_buf); \ 117 sprintf(__buf, text); \
118 sprintf(iucv_dbf_txt_buf, text); \ 118 debug_text_event(iucv_dbf_##name, level, __buf); \
119 debug_text_event(iucv_dbf_##name, level, \
120 iucv_dbf_txt_buf); \
121 put_cpu_var(iucv_dbf_txt_buf); \ 119 put_cpu_var(iucv_dbf_txt_buf); \
122 } \ 120 } \
123 } while (0) 121 } while (0)
@@ -161,7 +159,7 @@ static void netiucv_pm_complete(struct device *);
161static int netiucv_pm_freeze(struct device *); 159static int netiucv_pm_freeze(struct device *);
162static int netiucv_pm_restore_thaw(struct device *); 160static int netiucv_pm_restore_thaw(struct device *);
163 161
164static struct dev_pm_ops netiucv_pm_ops = { 162static const struct dev_pm_ops netiucv_pm_ops = {
165 .prepare = netiucv_pm_prepare, 163 .prepare = netiucv_pm_prepare,
166 .complete = netiucv_pm_complete, 164 .complete = netiucv_pm_complete,
167 .freeze = netiucv_pm_freeze, 165 .freeze = netiucv_pm_freeze,
@@ -741,13 +739,13 @@ static void conn_action_txdone(fsm_instance *fi, int event, void *arg)
741 if (single_flag) { 739 if (single_flag) {
742 if ((skb = skb_dequeue(&conn->commit_queue))) { 740 if ((skb = skb_dequeue(&conn->commit_queue))) {
743 atomic_dec(&skb->users); 741 atomic_dec(&skb->users);
744 dev_kfree_skb_any(skb);
745 if (privptr) { 742 if (privptr) {
746 privptr->stats.tx_packets++; 743 privptr->stats.tx_packets++;
747 privptr->stats.tx_bytes += 744 privptr->stats.tx_bytes +=
748 (skb->len - NETIUCV_HDRLEN 745 (skb->len - NETIUCV_HDRLEN
749 - NETIUCV_HDRLEN); 746 - NETIUCV_HDRLEN);
750 } 747 }
748 dev_kfree_skb_any(skb);
751 } 749 }
752 } 750 }
753 conn->tx_buff->data = conn->tx_buff->head; 751 conn->tx_buff->data = conn->tx_buff->head;
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 31a2b4e502ce..fcd005aad989 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -122,7 +122,6 @@ struct qeth_perf_stats {
122 __u64 outbound_do_qdio_start_time; 122 __u64 outbound_do_qdio_start_time;
123 unsigned int outbound_do_qdio_cnt; 123 unsigned int outbound_do_qdio_cnt;
124 unsigned int outbound_do_qdio_time; 124 unsigned int outbound_do_qdio_time;
125 /* eddp data */
126 unsigned int large_send_bytes; 125 unsigned int large_send_bytes;
127 unsigned int large_send_cnt; 126 unsigned int large_send_cnt;
128 unsigned int sg_skbs_sent; 127 unsigned int sg_skbs_sent;
@@ -135,6 +134,7 @@ struct qeth_perf_stats {
135 unsigned int sg_frags_rx; 134 unsigned int sg_frags_rx;
136 unsigned int sg_alloc_page_rx; 135 unsigned int sg_alloc_page_rx;
137 unsigned int tx_csum; 136 unsigned int tx_csum;
137 unsigned int tx_lin;
138}; 138};
139 139
140/* Routing stuff */ 140/* Routing stuff */
@@ -648,6 +648,8 @@ 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;
652 int sniffer;
651}; 653};
652 654
653/* 655/*
@@ -736,6 +738,7 @@ struct qeth_card {
736 struct qeth_discipline discipline; 738 struct qeth_discipline discipline;
737 atomic_t force_alloc_skb; 739 atomic_t force_alloc_skb;
738 struct service_level qeth_service_level; 740 struct service_level qeth_service_level;
741 struct qdio_ssqd_desc ssqd;
739}; 742};
740 743
741struct qeth_card_list_struct { 744struct qeth_card_list_struct {
@@ -760,7 +763,8 @@ static inline int qeth_get_micros(void)
760 763
761static inline int qeth_get_ip_version(struct sk_buff *skb) 764static inline int qeth_get_ip_version(struct sk_buff *skb)
762{ 765{
763 switch (skb->protocol) { 766 struct ethhdr *ehdr = (struct ethhdr *)skb->data;
767 switch (ehdr->h_proto) {
764 case ETH_P_IPV6: 768 case ETH_P_IPV6:
765 return 6; 769 return 6;
766 case ETH_P_IP: 770 case ETH_P_IP:
@@ -776,7 +780,6 @@ static inline void qeth_put_buffer_pool_entry(struct qeth_card *card,
776 list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list); 780 list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list);
777} 781}
778 782
779struct qeth_eddp_context;
780extern struct ccwgroup_driver qeth_l2_ccwgroup_driver; 783extern struct ccwgroup_driver qeth_l2_ccwgroup_driver;
781extern struct ccwgroup_driver qeth_l3_ccwgroup_driver; 784extern struct ccwgroup_driver qeth_l3_ccwgroup_driver;
782const char *qeth_get_cardname_short(struct qeth_card *); 785const char *qeth_get_cardname_short(struct qeth_card *);
@@ -811,7 +814,8 @@ int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
811struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *, 814struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *,
812 enum qeth_ipa_cmds, enum qeth_prot_versions); 815 enum qeth_ipa_cmds, enum qeth_prot_versions);
813int qeth_query_setadapterparms(struct qeth_card *); 816int qeth_query_setadapterparms(struct qeth_card *);
814int qeth_check_qdio_errors(struct qdio_buffer *, unsigned int, const char *); 817int qeth_check_qdio_errors(struct qeth_card *, struct qdio_buffer *,
818 unsigned int, const char *);
815void qeth_queue_input_buffer(struct qeth_card *, int); 819void qeth_queue_input_buffer(struct qeth_card *, int);
816struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, 820struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
817 struct qdio_buffer *, struct qdio_buffer_element **, int *, 821 struct qdio_buffer *, struct qdio_buffer_element **, int *,
@@ -836,7 +840,6 @@ void qeth_prepare_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, char);
836struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *); 840struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *);
837int qeth_mdio_read(struct net_device *, int, int); 841int qeth_mdio_read(struct net_device *, int, int);
838int qeth_snmp_command(struct qeth_card *, char __user *); 842int qeth_snmp_command(struct qeth_card *, char __user *);
839int qeth_set_large_send(struct qeth_card *, enum qeth_large_send_types);
840struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *, __u32, __u32); 843struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *, __u32, __u32);
841int qeth_default_setadapterparms_cb(struct qeth_card *, struct qeth_reply *, 844int qeth_default_setadapterparms_cb(struct qeth_card *, struct qeth_reply *,
842 unsigned long); 845 unsigned long);
@@ -849,13 +852,14 @@ int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *,
849 struct sk_buff *, struct qeth_hdr *, int, int, int); 852 struct sk_buff *, struct qeth_hdr *, int, int, int);
850int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *, 853int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *,
851 struct sk_buff *, struct qeth_hdr *, int); 854 struct sk_buff *, struct qeth_hdr *, int);
852int qeth_core_get_stats_count(struct net_device *); 855int qeth_core_get_sset_count(struct net_device *, int);
853void qeth_core_get_ethtool_stats(struct net_device *, 856void qeth_core_get_ethtool_stats(struct net_device *,
854 struct ethtool_stats *, u64 *); 857 struct ethtool_stats *, u64 *);
855void qeth_core_get_strings(struct net_device *, u32, u8 *); 858void qeth_core_get_strings(struct net_device *, u32, u8 *);
856void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); 859void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
857void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...); 860void 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 *); 861int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *);
862int qeth_set_access_ctrl_online(struct qeth_card *card);
859 863
860/* exports for OSN */ 864/* exports for OSN */
861int qeth_osn_assist(struct net_device *, void *, int); 865int 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 c4a42d970158..3ba738b2e271 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -20,6 +20,7 @@
20#include <linux/tcp.h> 20#include <linux/tcp.h>
21#include <linux/mii.h> 21#include <linux/mii.h>
22#include <linux/kthread.h> 22#include <linux/kthread.h>
23#include <linux/slab.h>
23 24
24#include <asm/ebcdic.h> 25#include <asm/ebcdic.h>
25#include <asm/io.h> 26#include <asm/io.h>
@@ -269,41 +270,7 @@ int qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt)
269 card->qdio.init_pool.buf_count = bufcnt; 270 card->qdio.init_pool.buf_count = bufcnt;
270 return qeth_alloc_buffer_pool(card); 271 return qeth_alloc_buffer_pool(card);
271} 272}
272 273EXPORT_SYMBOL_GPL(qeth_realloc_buffer_pool);
273int qeth_set_large_send(struct qeth_card *card,
274 enum qeth_large_send_types type)
275{
276 int rc = 0;
277
278 if (card->dev == NULL) {
279 card->options.large_send = type;
280 return 0;
281 }
282 if (card->state == CARD_STATE_UP)
283 netif_tx_disable(card->dev);
284 card->options.large_send = type;
285 switch (card->options.large_send) {
286 case QETH_LARGE_SEND_TSO:
287 if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
288 card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
289 NETIF_F_HW_CSUM;
290 } else {
291 card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
292 NETIF_F_HW_CSUM);
293 card->options.large_send = QETH_LARGE_SEND_NO;
294 rc = -EOPNOTSUPP;
295 }
296 break;
297 default: /* includes QETH_LARGE_SEND_NO */
298 card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
299 NETIF_F_HW_CSUM);
300 break;
301 }
302 if (card->state == CARD_STATE_UP)
303 netif_wake_queue(card->dev);
304 return rc;
305}
306EXPORT_SYMBOL_GPL(qeth_set_large_send);
307 274
308static int qeth_issue_next_read(struct qeth_card *card) 275static int qeth_issue_next_read(struct qeth_card *card)
309{ 276{
@@ -385,8 +352,10 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
385 if (IS_IPA(iob->data)) { 352 if (IS_IPA(iob->data)) {
386 cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data); 353 cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
387 if (IS_IPA_REPLY(cmd)) { 354 if (IS_IPA_REPLY(cmd)) {
388 if (cmd->hdr.command < IPA_CMD_SETCCID || 355 if (cmd->hdr.command != IPA_CMD_SETCCID &&
389 cmd->hdr.command > IPA_CMD_MODCCID) 356 cmd->hdr.command != IPA_CMD_DELCCID &&
357 cmd->hdr.command != IPA_CMD_MODCCID &&
358 cmd->hdr.command != IPA_CMD_SET_DIAG_ASS)
390 qeth_issue_ipa_msg(cmd, 359 qeth_issue_ipa_msg(cmd,
391 cmd->hdr.return_code, card); 360 cmd->hdr.return_code, card);
392 return cmd; 361 return cmd;
@@ -569,7 +538,8 @@ static void qeth_send_control_data_cb(struct qeth_channel *channel,
569 dev_err(&card->gdev->dev, 538 dev_err(&card->gdev->dev,
570 "The qeth device is not configured " 539 "The qeth device is not configured "
571 "for the OSI layer required by z/VM\n"); 540 "for the OSI layer required by z/VM\n");
572 qeth_schedule_recovery(card); 541 else
542 qeth_schedule_recovery(card);
573 goto out; 543 goto out;
574 } 544 }
575 545
@@ -1079,6 +1049,7 @@ static void qeth_set_intial_options(struct qeth_card *card)
1079 card->options.add_hhlen = DEFAULT_ADD_HHLEN; 1049 card->options.add_hhlen = DEFAULT_ADD_HHLEN;
1080 card->options.performance_stats = 0; 1050 card->options.performance_stats = 0;
1081 card->options.rx_sg_cb = QETH_RX_SG_CB; 1051 card->options.rx_sg_cb = QETH_RX_SG_CB;
1052 card->options.isolation = ISOLATION_MODE_NONE;
1082} 1053}
1083 1054
1084static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread) 1055static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
@@ -1134,11 +1105,6 @@ static int qeth_setup_card(struct qeth_card *card)
1134 card->thread_running_mask = 0; 1105 card->thread_running_mask = 0;
1135 INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread); 1106 INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread);
1136 INIT_LIST_HEAD(&card->ip_list); 1107 INIT_LIST_HEAD(&card->ip_list);
1137 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
1138 if (!card->ip_tbd_list) {
1139 QETH_DBF_TEXT(SETUP, 0, "iptbdnom");
1140 return -ENOMEM;
1141 }
1142 INIT_LIST_HEAD(card->ip_tbd_list); 1108 INIT_LIST_HEAD(card->ip_tbd_list);
1143 INIT_LIST_HEAD(&card->cmd_waiter_list); 1109 INIT_LIST_HEAD(&card->cmd_waiter_list);
1144 init_waitqueue_head(&card->wait_q); 1110 init_waitqueue_head(&card->wait_q);
@@ -1149,8 +1115,6 @@ static int qeth_setup_card(struct qeth_card *card)
1149 card->ipato.enabled = 0; 1115 card->ipato.enabled = 0;
1150 card->ipato.invert4 = 0; 1116 card->ipato.invert4 = 0;
1151 card->ipato.invert6 = 0; 1117 card->ipato.invert6 = 0;
1152 if (card->info.type == QETH_CARD_TYPE_IQD)
1153 card->options.checksum_type = NO_CHECKSUMMING;
1154 /* init QDIO stuff */ 1118 /* init QDIO stuff */
1155 qeth_init_qdio_info(card); 1119 qeth_init_qdio_info(card);
1156 return 0; 1120 return 0;
@@ -1172,21 +1136,30 @@ static struct qeth_card *qeth_alloc_card(void)
1172 QETH_DBF_TEXT(SETUP, 2, "alloccrd"); 1136 QETH_DBF_TEXT(SETUP, 2, "alloccrd");
1173 card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL); 1137 card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL);
1174 if (!card) 1138 if (!card)
1175 return NULL; 1139 goto out;
1176 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); 1140 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
1177 if (qeth_setup_channel(&card->read)) { 1141 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
1178 kfree(card); 1142 if (!card->ip_tbd_list) {
1179 return NULL; 1143 QETH_DBF_TEXT(SETUP, 0, "iptbdnom");
1180 } 1144 goto out_card;
1181 if (qeth_setup_channel(&card->write)) {
1182 qeth_clean_channel(&card->read);
1183 kfree(card);
1184 return NULL;
1185 } 1145 }
1146 if (qeth_setup_channel(&card->read))
1147 goto out_ip;
1148 if (qeth_setup_channel(&card->write))
1149 goto out_channel;
1186 card->options.layer2 = -1; 1150 card->options.layer2 = -1;
1187 card->qeth_service_level.seq_print = qeth_core_sl_print; 1151 card->qeth_service_level.seq_print = qeth_core_sl_print;
1188 register_service_level(&card->qeth_service_level); 1152 register_service_level(&card->qeth_service_level);
1189 return card; 1153 return card;
1154
1155out_channel:
1156 qeth_clean_channel(&card->read);
1157out_ip:
1158 kfree(card->ip_tbd_list);
1159out_card:
1160 kfree(card);
1161out:
1162 return NULL;
1190} 1163}
1191 1164
1192static int qeth_determine_card_type(struct qeth_card *card) 1165static int qeth_determine_card_type(struct qeth_card *card)
@@ -1389,26 +1362,29 @@ static int qeth_read_conf_data(struct qeth_card *card, void **buffer,
1389 return ret; 1362 return ret;
1390} 1363}
1391 1364
1392static int qeth_get_unitaddr(struct qeth_card *card) 1365static void qeth_configure_unitaddr(struct qeth_card *card, char *prcd)
1393{ 1366{
1394 int length; 1367 QETH_DBF_TEXT(SETUP, 2, "cfgunit");
1395 char *prcd;
1396 int rc;
1397
1398 QETH_DBF_TEXT(SETUP, 2, "getunit");
1399 rc = qeth_read_conf_data(card, (void **) &prcd, &length);
1400 if (rc) {
1401 QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n",
1402 dev_name(&card->gdev->dev), rc);
1403 return rc;
1404 }
1405 card->info.chpid = prcd[30]; 1368 card->info.chpid = prcd[30];
1406 card->info.unit_addr2 = prcd[31]; 1369 card->info.unit_addr2 = prcd[31];
1407 card->info.cula = prcd[63]; 1370 card->info.cula = prcd[63];
1408 card->info.guestlan = ((prcd[0x10] == _ascebc['V']) && 1371 card->info.guestlan = ((prcd[0x10] == _ascebc['V']) &&
1409 (prcd[0x11] == _ascebc['M'])); 1372 (prcd[0x11] == _ascebc['M']));
1410 kfree(prcd); 1373}
1411 return 0; 1374
1375static void qeth_configure_blkt_default(struct qeth_card *card, char *prcd)
1376{
1377 QETH_DBF_TEXT(SETUP, 2, "cfgblkt");
1378
1379 if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && prcd[76] == 0xF5) {
1380 card->info.blkt.time_total = 250;
1381 card->info.blkt.inter_packet = 5;
1382 card->info.blkt.inter_packet_jumbo = 15;
1383 } else {
1384 card->info.blkt.time_total = 0;
1385 card->info.blkt.inter_packet = 0;
1386 card->info.blkt.inter_packet_jumbo = 0;
1387 }
1412} 1388}
1413 1389
1414static void qeth_init_tokens(struct qeth_card *card) 1390static void qeth_init_tokens(struct qeth_card *card)
@@ -2607,8 +2583,8 @@ int qeth_query_setadapterparms(struct qeth_card *card)
2607} 2583}
2608EXPORT_SYMBOL_GPL(qeth_query_setadapterparms); 2584EXPORT_SYMBOL_GPL(qeth_query_setadapterparms);
2609 2585
2610int qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error, 2586int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
2611 const char *dbftext) 2587 unsigned int qdio_error, const char *dbftext)
2612{ 2588{
2613 if (qdio_error) { 2589 if (qdio_error) {
2614 QETH_DBF_TEXT(TRACE, 2, dbftext); 2590 QETH_DBF_TEXT(TRACE, 2, dbftext);
@@ -2618,7 +2594,11 @@ int qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
2618 QETH_DBF_TEXT_(QERR, 2, " F14=%02X", 2594 QETH_DBF_TEXT_(QERR, 2, " F14=%02X",
2619 buf->element[14].flags & 0xff); 2595 buf->element[14].flags & 0xff);
2620 QETH_DBF_TEXT_(QERR, 2, " qerr=%X", qdio_error); 2596 QETH_DBF_TEXT_(QERR, 2, " qerr=%X", qdio_error);
2621 return 1; 2597 if ((buf->element[15].flags & 0xff) == 0x12) {
2598 card->stats.rx_dropped++;
2599 return 0;
2600 } else
2601 return 1;
2622 } 2602 }
2623 return 0; 2603 return 0;
2624} 2604}
@@ -2701,7 +2681,7 @@ static int qeth_handle_send_error(struct qeth_card *card,
2701 qdio_err = 1; 2681 qdio_err = 1;
2702 } 2682 }
2703 } 2683 }
2704 qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr"); 2684 qeth_check_qdio_errors(card, buffer->buffer, qdio_err, "qouterr");
2705 2685
2706 if (!qdio_err) 2686 if (!qdio_err)
2707 return QETH_SEND_ERROR_NONE; 2687 return QETH_SEND_ERROR_NONE;
@@ -3389,10 +3369,161 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card)
3389} 3369}
3390EXPORT_SYMBOL_GPL(qeth_setadpparms_change_macaddr); 3370EXPORT_SYMBOL_GPL(qeth_setadpparms_change_macaddr);
3391 3371
3372static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
3373 struct qeth_reply *reply, unsigned long data)
3374{
3375 struct qeth_ipa_cmd *cmd;
3376 struct qeth_set_access_ctrl *access_ctrl_req;
3377 int rc;
3378
3379 QETH_DBF_TEXT(TRACE, 4, "setaccb");
3380
3381 cmd = (struct qeth_ipa_cmd *) data;
3382 access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
3383 QETH_DBF_TEXT_(SETUP, 2, "setaccb");
3384 QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
3385 QETH_DBF_TEXT_(SETUP, 2, "rc=%d",
3386 cmd->data.setadapterparms.hdr.return_code);
3387 switch (cmd->data.setadapterparms.hdr.return_code) {
3388 case SET_ACCESS_CTRL_RC_SUCCESS:
3389 case SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED:
3390 case SET_ACCESS_CTRL_RC_ALREADY_ISOLATED:
3391 {
3392 card->options.isolation = access_ctrl_req->subcmd_code;
3393 if (card->options.isolation == ISOLATION_MODE_NONE) {
3394 dev_info(&card->gdev->dev,
3395 "QDIO data connection isolation is deactivated\n");
3396 } else {
3397 dev_info(&card->gdev->dev,
3398 "QDIO data connection isolation is activated\n");
3399 }
3400 QETH_DBF_MESSAGE(3, "OK:SET_ACCESS_CTRL(%s, %d)==%d\n",
3401 card->gdev->dev.kobj.name,
3402 access_ctrl_req->subcmd_code,
3403 cmd->data.setadapterparms.hdr.return_code);
3404 rc = 0;
3405 break;
3406 }
3407 case SET_ACCESS_CTRL_RC_NOT_SUPPORTED:
3408 {
3409 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%s,%d)==%d\n",
3410 card->gdev->dev.kobj.name,
3411 access_ctrl_req->subcmd_code,
3412 cmd->data.setadapterparms.hdr.return_code);
3413 dev_err(&card->gdev->dev, "Adapter does not "
3414 "support QDIO data connection isolation\n");
3415
3416 /* ensure isolation mode is "none" */
3417 card->options.isolation = ISOLATION_MODE_NONE;
3418 rc = -EOPNOTSUPP;
3419 break;
3420 }
3421 case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER:
3422 {
3423 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
3424 card->gdev->dev.kobj.name,
3425 access_ctrl_req->subcmd_code,
3426 cmd->data.setadapterparms.hdr.return_code);
3427 dev_err(&card->gdev->dev,
3428 "Adapter is dedicated. "
3429 "QDIO data connection isolation not supported\n");
3430
3431 /* ensure isolation mode is "none" */
3432 card->options.isolation = ISOLATION_MODE_NONE;
3433 rc = -EOPNOTSUPP;
3434 break;
3435 }
3436 case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF:
3437 {
3438 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
3439 card->gdev->dev.kobj.name,
3440 access_ctrl_req->subcmd_code,
3441 cmd->data.setadapterparms.hdr.return_code);
3442 dev_err(&card->gdev->dev,
3443 "TSO does not permit QDIO data connection isolation\n");
3444
3445 /* ensure isolation mode is "none" */
3446 card->options.isolation = ISOLATION_MODE_NONE;
3447 rc = -EPERM;
3448 break;
3449 }
3450 default:
3451 {
3452 /* this should never happen */
3453 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d"
3454 "==UNKNOWN\n",
3455 card->gdev->dev.kobj.name,
3456 access_ctrl_req->subcmd_code,
3457 cmd->data.setadapterparms.hdr.return_code);
3458
3459 /* ensure isolation mode is "none" */
3460 card->options.isolation = ISOLATION_MODE_NONE;
3461 rc = 0;
3462 break;
3463 }
3464 }
3465 qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
3466 return rc;
3467}
3468
3469static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
3470 enum qeth_ipa_isolation_modes isolation)
3471{
3472 int rc;
3473 struct qeth_cmd_buffer *iob;
3474 struct qeth_ipa_cmd *cmd;
3475 struct qeth_set_access_ctrl *access_ctrl_req;
3476
3477 QETH_DBF_TEXT(TRACE, 4, "setacctl");
3478
3479 QETH_DBF_TEXT_(SETUP, 2, "setacctl");
3480 QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
3481
3482 iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL,
3483 sizeof(struct qeth_ipacmd_setadpparms_hdr) +
3484 sizeof(struct qeth_set_access_ctrl));
3485 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
3486 access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
3487 access_ctrl_req->subcmd_code = isolation;
3488
3489 rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_set_access_ctrl_cb,
3490 NULL);
3491 QETH_DBF_TEXT_(SETUP, 2, "rc=%d", rc);
3492 return rc;
3493}
3494
3495int qeth_set_access_ctrl_online(struct qeth_card *card)
3496{
3497 int rc = 0;
3498
3499 QETH_DBF_TEXT(TRACE, 4, "setactlo");
3500
3501 if (card->info.type == QETH_CARD_TYPE_OSAE &&
3502 qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) {
3503 rc = qeth_setadpparms_set_access_ctrl(card,
3504 card->options.isolation);
3505 if (rc) {
3506 QETH_DBF_MESSAGE(3,
3507 "IPA(SET_ACCESS_CTRL,%s,%d) sent failed",
3508 card->gdev->dev.kobj.name,
3509 rc);
3510 }
3511 } else if (card->options.isolation != ISOLATION_MODE_NONE) {
3512 card->options.isolation = ISOLATION_MODE_NONE;
3513
3514 dev_err(&card->gdev->dev, "Adapter does not "
3515 "support QDIO data connection isolation\n");
3516 rc = -EOPNOTSUPP;
3517 }
3518 return rc;
3519}
3520EXPORT_SYMBOL_GPL(qeth_set_access_ctrl_online);
3521
3392void qeth_tx_timeout(struct net_device *dev) 3522void qeth_tx_timeout(struct net_device *dev)
3393{ 3523{
3394 struct qeth_card *card; 3524 struct qeth_card *card;
3395 3525
3526 QETH_DBF_TEXT(TRACE, 4, "txtimeo");
3396 card = dev->ml_priv; 3527 card = dev->ml_priv;
3397 card->stats.tx_errors++; 3528 card->stats.tx_errors++;
3398 qeth_schedule_recovery(card); 3529 qeth_schedule_recovery(card);
@@ -3674,9 +3805,6 @@ static int qeth_qdio_establish(struct qeth_card *card)
3674 init_data.input_handler = card->discipline.input_handler; 3805 init_data.input_handler = card->discipline.input_handler;
3675 init_data.output_handler = card->discipline.output_handler; 3806 init_data.output_handler = card->discipline.output_handler;
3676 init_data.int_parm = (unsigned long) card; 3807 init_data.int_parm = (unsigned long) card;
3677 init_data.flags = QDIO_INBOUND_0COPY_SBALS |
3678 QDIO_OUTBOUND_0COPY_SBALS |
3679 QDIO_USE_OUTBOUND_PCIS;
3680 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; 3808 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
3681 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; 3809 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
3682 3810
@@ -3731,60 +3859,39 @@ static int qeth_core_driver_group(const char *buf, struct device *root_dev,
3731 3859
3732int qeth_core_hardsetup_card(struct qeth_card *card) 3860int qeth_core_hardsetup_card(struct qeth_card *card)
3733{ 3861{
3734 struct qdio_ssqd_desc *ssqd; 3862 int retries = 0;
3735 int retries = 3;
3736 int mpno = 0;
3737 int rc; 3863 int rc;
3738 3864
3739 QETH_DBF_TEXT(SETUP, 2, "hrdsetup"); 3865 QETH_DBF_TEXT(SETUP, 2, "hrdsetup");
3740 atomic_set(&card->force_alloc_skb, 0); 3866 atomic_set(&card->force_alloc_skb, 0);
3741retry: 3867retry:
3742 if (retries < 3) { 3868 if (retries)
3743 QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n", 3869 QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n",
3744 dev_name(&card->gdev->dev)); 3870 dev_name(&card->gdev->dev));
3745 ccw_device_set_offline(CARD_DDEV(card)); 3871 ccw_device_set_offline(CARD_DDEV(card));
3746 ccw_device_set_offline(CARD_WDEV(card)); 3872 ccw_device_set_offline(CARD_WDEV(card));
3747 ccw_device_set_offline(CARD_RDEV(card)); 3873 ccw_device_set_offline(CARD_RDEV(card));
3748 ccw_device_set_online(CARD_RDEV(card)); 3874 rc = ccw_device_set_online(CARD_RDEV(card));
3749 ccw_device_set_online(CARD_WDEV(card)); 3875 if (rc)
3750 ccw_device_set_online(CARD_DDEV(card)); 3876 goto retriable;
3751 } 3877 rc = ccw_device_set_online(CARD_WDEV(card));
3878 if (rc)
3879 goto retriable;
3880 rc = ccw_device_set_online(CARD_DDEV(card));
3881 if (rc)
3882 goto retriable;
3752 rc = qeth_qdio_clear_card(card, card->info.type != QETH_CARD_TYPE_IQD); 3883 rc = qeth_qdio_clear_card(card, card->info.type != QETH_CARD_TYPE_IQD);
3884retriable:
3753 if (rc == -ERESTARTSYS) { 3885 if (rc == -ERESTARTSYS) {
3754 QETH_DBF_TEXT(SETUP, 2, "break1"); 3886 QETH_DBF_TEXT(SETUP, 2, "break1");
3755 return rc; 3887 return rc;
3756 } else if (rc) { 3888 } else if (rc) {
3757 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); 3889 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
3758 if (--retries < 0) 3890 if (++retries > 3)
3759 goto out; 3891 goto out;
3760 else 3892 else
3761 goto retry; 3893 goto retry;
3762 } 3894 }
3763
3764 rc = qeth_get_unitaddr(card);
3765 if (rc) {
3766 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
3767 return rc;
3768 }
3769
3770 ssqd = kmalloc(sizeof(struct qdio_ssqd_desc), GFP_KERNEL);
3771 if (!ssqd) {
3772 rc = -ENOMEM;
3773 goto out;
3774 }
3775 rc = qdio_get_ssqd_desc(CARD_DDEV(card), ssqd);
3776 if (rc == 0)
3777 mpno = ssqd->pcnt;
3778 kfree(ssqd);
3779
3780 if (mpno)
3781 mpno = min(mpno - 1, QETH_MAX_PORTNO);
3782 if (card->info.portno > mpno) {
3783 QETH_DBF_MESSAGE(2, "Device %s does not offer port number %d"
3784 "\n.", CARD_BUS_ID(card), card->info.portno);
3785 rc = -ENODEV;
3786 goto out;
3787 }
3788 qeth_init_tokens(card); 3895 qeth_init_tokens(card);
3789 qeth_init_func_level(card); 3896 qeth_init_func_level(card);
3790 rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb); 3897 rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb);
@@ -3868,7 +3975,7 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
3868 struct qdio_buffer_element *element = *__element; 3975 struct qdio_buffer_element *element = *__element;
3869 int offset = *__offset; 3976 int offset = *__offset;
3870 struct sk_buff *skb = NULL; 3977 struct sk_buff *skb = NULL;
3871 int skb_len; 3978 int skb_len = 0;
3872 void *data_ptr; 3979 void *data_ptr;
3873 int data_len; 3980 int data_len;
3874 int headroom = 0; 3981 int headroom = 0;
@@ -3887,20 +3994,24 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
3887 *hdr = element->addr + offset; 3994 *hdr = element->addr + offset;
3888 3995
3889 offset += sizeof(struct qeth_hdr); 3996 offset += sizeof(struct qeth_hdr);
3890 if (card->options.layer2) { 3997 switch ((*hdr)->hdr.l2.id) {
3891 if (card->info.type == QETH_CARD_TYPE_OSN) { 3998 case QETH_HEADER_TYPE_LAYER2:
3892 skb_len = (*hdr)->hdr.osn.pdu_length; 3999 skb_len = (*hdr)->hdr.l2.pkt_length;
3893 headroom = sizeof(struct qeth_hdr); 4000 break;
3894 } else { 4001 case QETH_HEADER_TYPE_LAYER3:
3895 skb_len = (*hdr)->hdr.l2.pkt_length;
3896 }
3897 } else {
3898 skb_len = (*hdr)->hdr.l3.length; 4002 skb_len = (*hdr)->hdr.l3.length;
3899 if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || 4003 if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) ||
3900 (card->info.link_type == QETH_LINK_TYPE_HSTR)) 4004 (card->info.link_type == QETH_LINK_TYPE_HSTR))
3901 headroom = TR_HLEN; 4005 headroom = TR_HLEN;
3902 else 4006 else
3903 headroom = ETH_HLEN; 4007 headroom = ETH_HLEN;
4008 break;
4009 case QETH_HEADER_TYPE_OSN:
4010 skb_len = (*hdr)->hdr.osn.pdu_length;
4011 headroom = sizeof(struct qeth_hdr);
4012 break;
4013 default:
4014 break;
3904 } 4015 }
3905 4016
3906 if (!skb_len) 4017 if (!skb_len)
@@ -4055,6 +4166,41 @@ void qeth_core_free_discipline(struct qeth_card *card)
4055 card->discipline.ccwgdriver = NULL; 4166 card->discipline.ccwgdriver = NULL;
4056} 4167}
4057 4168
4169static void qeth_determine_capabilities(struct qeth_card *card)
4170{
4171 int rc;
4172 int length;
4173 char *prcd;
4174
4175 QETH_DBF_TEXT(SETUP, 2, "detcapab");
4176 rc = ccw_device_set_online(CARD_DDEV(card));
4177 if (rc) {
4178 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
4179 goto out;
4180 }
4181
4182
4183 rc = qeth_read_conf_data(card, (void **) &prcd, &length);
4184 if (rc) {
4185 QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n",
4186 dev_name(&card->gdev->dev), rc);
4187 QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
4188 goto out_offline;
4189 }
4190 qeth_configure_unitaddr(card, prcd);
4191 qeth_configure_blkt_default(card, prcd);
4192 kfree(prcd);
4193
4194 rc = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
4195 if (rc)
4196 QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
4197
4198out_offline:
4199 ccw_device_set_offline(CARD_DDEV(card));
4200out:
4201 return;
4202}
4203
4058static int qeth_core_probe_device(struct ccwgroup_device *gdev) 4204static int qeth_core_probe_device(struct ccwgroup_device *gdev)
4059{ 4205{
4060 struct qeth_card *card; 4206 struct qeth_card *card;
@@ -4120,6 +4266,8 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
4120 write_lock_irqsave(&qeth_core_card_list.rwlock, flags); 4266 write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
4121 list_add_tail(&card->list, &qeth_core_card_list.list); 4267 list_add_tail(&card->list, &qeth_core_card_list.list);
4122 write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags); 4268 write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
4269
4270 qeth_determine_capabilities(card);
4123 return 0; 4271 return 0;
4124 4272
4125err_card: 4273err_card:
@@ -4303,13 +4451,19 @@ static struct {
4303 {"tx do_QDIO time"}, 4451 {"tx do_QDIO time"},
4304 {"tx do_QDIO count"}, 4452 {"tx do_QDIO count"},
4305 {"tx csum"}, 4453 {"tx csum"},
4454 {"tx lin"},
4306}; 4455};
4307 4456
4308int qeth_core_get_stats_count(struct net_device *dev) 4457int qeth_core_get_sset_count(struct net_device *dev, int stringset)
4309{ 4458{
4310 return (sizeof(qeth_ethtool_stats_keys) / ETH_GSTRING_LEN); 4459 switch (stringset) {
4460 case ETH_SS_STATS:
4461 return (sizeof(qeth_ethtool_stats_keys) / ETH_GSTRING_LEN);
4462 default:
4463 return -EINVAL;
4464 }
4311} 4465}
4312EXPORT_SYMBOL_GPL(qeth_core_get_stats_count); 4466EXPORT_SYMBOL_GPL(qeth_core_get_sset_count);
4313 4467
4314void qeth_core_get_ethtool_stats(struct net_device *dev, 4468void qeth_core_get_ethtool_stats(struct net_device *dev,
4315 struct ethtool_stats *stats, u64 *data) 4469 struct ethtool_stats *stats, u64 *data)
@@ -4355,6 +4509,7 @@ void qeth_core_get_ethtool_stats(struct net_device *dev,
4355 data[31] = card->perf_stats.outbound_do_qdio_time; 4509 data[31] = card->perf_stats.outbound_do_qdio_time;
4356 data[32] = card->perf_stats.outbound_do_qdio_cnt; 4510 data[32] = card->perf_stats.outbound_do_qdio_cnt;
4357 data[33] = card->perf_stats.tx_csum; 4511 data[33] = card->perf_stats.tx_csum;
4512 data[34] = card->perf_stats.tx_lin;
4358} 4513}
4359EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats); 4514EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats);
4360 4515
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index eecb2ee62e85..104a3351e02b 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -156,6 +156,8 @@ enum qeth_ipa_return_codes {
156 IPA_RC_IP_TABLE_FULL = 0x0002, 156 IPA_RC_IP_TABLE_FULL = 0x0002,
157 IPA_RC_UNKNOWN_ERROR = 0x0003, 157 IPA_RC_UNKNOWN_ERROR = 0x0003,
158 IPA_RC_UNSUPPORTED_COMMAND = 0x0004, 158 IPA_RC_UNSUPPORTED_COMMAND = 0x0004,
159 IPA_RC_TRACE_ALREADY_ACTIVE = 0x0005,
160 IPA_RC_INVALID_FORMAT = 0x0006,
159 IPA_RC_DUP_IPV6_REMOTE = 0x0008, 161 IPA_RC_DUP_IPV6_REMOTE = 0x0008,
160 IPA_RC_DUP_IPV6_HOME = 0x0010, 162 IPA_RC_DUP_IPV6_HOME = 0x0010,
161 IPA_RC_UNREGISTERED_ADDR = 0x0011, 163 IPA_RC_UNREGISTERED_ADDR = 0x0011,
@@ -196,6 +198,11 @@ enum qeth_ipa_return_codes {
196 IPA_RC_INVALID_IP_VERSION2 = 0xf001, 198 IPA_RC_INVALID_IP_VERSION2 = 0xf001,
197 IPA_RC_FFFF = 0xffff 199 IPA_RC_FFFF = 0xffff
198}; 200};
201/* for DELIP */
202#define IPA_RC_IP_ADDRESS_NOT_DEFINED IPA_RC_PRIMARY_ALREADY_DEFINED
203/* for SET_DIAGNOSTIC_ASSIST */
204#define IPA_RC_INVALID_SUBCMD IPA_RC_IP_TABLE_FULL
205#define IPA_RC_HARDWARE_AUTH_ERROR IPA_RC_UNKNOWN_ERROR
199 206
200/* IPA function flags; each flag marks availability of respective function */ 207/* IPA function flags; each flag marks availability of respective function */
201enum qeth_ipa_funcs { 208enum qeth_ipa_funcs {
@@ -234,18 +241,20 @@ enum qeth_ipa_setdelip_flags {
234 241
235/* SETADAPTER IPA Command: ****************************************************/ 242/* SETADAPTER IPA Command: ****************************************************/
236enum qeth_ipa_setadp_cmd { 243enum qeth_ipa_setadp_cmd {
237 IPA_SETADP_QUERY_COMMANDS_SUPPORTED = 0x0001, 244 IPA_SETADP_QUERY_COMMANDS_SUPPORTED = 0x00000001L,
238 IPA_SETADP_ALTER_MAC_ADDRESS = 0x0002, 245 IPA_SETADP_ALTER_MAC_ADDRESS = 0x00000002L,
239 IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x0004, 246 IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x00000004L,
240 IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x0008, 247 IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x00000008L,
241 IPA_SETADP_SET_ADDRESSING_MODE = 0x0010, 248 IPA_SETADP_SET_ADDRESSING_MODE = 0x00000010L,
242 IPA_SETADP_SET_CONFIG_PARMS = 0x0020, 249 IPA_SETADP_SET_CONFIG_PARMS = 0x00000020L,
243 IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x0040, 250 IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x00000040L,
244 IPA_SETADP_SET_BROADCAST_MODE = 0x0080, 251 IPA_SETADP_SET_BROADCAST_MODE = 0x00000080L,
245 IPA_SETADP_SEND_OSA_MESSAGE = 0x0100, 252 IPA_SETADP_SEND_OSA_MESSAGE = 0x00000100L,
246 IPA_SETADP_SET_SNMP_CONTROL = 0x0200, 253 IPA_SETADP_SET_SNMP_CONTROL = 0x00000200L,
247 IPA_SETADP_QUERY_CARD_INFO = 0x0400, 254 IPA_SETADP_QUERY_CARD_INFO = 0x00000400L,
248 IPA_SETADP_SET_PROMISC_MODE = 0x0800, 255 IPA_SETADP_SET_PROMISC_MODE = 0x00000800L,
256 IPA_SETADP_SET_DIAG_ASSIST = 0x00002000L,
257 IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L,
249}; 258};
250enum qeth_ipa_mac_ops { 259enum qeth_ipa_mac_ops {
251 CHANGE_ADDR_READ_MAC = 0, 260 CHANGE_ADDR_READ_MAC = 0,
@@ -264,6 +273,20 @@ enum qeth_ipa_promisc_modes {
264 SET_PROMISC_MODE_OFF = 0, 273 SET_PROMISC_MODE_OFF = 0,
265 SET_PROMISC_MODE_ON = 1, 274 SET_PROMISC_MODE_ON = 1,
266}; 275};
276enum qeth_ipa_isolation_modes {
277 ISOLATION_MODE_NONE = 0x00000000L,
278 ISOLATION_MODE_FWD = 0x00000001L,
279 ISOLATION_MODE_DROP = 0x00000002L,
280};
281enum qeth_ipa_set_access_mode_rc {
282 SET_ACCESS_CTRL_RC_SUCCESS = 0x0000,
283 SET_ACCESS_CTRL_RC_NOT_SUPPORTED = 0x0004,
284 SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED = 0x0008,
285 SET_ACCESS_CTRL_RC_ALREADY_ISOLATED = 0x0010,
286 SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER = 0x0014,
287 SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF = 0x0018,
288};
289
267 290
268/* (SET)DELIP(M) IPA stuff ***************************************************/ 291/* (SET)DELIP(M) IPA stuff ***************************************************/
269struct qeth_ipacmd_setdelip4 { 292struct qeth_ipacmd_setdelip4 {
@@ -376,6 +399,11 @@ struct qeth_snmp_ureq {
376 struct qeth_snmp_cmd cmd; 399 struct qeth_snmp_cmd cmd;
377} __attribute__((packed)); 400} __attribute__((packed));
378 401
402/* SET_ACCESS_CONTROL: same format for request and reply */
403struct qeth_set_access_ctrl {
404 __u32 subcmd_code;
405} __attribute__((packed));
406
379struct qeth_ipacmd_setadpparms_hdr { 407struct qeth_ipacmd_setadpparms_hdr {
380 __u32 supp_hw_cmds; 408 __u32 supp_hw_cmds;
381 __u32 reserved1; 409 __u32 reserved1;
@@ -394,6 +422,7 @@ struct qeth_ipacmd_setadpparms {
394 struct qeth_query_cmds_supp query_cmds_supp; 422 struct qeth_query_cmds_supp query_cmds_supp;
395 struct qeth_change_addr change_addr; 423 struct qeth_change_addr change_addr;
396 struct qeth_snmp_cmd snmp; 424 struct qeth_snmp_cmd snmp;
425 struct qeth_set_access_ctrl set_access_ctrl;
397 __u32 mode; 426 __u32 mode;
398 } data; 427 } data;
399} __attribute__ ((packed)); 428} __attribute__ ((packed));
@@ -403,6 +432,40 @@ struct qeth_create_destroy_address {
403 __u8 unique_id[8]; 432 __u8 unique_id[8];
404} __attribute__ ((packed)); 433} __attribute__ ((packed));
405 434
435/* SET DIAGNOSTIC ASSIST IPA Command: *************************************/
436
437enum qeth_diags_cmds {
438 QETH_DIAGS_CMD_QUERY = 0x0001,
439 QETH_DIAGS_CMD_TRAP = 0x0002,
440 QETH_DIAGS_CMD_TRACE = 0x0004,
441 QETH_DIAGS_CMD_NOLOG = 0x0008,
442 QETH_DIAGS_CMD_DUMP = 0x0010,
443};
444
445enum qeth_diags_trace_types {
446 QETH_DIAGS_TYPE_HIPERSOCKET = 0x02,
447};
448
449enum qeth_diags_trace_cmds {
450 QETH_DIAGS_CMD_TRACE_ENABLE = 0x0001,
451 QETH_DIAGS_CMD_TRACE_DISABLE = 0x0002,
452 QETH_DIAGS_CMD_TRACE_MODIFY = 0x0004,
453 QETH_DIAGS_CMD_TRACE_REPLACE = 0x0008,
454 QETH_DIAGS_CMD_TRACE_QUERY = 0x0010,
455};
456
457struct qeth_ipacmd_diagass {
458 __u32 host_tod2;
459 __u32:32;
460 __u16 subcmd_len;
461 __u16:16;
462 __u32 subcmd;
463 __u8 type;
464 __u8 action;
465 __u16 options;
466 __u32:32;
467} __attribute__ ((packed));
468
406/* Header for each IPA command */ 469/* Header for each IPA command */
407struct qeth_ipacmd_hdr { 470struct qeth_ipacmd_hdr {
408 __u8 command; 471 __u8 command;
@@ -431,6 +494,7 @@ struct qeth_ipa_cmd {
431 struct qeth_create_destroy_address create_destroy_addr; 494 struct qeth_create_destroy_address create_destroy_addr;
432 struct qeth_ipacmd_setadpparms setadapterparms; 495 struct qeth_ipacmd_setadpparms setadapterparms;
433 struct qeth_set_routing setrtg; 496 struct qeth_set_routing setrtg;
497 struct qeth_ipacmd_diagass diagass;
434 } data; 498 } data;
435} __attribute__ ((packed)); 499} __attribute__ ((packed));
436 500
@@ -448,7 +512,6 @@ enum qeth_ipa_arp_return_codes {
448 QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008, 512 QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008,
449}; 513};
450 514
451
452extern char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc); 515extern char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
453extern char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd); 516extern char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
454 517
@@ -507,7 +570,7 @@ extern unsigned char ULP_ENABLE[];
507 (PDU_ENCAPSULATION(buffer) + 0x17) 570 (PDU_ENCAPSULATION(buffer) + 0x17)
508#define QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer) \ 571#define QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer) \
509 (PDU_ENCAPSULATION(buffer) + 0x2b) 572 (PDU_ENCAPSULATION(buffer) + 0x2b)
510/* Layer 2 defintions */ 573/* Layer 2 definitions */
511#define QETH_PROT_LAYER2 0x08 574#define QETH_PROT_LAYER2 0x08
512#define QETH_PROT_TCPIP 0x03 575#define QETH_PROT_TCPIP 0x03
513#define QETH_PROT_OSN2 0x0a 576#define QETH_PROT_OSN2 0x0a
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 33505c2a0e3a..25dfd5abd19b 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -8,6 +8,9 @@
8 * Frank Blaschka <frank.blaschka@de.ibm.com> 8 * Frank Blaschka <frank.blaschka@de.ibm.com>
9 */ 9 */
10 10
11#define KMSG_COMPONENT "qeth"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13
11#include <linux/list.h> 14#include <linux/list.h>
12#include <linux/rwsem.h> 15#include <linux/rwsem.h>
13#include <asm/ebcdic.h> 16#include <asm/ebcdic.h>
@@ -118,7 +121,7 @@ static ssize_t qeth_dev_portno_store(struct device *dev,
118{ 121{
119 struct qeth_card *card = dev_get_drvdata(dev); 122 struct qeth_card *card = dev_get_drvdata(dev);
120 char *tmp; 123 char *tmp;
121 unsigned int portno; 124 unsigned int portno, limit;
122 125
123 if (!card) 126 if (!card)
124 return -EINVAL; 127 return -EINVAL;
@@ -128,9 +131,11 @@ static ssize_t qeth_dev_portno_store(struct device *dev,
128 return -EPERM; 131 return -EPERM;
129 132
130 portno = simple_strtoul(buf, &tmp, 16); 133 portno = simple_strtoul(buf, &tmp, 16);
131 if (portno > QETH_MAX_PORTNO) { 134 if (portno > QETH_MAX_PORTNO)
135 return -EINVAL;
136 limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt);
137 if (portno > limit)
132 return -EINVAL; 138 return -EINVAL;
133 }
134 139
135 card->info.portno = portno; 140 card->info.portno = portno;
136 return count; 141 return count;
@@ -416,7 +421,11 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
416static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show, 421static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
417 qeth_dev_layer2_store); 422 qeth_dev_layer2_store);
418 423
419static ssize_t qeth_dev_large_send_show(struct device *dev, 424#define ATTR_QETH_ISOLATION_NONE ("none")
425#define ATTR_QETH_ISOLATION_FWD ("forward")
426#define ATTR_QETH_ISOLATION_DROP ("drop")
427
428static ssize_t qeth_dev_isolation_show(struct device *dev,
420 struct device_attribute *attr, char *buf) 429 struct device_attribute *attr, char *buf)
421{ 430{
422 struct qeth_card *card = dev_get_drvdata(dev); 431 struct qeth_card *card = dev_get_drvdata(dev);
@@ -424,44 +433,69 @@ static ssize_t qeth_dev_large_send_show(struct device *dev,
424 if (!card) 433 if (!card)
425 return -EINVAL; 434 return -EINVAL;
426 435
427 switch (card->options.large_send) { 436 switch (card->options.isolation) {
428 case QETH_LARGE_SEND_NO: 437 case ISOLATION_MODE_NONE:
429 return sprintf(buf, "%s\n", "no"); 438 return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_NONE);
430 case QETH_LARGE_SEND_TSO: 439 case ISOLATION_MODE_FWD:
431 return sprintf(buf, "%s\n", "TSO"); 440 return snprintf(buf, 9, "%s\n", ATTR_QETH_ISOLATION_FWD);
441 case ISOLATION_MODE_DROP:
442 return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_DROP);
432 default: 443 default:
433 return sprintf(buf, "%s\n", "N/A"); 444 return snprintf(buf, 5, "%s\n", "N/A");
434 } 445 }
435} 446}
436 447
437static ssize_t qeth_dev_large_send_store(struct device *dev, 448static ssize_t qeth_dev_isolation_store(struct device *dev,
438 struct device_attribute *attr, const char *buf, size_t count) 449 struct device_attribute *attr, const char *buf, size_t count)
439{ 450{
440 struct qeth_card *card = dev_get_drvdata(dev); 451 struct qeth_card *card = dev_get_drvdata(dev);
441 enum qeth_large_send_types type; 452 enum qeth_ipa_isolation_modes isolation;
442 int rc = 0; 453 int rc = 0;
443 char *tmp; 454 char *tmp, *curtoken;
455 curtoken = (char *) buf;
444 456
445 if (!card) 457 if (!card) {
446 return -EINVAL; 458 rc = -EINVAL;
447 tmp = strsep((char **) &buf, "\n"); 459 goto out;
448 if (!strcmp(tmp, "no")) { 460 }
449 type = QETH_LARGE_SEND_NO; 461
450 } else if (!strcmp(tmp, "TSO")) { 462 /* check for unknown, too, in case we do not yet know who we are */
451 type = QETH_LARGE_SEND_TSO; 463 if (card->info.type != QETH_CARD_TYPE_OSAE &&
464 card->info.type != QETH_CARD_TYPE_UNKNOWN) {
465 rc = -EOPNOTSUPP;
466 dev_err(&card->gdev->dev, "Adapter does not "
467 "support QDIO data connection isolation\n");
468 goto out;
469 }
470
471 /* parse input into isolation mode */
472 tmp = strsep(&curtoken, "\n");
473 if (!strcmp(tmp, ATTR_QETH_ISOLATION_NONE)) {
474 isolation = ISOLATION_MODE_NONE;
475 } else if (!strcmp(tmp, ATTR_QETH_ISOLATION_FWD)) {
476 isolation = ISOLATION_MODE_FWD;
477 } else if (!strcmp(tmp, ATTR_QETH_ISOLATION_DROP)) {
478 isolation = ISOLATION_MODE_DROP;
452 } else { 479 } else {
453 return -EINVAL; 480 rc = -EINVAL;
481 goto out;
454 } 482 }
455 if (card->options.large_send == type) 483 rc = count;
456 return count; 484
457 rc = qeth_set_large_send(card, type); 485 /* defer IP assist if device is offline (until discipline->set_online)*/
458 if (rc) 486 card->options.isolation = isolation;
459 return rc; 487 if (card->state == CARD_STATE_SOFTSETUP ||
460 return count; 488 card->state == CARD_STATE_UP) {
489 int ipa_rc = qeth_set_access_ctrl_online(card);
490 if (ipa_rc != 0)
491 rc = ipa_rc;
492 }
493out:
494 return rc;
461} 495}
462 496
463static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show, 497static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
464 qeth_dev_large_send_store); 498 qeth_dev_isolation_store);
465 499
466static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value) 500static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
467{ 501{
@@ -508,7 +542,7 @@ static ssize_t qeth_dev_blkt_total_store(struct device *dev,
508 struct qeth_card *card = dev_get_drvdata(dev); 542 struct qeth_card *card = dev_get_drvdata(dev);
509 543
510 return qeth_dev_blkt_store(card, buf, count, 544 return qeth_dev_blkt_store(card, buf, count,
511 &card->info.blkt.time_total, 1000); 545 &card->info.blkt.time_total, 5000);
512} 546}
513 547
514 548
@@ -530,7 +564,7 @@ static ssize_t qeth_dev_blkt_inter_store(struct device *dev,
530 struct qeth_card *card = dev_get_drvdata(dev); 564 struct qeth_card *card = dev_get_drvdata(dev);
531 565
532 return qeth_dev_blkt_store(card, buf, count, 566 return qeth_dev_blkt_store(card, buf, count,
533 &card->info.blkt.inter_packet, 100); 567 &card->info.blkt.inter_packet, 1000);
534} 568}
535 569
536static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show, 570static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,
@@ -551,7 +585,7 @@ static ssize_t qeth_dev_blkt_inter_jumbo_store(struct device *dev,
551 struct qeth_card *card = dev_get_drvdata(dev); 585 struct qeth_card *card = dev_get_drvdata(dev);
552 586
553 return qeth_dev_blkt_store(card, buf, count, 587 return qeth_dev_blkt_store(card, buf, count,
554 &card->info.blkt.inter_packet_jumbo, 100); 588 &card->info.blkt.inter_packet_jumbo, 1000);
555} 589}
556 590
557static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show, 591static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show,
@@ -582,7 +616,7 @@ static struct attribute *qeth_device_attrs[] = {
582 &dev_attr_recover.attr, 616 &dev_attr_recover.attr,
583 &dev_attr_performance_stats.attr, 617 &dev_attr_performance_stats.attr,
584 &dev_attr_layer2.attr, 618 &dev_attr_layer2.attr,
585 &dev_attr_large_send.attr, 619 &dev_attr_isolation.attr,
586 NULL, 620 NULL,
587}; 621};
588 622
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index f4f3ca1393b2..6a801dc3bf8e 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -16,6 +16,7 @@
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/slab.h>
19#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
20#include <linux/mii.h> 21#include <linux/mii.h>
21#include <linux/ip.h> 22#include <linux/ip.h>
@@ -486,22 +487,14 @@ static int qeth_l2_send_setmac_cb(struct qeth_card *card,
486 case IPA_RC_L2_DUP_MAC: 487 case IPA_RC_L2_DUP_MAC:
487 case IPA_RC_L2_DUP_LAYER3_MAC: 488 case IPA_RC_L2_DUP_LAYER3_MAC:
488 dev_warn(&card->gdev->dev, 489 dev_warn(&card->gdev->dev,
489 "MAC address " 490 "MAC address %pM already exists\n",
490 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " 491 card->dev->dev_addr);
491 "already exists\n",
492 card->dev->dev_addr[0], card->dev->dev_addr[1],
493 card->dev->dev_addr[2], card->dev->dev_addr[3],
494 card->dev->dev_addr[4], card->dev->dev_addr[5]);
495 break; 492 break;
496 case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: 493 case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP:
497 case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: 494 case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP:
498 dev_warn(&card->gdev->dev, 495 dev_warn(&card->gdev->dev,
499 "MAC address " 496 "MAC address %pM is not authorized\n",
500 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " 497 card->dev->dev_addr);
501 "is not authorized\n",
502 card->dev->dev_addr[0], card->dev->dev_addr[1],
503 card->dev->dev_addr[2], card->dev->dev_addr[3],
504 card->dev->dev_addr[4], card->dev->dev_addr[5]);
505 break; 498 break;
506 default: 499 default:
507 break; 500 break;
@@ -512,12 +505,8 @@ static int qeth_l2_send_setmac_cb(struct qeth_card *card,
512 memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac, 505 memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac,
513 OSA_ADDR_LEN); 506 OSA_ADDR_LEN);
514 dev_info(&card->gdev->dev, 507 dev_info(&card->gdev->dev,
515 "MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " 508 "MAC address %pM successfully registered on device %s\n",
516 "successfully registered on device %s\n", 509 card->dev->dev_addr, card->dev->name);
517 card->dev->dev_addr[0], card->dev->dev_addr[1],
518 card->dev->dev_addr[2], card->dev->dev_addr[3],
519 card->dev->dev_addr[4], card->dev->dev_addr[5],
520 card->dev->name);
521 } 510 }
522 return 0; 511 return 0;
523} 512}
@@ -634,7 +623,7 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
634 for (dm = dev->mc_list; dm; dm = dm->next) 623 for (dm = dev->mc_list; dm; dm = dm->next)
635 qeth_l2_add_mc(card, dm->da_addr, 0); 624 qeth_l2_add_mc(card, dm->da_addr, 0);
636 625
637 list_for_each_entry(ha, &dev->uc.list, list) 626 netdev_for_each_uc_addr(ha, dev)
638 qeth_l2_add_mc(card, ha->addr, 1); 627 qeth_l2_add_mc(card, ha->addr, 1);
639 628
640 spin_unlock_bh(&card->mclock); 629 spin_unlock_bh(&card->mclock);
@@ -781,7 +770,8 @@ static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev,
781 index = i % QDIO_MAX_BUFFERS_PER_Q; 770 index = i % QDIO_MAX_BUFFERS_PER_Q;
782 buffer = &card->qdio.in_q->bufs[index]; 771 buffer = &card->qdio.in_q->bufs[index];
783 if (!(qdio_err && 772 if (!(qdio_err &&
784 qeth_check_qdio_errors(buffer->buffer, qdio_err, "qinerr"))) 773 qeth_check_qdio_errors(card, buffer->buffer, qdio_err,
774 "qinerr")))
785 qeth_l2_process_inbound_buffer(card, buffer, index); 775 qeth_l2_process_inbound_buffer(card, buffer, index);
786 /* clear buffer and give back to hardware */ 776 /* clear buffer and give back to hardware */
787 qeth_put_buffer_pool_entry(card, buffer->pool_entry); 777 qeth_put_buffer_pool_entry(card, buffer->pool_entry);
@@ -866,7 +856,7 @@ static const struct ethtool_ops qeth_l2_ethtool_ops = {
866 .get_link = ethtool_op_get_link, 856 .get_link = ethtool_op_get_link,
867 .get_strings = qeth_core_get_strings, 857 .get_strings = qeth_core_get_strings,
868 .get_ethtool_stats = qeth_core_get_ethtool_stats, 858 .get_ethtool_stats = qeth_core_get_ethtool_stats,
869 .get_stats_count = qeth_core_get_stats_count, 859 .get_sset_count = qeth_core_get_sset_count,
870 .get_drvinfo = qeth_core_get_drvinfo, 860 .get_drvinfo = qeth_core_get_drvinfo,
871 .get_settings = qeth_core_ethtool_get_settings, 861 .get_settings = qeth_core_ethtool_get_settings,
872}; 862};
@@ -874,7 +864,7 @@ static const struct ethtool_ops qeth_l2_ethtool_ops = {
874static const struct ethtool_ops qeth_l2_osn_ops = { 864static const struct ethtool_ops qeth_l2_osn_ops = {
875 .get_strings = qeth_core_get_strings, 865 .get_strings = qeth_core_get_strings,
876 .get_ethtool_stats = qeth_core_get_ethtool_stats, 866 .get_ethtool_stats = qeth_core_get_ethtool_stats,
877 .get_stats_count = qeth_core_get_stats_count, 867 .get_sset_count = qeth_core_get_sset_count,
878 .get_drvinfo = qeth_core_get_drvinfo, 868 .get_drvinfo = qeth_core_get_drvinfo,
879}; 869};
880 870
@@ -938,32 +928,18 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
938 QETH_DBF_TEXT(SETUP, 2, "setonlin"); 928 QETH_DBF_TEXT(SETUP, 2, "setonlin");
939 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); 929 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
940 930
941 qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
942 recover_flag = card->state; 931 recover_flag = card->state;
943 rc = ccw_device_set_online(CARD_RDEV(card));
944 if (rc) {
945 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
946 return -EIO;
947 }
948 rc = ccw_device_set_online(CARD_WDEV(card));
949 if (rc) {
950 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
951 return -EIO;
952 }
953 rc = ccw_device_set_online(CARD_DDEV(card));
954 if (rc) {
955 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
956 return -EIO;
957 }
958
959 rc = qeth_core_hardsetup_card(card); 932 rc = qeth_core_hardsetup_card(card);
960 if (rc) { 933 if (rc) {
961 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); 934 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
935 rc = -ENODEV;
962 goto out_remove; 936 goto out_remove;
963 } 937 }
964 938
965 if (!card->dev && qeth_l2_setup_netdev(card)) 939 if (!card->dev && qeth_l2_setup_netdev(card)) {
940 rc = -ENODEV;
966 goto out_remove; 941 goto out_remove;
942 }
967 943
968 if (card->info.type != QETH_CARD_TYPE_OSN) 944 if (card->info.type != QETH_CARD_TYPE_OSN)
969 qeth_l2_send_setmac(card, &card->dev->dev_addr[0]); 945 qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
@@ -983,12 +959,14 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
983 card->lan_online = 0; 959 card->lan_online = 0;
984 return 0; 960 return 0;
985 } 961 }
962 rc = -ENODEV;
986 goto out_remove; 963 goto out_remove;
987 } else 964 } else
988 card->lan_online = 1; 965 card->lan_online = 1;
989 966
990 if (card->info.type != QETH_CARD_TYPE_OSN) { 967 if (card->info.type != QETH_CARD_TYPE_OSN) {
991 qeth_set_large_send(card, card->options.large_send); 968 /* configure isolation level */
969 qeth_set_access_ctrl_online(card);
992 qeth_l2_process_vlans(card, 0); 970 qeth_l2_process_vlans(card, 0);
993 } 971 }
994 972
@@ -997,6 +975,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
997 rc = qeth_init_qdio_queues(card); 975 rc = qeth_init_qdio_queues(card);
998 if (rc) { 976 if (rc) {
999 QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); 977 QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
978 rc = -ENODEV;
1000 goto out_remove; 979 goto out_remove;
1001 } 980 }
1002 card->state = CARD_STATE_SOFTSETUP; 981 card->state = CARD_STATE_SOFTSETUP;
@@ -1018,6 +997,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
1018 /* let user_space know that device is online */ 997 /* let user_space know that device is online */
1019 kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); 998 kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
1020 return 0; 999 return 0;
1000
1021out_remove: 1001out_remove:
1022 card->use_hard_stop = 1; 1002 card->use_hard_stop = 1;
1023 qeth_l2_stop_card(card, 0); 1003 qeth_l2_stop_card(card, 0);
@@ -1028,7 +1008,7 @@ out_remove:
1028 card->state = CARD_STATE_RECOVER; 1008 card->state = CARD_STATE_RECOVER;
1029 else 1009 else
1030 card->state = CARD_STATE_DOWN; 1010 card->state = CARD_STATE_DOWN;
1031 return -ENODEV; 1011 return rc;
1032} 1012}
1033 1013
1034static int qeth_l2_set_online(struct ccwgroup_device *gdev) 1014static int qeth_l2_set_online(struct ccwgroup_device *gdev)
@@ -1092,11 +1072,9 @@ static int qeth_l2_recover(void *ptr)
1092 dev_info(&card->gdev->dev, 1072 dev_info(&card->gdev->dev,
1093 "Device successfully recovered!\n"); 1073 "Device successfully recovered!\n");
1094 else { 1074 else {
1095 if (card->dev) { 1075 rtnl_lock();
1096 rtnl_lock(); 1076 dev_close(card->dev);
1097 dev_close(card->dev); 1077 rtnl_unlock();
1098 rtnl_unlock();
1099 }
1100 dev_warn(&card->gdev->dev, "The qeth device driver " 1078 dev_warn(&card->gdev->dev, "The qeth device driver "
1101 "failed to recover an error on the device\n"); 1079 "failed to recover an error on the device\n");
1102 } 1080 }
@@ -1150,11 +1128,9 @@ static int qeth_l2_pm_resume(struct ccwgroup_device *gdev)
1150 if (card->state == CARD_STATE_RECOVER) { 1128 if (card->state == CARD_STATE_RECOVER) {
1151 rc = __qeth_l2_set_online(card->gdev, 1); 1129 rc = __qeth_l2_set_online(card->gdev, 1);
1152 if (rc) { 1130 if (rc) {
1153 if (card->dev) { 1131 rtnl_lock();
1154 rtnl_lock(); 1132 dev_close(card->dev);
1155 dev_close(card->dev); 1133 rtnl_unlock();
1156 rtnl_unlock();
1157 }
1158 } 1134 }
1159 } else 1135 } else
1160 rc = __qeth_l2_set_online(card->gdev, 0); 1136 rc = __qeth_l2_set_online(card->gdev, 0);
diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h
index 9f143c83bba3..8447d233d0b3 100644
--- a/drivers/s390/net/qeth_l3.h
+++ b/drivers/s390/net/qeth_l3.h
@@ -13,6 +13,8 @@
13 13
14#include "qeth_core.h" 14#include "qeth_core.h"
15 15
16#define QETH_SNIFF_AVAIL 0x0008
17
16struct qeth_ipaddr { 18struct qeth_ipaddr {
17 struct list_head entry; 19 struct list_head entry;
18 enum qeth_ip_types type; 20 enum qeth_ip_types type;
@@ -60,5 +62,7 @@ void qeth_l3_del_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
60int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *); 62int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
61void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions, 63void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions,
62 const u8 *); 64 const u8 *);
65int qeth_l3_set_large_send(struct qeth_card *, enum qeth_large_send_types);
66int qeth_l3_set_rx_csum(struct qeth_card *, enum qeth_checksum_types);
63 67
64#endif /* __QETH_L3_H__ */ 68#endif /* __QETH_L3_H__ */
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 073b6d354915..fc6ca1da8b98 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -22,6 +22,7 @@
22#include <linux/ipv6.h> 22#include <linux/ipv6.h>
23#include <linux/inetdevice.h> 23#include <linux/inetdevice.h>
24#include <linux/igmp.h> 24#include <linux/igmp.h>
25#include <linux/slab.h>
25 26
26#include <net/ip.h> 27#include <net/ip.h>
27#include <net/arp.h> 28#include <net/arp.h>
@@ -41,6 +42,32 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *,
41static int __qeth_l3_set_online(struct ccwgroup_device *, int); 42static int __qeth_l3_set_online(struct ccwgroup_device *, int);
42static int __qeth_l3_set_offline(struct ccwgroup_device *, int); 43static int __qeth_l3_set_offline(struct ccwgroup_device *, int);
43 44
45int qeth_l3_set_large_send(struct qeth_card *card,
46 enum qeth_large_send_types type)
47{
48 int rc = 0;
49
50 card->options.large_send = type;
51 if (card->dev == NULL)
52 return 0;
53
54 if (card->options.large_send == QETH_LARGE_SEND_TSO) {
55 if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
56 card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
57 NETIF_F_HW_CSUM;
58 } else {
59 card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
60 NETIF_F_HW_CSUM);
61 card->options.large_send = QETH_LARGE_SEND_NO;
62 rc = -EOPNOTSUPP;
63 }
64 } else {
65 card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
66 NETIF_F_HW_CSUM);
67 card->options.large_send = QETH_LARGE_SEND_NO;
68 }
69 return rc;
70}
44 71
45static int qeth_l3_isxdigit(char *buf) 72static int qeth_l3_isxdigit(char *buf)
46{ 73{
@@ -216,6 +243,8 @@ static int __qeth_l3_insert_ip_todo(struct qeth_card *card,
216 struct qeth_ipaddr *tmp, *t; 243 struct qeth_ipaddr *tmp, *t;
217 int found = 0; 244 int found = 0;
218 245
246 if (card->options.sniffer)
247 return 0;
219 list_for_each_entry_safe(tmp, t, card->ip_tbd_list, entry) { 248 list_for_each_entry_safe(tmp, t, card->ip_tbd_list, entry) {
220 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) && 249 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
221 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC)) 250 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
@@ -431,6 +460,8 @@ static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
431 QETH_DBF_TEXT(TRACE, 2, "sdiplist"); 460 QETH_DBF_TEXT(TRACE, 2, "sdiplist");
432 QETH_DBF_HEX(TRACE, 2, &card, sizeof(void *)); 461 QETH_DBF_HEX(TRACE, 2, &card, sizeof(void *));
433 462
463 if (card->options.sniffer)
464 return;
434 spin_lock_irqsave(&card->ip_lock, flags); 465 spin_lock_irqsave(&card->ip_lock, flags);
435 tbd_list = card->ip_tbd_list; 466 tbd_list = card->ip_tbd_list;
436 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC); 467 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC);
@@ -469,7 +500,7 @@ static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
469 spin_unlock_irqrestore(&card->ip_lock, flags); 500 spin_unlock_irqrestore(&card->ip_lock, flags);
470 rc = qeth_l3_deregister_addr_entry(card, addr); 501 rc = qeth_l3_deregister_addr_entry(card, addr);
471 spin_lock_irqsave(&card->ip_lock, flags); 502 spin_lock_irqsave(&card->ip_lock, flags);
472 if (!rc || (rc == IPA_RC_PRIMARY_ALREADY_DEFINED)) 503 if (!rc || (rc == IPA_RC_IP_ADDRESS_NOT_DEFINED))
473 kfree(addr); 504 kfree(addr);
474 else 505 else
475 list_add_tail(&addr->entry, &card->ip_list); 506 list_add_tail(&addr->entry, &card->ip_list);
@@ -487,6 +518,8 @@ static void qeth_l3_clear_ip_list(struct qeth_card *card, int clean,
487 unsigned long flags; 518 unsigned long flags;
488 519
489 QETH_DBF_TEXT(TRACE, 4, "clearip"); 520 QETH_DBF_TEXT(TRACE, 4, "clearip");
521 if (recover && card->options.sniffer)
522 return;
490 spin_lock_irqsave(&card->ip_lock, flags); 523 spin_lock_irqsave(&card->ip_lock, flags);
491 /* clear todo list */ 524 /* clear todo list */
492 list_for_each_entry_safe(addr, tmp, card->ip_tbd_list, entry) { 525 list_for_each_entry_safe(addr, tmp, card->ip_tbd_list, entry) {
@@ -1439,6 +1472,35 @@ static int qeth_l3_send_checksum_command(struct qeth_card *card)
1439 return 0; 1472 return 0;
1440} 1473}
1441 1474
1475int qeth_l3_set_rx_csum(struct qeth_card *card,
1476 enum qeth_checksum_types csum_type)
1477{
1478 int rc = 0;
1479
1480 if (card->options.checksum_type == HW_CHECKSUMMING) {
1481 if ((csum_type != HW_CHECKSUMMING) &&
1482 (card->state != CARD_STATE_DOWN)) {
1483 rc = qeth_l3_send_simple_setassparms(card,
1484 IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
1485 if (rc)
1486 return -EIO;
1487 }
1488 } else {
1489 if (csum_type == HW_CHECKSUMMING) {
1490 if (card->state != CARD_STATE_DOWN) {
1491 if (!qeth_is_supported(card,
1492 IPA_INBOUND_CHECKSUM))
1493 return -EPERM;
1494 rc = qeth_l3_send_checksum_command(card);
1495 if (rc)
1496 return -EIO;
1497 }
1498 }
1499 }
1500 card->options.checksum_type = csum_type;
1501 return rc;
1502}
1503
1442static int qeth_l3_start_ipa_checksum(struct qeth_card *card) 1504static int qeth_l3_start_ipa_checksum(struct qeth_card *card)
1443{ 1505{
1444 int rc = 0; 1506 int rc = 0;
@@ -1506,6 +1568,8 @@ static int qeth_l3_start_ipa_tso(struct qeth_card *card)
1506static int qeth_l3_start_ipassists(struct qeth_card *card) 1568static int qeth_l3_start_ipassists(struct qeth_card *card)
1507{ 1569{
1508 QETH_DBF_TEXT(TRACE, 3, "strtipas"); 1570 QETH_DBF_TEXT(TRACE, 3, "strtipas");
1571
1572 qeth_set_access_ctrl_online(card); /* go on*/
1509 qeth_l3_start_ipa_arp_processing(card); /* go on*/ 1573 qeth_l3_start_ipa_arp_processing(card); /* go on*/
1510 qeth_l3_start_ipa_ip_fragmentation(card); /* go on*/ 1574 qeth_l3_start_ipa_ip_fragmentation(card); /* go on*/
1511 qeth_l3_start_ipa_source_mac(card); /* go on*/ 1575 qeth_l3_start_ipa_source_mac(card); /* go on*/
@@ -1617,6 +1681,80 @@ static int qeth_l3_get_unique_id(struct qeth_card *card)
1617 return rc; 1681 return rc;
1618} 1682}
1619 1683
1684static int
1685qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply,
1686 unsigned long data)
1687{
1688 struct qeth_ipa_cmd *cmd;
1689 __u16 rc;
1690
1691 QETH_DBF_TEXT(SETUP, 2, "diastrcb");
1692
1693 cmd = (struct qeth_ipa_cmd *)data;
1694 rc = cmd->hdr.return_code;
1695 if (rc)
1696 QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc);
1697 switch (cmd->data.diagass.action) {
1698 case QETH_DIAGS_CMD_TRACE_QUERY:
1699 break;
1700 case QETH_DIAGS_CMD_TRACE_DISABLE:
1701 switch (rc) {
1702 case 0:
1703 case IPA_RC_INVALID_SUBCMD:
1704 card->info.promisc_mode = SET_PROMISC_MODE_OFF;
1705 dev_info(&card->gdev->dev, "The HiperSockets network "
1706 "traffic analyzer is deactivated\n");
1707 break;
1708 default:
1709 break;
1710 }
1711 break;
1712 case QETH_DIAGS_CMD_TRACE_ENABLE:
1713 switch (rc) {
1714 case 0:
1715 card->info.promisc_mode = SET_PROMISC_MODE_ON;
1716 dev_info(&card->gdev->dev, "The HiperSockets network "
1717 "traffic analyzer is activated\n");
1718 break;
1719 case IPA_RC_HARDWARE_AUTH_ERROR:
1720 dev_warn(&card->gdev->dev, "The device is not "
1721 "authorized to run as a HiperSockets network "
1722 "traffic analyzer\n");
1723 break;
1724 case IPA_RC_TRACE_ALREADY_ACTIVE:
1725 dev_warn(&card->gdev->dev, "A HiperSockets "
1726 "network traffic analyzer is already "
1727 "active in the HiperSockets LAN\n");
1728 break;
1729 default:
1730 break;
1731 }
1732 break;
1733 default:
1734 QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n",
1735 cmd->data.diagass.action, QETH_CARD_IFNAME(card));
1736 }
1737
1738 return 0;
1739}
1740
1741static int
1742qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd)
1743{
1744 struct qeth_cmd_buffer *iob;
1745 struct qeth_ipa_cmd *cmd;
1746
1747 QETH_DBF_TEXT(SETUP, 2, "diagtrac");
1748
1749 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
1750 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1751 cmd->data.diagass.subcmd_len = 16;
1752 cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE;
1753 cmd->data.diagass.type = QETH_DIAGS_TYPE_HIPERSOCKET;
1754 cmd->data.diagass.action = diags_cmd;
1755 return qeth_send_ipa_cmd(card, iob, qeth_diags_trace_cb, NULL);
1756}
1757
1620static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac, 1758static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac,
1621 struct net_device *dev) 1759 struct net_device *dev)
1622{ 1760{
@@ -1894,7 +2032,10 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
1894 case QETH_CAST_ANYCAST: 2032 case QETH_CAST_ANYCAST:
1895 case QETH_CAST_NOCAST: 2033 case QETH_CAST_NOCAST:
1896 default: 2034 default:
1897 skb->pkt_type = PACKET_HOST; 2035 if (card->options.sniffer)
2036 skb->pkt_type = PACKET_OTHERHOST;
2037 else
2038 skb->pkt_type = PACKET_HOST;
1898 memcpy(tg_addr, card->dev->dev_addr, 2039 memcpy(tg_addr, card->dev->dev_addr,
1899 card->dev->addr_len); 2040 card->dev->addr_len);
1900 } 2041 }
@@ -1950,7 +2091,6 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
1950 int offset; 2091 int offset;
1951 __u16 vlan_tag = 0; 2092 __u16 vlan_tag = 0;
1952 unsigned int len; 2093 unsigned int len;
1953
1954 /* get first element of current buffer */ 2094 /* get first element of current buffer */
1955 element = (struct qdio_buffer_element *)&buf->buffer->element[0]; 2095 element = (struct qdio_buffer_element *)&buf->buffer->element[0];
1956 offset = 0; 2096 offset = 0;
@@ -1969,7 +2109,7 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
1969 case QETH_HEADER_TYPE_LAYER3: 2109 case QETH_HEADER_TYPE_LAYER3:
1970 vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr); 2110 vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr);
1971 len = skb->len; 2111 len = skb->len;
1972 if (vlan_tag) 2112 if (vlan_tag && !card->options.sniffer)
1973 if (card->vlangrp) 2113 if (card->vlangrp)
1974 vlan_hwaccel_rx(skb, card->vlangrp, 2114 vlan_hwaccel_rx(skb, card->vlangrp,
1975 vlan_tag); 2115 vlan_tag);
@@ -1980,6 +2120,16 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
1980 else 2120 else
1981 netif_rx(skb); 2121 netif_rx(skb);
1982 break; 2122 break;
2123 case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
2124 skb->pkt_type = PACKET_HOST;
2125 skb->protocol = eth_type_trans(skb, skb->dev);
2126 if (card->options.checksum_type == NO_CHECKSUMMING)
2127 skb->ip_summed = CHECKSUM_UNNECESSARY;
2128 else
2129 skb->ip_summed = CHECKSUM_NONE;
2130 len = skb->len;
2131 netif_receive_skb(skb);
2132 break;
1983 default: 2133 default:
1984 dev_kfree_skb_any(skb); 2134 dev_kfree_skb_any(skb);
1985 QETH_DBF_TEXT(TRACE, 3, "inbunkno"); 2135 QETH_DBF_TEXT(TRACE, 3, "inbunkno");
@@ -2061,17 +2211,18 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
2061 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); 2211 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
2062 2212
2063 qeth_set_allowed_threads(card, 0, 1); 2213 qeth_set_allowed_threads(card, 0, 1);
2214 if (card->options.sniffer &&
2215 (card->info.promisc_mode == SET_PROMISC_MODE_ON))
2216 qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE);
2064 if (card->read.state == CH_STATE_UP && 2217 if (card->read.state == CH_STATE_UP &&
2065 card->write.state == CH_STATE_UP && 2218 card->write.state == CH_STATE_UP &&
2066 (card->state == CARD_STATE_UP)) { 2219 (card->state == CARD_STATE_UP)) {
2067 if (recovery_mode) 2220 if (recovery_mode)
2068 qeth_l3_stop(card->dev); 2221 qeth_l3_stop(card->dev);
2069 else { 2222 else {
2070 if (card->dev) { 2223 rtnl_lock();
2071 rtnl_lock(); 2224 dev_close(card->dev);
2072 dev_close(card->dev); 2225 rtnl_unlock();
2073 rtnl_unlock();
2074 }
2075 } 2226 }
2076 if (!card->use_hard_stop) { 2227 if (!card->use_hard_stop) {
2077 rc = qeth_send_stoplan(card); 2228 rc = qeth_send_stoplan(card);
@@ -2105,6 +2256,36 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
2105 return rc; 2256 return rc;
2106} 2257}
2107 2258
2259/*
2260 * test for and Switch promiscuous mode (on or off)
2261 * either for guestlan or HiperSocket Sniffer
2262 */
2263static void
2264qeth_l3_handle_promisc_mode(struct qeth_card *card)
2265{
2266 struct net_device *dev = card->dev;
2267
2268 if (((dev->flags & IFF_PROMISC) &&
2269 (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
2270 (!(dev->flags & IFF_PROMISC) &&
2271 (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
2272 return;
2273
2274 if (card->info.guestlan) { /* Guestlan trace */
2275 if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
2276 qeth_setadp_promisc_mode(card);
2277 } else if (card->options.sniffer && /* HiperSockets trace */
2278 qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) {
2279 if (dev->flags & IFF_PROMISC) {
2280 QETH_DBF_TEXT(TRACE, 3, "+promisc");
2281 qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_ENABLE);
2282 } else {
2283 QETH_DBF_TEXT(TRACE, 3, "-promisc");
2284 qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE);
2285 }
2286 }
2287}
2288
2108static void qeth_l3_set_multicast_list(struct net_device *dev) 2289static void qeth_l3_set_multicast_list(struct net_device *dev)
2109{ 2290{
2110 struct qeth_card *card = dev->ml_priv; 2291 struct qeth_card *card = dev->ml_priv;
@@ -2113,15 +2294,17 @@ static void qeth_l3_set_multicast_list(struct net_device *dev)
2113 if (qeth_threads_running(card, QETH_RECOVER_THREAD) && 2294 if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
2114 (card->state != CARD_STATE_UP)) 2295 (card->state != CARD_STATE_UP))
2115 return; 2296 return;
2116 qeth_l3_delete_mc_addresses(card); 2297 if (!card->options.sniffer) {
2117 qeth_l3_add_multicast_ipv4(card); 2298 qeth_l3_delete_mc_addresses(card);
2299 qeth_l3_add_multicast_ipv4(card);
2118#ifdef CONFIG_QETH_IPV6 2300#ifdef CONFIG_QETH_IPV6
2119 qeth_l3_add_multicast_ipv6(card); 2301 qeth_l3_add_multicast_ipv6(card);
2120#endif 2302#endif
2121 qeth_l3_set_ip_addr_list(card); 2303 qeth_l3_set_ip_addr_list(card);
2122 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) 2304 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
2123 return; 2305 return;
2124 qeth_setadp_promisc_mode(card); 2306 }
2307 qeth_l3_handle_promisc_mode(card);
2125} 2308}
2126 2309
2127static const char *qeth_l3_arp_get_error_cause(int *rc) 2310static const char *qeth_l3_arp_get_error_cause(int *rc)
@@ -2684,6 +2867,24 @@ static void qeth_tx_csum(struct sk_buff *skb)
2684 *(__sum16 *)(skb->data + offset) = csum_fold(csum); 2867 *(__sum16 *)(skb->data + offset) = csum_fold(csum);
2685} 2868}
2686 2869
2870static inline int qeth_l3_tso_elements(struct sk_buff *skb)
2871{
2872 unsigned long tcpd = (unsigned long)tcp_hdr(skb) +
2873 tcp_hdr(skb)->doff * 4;
2874 int tcpd_len = skb->len - (tcpd - (unsigned long)skb->data);
2875 int elements = PFN_UP(tcpd + tcpd_len) - PFN_DOWN(tcpd);
2876 elements += skb_shinfo(skb)->nr_frags;
2877 return elements;
2878}
2879
2880static inline int qeth_l3_tso_check(struct sk_buff *skb)
2881{
2882 int len = ((unsigned long)tcp_hdr(skb) + tcp_hdr(skb)->doff * 4) -
2883 (unsigned long)skb->data;
2884 return (((unsigned long)skb->data & PAGE_MASK) !=
2885 (((unsigned long)skb->data + len) & PAGE_MASK));
2886}
2887
2687static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) 2888static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
2688{ 2889{
2689 int rc; 2890 int rc;
@@ -2702,9 +2903,8 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
2702 int data_offset = -1; 2903 int data_offset = -1;
2703 int nr_frags; 2904 int nr_frags;
2704 2905
2705 if ((card->info.type == QETH_CARD_TYPE_IQD) && 2906 if (((card->info.type == QETH_CARD_TYPE_IQD) && (!ipv)) ||
2706 (skb->protocol != htons(ETH_P_IPV6)) && 2907 card->options.sniffer)
2707 (skb->protocol != htons(ETH_P_IP)))
2708 goto tx_drop; 2908 goto tx_drop;
2709 2909
2710 if ((card->state != CARD_STATE_UP) || !card->lan_online) { 2910 if ((card->state != CARD_STATE_UP) || !card->lan_online) {
@@ -2750,14 +2950,14 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
2750 if (data_offset < 0) 2950 if (data_offset < 0)
2751 skb_pull(new_skb, ETH_HLEN); 2951 skb_pull(new_skb, ETH_HLEN);
2752 } else { 2952 } else {
2753 if (new_skb->protocol == htons(ETH_P_IP)) { 2953 if (ipv == 4) {
2754 if (card->dev->type == ARPHRD_IEEE802_TR) 2954 if (card->dev->type == ARPHRD_IEEE802_TR)
2755 skb_pull(new_skb, TR_HLEN); 2955 skb_pull(new_skb, TR_HLEN);
2756 else 2956 else
2757 skb_pull(new_skb, ETH_HLEN); 2957 skb_pull(new_skb, ETH_HLEN);
2758 } 2958 }
2759 2959
2760 if (new_skb->protocol == ETH_P_IPV6 && card->vlangrp && 2960 if (ipv == 6 && card->vlangrp &&
2761 vlan_tx_tag_present(new_skb)) { 2961 vlan_tx_tag_present(new_skb)) {
2762 skb_push(new_skb, VLAN_HLEN); 2962 skb_push(new_skb, VLAN_HLEN);
2763 skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4); 2963 skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4);
@@ -2777,16 +2977,21 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
2777 /* fix hardware limitation: as long as we do not have sbal 2977 /* fix hardware limitation: as long as we do not have sbal
2778 * chaining we can not send long frag lists 2978 * chaining we can not send long frag lists
2779 */ 2979 */
2780 if ((large_send == QETH_LARGE_SEND_TSO) && 2980 if (large_send == QETH_LARGE_SEND_TSO) {
2781 ((skb_shinfo(new_skb)->nr_frags + 2) > 16)) { 2981 if (qeth_l3_tso_elements(new_skb) + 1 > 16) {
2782 if (skb_linearize(new_skb)) 2982 if (skb_linearize(new_skb))
2783 goto tx_drop; 2983 goto tx_drop;
2984 if (card->options.performance_stats)
2985 card->perf_stats.tx_lin++;
2986 }
2784 } 2987 }
2785 2988
2786 if ((large_send == QETH_LARGE_SEND_TSO) && 2989 if ((large_send == QETH_LARGE_SEND_TSO) &&
2787 (cast_type == RTN_UNSPEC)) { 2990 (cast_type == RTN_UNSPEC)) {
2788 hdr = (struct qeth_hdr *)skb_push(new_skb, 2991 hdr = (struct qeth_hdr *)skb_push(new_skb,
2789 sizeof(struct qeth_hdr_tso)); 2992 sizeof(struct qeth_hdr_tso));
2993 if (qeth_l3_tso_check(new_skb))
2994 QETH_DBF_MESSAGE(2, "tso skb misaligned\n");
2790 memset(hdr, 0, sizeof(struct qeth_hdr_tso)); 2995 memset(hdr, 0, sizeof(struct qeth_hdr_tso));
2791 qeth_l3_fill_header(card, hdr, new_skb, ipv, cast_type); 2996 qeth_l3_fill_header(card, hdr, new_skb, ipv, cast_type);
2792 qeth_tso_fill_header(card, hdr, new_skb); 2997 qeth_tso_fill_header(card, hdr, new_skb);
@@ -2903,46 +3108,28 @@ static u32 qeth_l3_ethtool_get_rx_csum(struct net_device *dev)
2903static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data) 3108static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data)
2904{ 3109{
2905 struct qeth_card *card = dev->ml_priv; 3110 struct qeth_card *card = dev->ml_priv;
2906 enum qeth_card_states old_state;
2907 enum qeth_checksum_types csum_type; 3111 enum qeth_checksum_types csum_type;
2908 3112
2909 if ((card->state != CARD_STATE_UP) &&
2910 (card->state != CARD_STATE_DOWN))
2911 return -EPERM;
2912
2913 if (data) 3113 if (data)
2914 csum_type = HW_CHECKSUMMING; 3114 csum_type = HW_CHECKSUMMING;
2915 else 3115 else
2916 csum_type = SW_CHECKSUMMING; 3116 csum_type = SW_CHECKSUMMING;
2917 3117
2918 if (card->options.checksum_type != csum_type) { 3118 return qeth_l3_set_rx_csum(card, csum_type);
2919 old_state = card->state;
2920 if (card->state == CARD_STATE_UP)
2921 __qeth_l3_set_offline(card->gdev, 1);
2922 card->options.checksum_type = csum_type;
2923 if (old_state == CARD_STATE_UP)
2924 __qeth_l3_set_online(card->gdev, 1);
2925 }
2926 return 0;
2927} 3119}
2928 3120
2929static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data) 3121static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data)
2930{ 3122{
2931 struct qeth_card *card = dev->ml_priv; 3123 struct qeth_card *card = dev->ml_priv;
3124 int rc = 0;
2932 3125
2933 if (data) { 3126 if (data) {
2934 if (card->options.large_send == QETH_LARGE_SEND_NO) { 3127 rc = qeth_l3_set_large_send(card, QETH_LARGE_SEND_TSO);
2935 if (card->info.type == QETH_CARD_TYPE_IQD)
2936 return -EPERM;
2937 else
2938 card->options.large_send = QETH_LARGE_SEND_TSO;
2939 dev->features |= NETIF_F_TSO;
2940 }
2941 } else { 3128 } else {
2942 dev->features &= ~NETIF_F_TSO; 3129 dev->features &= ~NETIF_F_TSO;
2943 card->options.large_send = QETH_LARGE_SEND_NO; 3130 card->options.large_send = QETH_LARGE_SEND_NO;
2944 } 3131 }
2945 return 0; 3132 return rc;
2946} 3133}
2947 3134
2948static const struct ethtool_ops qeth_l3_ethtool_ops = { 3135static const struct ethtool_ops qeth_l3_ethtool_ops = {
@@ -2957,7 +3144,7 @@ static const struct ethtool_ops qeth_l3_ethtool_ops = {
2957 .set_tso = qeth_l3_ethtool_set_tso, 3144 .set_tso = qeth_l3_ethtool_set_tso,
2958 .get_strings = qeth_core_get_strings, 3145 .get_strings = qeth_core_get_strings,
2959 .get_ethtool_stats = qeth_core_get_ethtool_stats, 3146 .get_ethtool_stats = qeth_core_get_ethtool_stats,
2960 .get_stats_count = qeth_core_get_stats_count, 3147 .get_sset_count = qeth_core_get_sset_count,
2961 .get_drvinfo = qeth_core_get_drvinfo, 3148 .get_drvinfo = qeth_core_get_drvinfo,
2962 .get_settings = qeth_core_ethtool_get_settings, 3149 .get_settings = qeth_core_ethtool_get_settings,
2963}; 3150};
@@ -3058,6 +3245,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
3058 NETIF_F_HW_VLAN_RX | 3245 NETIF_F_HW_VLAN_RX |
3059 NETIF_F_HW_VLAN_FILTER; 3246 NETIF_F_HW_VLAN_FILTER;
3060 card->dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; 3247 card->dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
3248 card->dev->gso_max_size = 15 * PAGE_SIZE;
3061 3249
3062 SET_NETDEV_DEV(card->dev, &card->gdev->dev); 3250 SET_NETDEV_DEV(card->dev, &card->gdev->dev);
3063 return register_netdev(card->dev); 3251 return register_netdev(card->dev);
@@ -3092,7 +3280,7 @@ static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev,
3092 index = i % QDIO_MAX_BUFFERS_PER_Q; 3280 index = i % QDIO_MAX_BUFFERS_PER_Q;
3093 buffer = &card->qdio.in_q->bufs[index]; 3281 buffer = &card->qdio.in_q->bufs[index];
3094 if (!(qdio_err && 3282 if (!(qdio_err &&
3095 qeth_check_qdio_errors(buffer->buffer, 3283 qeth_check_qdio_errors(card, buffer->buffer,
3096 qdio_err, "qinerr"))) 3284 qdio_err, "qinerr")))
3097 qeth_l3_process_inbound_buffer(card, buffer, index); 3285 qeth_l3_process_inbound_buffer(card, buffer, index);
3098 /* clear buffer and give back to hardware */ 3286 /* clear buffer and give back to hardware */
@@ -3151,35 +3339,20 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
3151 QETH_DBF_TEXT(SETUP, 2, "setonlin"); 3339 QETH_DBF_TEXT(SETUP, 2, "setonlin");
3152 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); 3340 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
3153 3341
3154 qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
3155
3156 recover_flag = card->state; 3342 recover_flag = card->state;
3157 rc = ccw_device_set_online(CARD_RDEV(card));
3158 if (rc) {
3159 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
3160 return -EIO;
3161 }
3162 rc = ccw_device_set_online(CARD_WDEV(card));
3163 if (rc) {
3164 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
3165 return -EIO;
3166 }
3167 rc = ccw_device_set_online(CARD_DDEV(card));
3168 if (rc) {
3169 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
3170 return -EIO;
3171 }
3172
3173 rc = qeth_core_hardsetup_card(card); 3343 rc = qeth_core_hardsetup_card(card);
3174 if (rc) { 3344 if (rc) {
3175 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); 3345 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
3346 rc = -ENODEV;
3176 goto out_remove; 3347 goto out_remove;
3177 } 3348 }
3178 3349
3179 qeth_l3_query_ipassists(card, QETH_PROT_IPV4); 3350 qeth_l3_query_ipassists(card, QETH_PROT_IPV4);
3180 3351
3181 if (!card->dev && qeth_l3_setup_netdev(card)) 3352 if (!card->dev && qeth_l3_setup_netdev(card)) {
3353 rc = -ENODEV;
3182 goto out_remove; 3354 goto out_remove;
3355 }
3183 3356
3184 card->state = CARD_STATE_HARDSETUP; 3357 card->state = CARD_STATE_HARDSETUP;
3185 qeth_print_status_message(card); 3358 qeth_print_status_message(card);
@@ -3196,28 +3369,32 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
3196 card->lan_online = 0; 3369 card->lan_online = 0;
3197 return 0; 3370 return 0;
3198 } 3371 }
3372 rc = -ENODEV;
3199 goto out_remove; 3373 goto out_remove;
3200 } else 3374 } else
3201 card->lan_online = 1; 3375 card->lan_online = 1;
3202 qeth_set_large_send(card, card->options.large_send);
3203 3376
3204 rc = qeth_l3_setadapter_parms(card); 3377 rc = qeth_l3_setadapter_parms(card);
3205 if (rc) 3378 if (rc)
3206 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); 3379 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
3207 rc = qeth_l3_start_ipassists(card); 3380 if (!card->options.sniffer) {
3208 if (rc) 3381 rc = qeth_l3_start_ipassists(card);
3209 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); 3382 if (rc)
3210 rc = qeth_l3_setrouting_v4(card); 3383 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
3211 if (rc) 3384 qeth_l3_set_large_send(card, card->options.large_send);
3212 QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); 3385 rc = qeth_l3_setrouting_v4(card);
3213 rc = qeth_l3_setrouting_v6(card); 3386 if (rc)
3214 if (rc) 3387 QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc);
3215 QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); 3388 rc = qeth_l3_setrouting_v6(card);
3389 if (rc)
3390 QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
3391 }
3216 netif_tx_disable(card->dev); 3392 netif_tx_disable(card->dev);
3217 3393
3218 rc = qeth_init_qdio_queues(card); 3394 rc = qeth_init_qdio_queues(card);
3219 if (rc) { 3395 if (rc) {
3220 QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); 3396 QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
3397 rc = -ENODEV;
3221 goto out_remove; 3398 goto out_remove;
3222 } 3399 }
3223 card->state = CARD_STATE_SOFTSETUP; 3400 card->state = CARD_STATE_SOFTSETUP;
@@ -3248,7 +3425,7 @@ out_remove:
3248 card->state = CARD_STATE_RECOVER; 3425 card->state = CARD_STATE_RECOVER;
3249 else 3426 else
3250 card->state = CARD_STATE_DOWN; 3427 card->state = CARD_STATE_DOWN;
3251 return -ENODEV; 3428 return rc;
3252} 3429}
3253 3430
3254static int qeth_l3_set_online(struct ccwgroup_device *gdev) 3431static int qeth_l3_set_online(struct ccwgroup_device *gdev)
@@ -3358,11 +3535,9 @@ static int qeth_l3_pm_resume(struct ccwgroup_device *gdev)
3358 if (card->state == CARD_STATE_RECOVER) { 3535 if (card->state == CARD_STATE_RECOVER) {
3359 rc = __qeth_l3_set_online(card->gdev, 1); 3536 rc = __qeth_l3_set_online(card->gdev, 1);
3360 if (rc) { 3537 if (rc) {
3361 if (card->dev) { 3538 rtnl_lock();
3362 rtnl_lock(); 3539 dev_close(card->dev);
3363 dev_close(card->dev); 3540 rtnl_unlock();
3364 rtnl_unlock();
3365 }
3366 } 3541 }
3367 } else 3542 } else
3368 rc = __qeth_l3_set_online(card->gdev, 0); 3543 rc = __qeth_l3_set_online(card->gdev, 0);
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c
index c144b9924d52..25b3e7aae44f 100644
--- a/drivers/s390/net/qeth_l3_sys.c
+++ b/drivers/s390/net/qeth_l3_sys.c
@@ -8,6 +8,8 @@
8 * Frank Blaschka <frank.blaschka@de.ibm.com> 8 * Frank Blaschka <frank.blaschka@de.ibm.com>
9 */ 9 */
10 10
11#include <linux/slab.h>
12
11#include "qeth_l3.h" 13#include "qeth_l3.h"
12 14
13#define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \ 15#define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
@@ -293,31 +295,134 @@ static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
293 struct device_attribute *attr, const char *buf, size_t count) 295 struct device_attribute *attr, const char *buf, size_t count)
294{ 296{
295 struct qeth_card *card = dev_get_drvdata(dev); 297 struct qeth_card *card = dev_get_drvdata(dev);
298 enum qeth_checksum_types csum_type;
296 char *tmp; 299 char *tmp;
300 int rc;
297 301
298 if (!card) 302 if (!card)
299 return -EINVAL; 303 return -EINVAL;
300 304
301 if ((card->state != CARD_STATE_DOWN) &&
302 (card->state != CARD_STATE_RECOVER))
303 return -EPERM;
304
305 tmp = strsep((char **) &buf, "\n"); 305 tmp = strsep((char **) &buf, "\n");
306 if (!strcmp(tmp, "sw_checksumming")) 306 if (!strcmp(tmp, "sw_checksumming"))
307 card->options.checksum_type = SW_CHECKSUMMING; 307 csum_type = SW_CHECKSUMMING;
308 else if (!strcmp(tmp, "hw_checksumming")) 308 else if (!strcmp(tmp, "hw_checksumming"))
309 card->options.checksum_type = HW_CHECKSUMMING; 309 csum_type = HW_CHECKSUMMING;
310 else if (!strcmp(tmp, "no_checksumming")) 310 else if (!strcmp(tmp, "no_checksumming"))
311 card->options.checksum_type = NO_CHECKSUMMING; 311 csum_type = NO_CHECKSUMMING;
312 else { 312 else
313 return -EINVAL; 313 return -EINVAL;
314 } 314
315 rc = qeth_l3_set_rx_csum(card, csum_type);
316 if (rc)
317 return rc;
315 return count; 318 return count;
316} 319}
317 320
318static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show, 321static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
319 qeth_l3_dev_checksum_store); 322 qeth_l3_dev_checksum_store);
320 323
324static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
325 struct device_attribute *attr, char *buf)
326{
327 struct qeth_card *card = dev_get_drvdata(dev);
328
329 if (!card)
330 return -EINVAL;
331
332 return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
333}
334
335static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
336 struct device_attribute *attr, const char *buf, size_t count)
337{
338 struct qeth_card *card = dev_get_drvdata(dev);
339 int ret;
340 unsigned long i;
341
342 if (!card)
343 return -EINVAL;
344
345 if (card->info.type != QETH_CARD_TYPE_IQD)
346 return -EPERM;
347
348 if ((card->state != CARD_STATE_DOWN) &&
349 (card->state != CARD_STATE_RECOVER))
350 return -EPERM;
351
352 ret = strict_strtoul(buf, 16, &i);
353 if (ret)
354 return -EINVAL;
355 switch (i) {
356 case 0:
357 card->options.sniffer = i;
358 break;
359 case 1:
360 ret = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
361 if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
362 card->options.sniffer = i;
363 if (card->qdio.init_pool.buf_count !=
364 QETH_IN_BUF_COUNT_MAX)
365 qeth_realloc_buffer_pool(card,
366 QETH_IN_BUF_COUNT_MAX);
367 break;
368 } else
369 return -EPERM;
370 default: /* fall through */
371 return -EINVAL;
372 }
373 return count;
374}
375
376static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
377 qeth_l3_dev_sniffer_store);
378
379static ssize_t qeth_l3_dev_large_send_show(struct device *dev,
380 struct device_attribute *attr, char *buf)
381{
382 struct qeth_card *card = dev_get_drvdata(dev);
383
384 if (!card)
385 return -EINVAL;
386
387 switch (card->options.large_send) {
388 case QETH_LARGE_SEND_NO:
389 return sprintf(buf, "%s\n", "no");
390 case QETH_LARGE_SEND_TSO:
391 return sprintf(buf, "%s\n", "TSO");
392 default:
393 return sprintf(buf, "%s\n", "N/A");
394 }
395}
396
397static ssize_t qeth_l3_dev_large_send_store(struct device *dev,
398 struct device_attribute *attr, const char *buf, size_t count)
399{
400 struct qeth_card *card = dev_get_drvdata(dev);
401 enum qeth_large_send_types type;
402 int rc = 0;
403 char *tmp;
404
405 if (!card)
406 return -EINVAL;
407 tmp = strsep((char **) &buf, "\n");
408 if (!strcmp(tmp, "no"))
409 type = QETH_LARGE_SEND_NO;
410 else if (!strcmp(tmp, "TSO"))
411 type = QETH_LARGE_SEND_TSO;
412 else
413 return -EINVAL;
414
415 if (card->options.large_send == type)
416 return count;
417 rc = qeth_l3_set_large_send(card, type);
418 if (rc)
419 return rc;
420 return count;
421}
422
423static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show,
424 qeth_l3_dev_large_send_store);
425
321static struct attribute *qeth_l3_device_attrs[] = { 426static struct attribute *qeth_l3_device_attrs[] = {
322 &dev_attr_route4.attr, 427 &dev_attr_route4.attr,
323 &dev_attr_route6.attr, 428 &dev_attr_route6.attr,
@@ -325,6 +430,8 @@ static struct attribute *qeth_l3_device_attrs[] = {
325 &dev_attr_broadcast_mode.attr, 430 &dev_attr_broadcast_mode.attr,
326 &dev_attr_canonical_macaddr.attr, 431 &dev_attr_canonical_macaddr.attr,
327 &dev_attr_checksumming.attr, 432 &dev_attr_checksumming.attr,
433 &dev_attr_sniffer.attr,
434 &dev_attr_large_send.attr,
328 NULL, 435 NULL,
329}; 436};
330 437
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index 3012355f8304..70491274da16 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -24,6 +24,7 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/device.h> 26#include <linux/device.h>
27#include <linux/slab.h>
27#include <net/iucv/iucv.h> 28#include <net/iucv/iucv.h>
28#include <asm/cpcmd.h> 29#include <asm/cpcmd.h>
29#include <asm/ebcdic.h> 30#include <asm/ebcdic.h>
@@ -31,9 +32,9 @@
31 32
32struct smsg_callback { 33struct smsg_callback {
33 struct list_head list; 34 struct list_head list;
34 char *prefix; 35 const char *prefix;
35 int len; 36 int len;
36 void (*callback)(char *from, char *str); 37 void (*callback)(const char *from, char *str);
37}; 38};
38 39
39MODULE_AUTHOR 40MODULE_AUTHOR
@@ -100,8 +101,8 @@ static void smsg_message_pending(struct iucv_path *path,
100 kfree(buffer); 101 kfree(buffer);
101} 102}
102 103
103int smsg_register_callback(char *prefix, 104int smsg_register_callback(const char *prefix,
104 void (*callback)(char *from, char *str)) 105 void (*callback)(const char *from, char *str))
105{ 106{
106 struct smsg_callback *cb; 107 struct smsg_callback *cb;
107 108
@@ -117,8 +118,9 @@ int smsg_register_callback(char *prefix,
117 return 0; 118 return 0;
118} 119}
119 120
120void smsg_unregister_callback(char *prefix, 121void smsg_unregister_callback(const char *prefix,
121 void (*callback)(char *from, char *str)) 122 void (*callback)(const char *from,
123 char *str))
122{ 124{
123 struct smsg_callback *cb, *tmp; 125 struct smsg_callback *cb, *tmp;
124 126
@@ -168,7 +170,7 @@ static int smsg_pm_restore_thaw(struct device *dev)
168 return 0; 170 return 0;
169} 171}
170 172
171static struct dev_pm_ops smsg_pm_ops = { 173static const struct dev_pm_ops smsg_pm_ops = {
172 .freeze = smsg_pm_freeze, 174 .freeze = smsg_pm_freeze,
173 .thaw = smsg_pm_restore_thaw, 175 .thaw = smsg_pm_restore_thaw,
174 .restore = smsg_pm_restore_thaw, 176 .restore = smsg_pm_restore_thaw,
@@ -176,7 +178,7 @@ static struct dev_pm_ops smsg_pm_ops = {
176 178
177static struct device_driver smsg_driver = { 179static struct device_driver smsg_driver = {
178 .owner = THIS_MODULE, 180 .owner = THIS_MODULE,
179 .name = "SMSGIUCV", 181 .name = SMSGIUCV_DRV_NAME,
180 .bus = &iucv_bus, 182 .bus = &iucv_bus,
181 .pm = &smsg_pm_ops, 183 .pm = &smsg_pm_ops,
182}; 184};
diff --git a/drivers/s390/net/smsgiucv.h b/drivers/s390/net/smsgiucv.h
index 67f5d4f8378d..149a1151608d 100644
--- a/drivers/s390/net/smsgiucv.h
+++ b/drivers/s390/net/smsgiucv.h
@@ -5,6 +5,10 @@
5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
6 */ 6 */
7 7
8int smsg_register_callback(char *, void (*)(char *, char *)); 8#define SMSGIUCV_DRV_NAME "SMSGIUCV"
9void smsg_unregister_callback(char *, void (*)(char *, char *)); 9
10int smsg_register_callback(const char *,
11 void (*)(const char *, char *));
12void smsg_unregister_callback(const char *,
13 void (*)(const char *, char *));
10 14
diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c
new file mode 100644
index 000000000000..137688790207
--- /dev/null
+++ b/drivers/s390/net/smsgiucv_app.c
@@ -0,0 +1,212 @@
1/*
2 * Deliver z/VM CP special messages (SMSG) as uevents.
3 *
4 * The driver registers for z/VM CP special messages with the
5 * "APP" prefix. Incoming messages are delivered to user space
6 * as uevents.
7 *
8 * Copyright IBM Corp. 2010
9 * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
10 *
11 */
12#define KMSG_COMPONENT "smsgiucv_app"
13#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
14
15#include <linux/ctype.h>
16#include <linux/err.h>
17#include <linux/device.h>
18#include <linux/list.h>
19#include <linux/kobject.h>
20#include <linux/module.h>
21#include <linux/slab.h>
22#include <linux/spinlock.h>
23#include <linux/workqueue.h>
24#include <net/iucv/iucv.h>
25#include "smsgiucv.h"
26
27/* prefix used for SMSG registration */
28#define SMSG_PREFIX "APP"
29
30/* SMSG related uevent environment variables */
31#define ENV_SENDER_STR "SMSG_SENDER="
32#define ENV_SENDER_LEN (strlen(ENV_SENDER_STR) + 8 + 1)
33#define ENV_PREFIX_STR "SMSG_ID="
34#define ENV_PREFIX_LEN (strlen(ENV_PREFIX_STR) + \
35 strlen(SMSG_PREFIX) + 1)
36#define ENV_TEXT_STR "SMSG_TEXT="
37#define ENV_TEXT_LEN(msg) (strlen(ENV_TEXT_STR) + strlen((msg)) + 1)
38
39/* z/VM user ID which is permitted to send SMSGs
40 * If the value is undefined or empty (""), special messages are
41 * accepted from any z/VM user ID. */
42static char *sender;
43module_param(sender, charp, 0400);
44MODULE_PARM_DESC(sender, "z/VM user ID from which CP SMSGs are accepted");
45
46/* SMSG device representation */
47static struct device *smsg_app_dev;
48
49/* list element for queuing received messages for delivery */
50struct smsg_app_event {
51 struct list_head list;
52 char *buf;
53 char *envp[4];
54};
55
56/* queue for outgoing uevents */
57static LIST_HEAD(smsg_event_queue);
58static DEFINE_SPINLOCK(smsg_event_queue_lock);
59
60static void smsg_app_event_free(struct smsg_app_event *ev)
61{
62 kfree(ev->buf);
63 kfree(ev);
64}
65
66static struct smsg_app_event *smsg_app_event_alloc(const char *from,
67 const char *msg)
68{
69 struct smsg_app_event *ev;
70
71 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
72 if (!ev)
73 return NULL;
74
75 ev->buf = kzalloc(ENV_SENDER_LEN + ENV_PREFIX_LEN +
76 ENV_TEXT_LEN(msg), GFP_ATOMIC);
77 if (!ev->buf) {
78 kfree(ev);
79 return NULL;
80 }
81
82 /* setting up environment pointers into buf */
83 ev->envp[0] = ev->buf;
84 ev->envp[1] = ev->envp[0] + ENV_SENDER_LEN;
85 ev->envp[2] = ev->envp[1] + ENV_PREFIX_LEN;
86 ev->envp[3] = NULL;
87
88 /* setting up environment: sender, prefix name, and message text */
89 snprintf(ev->envp[0], ENV_SENDER_LEN, ENV_SENDER_STR "%s", from);
90 snprintf(ev->envp[1], ENV_PREFIX_LEN, ENV_PREFIX_STR "%s", SMSG_PREFIX);
91 snprintf(ev->envp[2], ENV_TEXT_LEN(msg), ENV_TEXT_STR "%s", msg);
92
93 return ev;
94}
95
96static void smsg_event_work_fn(struct work_struct *work)
97{
98 LIST_HEAD(event_queue);
99 struct smsg_app_event *p, *n;
100 struct device *dev;
101
102 dev = get_device(smsg_app_dev);
103 if (!dev)
104 return;
105
106 spin_lock_bh(&smsg_event_queue_lock);
107 list_splice_init(&smsg_event_queue, &event_queue);
108 spin_unlock_bh(&smsg_event_queue_lock);
109
110 list_for_each_entry_safe(p, n, &event_queue, list) {
111 list_del(&p->list);
112 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, p->envp);
113 smsg_app_event_free(p);
114 }
115
116 put_device(dev);
117}
118static DECLARE_WORK(smsg_event_work, smsg_event_work_fn);
119
120static void smsg_app_callback(const char *from, char *msg)
121{
122 struct smsg_app_event *se;
123
124 /* check if the originating z/VM user ID matches
125 * the configured sender. */
126 if (sender && strlen(sender) > 0 && strcmp(from, sender) != 0)
127 return;
128
129 /* get start of message text (skip prefix and leading blanks) */
130 msg += strlen(SMSG_PREFIX);
131 while (*msg && isspace(*msg))
132 msg++;
133 if (*msg == '\0')
134 return;
135
136 /* allocate event list element and its environment */
137 se = smsg_app_event_alloc(from, msg);
138 if (!se)
139 return;
140
141 /* queue event and schedule work function */
142 spin_lock(&smsg_event_queue_lock);
143 list_add_tail(&se->list, &smsg_event_queue);
144 spin_unlock(&smsg_event_queue_lock);
145
146 schedule_work(&smsg_event_work);
147 return;
148}
149
150static int __init smsgiucv_app_init(void)
151{
152 struct device_driver *smsgiucv_drv;
153 int rc;
154
155 if (!MACHINE_IS_VM)
156 return -ENODEV;
157
158 smsg_app_dev = kzalloc(sizeof(*smsg_app_dev), GFP_KERNEL);
159 if (!smsg_app_dev)
160 return -ENOMEM;
161
162 smsgiucv_drv = driver_find(SMSGIUCV_DRV_NAME, &iucv_bus);
163 if (!smsgiucv_drv) {
164 kfree(smsg_app_dev);
165 return -ENODEV;
166 }
167
168 rc = dev_set_name(smsg_app_dev, KMSG_COMPONENT);
169 if (rc) {
170 kfree(smsg_app_dev);
171 goto fail_put_driver;
172 }
173 smsg_app_dev->bus = &iucv_bus;
174 smsg_app_dev->parent = iucv_root;
175 smsg_app_dev->release = (void (*)(struct device *)) kfree;
176 smsg_app_dev->driver = smsgiucv_drv;
177 rc = device_register(smsg_app_dev);
178 if (rc) {
179 put_device(smsg_app_dev);
180 goto fail_put_driver;
181 }
182
183 /* register with the smsgiucv device driver */
184 rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback);
185 if (rc) {
186 device_unregister(smsg_app_dev);
187 goto fail_put_driver;
188 }
189
190 rc = 0;
191fail_put_driver:
192 put_driver(smsgiucv_drv);
193 return rc;
194}
195module_init(smsgiucv_app_init);
196
197static void __exit smsgiucv_app_exit(void)
198{
199 /* unregister callback */
200 smsg_unregister_callback(SMSG_PREFIX, smsg_app_callback);
201
202 /* cancel pending work and flush any queued event work */
203 cancel_work_sync(&smsg_event_work);
204 smsg_event_work_fn(&smsg_event_work);
205
206 device_unregister(smsg_app_dev);
207}
208module_exit(smsgiucv_app_exit);
209
210MODULE_LICENSE("GPL v2");
211MODULE_DESCRIPTION("Deliver z/VM CP SMSG as uevents");
212MODULE_AUTHOR("Hendrik Brueckner <brueckner@linux.vnet.ibm.com>");