Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64ef8957 authored by Frank Blaschka's avatar Frank Blaschka Committed by David S. Miller
Browse files

qeth: remove EDDP



Performance measurements showed EDDP does not lower CPU costs but increase
them. So we dump out EDDP code from qeth driver.

Signed-off-by: default avatarFrank Blaschka <frank.blaschka@de.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f61a0d05
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
obj-$(CONFIG_LCS) += lcs.o cu3088.o
obj-$(CONFIG_CLAW) += claw.o cu3088.o
qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o qeth_core_offl.o
qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o
obj-$(CONFIG_QETH) += qeth.o
qeth_l2-y += qeth_l2_main.o
obj-$(CONFIG_QETH_L2) += qeth_l2.o
+2 −5
Original line number Diff line number Diff line
@@ -404,7 +404,6 @@ struct qeth_qdio_q {
/* possible types of qeth large_send support */
enum qeth_large_send_types {
	QETH_LARGE_SEND_NO,
	QETH_LARGE_SEND_EDDP,
	QETH_LARGE_SEND_TSO,
};

@@ -839,11 +838,9 @@ int qeth_get_cast_type(struct qeth_card *, struct sk_buff *);
int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int);
int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int);
int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *,
			struct sk_buff *, struct qeth_hdr *, int,
			struct qeth_eddp_context *, int, int);
			struct sk_buff *, struct qeth_hdr *, int, int, int);
int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *,
		    struct sk_buff *, struct qeth_hdr *,
		    int, struct qeth_eddp_context *);
		    struct sk_buff *, struct qeth_hdr *, int);
int qeth_core_get_stats_count(struct net_device *);
void qeth_core_get_ethtool_stats(struct net_device *,
				struct ethtool_stats *, u64 *);
+23 −76
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/tcp.h>
#include <linux/mii.h>
#include <linux/kthread.h>
@@ -26,7 +25,6 @@
#include <asm/io.h>

#include "qeth_core.h"
#include "qeth_core_offl.h"

struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = {
	/* define dbf - Name, Pages, Areas, Maxlen, Level, View, Handle */
@@ -285,17 +283,6 @@ int qeth_set_large_send(struct qeth_card *card,
		netif_tx_disable(card->dev);
	card->options.large_send = type;
	switch (card->options.large_send) {
	case QETH_LARGE_SEND_EDDP:
		if (card->info.type != QETH_CARD_TYPE_IQD) {
			card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
					NETIF_F_HW_CSUM;
		} else {
			card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
						NETIF_F_HW_CSUM);
			card->options.large_send = QETH_LARGE_SEND_NO;
			rc = -EOPNOTSUPP;
		}
		break;
	case QETH_LARGE_SEND_TSO:
		if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
			card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
@@ -956,7 +943,6 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
		dev_kfree_skb_any(skb);
		skb = skb_dequeue(&buf->skb_list);
	}
	qeth_eddp_buf_release_contexts(buf);
	for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i) {
		if (buf->buffer->element[i].addr && buf->is_header[i])
			kmem_cache_free(qeth_core_header_cache,
@@ -3187,11 +3173,9 @@ static inline int qeth_fill_buffer(struct qeth_qdio_out_q *queue,
int qeth_do_send_packet_fast(struct qeth_card *card,
		struct qeth_qdio_out_q *queue, struct sk_buff *skb,
		struct qeth_hdr *hdr, int elements_needed,
		struct qeth_eddp_context *ctx, int offset, int hd_len)
		int offset, int hd_len)
{
	struct qeth_qdio_out_buffer *buffer;
	int buffers_needed = 0;
	int flush_cnt = 0;
	int index;

	/* spin until we get the queue ... */
@@ -3206,27 +3190,11 @@ int qeth_do_send_packet_fast(struct qeth_card *card,
	 */
	if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
		goto out;
	if (ctx == NULL)
	queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
					  QDIO_MAX_BUFFERS_PER_Q;
	else {
		buffers_needed = qeth_eddp_check_buffers_for_context(queue,
									ctx);
		if (buffers_needed < 0)
			goto out;
		queue->next_buf_to_fill =
			(queue->next_buf_to_fill + buffers_needed) %
			QDIO_MAX_BUFFERS_PER_Q;
	}
	atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
	if (ctx == NULL) {
	qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
	qeth_flush_buffers(queue, index, 1);
	} else {
		flush_cnt = qeth_eddp_fill_buffer(queue, ctx, index);
		WARN_ON(buffers_needed != flush_cnt);
		qeth_flush_buffers(queue, index, flush_cnt);
	}
	return 0;
out:
	atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
@@ -3236,7 +3204,7 @@ EXPORT_SYMBOL_GPL(qeth_do_send_packet_fast);

int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
		struct sk_buff *skb, struct qeth_hdr *hdr,
		int elements_needed, struct qeth_eddp_context *ctx)
		int elements_needed)
{
	struct qeth_qdio_out_buffer *buffer;
	int start_index;
@@ -3262,13 +3230,11 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
	qeth_switch_to_packing_if_needed(queue);
	if (queue->do_pack) {
		do_pack = 1;
		if (ctx == NULL) {
		/* does packet fit in current buffer? */
		if ((QETH_MAX_BUFFER_ELEMENTS(card) -
		    buffer->next_element_to_fill) < elements_needed) {
			/* ... no -> set state PRIMED */
				atomic_set(&buffer->state,
					QETH_QDIO_BUF_PRIMED);
			atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
			flush_count++;
			queue->next_buf_to_fill =
				(queue->next_buf_to_fill + 1) %
@@ -3285,30 +3251,11 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
				return -EBUSY;
			}
		}
		} else {
			/* check if we have enough elements (including following
			 * free buffers) to handle eddp context */
			if (qeth_eddp_check_buffers_for_context(queue, ctx)
				< 0) {
				rc = -EBUSY;
				goto out;
	}
		}
	}
	if (ctx == NULL)
	tmp = qeth_fill_buffer(queue, buffer, skb, hdr, -1, 0);
	else {
		tmp = qeth_eddp_fill_buffer(queue, ctx,
						queue->next_buf_to_fill);
		if (tmp < 0) {
			rc = -EBUSY;
			goto out;
		}
	}
	queue->next_buf_to_fill = (queue->next_buf_to_fill + tmp) %
				  QDIO_MAX_BUFFERS_PER_Q;
	flush_count += tmp;
out:
	if (flush_count)
		qeth_flush_buffers(queue, start_index, flush_count);
	else if (!atomic_read(&queue->set_pci_flags_count))
+0 −699

File changed.

Preview size limit exceeded, changes collapsed.

+0 −76
Original line number Diff line number Diff line
/*
 *  drivers/s390/net/qeth_core_offl.h
 *
 *    Copyright IBM Corp. 2007
 *    Author(s): Thomas Spatzier <tspat@de.ibm.com>,
 *		 Frank Blaschka <frank.blaschka@de.ibm.com>
 */

#ifndef __QETH_CORE_OFFL_H__
#define __QETH_CORE_OFFL_H__

struct qeth_eddp_element {
	u32 flags;
	u32 length;
	void *addr;
};

struct qeth_eddp_context {
	atomic_t refcnt;
	enum qeth_large_send_types type;
	int num_pages;			    /* # of allocated pages */
	u8 **pages;			    /* pointers to pages */
	int offset;			    /* offset in ctx during creation */
	int num_elements;		    /* # of required 'SBALEs' */
	struct qeth_eddp_element *elements; /* array of 'SBALEs' */
	int elements_per_skb;		    /* # of 'SBALEs' per skb **/
};

struct qeth_eddp_context_reference {
	struct list_head list;
	struct qeth_eddp_context *ctx;
};

struct qeth_eddp_data {
	struct qeth_hdr qh;
	struct ethhdr mac;
	__be16 vlan[2];
	union {
		struct {
			struct iphdr h;
			u8 options[40];
		} ip4;
		struct {
			struct ipv6hdr h;
		} ip6;
	} nh;
	u8 nhl;
	void *nh_in_ctx;	/* address of nh within the ctx */
	union {
		struct {
			struct tcphdr h;
			u8 options[40];
		} tcp;
	} th;
	u8 thl;
	void *th_in_ctx;	/* address of th within the ctx */
	struct sk_buff *skb;
	int skb_offset;
	int frag;
	int frag_offset;
} __attribute__ ((packed));

extern struct qeth_eddp_context *qeth_eddp_create_context(struct qeth_card *,
		 struct sk_buff *, struct qeth_hdr *, unsigned char);
extern void qeth_eddp_put_context(struct qeth_eddp_context *);
extern int qeth_eddp_fill_buffer(struct qeth_qdio_out_q *,
		struct qeth_eddp_context *, int);
extern void qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *);
extern int qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *,
		struct qeth_eddp_context *);

void qeth_tso_fill_header(struct qeth_card *, struct qeth_hdr *,
		struct sk_buff *);
void qeth_tx_csum(struct sk_buff *skb);

#endif /* __QETH_CORE_EDDP_H__ */
Loading