提交 9cb90de8 编写于 作者: F Frank Pavlic 提交者: Jeff Garzik

[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: NFrank 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: NJeff Garzik <jgarzik@pobox.com>
上级 e172577d
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "qeth_mpc.h" #include "qeth_mpc.h"
#define VERSION_QETH_H "$Revision: 1.139 $" #define VERSION_QETH_H "$Revision: 1.141 $"
#ifdef CONFIG_QETH_IPV6 #ifdef CONFIG_QETH_IPV6
#define QETH_VERSION_IPV6 ":IPv6" #define QETH_VERSION_IPV6 ":IPv6"
...@@ -1172,7 +1172,7 @@ extern int ...@@ -1172,7 +1172,7 @@ extern int
qeth_realloc_buffer_pool(struct qeth_card *, int); qeth_realloc_buffer_pool(struct qeth_card *, int);
extern int extern int
qeth_set_large_send(struct qeth_card *); qeth_set_large_send(struct qeth_card *, enum qeth_large_send_types);
extern void extern void
qeth_fill_header(struct qeth_card *, struct qeth_hdr *, qeth_fill_header(struct qeth_card *, struct qeth_hdr *,
......
/* /*
* *
* linux/drivers/s390/net/qeth_main.c ($Revision: 1.214 $) * linux/drivers/s390/net/qeth_main.c ($Revision: 1.219 $)
* *
* Linux on zSeries OSA Express and HiperSockets support * Linux on zSeries OSA Express and HiperSockets support
* *
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* Frank Pavlic (pavlic@de.ibm.com) and * Frank Pavlic (pavlic@de.ibm.com) and
* Thomas Spatzier <tspat@de.ibm.com> * Thomas Spatzier <tspat@de.ibm.com>
* *
* $Revision: 1.214 $ $Date: 2005/05/04 20:19:18 $ * $Revision: 1.219 $ $Date: 2005/05/04 20:19:18 $
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -80,7 +80,7 @@ qeth_eyecatcher(void) ...@@ -80,7 +80,7 @@ qeth_eyecatcher(void)
#include "qeth_eddp.h" #include "qeth_eddp.h"
#include "qeth_tso.h" #include "qeth_tso.h"
#define VERSION_QETH_C "$Revision: 1.214 $" #define VERSION_QETH_C "$Revision: 1.219 $"
static const char *version = "qeth S/390 OSA-Express driver"; static const char *version = "qeth S/390 OSA-Express driver";
/** /**
...@@ -3795,12 +3795,16 @@ static inline int ...@@ -3795,12 +3795,16 @@ static inline int
qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb,
struct qeth_hdr **hdr, int ipv) struct qeth_hdr **hdr, int ipv)
{ {
int rc;
#ifdef CONFIG_QETH_VLAN #ifdef CONFIG_QETH_VLAN
u16 *tag; u16 *tag;
#endif #endif
QETH_DBF_TEXT(trace, 6, "prepskb"); QETH_DBF_TEXT(trace, 6, "prepskb");
rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr));
if (rc)
return rc;
#ifdef CONFIG_QETH_VLAN #ifdef CONFIG_QETH_VLAN
if (card->vlangrp && vlan_tx_tag_present(*skb) && if (card->vlangrp && vlan_tx_tag_present(*skb) &&
((ipv == 6) || card->options.layer2) ) { ((ipv == 6) || card->options.layer2) ) {
...@@ -4251,7 +4255,8 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, ...@@ -4251,7 +4255,8 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
} }
static inline int static inline int
qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) qeth_get_elements_no(struct qeth_card *card, void *hdr,
struct sk_buff *skb, int elems)
{ {
int elements_needed = 0; int elements_needed = 0;
...@@ -4261,9 +4266,10 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) ...@@ -4261,9 +4266,10 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb)
if (elements_needed == 0 ) if (elements_needed == 0 )
elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE)
+ skb->len) >> PAGE_SHIFT); + skb->len) >> PAGE_SHIFT);
if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){
PRINT_ERR("qeth_do_send_packet: invalid size of " PRINT_ERR("qeth_do_send_packet: invalid size of "
"IP packet. Discarded."); "IP packet (Number=%d / Length=%d). Discarded.\n",
(elements_needed+elems), skb->len);
return 0; return 0;
} }
return elements_needed; return elements_needed;
...@@ -4337,9 +4343,11 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) ...@@ -4337,9 +4343,11 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
return -EINVAL; return -EINVAL;
} }
} else { } else {
elements_needed += qeth_get_elements_no(card,(void*) hdr, skb); int elems = qeth_get_elements_no(card,(void*) hdr, skb,
if (!elements_needed) elements_needed);
if (!elems)
return -EINVAL; return -EINVAL;
elements_needed += elems;
} }
if (card->info.type != QETH_CARD_TYPE_IQD) if (card->info.type != QETH_CARD_TYPE_IQD)
...@@ -7038,14 +7046,16 @@ qeth_setrouting_v6(struct qeth_card *card) ...@@ -7038,14 +7046,16 @@ qeth_setrouting_v6(struct qeth_card *card)
} }
int int
qeth_set_large_send(struct qeth_card *card) qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
{ {
int rc = 0; int rc = 0;
if (card->dev == NULL) if (card->dev == NULL) {
card->options.large_send = type;
return 0; return 0;
}
netif_stop_queue(card->dev); netif_stop_queue(card->dev);
card->options.large_send = type;
switch (card->options.large_send) { switch (card->options.large_send) {
case QETH_LARGE_SEND_EDDP: case QETH_LARGE_SEND_EDDP:
card->dev->features |= NETIF_F_TSO | NETIF_F_SG; card->dev->features |= NETIF_F_TSO | NETIF_F_SG;
...@@ -7066,7 +7076,6 @@ qeth_set_large_send(struct qeth_card *card) ...@@ -7066,7 +7076,6 @@ qeth_set_large_send(struct qeth_card *card)
card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG); card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
break; break;
} }
netif_wake_queue(card->dev); netif_wake_queue(card->dev);
return rc; return rc;
} }
......
/* /*
* *
* linux/drivers/s390/net/qeth_sys.c ($Revision: 1.51 $) * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.53 $)
* *
* Linux on zSeries OSA Express and HiperSockets support * Linux on zSeries OSA Express and HiperSockets support
* This file contains code related to sysfs. * This file contains code related to sysfs.
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include "qeth_mpc.h" #include "qeth_mpc.h"
#include "qeth_fs.h" #include "qeth_fs.h"
const char *VERSION_QETH_SYS_C = "$Revision: 1.51 $"; const char *VERSION_QETH_SYS_C = "$Revision: 1.53 $";
/*****************************************************************************/ /*****************************************************************************/
/* */ /* */
...@@ -771,9 +771,7 @@ qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, con ...@@ -771,9 +771,7 @@ qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, con
if (!card) if (!card)
return -EINVAL; return -EINVAL;
tmp = strsep((char **) &buf, "\n"); tmp = strsep((char **) &buf, "\n");
if (!strcmp(tmp, "no")){ if (!strcmp(tmp, "no")){
type = QETH_LARGE_SEND_NO; type = QETH_LARGE_SEND_NO;
} else if (!strcmp(tmp, "EDDP")) { } else if (!strcmp(tmp, "EDDP")) {
...@@ -786,10 +784,8 @@ qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, con ...@@ -786,10 +784,8 @@ qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, con
} }
if (card->options.large_send == type) if (card->options.large_send == type)
return count; return count;
card->options.large_send = type; if ((rc = qeth_set_large_send(card, type)))
if ((rc = qeth_set_large_send(card)))
return rc; return rc;
return count; return count;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册