diff options
author | Frank Pavlic <pavlic@de.ibm.com> | 2005-09-14 12:03:26 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-14 12:15:31 -0400 |
commit | 9cb90de84b1d9c4686f12042a3696df38e0114c3 (patch) | |
tree | 56c78d13b220541d795f4e2558510e4abe931f3c /drivers/s390/net/qeth_main.c | |
parent | e172577da02cde3916e75406b314e6f01c228a5c (diff) |
[PATCH] s390: TSO related fixes in qeth driver
Jeff,
I'm sorry seems that they have not been sent out either ...
ok here they come ...
[patch 3/4] s390: TSO related fixes in qeth driver
From: Frank Pavlic <pavlic@de.ibm.com>
TSO related fixes :
- changing value of large_send attribute while network traffic
is running caused program check and thus device recovery.
- Due to hardware restriction discard packet when it exceeds 60K
otherwise qeth will cause program checks and thus traffic stall
when trying to send such huge packets.
Signed-off-by: Frank Pavlic <pavlic@de.ibm.com>
diffstat:
qeth.h | 4 ++--
qeth_main.c | 33 +++++++++++++++++++++------------
qeth_sys.c | 10 +++-------
3 files changed, 26 insertions(+), 21 deletions(-)
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/s390/net/qeth_main.c')
-rw-r--r-- | drivers/s390/net/qeth_main.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 79c74f3a11f5..6f784c3f43d5 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * | 2 | * |
3 | * linux/drivers/s390/net/qeth_main.c ($Revision: 1.214 $) | 3 | * linux/drivers/s390/net/qeth_main.c ($Revision: 1.219 $) |
4 | * | 4 | * |
5 | * Linux on zSeries OSA Express and HiperSockets support | 5 | * Linux on zSeries OSA Express and HiperSockets support |
6 | * | 6 | * |
@@ -12,7 +12,7 @@ | |||
12 | * Frank Pavlic (pavlic@de.ibm.com) and | 12 | * Frank Pavlic (pavlic@de.ibm.com) and |
13 | * Thomas Spatzier <tspat@de.ibm.com> | 13 | * Thomas Spatzier <tspat@de.ibm.com> |
14 | * | 14 | * |
15 | * $Revision: 1.214 $ $Date: 2005/05/04 20:19:18 $ | 15 | * $Revision: 1.219 $ $Date: 2005/05/04 20:19:18 $ |
16 | * | 16 | * |
17 | * This program is free software; you can redistribute it and/or modify | 17 | * This program is free software; you can redistribute it and/or modify |
18 | * it under the terms of the GNU General Public License as published by | 18 | * it under the terms of the GNU General Public License as published by |
@@ -80,7 +80,7 @@ qeth_eyecatcher(void) | |||
80 | #include "qeth_eddp.h" | 80 | #include "qeth_eddp.h" |
81 | #include "qeth_tso.h" | 81 | #include "qeth_tso.h" |
82 | 82 | ||
83 | #define VERSION_QETH_C "$Revision: 1.214 $" | 83 | #define VERSION_QETH_C "$Revision: 1.219 $" |
84 | static const char *version = "qeth S/390 OSA-Express driver"; | 84 | static const char *version = "qeth S/390 OSA-Express driver"; |
85 | 85 | ||
86 | /** | 86 | /** |
@@ -3795,12 +3795,16 @@ static inline int | |||
3795 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, | 3795 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, |
3796 | struct qeth_hdr **hdr, int ipv) | 3796 | struct qeth_hdr **hdr, int ipv) |
3797 | { | 3797 | { |
3798 | int rc; | ||
3798 | #ifdef CONFIG_QETH_VLAN | 3799 | #ifdef CONFIG_QETH_VLAN |
3799 | u16 *tag; | 3800 | u16 *tag; |
3800 | #endif | 3801 | #endif |
3801 | 3802 | ||
3802 | QETH_DBF_TEXT(trace, 6, "prepskb"); | 3803 | QETH_DBF_TEXT(trace, 6, "prepskb"); |
3803 | 3804 | ||
3805 | rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr)); | ||
3806 | if (rc) | ||
3807 | return rc; | ||
3804 | #ifdef CONFIG_QETH_VLAN | 3808 | #ifdef CONFIG_QETH_VLAN |
3805 | if (card->vlangrp && vlan_tx_tag_present(*skb) && | 3809 | if (card->vlangrp && vlan_tx_tag_present(*skb) && |
3806 | ((ipv == 6) || card->options.layer2) ) { | 3810 | ((ipv == 6) || card->options.layer2) ) { |
@@ -4251,7 +4255,8 @@ out: | |||
4251 | } | 4255 | } |
4252 | 4256 | ||
4253 | static inline int | 4257 | static inline int |
4254 | qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) | 4258 | qeth_get_elements_no(struct qeth_card *card, void *hdr, |
4259 | struct sk_buff *skb, int elems) | ||
4255 | { | 4260 | { |
4256 | int elements_needed = 0; | 4261 | int elements_needed = 0; |
4257 | 4262 | ||
@@ -4261,9 +4266,10 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) | |||
4261 | if (elements_needed == 0 ) | 4266 | if (elements_needed == 0 ) |
4262 | elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) | 4267 | elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) |
4263 | + skb->len) >> PAGE_SHIFT); | 4268 | + skb->len) >> PAGE_SHIFT); |
4264 | if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ | 4269 | if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){ |
4265 | PRINT_ERR("qeth_do_send_packet: invalid size of " | 4270 | PRINT_ERR("qeth_do_send_packet: invalid size of " |
4266 | "IP packet. Discarded."); | 4271 | "IP packet (Number=%d / Length=%d). Discarded.\n", |
4272 | (elements_needed+elems), skb->len); | ||
4267 | return 0; | 4273 | return 0; |
4268 | } | 4274 | } |
4269 | return elements_needed; | 4275 | return elements_needed; |
@@ -4337,9 +4343,11 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) | |||
4337 | return -EINVAL; | 4343 | return -EINVAL; |
4338 | } | 4344 | } |
4339 | } else { | 4345 | } else { |
4340 | elements_needed += qeth_get_elements_no(card,(void*) hdr, skb); | 4346 | int elems = qeth_get_elements_no(card,(void*) hdr, skb, |
4341 | if (!elements_needed) | 4347 | elements_needed); |
4348 | if (!elems) | ||
4342 | return -EINVAL; | 4349 | return -EINVAL; |
4350 | elements_needed += elems; | ||
4343 | } | 4351 | } |
4344 | 4352 | ||
4345 | if (card->info.type != QETH_CARD_TYPE_IQD) | 4353 | if (card->info.type != QETH_CARD_TYPE_IQD) |
@@ -7038,14 +7046,16 @@ qeth_setrouting_v6(struct qeth_card *card) | |||
7038 | } | 7046 | } |
7039 | 7047 | ||
7040 | int | 7048 | int |
7041 | qeth_set_large_send(struct qeth_card *card) | 7049 | qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type) |
7042 | { | 7050 | { |
7043 | int rc = 0; | 7051 | int rc = 0; |
7044 | 7052 | ||
7045 | if (card->dev == NULL) | 7053 | if (card->dev == NULL) { |
7054 | card->options.large_send = type; | ||
7046 | return 0; | 7055 | return 0; |
7047 | 7056 | } | |
7048 | netif_stop_queue(card->dev); | 7057 | netif_stop_queue(card->dev); |
7058 | card->options.large_send = type; | ||
7049 | switch (card->options.large_send) { | 7059 | switch (card->options.large_send) { |
7050 | case QETH_LARGE_SEND_EDDP: | 7060 | case QETH_LARGE_SEND_EDDP: |
7051 | card->dev->features |= NETIF_F_TSO | NETIF_F_SG; | 7061 | card->dev->features |= NETIF_F_TSO | NETIF_F_SG; |
@@ -7066,7 +7076,6 @@ qeth_set_large_send(struct qeth_card *card) | |||
7066 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG); | 7076 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG); |
7067 | break; | 7077 | break; |
7068 | } | 7078 | } |
7069 | |||
7070 | netif_wake_queue(card->dev); | 7079 | netif_wake_queue(card->dev); |
7071 | return rc; | 7080 | return rc; |
7072 | } | 7081 | } |