|
@@ -1,6 +1,6 @@
|
|
/*
|
|
/*
|
|
*
|
|
*
|
|
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.219 $)
|
|
|
|
|
|
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.224 $)
|
|
*
|
|
*
|
|
* Linux on zSeries OSA Express and HiperSockets support
|
|
* Linux on zSeries OSA Express and HiperSockets support
|
|
*
|
|
*
|
|
@@ -12,7 +12,7 @@
|
|
* Frank Pavlic (pavlic@de.ibm.com) and
|
|
* Frank Pavlic (pavlic@de.ibm.com) and
|
|
* Thomas Spatzier <tspat@de.ibm.com>
|
|
* Thomas Spatzier <tspat@de.ibm.com>
|
|
*
|
|
*
|
|
- * $Revision: 1.219 $ $Date: 2005/05/04 20:19:18 $
|
|
|
|
|
|
+ * $Revision: 1.224 $ $Date: 2005/05/04 20:19:18 $
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* it under the terms of the GNU General Public License as published by
|
|
@@ -29,14 +29,6 @@
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
*/
|
|
|
|
|
|
-/***
|
|
|
|
- * eye catcher; just for debugging purposes
|
|
|
|
- */
|
|
|
|
-void volatile
|
|
|
|
-qeth_eyecatcher(void)
|
|
|
|
-{
|
|
|
|
- return;
|
|
|
|
-}
|
|
|
|
|
|
|
|
#include <linux/config.h>
|
|
#include <linux/config.h>
|
|
#include <linux/module.h>
|
|
#include <linux/module.h>
|
|
@@ -80,7 +72,7 @@ qeth_eyecatcher(void)
|
|
#include "qeth_eddp.h"
|
|
#include "qeth_eddp.h"
|
|
#include "qeth_tso.h"
|
|
#include "qeth_tso.h"
|
|
|
|
|
|
-#define VERSION_QETH_C "$Revision: 1.219 $"
|
|
|
|
|
|
+#define VERSION_QETH_C "$Revision: 1.224 $"
|
|
static const char *version = "qeth S/390 OSA-Express driver";
|
|
static const char *version = "qeth S/390 OSA-Express driver";
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -2759,11 +2751,9 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
|
|
queue->card->perf_stats.outbound_do_qdio_start_time;
|
|
queue->card->perf_stats.outbound_do_qdio_start_time;
|
|
#endif
|
|
#endif
|
|
if (rc){
|
|
if (rc){
|
|
- QETH_DBF_SPRINTF(trace, 0, "qeth_flush_buffers: do_QDIO "
|
|
|
|
- "returned error (%i) on device %s.",
|
|
|
|
- rc, CARD_DDEV_ID(queue->card));
|
|
|
|
QETH_DBF_TEXT(trace, 2, "flushbuf");
|
|
QETH_DBF_TEXT(trace, 2, "flushbuf");
|
|
QETH_DBF_TEXT_(trace, 2, " err%d", rc);
|
|
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;
|
|
queue->card->stats.tx_errors += count;
|
|
/* this must not happen under normal circumstances. if it
|
|
/* this must not happen under normal circumstances. if it
|
|
* happens something is really wrong -> recover */
|
|
* happens something is really wrong -> recover */
|
|
@@ -2909,11 +2899,8 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status,
|
|
QETH_DBF_TEXT(trace, 6, "qdouhdl");
|
|
QETH_DBF_TEXT(trace, 6, "qdouhdl");
|
|
if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
|
|
if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
|
|
if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){
|
|
if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){
|
|
- QETH_DBF_SPRINTF(trace, 2, "On device %s: "
|
|
|
|
- "received active check "
|
|
|
|
- "condition (0x%08x).",
|
|
|
|
- CARD_BUS_ID(card), status);
|
|
|
|
- QETH_DBF_TEXT(trace, 2, "chkcond");
|
|
|
|
|
|
+ QETH_DBF_TEXT(trace, 2, "achkcond");
|
|
|
|
+ QETH_DBF_TEXT_(trace, 2, "%s", CARD_BUS_ID(card));
|
|
QETH_DBF_TEXT_(trace, 2, "%08x", status);
|
|
QETH_DBF_TEXT_(trace, 2, "%08x", status);
|
|
netif_stop_queue(card->dev);
|
|
netif_stop_queue(card->dev);
|
|
qeth_schedule_recovery(card);
|
|
qeth_schedule_recovery(card);
|
|
@@ -3356,26 +3343,32 @@ qeth_halt_channel(struct qeth_channel *channel)
|
|
static int
|
|
static int
|
|
qeth_halt_channels(struct qeth_card *card)
|
|
qeth_halt_channels(struct qeth_card *card)
|
|
{
|
|
{
|
|
- int rc = 0;
|
|
|
|
|
|
+ int rc1 = 0, rc2=0, rc3 = 0;
|
|
|
|
|
|
QETH_DBF_TEXT(trace,3,"haltchs");
|
|
QETH_DBF_TEXT(trace,3,"haltchs");
|
|
- if ((rc = qeth_halt_channel(&card->read)))
|
|
|
|
- return rc;
|
|
|
|
- if ((rc = qeth_halt_channel(&card->write)))
|
|
|
|
- return rc;
|
|
|
|
- return qeth_halt_channel(&card->data);
|
|
|
|
|
|
+ rc1 = qeth_halt_channel(&card->read);
|
|
|
|
+ rc2 = qeth_halt_channel(&card->write);
|
|
|
|
+ rc3 = qeth_halt_channel(&card->data);
|
|
|
|
+ if (rc1)
|
|
|
|
+ return rc1;
|
|
|
|
+ if (rc2)
|
|
|
|
+ return rc2;
|
|
|
|
+ return rc3;
|
|
}
|
|
}
|
|
static int
|
|
static int
|
|
qeth_clear_channels(struct qeth_card *card)
|
|
qeth_clear_channels(struct qeth_card *card)
|
|
{
|
|
{
|
|
- int rc = 0;
|
|
|
|
|
|
+ int rc1 = 0, rc2=0, rc3 = 0;
|
|
|
|
|
|
QETH_DBF_TEXT(trace,3,"clearchs");
|
|
QETH_DBF_TEXT(trace,3,"clearchs");
|
|
- if ((rc = qeth_clear_channel(&card->read)))
|
|
|
|
- return rc;
|
|
|
|
- if ((rc = qeth_clear_channel(&card->write)))
|
|
|
|
- return rc;
|
|
|
|
- return qeth_clear_channel(&card->data);
|
|
|
|
|
|
+ rc1 = qeth_clear_channel(&card->read);
|
|
|
|
+ rc2 = qeth_clear_channel(&card->write);
|
|
|
|
+ rc3 = qeth_clear_channel(&card->data);
|
|
|
|
+ if (rc1)
|
|
|
|
+ return rc1;
|
|
|
|
+ if (rc2)
|
|
|
|
+ return rc2;
|
|
|
|
+ return rc3;
|
|
}
|
|
}
|
|
|
|
|
|
static int
|
|
static int
|
|
@@ -3445,23 +3438,23 @@ qeth_mpc_initialize(struct qeth_card *card)
|
|
}
|
|
}
|
|
if ((rc = qeth_cm_enable(card))){
|
|
if ((rc = qeth_cm_enable(card))){
|
|
QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
|
|
QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
|
|
- return rc;
|
|
|
|
|
|
+ goto out_qdio;
|
|
}
|
|
}
|
|
if ((rc = qeth_cm_setup(card))){
|
|
if ((rc = qeth_cm_setup(card))){
|
|
QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
|
|
QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
|
|
- return rc;
|
|
|
|
|
|
+ goto out_qdio;
|
|
}
|
|
}
|
|
if ((rc = qeth_ulp_enable(card))){
|
|
if ((rc = qeth_ulp_enable(card))){
|
|
QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
|
|
QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
|
|
- return rc;
|
|
|
|
|
|
+ goto out_qdio;
|
|
}
|
|
}
|
|
if ((rc = qeth_ulp_setup(card))){
|
|
if ((rc = qeth_ulp_setup(card))){
|
|
QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
|
|
QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
|
|
- return rc;
|
|
|
|
|
|
+ goto out_qdio;
|
|
}
|
|
}
|
|
if ((rc = qeth_alloc_qdio_buffers(card))){
|
|
if ((rc = qeth_alloc_qdio_buffers(card))){
|
|
QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
|
|
QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
|
|
- return rc;
|
|
|
|
|
|
+ goto out_qdio;
|
|
}
|
|
}
|
|
if ((rc = qeth_qdio_establish(card))){
|
|
if ((rc = qeth_qdio_establish(card))){
|
|
QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
|
|
QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
|
|
@@ -4281,7 +4274,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
|
|
int ipv = 0;
|
|
int ipv = 0;
|
|
int cast_type;
|
|
int cast_type;
|
|
struct qeth_qdio_out_q *queue;
|
|
struct qeth_qdio_out_q *queue;
|
|
- struct qeth_hdr *hdr;
|
|
|
|
|
|
+ struct qeth_hdr *hdr = NULL;
|
|
int elements_needed = 0;
|
|
int elements_needed = 0;
|
|
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
|
|
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
|
|
struct qeth_eddp_context *ctx = NULL;
|
|
struct qeth_eddp_context *ctx = NULL;
|
|
@@ -4512,7 +4505,11 @@ qeth_arp_set_no_entries(struct qeth_card *card, int no_entries)
|
|
|
|
|
|
QETH_DBF_TEXT(trace,3,"arpstnoe");
|
|
QETH_DBF_TEXT(trace,3,"arpstnoe");
|
|
|
|
|
|
- /* TODO: really not supported by GuestLAN? */
|
|
|
|
|
|
+ /*
|
|
|
|
+ * currently GuestLAN only supports the ARP assist function
|
|
|
|
+ * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_SET_NO_ENTRIES;
|
|
|
|
+ * thus we say EOPNOTSUPP for this ARP function
|
|
|
|
+ */
|
|
if (card->info.guestlan)
|
|
if (card->info.guestlan)
|
|
return -EOPNOTSUPP;
|
|
return -EOPNOTSUPP;
|
|
if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
|
|
if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
|
|
@@ -4689,14 +4686,6 @@ qeth_arp_query(struct qeth_card *card, char *udata)
|
|
|
|
|
|
QETH_DBF_TEXT(trace,3,"arpquery");
|
|
QETH_DBF_TEXT(trace,3,"arpquery");
|
|
|
|
|
|
- /*
|
|
|
|
- * currently GuestLAN does only deliver all zeros on query arp,
|
|
|
|
- * even though arp processing is supported (according to IPA supp.
|
|
|
|
- * funcs flags); since all zeros is no valueable information,
|
|
|
|
- * we say EOPNOTSUPP for all ARP functions
|
|
|
|
- */
|
|
|
|
- /*if (card->info.guestlan)
|
|
|
|
- return -EOPNOTSUPP; */
|
|
|
|
if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/
|
|
if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/
|
|
IPA_ARP_PROCESSING)) {
|
|
IPA_ARP_PROCESSING)) {
|
|
PRINT_WARN("ARP processing not supported "
|
|
PRINT_WARN("ARP processing not supported "
|
|
@@ -4902,10 +4891,9 @@ qeth_arp_add_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry)
|
|
QETH_DBF_TEXT(trace,3,"arpadent");
|
|
QETH_DBF_TEXT(trace,3,"arpadent");
|
|
|
|
|
|
/*
|
|
/*
|
|
- * currently GuestLAN does only deliver all zeros on query arp,
|
|
|
|
- * even though arp processing is supported (according to IPA supp.
|
|
|
|
- * funcs flags); since all zeros is no valueable information,
|
|
|
|
- * we say EOPNOTSUPP for all ARP functions
|
|
|
|
|
|
+ * currently GuestLAN only supports the ARP assist function
|
|
|
|
+ * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_ADD_ENTRY;
|
|
|
|
+ * thus we say EOPNOTSUPP for this ARP function
|
|
*/
|
|
*/
|
|
if (card->info.guestlan)
|
|
if (card->info.guestlan)
|
|
return -EOPNOTSUPP;
|
|
return -EOPNOTSUPP;
|
|
@@ -4945,10 +4933,9 @@ qeth_arp_remove_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry
|
|
QETH_DBF_TEXT(trace,3,"arprment");
|
|
QETH_DBF_TEXT(trace,3,"arprment");
|
|
|
|
|
|
/*
|
|
/*
|
|
- * currently GuestLAN does only deliver all zeros on query arp,
|
|
|
|
- * even though arp processing is supported (according to IPA supp.
|
|
|
|
- * funcs flags); since all zeros is no valueable information,
|
|
|
|
- * we say EOPNOTSUPP for all ARP functions
|
|
|
|
|
|
+ * currently GuestLAN only supports the ARP assist function
|
|
|
|
+ * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_REMOVE_ENTRY;
|
|
|
|
+ * thus we say EOPNOTSUPP for this ARP function
|
|
*/
|
|
*/
|
|
if (card->info.guestlan)
|
|
if (card->info.guestlan)
|
|
return -EOPNOTSUPP;
|
|
return -EOPNOTSUPP;
|
|
@@ -4986,11 +4973,10 @@ qeth_arp_flush_cache(struct qeth_card *card)
|
|
QETH_DBF_TEXT(trace,3,"arpflush");
|
|
QETH_DBF_TEXT(trace,3,"arpflush");
|
|
|
|
|
|
/*
|
|
/*
|
|
- * currently GuestLAN does only deliver all zeros on query arp,
|
|
|
|
- * even though arp processing is supported (according to IPA supp.
|
|
|
|
- * funcs flags); since all zeros is no valueable information,
|
|
|
|
- * we say EOPNOTSUPP for all ARP functions
|
|
|
|
- */
|
|
|
|
|
|
+ * currently GuestLAN only supports the ARP assist function
|
|
|
|
+ * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_FLUSH_CACHE;
|
|
|
|
+ * thus we say EOPNOTSUPP for this ARP function
|
|
|
|
+ */
|
|
if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD))
|
|
if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD))
|
|
return -EOPNOTSUPP;
|
|
return -EOPNOTSUPP;
|
|
if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
|
|
if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
|
|
@@ -8266,7 +8252,6 @@ qeth_init(void)
|
|
{
|
|
{
|
|
int rc=0;
|
|
int rc=0;
|
|
|
|
|
|
- qeth_eyecatcher();
|
|
|
|
PRINT_INFO("loading %s (%s/%s/%s/%s/%s/%s/%s %s %s)\n",
|
|
PRINT_INFO("loading %s (%s/%s/%s/%s/%s/%s/%s %s %s)\n",
|
|
version, VERSION_QETH_C, VERSION_QETH_H,
|
|
version, VERSION_QETH_C, VERSION_QETH_H,
|
|
VERSION_QETH_MPC_H, VERSION_QETH_MPC_C,
|
|
VERSION_QETH_MPC_H, VERSION_QETH_MPC_C,
|
|
@@ -8347,7 +8332,6 @@ again:
|
|
printk("qeth: removed\n");
|
|
printk("qeth: removed\n");
|
|
}
|
|
}
|
|
|
|
|
|
-EXPORT_SYMBOL(qeth_eyecatcher);
|
|
|
|
module_init(qeth_init);
|
|
module_init(qeth_init);
|
|
module_exit(qeth_exit);
|
|
module_exit(qeth_exit);
|
|
MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");
|
|
MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");
|