From: Julian Wiedmann <jwi@linux.ibm.com>
Subject: s390/ccwgroup: tie a ccwgroup driver to its ccw driver
Patch-mainline: v4.15-rc1
Git-commit: f9a5d70cfaf3e32308de0abfcc95dafe4e36ea51
References: FATE#326350, LTC#169511, bsc#1113509

Summary:     qeth: performance improvements
Description: This adds recent functional and performance improvements for the
             qeth network driver.
             Primarily this brings Scatter-Gather support for HiperSockets,
             reduced CPU consumption in the L3 IPv4 transmit path for OSA,
             improved Promiscuous Mode performance due to IFF_UNICAST_FLT,
             support for Scatter-Gather on z/VM virtual NICs, and
             support for delayed GRO flushing.

             For sanity & stability reasons, this effectively constitutes a
             backport of the qeth device driver from 4.19 mainline.
             

Upstream-Description:

             s390/ccwgroup: tie a ccwgroup driver to its ccw driver

             When grouping devices, the ccwgroup core only checks whether all of the
             devices are bound to the same ccw_driver. It has no means of checking
             if the requesting ccwgroup driver actually supports this device type.
             qeth implements its own device matching in qeth_core_probe_device(),
             while ctcm and lcs currently have no sanity-checking at all.

             Enable ccwgroup drivers to optionally defer the device type checking to
             the ccwgroup core, by specifying their supported ccw_driver.
             This allows us drop the device type matching from qeth, and improves
             the robustness of ctcm and lcs.

             Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
             Acked-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
             Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
             Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 arch/s390/include/asm/ccwgroup.h  |    2 ++
 drivers/s390/cio/ccwgroup.c       |    6 ++++++
 drivers/s390/net/ctcm_main.c      |    1 +
 drivers/s390/net/lcs.c            |    1 +
 drivers/s390/net/qeth_core_main.c |    1 +
 5 files changed, 11 insertions(+)

--- a/arch/s390/include/asm/ccwgroup.h
+++ b/arch/s390/include/asm/ccwgroup.h
@@ -41,6 +41,7 @@ struct ccwgroup_device {
  * @thaw: undo work done in @freeze
  * @restore: callback for restoring after hibernation
  * @driver: embedded driver structure
+ * @ccw_driver: supported ccw_driver (optional)
  */
 struct ccwgroup_driver {
 	int (*setup) (struct ccwgroup_device *);
@@ -55,6 +56,7 @@ struct ccwgroup_driver {
 	int (*restore)(struct ccwgroup_device *);
 
 	struct device_driver driver;
+	struct ccw_driver *ccw_driver;
 };
 
 extern int  ccwgroup_driver_register   (struct ccwgroup_driver *cdriver);
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -373,6 +373,12 @@ int ccwgroup_create_dev(struct device *p
 		rc = -EINVAL;
 		goto error;
 	}
+	/* Check if the devices are bound to the required ccw driver. */
+	if (gdev->count && gdrv && gdrv->ccw_driver &&
+	    gdev->cdev[0]->drv != gdrv->ccw_driver) {
+		rc = -EINVAL;
+		goto error;
+	}
 
 	dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev));
 	gdev->dev.groups = ccwgroup_attr_groups;
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -1761,6 +1761,7 @@ static struct ccwgroup_driver ctcm_group
 		.owner	= THIS_MODULE,
 		.name	= CTC_DRIVER_NAME,
 	},
+	.ccw_driver  = &ctcm_ccw_driver,
 	.setup	     = ctcm_probe_device,
 	.remove      = ctcm_remove_device,
 	.set_online  = ctcm_new_device,
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -2396,6 +2396,7 @@ static struct ccwgroup_driver lcs_group_
 		.owner	= THIS_MODULE,
 		.name	= "lcs",
 	},
+	.ccw_driver  = &lcs_ccw_driver,
 	.setup	     = lcs_probe_device,
 	.remove      = lcs_remove_device,
 	.set_online  = lcs_new_device,
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -5886,6 +5886,7 @@ static struct ccwgroup_driver qeth_core_
 		.owner = THIS_MODULE,
 		.name = "qeth",
 	},
+	.ccw_driver = &qeth_ccw_driver,
 	.setup = qeth_core_probe_device,
 	.remove = qeth_core_remove_device,
 	.set_online = qeth_core_set_online,
