aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorStefan Raspl <raspl@linux.vnet.ibm.com>2014-04-28 04:05:08 -0400
committerDavid S. Miller <davem@davemloft.net>2014-04-28 13:44:10 -0400
commit290b8348c0ef7f23de8a974d83c96fc095d3bda7 (patch)
tree0d417277f8da4933d3f1a31ea144d95338358639 /drivers/s390
parent9262c6c29927c73b1e7db364defcd6044a7e32a3 (diff)
qeth: Extend priority queueing to IPv6
Make the current priority queueing logic apply to IPv6 traffic. Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com> Reviewed-by: Ursula Braun <ursula.braun@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/net/qeth_core.h4
-rw-r--r--drivers/s390/net/qeth_core_main.c62
-rw-r--r--drivers/s390/net/qeth_l2_main.c11
-rw-r--r--drivers/s390/net/qeth_l3_main.c7
4 files changed, 48 insertions, 36 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 5333b2c018e7..0a4148d2d962 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -268,10 +268,6 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
268#define QETH_NO_PRIO_QUEUEING 0 268#define QETH_NO_PRIO_QUEUEING 0
269#define QETH_PRIO_Q_ING_PREC 1 269#define QETH_PRIO_Q_ING_PREC 1
270#define QETH_PRIO_Q_ING_TOS 2 270#define QETH_PRIO_Q_ING_TOS 2
271#define IP_TOS_LOWDELAY 0x10
272#define IP_TOS_HIGHTHROUGHPUT 0x08
273#define IP_TOS_HIGHRELIABILITY 0x04
274#define IP_TOS_NOTIMPORTANT 0x02
275 271
276/* Packing */ 272/* Packing */
277#define QETH_LOW_WATERMARK_PACK 2 273#define QETH_LOW_WATERMARK_PACK 2
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index f5bd4229b192..dca5161beaed 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -20,6 +20,7 @@
20#include <linux/kthread.h> 20#include <linux/kthread.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <net/iucv/af_iucv.h> 22#include <net/iucv/af_iucv.h>
23#include <net/dsfield.h>
23 24
24#include <asm/ebcdic.h> 25#include <asm/ebcdic.h>
25#include <asm/io.h> 26#include <asm/io.h>
@@ -3670,42 +3671,49 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
3670} 3671}
3671EXPORT_SYMBOL_GPL(qeth_qdio_output_handler); 3672EXPORT_SYMBOL_GPL(qeth_qdio_output_handler);
3672 3673
3674/**
3675 * Note: Function assumes that we have 4 outbound queues.
3676 */
3673int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb, 3677int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb,
3674 int ipv, int cast_type) 3678 int ipv, int cast_type)
3675{ 3679{
3680 u8 tos;
3681
3676 if (!ipv && (card->info.type == QETH_CARD_TYPE_OSD || 3682 if (!ipv && (card->info.type == QETH_CARD_TYPE_OSD ||
3677 card->info.type == QETH_CARD_TYPE_OSX)) 3683 card->info.type == QETH_CARD_TYPE_OSX))
3678 return card->qdio.default_out_queue; 3684 return card->qdio.default_out_queue;
3679 switch (card->qdio.no_out_queues) { 3685
3680 case 4: 3686 if (cast_type && card->info.is_multicast_different)
3681 if (cast_type && card->info.is_multicast_different) 3687 return card->info.is_multicast_different &
3682 return card->info.is_multicast_different & 3688 (card->qdio.no_out_queues - 1);
3683 (card->qdio.no_out_queues - 1); 3689
3684 if (card->qdio.do_prio_queueing && (ipv == 4)) { 3690 switch (card->qdio.do_prio_queueing) {
3685 const u8 tos = ip_hdr(skb)->tos; 3691 case QETH_PRIO_Q_ING_TOS:
3686 3692 case QETH_PRIO_Q_ING_PREC:
3687 if (card->qdio.do_prio_queueing == 3693 switch (ipv) {
3688 QETH_PRIO_Q_ING_TOS) { 3694 case 4:
3689 if (tos & IP_TOS_NOTIMPORTANT) 3695 tos = ipv4_get_dsfield(ip_hdr(skb));
3690 return 3; 3696 break;
3691 if (tos & IP_TOS_HIGHRELIABILITY) 3697 case 6:
3692 return 2; 3698 tos = ipv6_get_dsfield(ipv6_hdr(skb));
3693 if (tos & IP_TOS_HIGHTHROUGHPUT) 3699 break;
3694 return 1; 3700 default:
3695 if (tos & IP_TOS_LOWDELAY) 3701 return card->qdio.default_out_queue;
3696 return 0;
3697 }
3698 if (card->qdio.do_prio_queueing ==
3699 QETH_PRIO_Q_ING_PREC)
3700 return 3 - (tos >> 6);
3701 } else if (card->qdio.do_prio_queueing && (ipv == 6)) {
3702 /* TODO: IPv6!!! */
3703 } 3702 }
3704 return card->qdio.default_out_queue; 3703 if (card->qdio.do_prio_queueing == QETH_PRIO_Q_ING_PREC)
3705 case 1: /* fallthrough for single-out-queue 1920-device */ 3704 return ~tos >> 6 & 3;
3705 if (tos & IPTOS_MINCOST)
3706 return 3;
3707 if (tos & IPTOS_RELIABILITY)
3708 return 2;
3709 if (tos & IPTOS_THROUGHPUT)
3710 return 1;
3711 if (tos & IPTOS_LOWDELAY)
3712 return 0;
3706 default: 3713 default:
3707 return card->qdio.default_out_queue; 3714 break;
3708 } 3715 }
3716 return card->qdio.default_out_queue;
3709} 3717}
3710EXPORT_SYMBOL_GPL(qeth_get_priority_queue); 3718EXPORT_SYMBOL_GPL(qeth_get_priority_queue);
3711 3719
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 8dea3f12ccc1..e232ceca38fe 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -725,15 +725,20 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
725 int elements = 0; 725 int elements = 0;
726 struct qeth_card *card = dev->ml_priv; 726 struct qeth_card *card = dev->ml_priv;
727 struct sk_buff *new_skb = skb; 727 struct sk_buff *new_skb = skb;
728 int ipv = qeth_get_ip_version(skb);
729 int cast_type = qeth_l2_get_cast_type(card, skb); 728 int cast_type = qeth_l2_get_cast_type(card, skb);
730 struct qeth_qdio_out_q *queue = card->qdio.out_qs 729 struct qeth_qdio_out_q *queue;
731 [qeth_get_priority_queue(card, skb, ipv, cast_type)];
732 int tx_bytes = skb->len; 730 int tx_bytes = skb->len;
733 int data_offset = -1; 731 int data_offset = -1;
734 int elements_needed = 0; 732 int elements_needed = 0;
735 int hd_len = 0; 733 int hd_len = 0;
736 734
735 if (card->qdio.do_prio_queueing || (cast_type &&
736 card->info.is_multicast_different))
737 queue = card->qdio.out_qs[qeth_get_priority_queue(card, skb,
738 qeth_get_ip_version(skb), cast_type)];
739 else
740 queue = card->qdio.out_qs[card->qdio.default_out_queue];
741
737 if ((card->state != CARD_STATE_UP) || !card->lan_online) { 742 if ((card->state != CARD_STATE_UP) || !card->lan_online) {
738 card->stats.tx_carrier_errors++; 743 card->stats.tx_carrier_errors++;
739 goto tx_drop; 744 goto tx_drop;
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 3524d34ff694..c8d91d797ec8 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2926,8 +2926,11 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
2926 struct sk_buff *new_skb = NULL; 2926 struct sk_buff *new_skb = NULL;
2927 int ipv = qeth_get_ip_version(skb); 2927 int ipv = qeth_get_ip_version(skb);
2928 int cast_type = qeth_l3_get_cast_type(card, skb); 2928 int cast_type = qeth_l3_get_cast_type(card, skb);
2929 struct qeth_qdio_out_q *queue = card->qdio.out_qs 2929 struct qeth_qdio_out_q *queue =
2930 [qeth_get_priority_queue(card, skb, ipv, cast_type)]; 2930 card->qdio.out_qs[card->qdio.do_prio_queueing
2931 || (cast_type && card->info.is_multicast_different) ?
2932 qeth_get_priority_queue(card, skb, ipv, cast_type) :
2933 card->qdio.default_out_queue];
2931 int tx_bytes = skb->len; 2934 int tx_bytes = skb->len;
2932 bool large_send; 2935 bool large_send;
2933 int data_offset = -1; 2936 int data_offset = -1;