aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/net/qeth_core_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/net/qeth_core_main.c')
-rw-r--r--drivers/s390/net/qeth_core_main.c165
1 files changed, 47 insertions, 118 deletions
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index d1b5bebea7fb..c827d69b5a91 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -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,
@@ -1690,7 +1676,7 @@ int qeth_send_control_data(struct qeth_card *card, int len,
int rc;
unsigned long flags;
struct qeth_reply *reply = NULL;
- unsigned long timeout;
+ unsigned long timeout, event_timeout;
struct qeth_ipa_cmd *cmd;
QETH_DBF_TEXT(TRACE, 2, "sendctl");
@@ -1715,9 +1701,10 @@ int qeth_send_control_data(struct qeth_card *card, int len,
qeth_prepare_control_data(card, len, iob);
if (IS_IPA(iob->data))
- timeout = jiffies + QETH_IPA_TIMEOUT;
+ event_timeout = QETH_IPA_TIMEOUT;
else
- timeout = jiffies + QETH_TIMEOUT;
+ event_timeout = QETH_TIMEOUT;
+ timeout = jiffies + event_timeout;
QETH_DBF_TEXT(TRACE, 6, "noirqpnd");
spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
@@ -1745,7 +1732,7 @@ int qeth_send_control_data(struct qeth_card *card, int len,
if ((cmd->hdr.command == IPA_CMD_SETIP) &&
(cmd->hdr.prot_version == QETH_PROT_IPV4)) {
if (!wait_event_timeout(reply->wait_q,
- atomic_read(&reply->received), timeout))
+ atomic_read(&reply->received), event_timeout))
goto time_err;
} else {
while (!atomic_read(&reply->received)) {
@@ -2693,40 +2680,21 @@ static int qeth_handle_send_error(struct qeth_card *card,
struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err)
{
int sbalf15 = buffer->buffer->element[15].flags & 0xff;
- int cc = qdio_err & 3;
QETH_DBF_TEXT(TRACE, 6, "hdsnderr");
qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr");
- switch (cc) {
- case 0:
- if (qdio_err) {
- QETH_DBF_TEXT(TRACE, 1, "lnkfail");
- QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
- QETH_DBF_TEXT_(TRACE, 1, "%04x %02x",
- (u16)qdio_err, (u8)sbalf15);
- return QETH_SEND_ERROR_LINK_FAILURE;
- }
+
+ if (!qdio_err)
return QETH_SEND_ERROR_NONE;
- case 2:
- if (qdio_err & QDIO_ERROR_SIGA_BUSY) {
- QETH_DBF_TEXT(TRACE, 1, "SIGAcc2B");
- QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
- return QETH_SEND_ERROR_KICK_IT;
- }
- if ((sbalf15 >= 15) && (sbalf15 <= 31))
- return QETH_SEND_ERROR_RETRY;
- return QETH_SEND_ERROR_LINK_FAILURE;
- /* look at qdio_error and sbalf 15 */
- case 1:
- QETH_DBF_TEXT(TRACE, 1, "SIGAcc1");
- QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
- return QETH_SEND_ERROR_LINK_FAILURE;
- case 3:
- default:
- QETH_DBF_TEXT(TRACE, 1, "SIGAcc3");
- QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
- return QETH_SEND_ERROR_KICK_IT;
- }
+
+ if ((sbalf15 >= 15) && (sbalf15 <= 31))
+ return QETH_SEND_ERROR_RETRY;
+
+ QETH_DBF_TEXT(TRACE, 1, "lnkfail");
+ QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
+ QETH_DBF_TEXT_(TRACE, 1, "%04x %02x",
+ (u16)qdio_err, (u8)sbalf15);
+ return QETH_SEND_ERROR_LINK_FAILURE;
}
/*
@@ -2862,10 +2830,14 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
qeth_get_micros() -
queue->card->perf_stats.outbound_do_qdio_start_time;
if (rc) {
+ queue->card->stats.tx_errors += count;
+ /* ignore temporary SIGA errors without busy condition */
+ if (rc == QDIO_ERROR_SIGA_TARGET)
+ return;
QETH_DBF_TEXT(TRACE, 2, "flushbuf");
QETH_DBF_TEXT_(TRACE, 2, " err%d", rc);
QETH_DBF_TEXT_(TRACE, 2, "%s", CARD_DDEV_ID(queue->card));
- queue->card->stats.tx_errors += count;
+
/* this must not happen under normal circumstances. if it
* happens something is really wrong -> recover */
qeth_schedule_recovery(queue->card);
@@ -2940,13 +2912,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
}
for (i = first_element; i < (first_element + count); ++i) {
buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
- /*we only handle the KICK_IT error by doing a recovery */
- if (qeth_handle_send_error(card, buffer, qdio_error)
- == QETH_SEND_ERROR_KICK_IT){
- netif_stop_queue(card->dev);
- qeth_schedule_recovery(card);
- return;
- }
+ qeth_handle_send_error(card, buffer, qdio_error);
qeth_clear_output_buffer(queue, buffer);
}
atomic_sub(count, &queue->used_buffers);
@@ -3187,11 +3153,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 +3170,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) %
+ 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);
- }
+ qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
+ qeth_flush_buffers(queue, index, 1);
return 0;
out:
atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
@@ -3236,7 +3184,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,53 +3210,32 @@ 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);
- flush_count++;
- queue->next_buf_to_fill =
- (queue->next_buf_to_fill + 1) %
- QDIO_MAX_BUFFERS_PER_Q;
- buffer = &queue->bufs[queue->next_buf_to_fill];
- /* we did a step forward, so check buffer state
- * again */
- if (atomic_read(&buffer->state) !=
- QETH_QDIO_BUF_EMPTY){
- qeth_flush_buffers(queue, start_index,
+ /* 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);
+ flush_count++;
+ queue->next_buf_to_fill =
+ (queue->next_buf_to_fill + 1) %
+ QDIO_MAX_BUFFERS_PER_Q;
+ buffer = &queue->bufs[queue->next_buf_to_fill];
+ /* we did a step forward, so check buffer state
+ * again */
+ if (atomic_read(&buffer->state) !=
+ QETH_QDIO_BUF_EMPTY) {
+ qeth_flush_buffers(queue, start_index,
flush_count);
- atomic_set(&queue->state,
+ atomic_set(&queue->state,
QETH_OUT_Q_UNLOCKED);
- 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;
+ return -EBUSY;
}
}
}
- 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;
- }
- }
+ tmp = qeth_fill_buffer(queue, buffer, skb, hdr, -1, 0);
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))
@@ -4327,6 +4254,7 @@ static struct {
/* 30 */{"tx count"},
{"tx do_QDIO time"},
{"tx do_QDIO count"},
+ {"tx csum"},
};
int qeth_core_get_stats_count(struct net_device *dev)
@@ -4378,6 +4306,7 @@ void qeth_core_get_ethtool_stats(struct net_device *dev,
data[30] = card->perf_stats.outbound_cnt;
data[31] = card->perf_stats.outbound_do_qdio_time;
data[32] = card->perf_stats.outbound_do_qdio_cnt;
+ data[33] = card->perf_stats.tx_csum;
}
EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats);