]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - drivers/s390/net/qeth_core_main.c
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
[linux-2.6.git] / drivers / s390 / net / qeth_core_main.c
index d1b5bebea7fbb3a36ad29b5eff6f231ce2a3f4d5..c827d69b5a912c83244afd3cdd1eeb98b630b7e9 100644 (file)
@@ -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);