summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Richter <tmricht@linux.vnet.ibm.com>2017-01-12 15:48:33 +0100
committerDavid S. Miller <davem@davemloft.net>2017-01-12 10:02:43 -0500
commitf9d8e6dc0fdee06e3eaf779a52530f4b8be6966f (patch)
tree51b6df53b62afa27e19842f434ff0fd3f58d80b8
parentc9475369bd2bce788796aa313036faecb9725194 (diff)
s390/qeth: test RX/TX checksum offload reply
Turning on receive and/or transmit checksum offload support on the OSA card requires 2 commands: 1. start command which replies with available features 2. enable command to turn on selected features. The current version does not check the reply of the start command and simply uses the returned value to enable offload features. When the start command returns zero, this leads to a situation where no checksum offload is turned on by the hardware. Even worse no error indication is returned. The Linux kernel assumes the OSA card performs RX/TX checksum offload, but the hardware does not perform any checksum verification at all. This patch checks the return of the start and enable command responses from the hardware and turns off checksum offloading if the commands fails or does not respond with the correct bit setting. Signed-off-by: Thomas Richter <tmricht@linux.vnet.ibm.com> Reviewed-by: Julian Wiedmann <jwi@linux.vnet.ibm.com> Reviewed-by: Ursula Braun <ubraun@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/s390/net/qeth_core_main.c13
-rw-r--r--drivers/s390/net/qeth_core_mpc.h10
2 files changed, 23 insertions, 0 deletions
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 5ab80ea0e099..49b813f8f91b 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -6104,11 +6104,19 @@ static int qeth_ipa_checksum_run_cmd(struct qeth_card *card,
static int qeth_send_checksum_on(struct qeth_card *card, int cstype)
{
+ const __u32 required_features = QETH_IPA_CHECKSUM_IP_HDR |
+ QETH_IPA_CHECKSUM_UDP |
+ QETH_IPA_CHECKSUM_TCP;
struct qeth_checksum_cmd chksum_cb;
int rc;
rc = qeth_ipa_checksum_run_cmd(card, cstype, IPA_CMD_ASS_START, 0,
&chksum_cb);
+ if (!rc) {
+ if ((required_features & chksum_cb.supported) !=
+ required_features)
+ rc = -EIO;
+ }
if (rc) {
qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_STOP, 0);
dev_warn(&card->gdev->dev,
@@ -6118,6 +6126,11 @@ static int qeth_send_checksum_on(struct qeth_card *card, int cstype)
}
rc = qeth_ipa_checksum_run_cmd(card, cstype, IPA_CMD_ASS_ENABLE,
chksum_cb.supported, &chksum_cb);
+ if (!rc) {
+ if ((required_features & chksum_cb.enabled) !=
+ required_features)
+ rc = -EIO;
+ }
if (rc) {
qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_STOP, 0);
dev_warn(&card->gdev->dev,
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index f54ea7224b89..bc69d0a338ad 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -352,6 +352,16 @@ struct qeth_arp_query_info {
char *udata;
};
+/* IPA set assist segmentation bit definitions for receive and
+ * transmit checksum offloading.
+ */
+enum qeth_ipa_checksum_bits {
+ QETH_IPA_CHECKSUM_IP_HDR = 0x0002,
+ QETH_IPA_CHECKSUM_UDP = 0x0008,
+ QETH_IPA_CHECKSUM_TCP = 0x0010,
+ QETH_IPA_CHECKSUM_LP2LP = 0x0020
+};
+
/* IPA Assist checksum offload reply layout. */
struct qeth_checksum_cmd {
__u32 supported;