diff options
author | Frank Blaschka <frank.blaschka@de.ibm.com> | 2009-11-11 19:11:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-16 05:42:09 -0500 |
commit | 3fd434d846a2c87f8f705b6876f81e4053f93749 (patch) | |
tree | d4d20edd391abc26948c67c022061ef271e4c053 /drivers/s390 | |
parent | c3b4a740db3688b245282ac957a01f3fb8d1186d (diff) |
qeth: allow dynamic change of rx checksumming
Technically there is no need to set the card offline to change
RX checksumming. Get rid of this stupid limitation.
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/net/qeth_l3.h | 1 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 44 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_sys.c | 19 |
3 files changed, 41 insertions, 23 deletions
diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h index ffa6fe4da26a..321988fa9f7d 100644 --- a/drivers/s390/net/qeth_l3.h +++ b/drivers/s390/net/qeth_l3.h | |||
@@ -61,5 +61,6 @@ int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *); | |||
61 | void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions, | 61 | void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions, |
62 | const u8 *); | 62 | const u8 *); |
63 | int qeth_l3_set_large_send(struct qeth_card *, enum qeth_large_send_types); | 63 | int qeth_l3_set_large_send(struct qeth_card *, enum qeth_large_send_types); |
64 | int qeth_l3_set_rx_csum(struct qeth_card *, enum qeth_checksum_types); | ||
64 | 65 | ||
65 | #endif /* __QETH_L3_H__ */ | 66 | #endif /* __QETH_L3_H__ */ |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 2048b4354216..fd1b6ed3721f 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -1465,6 +1465,35 @@ static int qeth_l3_send_checksum_command(struct qeth_card *card) | |||
1465 | return 0; | 1465 | return 0; |
1466 | } | 1466 | } |
1467 | 1467 | ||
1468 | int qeth_l3_set_rx_csum(struct qeth_card *card, | ||
1469 | enum qeth_checksum_types csum_type) | ||
1470 | { | ||
1471 | int rc = 0; | ||
1472 | |||
1473 | if (card->options.checksum_type == HW_CHECKSUMMING) { | ||
1474 | if ((csum_type != HW_CHECKSUMMING) && | ||
1475 | (card->state != CARD_STATE_DOWN)) { | ||
1476 | rc = qeth_l3_send_simple_setassparms(card, | ||
1477 | IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0); | ||
1478 | if (rc) | ||
1479 | return -EIO; | ||
1480 | } | ||
1481 | } else { | ||
1482 | if (csum_type == HW_CHECKSUMMING) { | ||
1483 | if (card->state != CARD_STATE_DOWN) { | ||
1484 | if (!qeth_is_supported(card, | ||
1485 | IPA_INBOUND_CHECKSUM)) | ||
1486 | return -EPERM; | ||
1487 | rc = qeth_l3_send_checksum_command(card); | ||
1488 | if (rc) | ||
1489 | return -EIO; | ||
1490 | } | ||
1491 | } | ||
1492 | } | ||
1493 | card->options.checksum_type = csum_type; | ||
1494 | return rc; | ||
1495 | } | ||
1496 | |||
1468 | static int qeth_l3_start_ipa_checksum(struct qeth_card *card) | 1497 | static int qeth_l3_start_ipa_checksum(struct qeth_card *card) |
1469 | { | 1498 | { |
1470 | int rc = 0; | 1499 | int rc = 0; |
@@ -2954,27 +2983,14 @@ static u32 qeth_l3_ethtool_get_rx_csum(struct net_device *dev) | |||
2954 | static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data) | 2983 | static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data) |
2955 | { | 2984 | { |
2956 | struct qeth_card *card = dev->ml_priv; | 2985 | struct qeth_card *card = dev->ml_priv; |
2957 | enum qeth_card_states old_state; | ||
2958 | enum qeth_checksum_types csum_type; | 2986 | enum qeth_checksum_types csum_type; |
2959 | 2987 | ||
2960 | if ((card->state != CARD_STATE_UP) && | ||
2961 | (card->state != CARD_STATE_DOWN)) | ||
2962 | return -EPERM; | ||
2963 | |||
2964 | if (data) | 2988 | if (data) |
2965 | csum_type = HW_CHECKSUMMING; | 2989 | csum_type = HW_CHECKSUMMING; |
2966 | else | 2990 | else |
2967 | csum_type = SW_CHECKSUMMING; | 2991 | csum_type = SW_CHECKSUMMING; |
2968 | 2992 | ||
2969 | if (card->options.checksum_type != csum_type) { | 2993 | return qeth_l3_set_rx_csum(card, csum_type); |
2970 | old_state = card->state; | ||
2971 | if (card->state == CARD_STATE_UP) | ||
2972 | __qeth_l3_set_offline(card->gdev, 1); | ||
2973 | card->options.checksum_type = csum_type; | ||
2974 | if (old_state == CARD_STATE_UP) | ||
2975 | __qeth_l3_set_online(card->gdev, 1); | ||
2976 | } | ||
2977 | return 0; | ||
2978 | } | 2994 | } |
2979 | 2995 | ||
2980 | static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data) | 2996 | static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data) |
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 88f200c8ea3c..3360b0941aa1 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c | |||
@@ -293,25 +293,26 @@ static ssize_t qeth_l3_dev_checksum_store(struct device *dev, | |||
293 | struct device_attribute *attr, const char *buf, size_t count) | 293 | struct device_attribute *attr, const char *buf, size_t count) |
294 | { | 294 | { |
295 | struct qeth_card *card = dev_get_drvdata(dev); | 295 | struct qeth_card *card = dev_get_drvdata(dev); |
296 | enum qeth_checksum_types csum_type; | ||
296 | char *tmp; | 297 | char *tmp; |
298 | int rc; | ||
297 | 299 | ||
298 | if (!card) | 300 | if (!card) |
299 | return -EINVAL; | 301 | return -EINVAL; |
300 | 302 | ||
301 | if ((card->state != CARD_STATE_DOWN) && | ||
302 | (card->state != CARD_STATE_RECOVER)) | ||
303 | return -EPERM; | ||
304 | |||
305 | tmp = strsep((char **) &buf, "\n"); | 303 | tmp = strsep((char **) &buf, "\n"); |
306 | if (!strcmp(tmp, "sw_checksumming")) | 304 | if (!strcmp(tmp, "sw_checksumming")) |
307 | card->options.checksum_type = SW_CHECKSUMMING; | 305 | csum_type = SW_CHECKSUMMING; |
308 | else if (!strcmp(tmp, "hw_checksumming")) | 306 | else if (!strcmp(tmp, "hw_checksumming")) |
309 | card->options.checksum_type = HW_CHECKSUMMING; | 307 | csum_type = HW_CHECKSUMMING; |
310 | else if (!strcmp(tmp, "no_checksumming")) | 308 | else if (!strcmp(tmp, "no_checksumming")) |
311 | card->options.checksum_type = NO_CHECKSUMMING; | 309 | csum_type = NO_CHECKSUMMING; |
312 | else { | 310 | else |
313 | return -EINVAL; | 311 | return -EINVAL; |
314 | } | 312 | |
313 | rc = qeth_l3_set_rx_csum(card, csum_type); | ||
314 | if (rc) | ||
315 | return rc; | ||
315 | return count; | 316 | return count; |
316 | } | 317 | } |
317 | 318 | ||