|
@@ -1,6 +1,6 @@
|
|
/*
|
|
/*
|
|
*
|
|
*
|
|
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.242 $)
|
|
|
|
|
|
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.246 $)
|
|
*
|
|
*
|
|
* Linux on zSeries OSA Express and HiperSockets support
|
|
* Linux on zSeries OSA Express and HiperSockets support
|
|
*
|
|
*
|
|
@@ -72,7 +72,7 @@
|
|
#include "qeth_eddp.h"
|
|
#include "qeth_eddp.h"
|
|
#include "qeth_tso.h"
|
|
#include "qeth_tso.h"
|
|
|
|
|
|
-#define VERSION_QETH_C "$Revision: 1.242 $"
|
|
|
|
|
|
+#define VERSION_QETH_C "$Revision: 1.246 $"
|
|
static const char *version = "qeth S/390 OSA-Express driver";
|
|
static const char *version = "qeth S/390 OSA-Express driver";
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -2203,24 +2203,21 @@ qeth_ulp_setup(struct qeth_card *card)
|
|
}
|
|
}
|
|
|
|
|
|
static inline int
|
|
static inline int
|
|
-qeth_check_for_inbound_error(struct qeth_qdio_buffer *buf,
|
|
|
|
- unsigned int qdio_error,
|
|
|
|
- unsigned int siga_error)
|
|
|
|
|
|
+qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
|
|
|
|
+ unsigned int siga_error, const char *dbftext)
|
|
{
|
|
{
|
|
- int rc = 0;
|
|
|
|
-
|
|
|
|
if (qdio_error || siga_error) {
|
|
if (qdio_error || siga_error) {
|
|
- QETH_DBF_TEXT(trace, 2, "qdinerr");
|
|
|
|
- QETH_DBF_TEXT(qerr, 2, "qdinerr");
|
|
|
|
|
|
+ QETH_DBF_TEXT(trace, 2, dbftext);
|
|
|
|
+ QETH_DBF_TEXT(qerr, 2, dbftext);
|
|
QETH_DBF_TEXT_(qerr, 2, " F15=%02X",
|
|
QETH_DBF_TEXT_(qerr, 2, " F15=%02X",
|
|
- buf->buffer->element[15].flags & 0xff);
|
|
|
|
|
|
+ buf->element[15].flags & 0xff);
|
|
QETH_DBF_TEXT_(qerr, 2, " F14=%02X",
|
|
QETH_DBF_TEXT_(qerr, 2, " F14=%02X",
|
|
- buf->buffer->element[14].flags & 0xff);
|
|
|
|
|
|
+ buf->element[14].flags & 0xff);
|
|
QETH_DBF_TEXT_(qerr, 2, " qerr=%X", qdio_error);
|
|
QETH_DBF_TEXT_(qerr, 2, " qerr=%X", qdio_error);
|
|
QETH_DBF_TEXT_(qerr, 2, " serr=%X", siga_error);
|
|
QETH_DBF_TEXT_(qerr, 2, " serr=%X", siga_error);
|
|
- rc = 1;
|
|
|
|
|
|
+ return 1;
|
|
}
|
|
}
|
|
- return rc;
|
|
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
static inline struct sk_buff *
|
|
static inline struct sk_buff *
|
|
@@ -2769,8 +2766,9 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
|
|
for (i = first_element; i < (first_element + count); ++i) {
|
|
for (i = first_element; i < (first_element + count); ++i) {
|
|
index = i % QDIO_MAX_BUFFERS_PER_Q;
|
|
index = i % QDIO_MAX_BUFFERS_PER_Q;
|
|
buffer = &card->qdio.in_q->bufs[index];
|
|
buffer = &card->qdio.in_q->bufs[index];
|
|
- if (!((status == QDIO_STATUS_LOOK_FOR_ERROR) &&
|
|
|
|
- qeth_check_for_inbound_error(buffer, qdio_err, siga_err)))
|
|
|
|
|
|
+ if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) &&
|
|
|
|
+ qeth_check_qdio_errors(buffer->buffer,
|
|
|
|
+ qdio_err, siga_err,"qinerr")))
|
|
qeth_process_inbound_buffer(card, buffer, index);
|
|
qeth_process_inbound_buffer(card, buffer, index);
|
|
/* clear buffer and give back to hardware */
|
|
/* clear buffer and give back to hardware */
|
|
qeth_put_buffer_pool_entry(card, buffer->pool_entry);
|
|
qeth_put_buffer_pool_entry(card, buffer->pool_entry);
|
|
@@ -2785,12 +2783,13 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
|
|
static inline int
|
|
static inline int
|
|
qeth_handle_send_error(struct qeth_card *card,
|
|
qeth_handle_send_error(struct qeth_card *card,
|
|
struct qeth_qdio_out_buffer *buffer,
|
|
struct qeth_qdio_out_buffer *buffer,
|
|
- int qdio_err, int siga_err)
|
|
|
|
|
|
+ unsigned int qdio_err, unsigned int siga_err)
|
|
{
|
|
{
|
|
int sbalf15 = buffer->buffer->element[15].flags & 0xff;
|
|
int sbalf15 = buffer->buffer->element[15].flags & 0xff;
|
|
int cc = siga_err & 3;
|
|
int cc = siga_err & 3;
|
|
|
|
|
|
QETH_DBF_TEXT(trace, 6, "hdsnderr");
|
|
QETH_DBF_TEXT(trace, 6, "hdsnderr");
|
|
|
|
+ qeth_check_qdio_errors(buffer->buffer, qdio_err, siga_err, "qouterr");
|
|
switch (cc) {
|
|
switch (cc) {
|
|
case 0:
|
|
case 0:
|
|
if (qdio_err){
|
|
if (qdio_err){
|
|
@@ -3047,7 +3046,8 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status,
|
|
for(i = first_element; i < (first_element + count); ++i){
|
|
for(i = first_element; i < (first_element + count); ++i){
|
|
buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
|
|
buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
|
|
/*we only handle the KICK_IT error by doing a recovery */
|
|
/*we only handle the KICK_IT error by doing a recovery */
|
|
- if (qeth_handle_send_error(card, buffer, qdio_error, siga_error)
|
|
|
|
|
|
+ if (qeth_handle_send_error(card, buffer,
|
|
|
|
+ qdio_error, siga_error)
|
|
== QETH_SEND_ERROR_KICK_IT){
|
|
== QETH_SEND_ERROR_KICK_IT){
|
|
netif_stop_queue(card->dev);
|
|
netif_stop_queue(card->dev);
|
|
qeth_schedule_recovery(card);
|
|
qeth_schedule_recovery(card);
|
|
@@ -3289,7 +3289,6 @@ qeth_init_qdio_info(struct qeth_card *card)
|
|
card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count;
|
|
card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count;
|
|
INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
|
|
INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
|
|
INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
|
|
INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
|
|
- /* outbound */
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static int
|
|
static int
|
|
@@ -3731,6 +3730,9 @@ qeth_verify_vlan_dev(struct net_device *dev, struct qeth_card *card)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ if (rc && !(VLAN_DEV_INFO(dev)->real_dev->priv == (void *)card))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
#endif
|
|
#endif
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
@@ -5870,10 +5872,8 @@ qeth_add_multicast_ipv6(struct qeth_card *card)
|
|
struct inet6_dev *in6_dev;
|
|
struct inet6_dev *in6_dev;
|
|
|
|
|
|
QETH_DBF_TEXT(trace,4,"chkmcv6");
|
|
QETH_DBF_TEXT(trace,4,"chkmcv6");
|
|
- if ((card->options.layer2 == 0) &&
|
|
|
|
- (!qeth_is_supported(card, IPA_IPV6)) )
|
|
|
|
|
|
+ if (!qeth_is_supported(card, IPA_IPV6))
|
|
return ;
|
|
return ;
|
|
-
|
|
|
|
in6_dev = in6_dev_get(card->dev);
|
|
in6_dev = in6_dev_get(card->dev);
|
|
if (in6_dev == NULL)
|
|
if (in6_dev == NULL)
|
|
return;
|
|
return;
|