summaryrefslogtreecommitdiff
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd.c19
-rw-r--r--drivers/s390/char/sclp.h4
-rw-r--r--drivers/s390/char/sclp_early.c2
-rw-r--r--drivers/s390/cio/qdio_setup.c6
-rw-r--r--drivers/s390/cio/vfio_ccw_cp.c55
-rw-r--r--drivers/s390/crypto/ap_bus.c19
-rw-r--r--drivers/s390/crypto/ap_bus.h3
-rw-r--r--drivers/s390/crypto/ap_queue.c7
-rw-r--r--drivers/s390/crypto/pkey_api.c2
-rw-r--r--drivers/s390/crypto/vfio_ap_drv.c44
-rw-r--r--drivers/s390/crypto/vfio_ap_ops.c4
-rw-r--r--drivers/s390/crypto/vfio_ap_private.h1
-rw-r--r--drivers/s390/net/Makefile2
-rw-r--r--drivers/s390/net/ism_drv.c12
-rw-r--r--drivers/s390/net/qeth_core.h164
-rw-r--r--drivers/s390/net/qeth_core_main.c1206
-rw-r--r--drivers/s390/net/qeth_core_mpc.c23
-rw-r--r--drivers/s390/net/qeth_core_mpc.h17
-rw-r--r--drivers/s390/net/qeth_core_sys.c64
-rw-r--r--drivers/s390/net/qeth_ethtool.c370
-rw-r--r--drivers/s390/net/qeth_l2_main.c548
-rw-r--r--drivers/s390/net/qeth_l3_main.c363
-rw-r--r--drivers/s390/net/qeth_l3_sys.c12
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c4
24 files changed, 1313 insertions, 1638 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 397af07e4d88..e03304fe25bb 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -3965,13 +3965,11 @@ int dasd_generic_restore_device(struct ccw_device *cdev)
EXPORT_SYMBOL_GPL(dasd_generic_restore_device);
static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
- void *rdc_buffer,
int rdc_buffer_size,
int magic)
{
struct dasd_ccw_req *cqr;
struct ccw1 *ccw;
- unsigned long *idaw;
cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device,
NULL);
@@ -3986,16 +3984,8 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
ccw = cqr->cpaddr;
ccw->cmd_code = CCW_CMD_RDC;
- if (idal_is_needed(rdc_buffer, rdc_buffer_size)) {
- idaw = (unsigned long *) (cqr->data);
- ccw->cda = (__u32)(addr_t) idaw;
- ccw->flags = CCW_FLAG_IDA;
- idaw = idal_create_words(idaw, rdc_buffer, rdc_buffer_size);
- } else {
- ccw->cda = (__u32)(addr_t) rdc_buffer;
- ccw->flags = 0;
- }
-
+ ccw->cda = (__u32)(addr_t) cqr->data;
+ ccw->flags = 0;
ccw->count = rdc_buffer_size;
cqr->startdev = device;
cqr->memdev = device;
@@ -4013,12 +4003,13 @@ int dasd_generic_read_dev_chars(struct dasd_device *device, int magic,
int ret;
struct dasd_ccw_req *cqr;
- cqr = dasd_generic_build_rdc(device, rdc_buffer, rdc_buffer_size,
- magic);
+ cqr = dasd_generic_build_rdc(device, rdc_buffer_size, magic);
if (IS_ERR(cqr))
return PTR_ERR(cqr);
ret = dasd_sleep_on(cqr);
+ if (ret == 0)
+ memcpy(rdc_buffer, cqr->data, rdc_buffer_size);
dasd_sfree_request(cqr, cqr->memdev);
return ret;
}
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index b3fcc24b1182..367e9d384d85 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -195,7 +195,9 @@ struct read_info_sccb {
u16 hcpua; /* 120-121 */
u8 _pad_122[124 - 122]; /* 122-123 */
u32 hmfai; /* 124-127 */
- u8 _pad_128[4096 - 128]; /* 128-4095 */
+ u8 _pad_128[134 - 128]; /* 128-133 */
+ u8 byte_134; /* 134 */
+ u8 _pad_135[4096 - 135]; /* 135-4095 */
} __packed __aligned(PAGE_SIZE);
struct read_storage_sccb {
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c
index e792cee3b51c..8332788681c4 100644
--- a/drivers/s390/char/sclp_early.c
+++ b/drivers/s390/char/sclp_early.c
@@ -44,6 +44,8 @@ static void __init sclp_early_facilities_detect(struct read_info_sccb *sccb)
S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP;
if (sccb->fac91 & 0x40)
S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_GUEST;
+ if (sccb->cpuoff > 134)
+ sclp.has_diag318 = !!(sccb->byte_134 & 0x80);
sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
sclp.rzm <<= 20;
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index e324d890a4f6..a59887fad13e 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -181,7 +181,7 @@ static void setup_queues_misc(struct qdio_q *q, struct qdio_irq *irq_ptr,
}
static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr,
- void **sbals_array, int i)
+ struct qdio_buffer **sbals_array, int i)
{
struct qdio_q *prev;
int j;
@@ -212,8 +212,8 @@ static void setup_queues(struct qdio_irq *irq_ptr,
struct qdio_initialize *qdio_init)
{
struct qdio_q *q;
- void **input_sbal_array = qdio_init->input_sbal_addr_array;
- void **output_sbal_array = qdio_init->output_sbal_addr_array;
+ struct qdio_buffer **input_sbal_array = qdio_init->input_sbal_addr_array;
+ struct qdio_buffer **output_sbal_array = qdio_init->output_sbal_addr_array;
struct qdio_outbuf_state *output_sbal_state_array =
qdio_init->output_sbal_state_array;
int i;
diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c
index 70a006ba4d05..384b3987eeb4 100644
--- a/drivers/s390/cio/vfio_ccw_cp.c
+++ b/drivers/s390/cio/vfio_ccw_cp.c
@@ -283,6 +283,33 @@ static long copy_ccw_from_iova(struct channel_program *cp,
#define ccw_is_chain(_ccw) ((_ccw)->flags & (CCW_FLAG_CC | CCW_FLAG_DC))
+/*
+ * is_cpa_within_range()
+ *
+ * @cpa: channel program address being questioned
+ * @head: address of the beginning of a CCW chain
+ * @len: number of CCWs within the chain
+ *
+ * Determine whether the address of a CCW (whether a new chain,
+ * or the target of a TIC) falls within a range (including the end points).
+ *
+ * Returns 1 if yes, 0 if no.
+ */
+static inline int is_cpa_within_range(u32 cpa, u32 head, int len)
+{
+ u32 tail = head + (len - 1) * sizeof(struct ccw1);
+
+ return (head <= cpa && cpa <= tail);
+}
+
+static inline int is_tic_within_range(struct ccw1 *ccw, u32 head, int len)
+{
+ if (!ccw_is_tic(ccw))
+ return 0;
+
+ return is_cpa_within_range(ccw->cda, head, len);
+}
+
static struct ccwchain *ccwchain_alloc(struct channel_program *cp, int len)
{
struct ccwchain *chain;
@@ -392,7 +419,15 @@ static int ccwchain_calc_length(u64 iova, struct channel_program *cp)
return -EOPNOTSUPP;
}
- if ((!ccw_is_chain(ccw)) && (!ccw_is_tic(ccw)))
+ /*
+ * We want to keep counting if the current CCW has the
+ * command-chaining flag enabled, or if it is a TIC CCW
+ * that loops back into the current chain. The latter
+ * is used for device orientation, where the CCW PRIOR to
+ * the TIC can either jump to the TIC or a CCW immediately
+ * after the TIC, depending on the results of its operation.
+ */
+ if (!ccw_is_chain(ccw) && !is_tic_within_range(ccw, iova, cnt))
break;
ccw++;
@@ -408,13 +443,11 @@ static int ccwchain_calc_length(u64 iova, struct channel_program *cp)
static int tic_target_chain_exists(struct ccw1 *tic, struct channel_program *cp)
{
struct ccwchain *chain;
- u32 ccw_head, ccw_tail;
+ u32 ccw_head;
list_for_each_entry(chain, &cp->ccwchain_list, next) {
ccw_head = chain->ch_iova;
- ccw_tail = ccw_head + (chain->ch_len - 1) * sizeof(struct ccw1);
-
- if ((ccw_head <= tic->cda) && (tic->cda <= ccw_tail))
+ if (is_cpa_within_range(tic->cda, ccw_head, chain->ch_len))
return 1;
}
@@ -481,13 +514,11 @@ static int ccwchain_fetch_tic(struct ccwchain *chain,
{
struct ccw1 *ccw = chain->ch_ccw + idx;
struct ccwchain *iter;
- u32 ccw_head, ccw_tail;
+ u32 ccw_head;
list_for_each_entry(iter, &cp->ccwchain_list, next) {
ccw_head = iter->ch_iova;
- ccw_tail = ccw_head + (iter->ch_len - 1) * sizeof(struct ccw1);
-
- if ((ccw_head <= ccw->cda) && (ccw->cda <= ccw_tail)) {
+ if (is_cpa_within_range(ccw->cda, ccw_head, iter->ch_len)) {
ccw->cda = (__u32) (addr_t) (((char *)iter->ch_ccw) +
(ccw->cda - ccw_head));
return 0;
@@ -829,7 +860,7 @@ void cp_update_scsw(struct channel_program *cp, union scsw *scsw)
{
struct ccwchain *chain;
u32 cpa = scsw->cmd.cpa;
- u32 ccw_head, ccw_tail;
+ u32 ccw_head;
/*
* LATER:
@@ -839,9 +870,7 @@ void cp_update_scsw(struct channel_program *cp, union scsw *scsw)
*/
list_for_each_entry(chain, &cp->ccwchain_list, next) {
ccw_head = (u32)(u64)chain->ch_ccw;
- ccw_tail = (u32)(u64)(chain->ch_ccw + chain->ch_len - 1);
-
- if ((ccw_head <= cpa) && (cpa <= ccw_tail)) {
+ if (is_cpa_within_range(cpa, ccw_head, chain->ch_len)) {
/*
* (cpa - ccw_head) is the offset value of the host
* physical ccw to its chain head.
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 5a699746c357..e15816ff1265 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -1336,6 +1336,16 @@ static int __match_queue_device_with_qid(struct device *dev, void *data)
}
/*
+ * Helper function to be used with bus_find_dev
+ * matches any queue device with given queue id
+ */
+static int __match_queue_device_with_queue_id(struct device *dev, void *data)
+{
+ return is_queue_dev(dev)
+ && AP_QID_QUEUE(to_ap_queue(dev)->qid) == (int)(long) data;
+}
+
+/*
* Helper function for ap_scan_bus().
* Does the scan bus job for the given adapter id.
*/
@@ -1435,8 +1445,13 @@ static void _ap_scan_bus_adapter(int id)
borked = aq->state == AP_STATE_BORKED;
spin_unlock_bh(&aq->lock);
}
- if (borked) /* Remove broken device */
+ if (borked) {
+ /* Remove broken device */
+ AP_DBF(DBF_DEBUG,
+ "removing broken queue=%02x.%04x\n",
+ id, dom);
device_unregister(dev);
+ }
put_device(dev);
continue;
}
@@ -1506,7 +1521,7 @@ static void ap_scan_bus(struct work_struct *unused)
struct device *dev =
bus_find_device(&ap_bus_type, NULL,
(void *)(long) ap_domain_index,
- __match_queue_device_with_qid);
+ __match_queue_device_with_queue_id);
if (dev)
put_device(dev);
else
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index bfc66e4a9de1..d0059eae5d94 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -91,7 +91,8 @@ enum ap_state {
AP_STATE_WORKING,
AP_STATE_QUEUE_FULL,
AP_STATE_SUSPEND_WAIT,
- AP_STATE_BORKED,
+ AP_STATE_UNBOUND, /* momentary not bound to a driver */
+ AP_STATE_BORKED, /* broken */
NR_AP_STATES
};
diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c
index 576ac08777c5..ba261210c6da 100644
--- a/drivers/s390/crypto/ap_queue.c
+++ b/drivers/s390/crypto/ap_queue.c
@@ -420,6 +420,10 @@ static ap_func_t *ap_jumptable[NR_AP_STATES][NR_AP_EVENTS] = {
[AP_EVENT_POLL] = ap_sm_suspend_read,
[AP_EVENT_TIMEOUT] = ap_sm_nop,
},
+ [AP_STATE_UNBOUND] = {
+ [AP_EVENT_POLL] = ap_sm_nop,
+ [AP_EVENT_TIMEOUT] = ap_sm_nop,
+ },
[AP_STATE_BORKED] = {
[AP_EVENT_POLL] = ap_sm_nop,
[AP_EVENT_TIMEOUT] = ap_sm_nop,
@@ -725,6 +729,7 @@ static void __ap_flush_queue(struct ap_queue *aq)
ap_msg->rc = -EAGAIN;
ap_msg->receive(aq, ap_msg, NULL);
}
+ aq->queue_count = 0;
}
void ap_flush_queue(struct ap_queue *aq)
@@ -743,7 +748,7 @@ void ap_queue_remove(struct ap_queue *aq)
/* reset with zero, also clears irq registration */
spin_lock_bh(&aq->lock);
ap_zapq(aq->qid);
- aq->state = AP_STATE_BORKED;
+ aq->state = AP_STATE_UNBOUND;
spin_unlock_bh(&aq->lock);
}
EXPORT_SYMBOL(ap_queue_remove);
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index 2f92bbed4bf6..3e85d665c572 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -1079,7 +1079,7 @@ int pkey_verifykey(const struct pkey_seckey *seckey,
rc = mkvp_cache_fetch(cardnr, domain, mkvp);
if (rc)
goto out;
- if (t->mkvp == mkvp[1]) {
+ if (t->mkvp == mkvp[1] && t->mkvp != mkvp[0]) {
DEBUG_DBG("%s secure key has old mkvp\n", __func__);
if (pattributes)
*pattributes |= PKEY_VERIFY_ATTR_OLD_MKVP;
diff --git a/drivers/s390/crypto/vfio_ap_drv.c b/drivers/s390/crypto/vfio_ap_drv.c
index 31c6c847eaca..e9824c35c34f 100644
--- a/drivers/s390/crypto/vfio_ap_drv.c
+++ b/drivers/s390/crypto/vfio_ap_drv.c
@@ -15,7 +15,6 @@
#include "vfio_ap_private.h"
#define VFIO_AP_ROOT_NAME "vfio_ap"
-#define VFIO_AP_DEV_TYPE_NAME "ap_matrix"
#define VFIO_AP_DEV_NAME "matrix"
MODULE_AUTHOR("IBM Corporation");
@@ -24,10 +23,6 @@ MODULE_LICENSE("GPL v2");
static struct ap_driver vfio_ap_drv;
-static struct device_type vfio_ap_dev_type = {
- .name = VFIO_AP_DEV_TYPE_NAME,
-};
-
struct ap_matrix_dev *matrix_dev;
/* Only type 10 adapters (CEX4 and later) are supported
@@ -62,6 +57,22 @@ static void vfio_ap_matrix_dev_release(struct device *dev)
kfree(matrix_dev);
}
+static int matrix_bus_match(struct device *dev, struct device_driver *drv)
+{
+ return 1;
+}
+
+static struct bus_type matrix_bus = {
+ .name = "matrix",
+ .match = &matrix_bus_match,
+};
+
+static struct device_driver matrix_driver = {
+ .name = "vfio_ap",
+ .bus = &matrix_bus,
+ .suppress_bind_attrs = true,
+};
+
static int vfio_ap_matrix_dev_create(void)
{
int ret;
@@ -71,6 +82,10 @@ static int vfio_ap_matrix_dev_create(void)
if (IS_ERR(root_device))
return PTR_ERR(root_device);
+ ret = bus_register(&matrix_bus);
+ if (ret)
+ goto bus_register_err;
+
matrix_dev = kzalloc(sizeof(*matrix_dev), GFP_KERNEL);
if (!matrix_dev) {
ret = -ENOMEM;
@@ -87,30 +102,41 @@ static int vfio_ap_matrix_dev_create(void)
mutex_init(&matrix_dev->lock);
INIT_LIST_HEAD(&matrix_dev->mdev_list);
- matrix_dev->device.type = &vfio_ap_dev_type;
dev_set_name(&matrix_dev->device, "%s", VFIO_AP_DEV_NAME);
matrix_dev->device.parent = root_device;
+ matrix_dev->device.bus = &matrix_bus;
matrix_dev->device.release = vfio_ap_matrix_dev_release;
- matrix_dev->device.driver = &vfio_ap_drv.driver;
+ matrix_dev->vfio_ap_drv = &vfio_ap_drv;
ret = device_register(&matrix_dev->device);
if (ret)
goto matrix_reg_err;
+ ret = driver_register(&matrix_driver);
+ if (ret)
+ goto matrix_drv_err;
+
return 0;
+matrix_drv_err:
+ device_unregister(&matrix_dev->device);
matrix_reg_err:
put_device(&matrix_dev->device);
matrix_alloc_err:
+ bus_unregister(&matrix_bus);
+bus_register_err:
root_device_unregister(root_device);
-
return ret;
}
static void vfio_ap_matrix_dev_destroy(void)
{
+ struct device *root_device = matrix_dev->device.parent;
+
+ driver_unregister(&matrix_driver);
device_unregister(&matrix_dev->device);
- root_device_unregister(matrix_dev->device.parent);
+ bus_unregister(&matrix_bus);
+ root_device_unregister(root_device);
}
static int __init vfio_ap_init(void)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 272ef427dcc0..900b9cf20ca5 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -198,8 +198,8 @@ static int vfio_ap_verify_queue_reserved(unsigned long *apid,
qres.apqi = apqi;
qres.reserved = false;
- ret = driver_for_each_device(matrix_dev->device.driver, NULL, &qres,
- vfio_ap_has_queue);
+ ret = driver_for_each_device(&matrix_dev->vfio_ap_drv->driver, NULL,
+ &qres, vfio_ap_has_queue);
if (ret)
return ret;
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index 5675492233c7..76b7f98e47e9 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -40,6 +40,7 @@ struct ap_matrix_dev {
struct ap_config_info info;
struct list_head mdev_list;
struct mutex lock;
+ struct ap_driver *vfio_ap_drv;
};
extern struct ap_matrix_dev *matrix_dev;
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index f2d6bbe57a6f..bc55ec316adb 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
obj-$(CONFIG_SMSGIUCV_EVENT) += smsgiucv_app.o
obj-$(CONFIG_LCS) += lcs.o
-qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o
+qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o qeth_ethtool.o
obj-$(CONFIG_QETH) += qeth.o
qeth_l2-y += qeth_l2_main.o qeth_l2_sys.o
obj-$(CONFIG_QETH_L2) += qeth_l2.o
diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c
index ed8e58f09054..3e132592c1fe 100644
--- a/drivers/s390/net/ism_drv.c
+++ b/drivers/s390/net/ism_drv.c
@@ -141,10 +141,13 @@ static int register_ieq(struct ism_dev *ism)
static int unregister_sba(struct ism_dev *ism)
{
+ int ret;
+
if (!ism->sba)
return 0;
- if (ism_cmd_simple(ism, ISM_UNREG_SBA))
+ ret = ism_cmd_simple(ism, ISM_UNREG_SBA);
+ if (ret && ret != ISM_ERROR)
return -EIO;
dma_free_coherent(&ism->pdev->dev, PAGE_SIZE,
@@ -158,10 +161,13 @@ static int unregister_sba(struct ism_dev *ism)
static int unregister_ieq(struct ism_dev *ism)
{
+ int ret;
+
if (!ism->ieq)
return 0;
- if (ism_cmd_simple(ism, ISM_UNREG_IEQ))
+ ret = ism_cmd_simple(ism, ISM_UNREG_IEQ);
+ if (ret && ret != ISM_ERROR)
return -EIO;
dma_free_coherent(&ism->pdev->dev, PAGE_SIZE,
@@ -287,7 +293,7 @@ static int ism_unregister_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb)
cmd.request.dmb_tok = dmb->dmb_tok;
ret = ism_cmd(ism, &cmd);
- if (ret)
+ if (ret && ret != ISM_ERROR)
goto out;
ism_free_dmb(ism, dmb);
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 122059ecad84..c851cf6e01c4 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -18,7 +18,6 @@
#include <linux/in6.h>
#include <linux/bitops.h>
#include <linux/seq_file.h>
-#include <linux/ethtool.h>
#include <linux/hashtable.h>
#include <linux/ip.h>
#include <linux/refcount.h>
@@ -35,6 +34,8 @@
#include <asm/ccwgroup.h>
#include <asm/sysinfo.h>
+#include <uapi/linux/if_link.h>
+
#include "qeth_core_mpc.h"
/**
@@ -113,59 +114,6 @@ static inline u32 qeth_get_device_id(struct ccw_device *cdev)
#define CCW_DEVID(cdev) (qeth_get_device_id(cdev))
#define CARD_DEVID(card) (CCW_DEVID(CARD_RDEV(card)))
-/**
- * card stuff
- */
-struct qeth_perf_stats {
- unsigned int bufs_rec;
- unsigned int bufs_sent;
- unsigned int buf_elements_sent;
-
- unsigned int skbs_sent_pack;
- unsigned int bufs_sent_pack;
-
- unsigned int sc_dp_p;
- unsigned int sc_p_dp;
- /* qdio_cq_handler: number of times called, time spent in */
- __u64 cq_start_time;
- unsigned int cq_cnt;
- unsigned int cq_time;
- /* qdio_input_handler: number of times called, time spent in */
- __u64 inbound_start_time;
- unsigned int inbound_cnt;
- unsigned int inbound_time;
- /* qeth_send_packet: number of times called, time spent in */
- __u64 outbound_start_time;
- unsigned int outbound_cnt;
- unsigned int outbound_time;
- /* qdio_output_handler: number of times called, time spent in */
- __u64 outbound_handler_start_time;
- unsigned int outbound_handler_cnt;
- unsigned int outbound_handler_time;
- /* number of calls to and time spent in do_QDIO for inbound queue */
- __u64 inbound_do_qdio_start_time;
- unsigned int inbound_do_qdio_cnt;
- unsigned int inbound_do_qdio_time;
- /* number of calls to and time spent in do_QDIO for outbound queues */
- __u64 outbound_do_qdio_start_time;
- unsigned int outbound_do_qdio_cnt;
- unsigned int outbound_do_qdio_time;
- unsigned int large_send_bytes;
- unsigned int large_send_cnt;
- unsigned int sg_skbs_sent;
- /* initial values when measuring starts */
- unsigned long initial_rx_packets;
- unsigned long initial_tx_packets;
- /* inbound scatter gather data */
- unsigned int sg_skbs_rx;
- unsigned int sg_frags_rx;
- unsigned int sg_alloc_page_rx;
- unsigned int tx_csum;
- unsigned int tx_lin;
- unsigned int tx_linfail;
- unsigned int rx_csum;
-};
-
/* Routing stuff */
struct qeth_routing_info {
enum qeth_routing_types type;
@@ -495,10 +443,53 @@ enum qeth_out_q_states {
QETH_OUT_Q_LOCKED_FLUSH,
};
+#define QETH_CARD_STAT_ADD(_c, _stat, _val) ((_c)->stats._stat += (_val))
+#define QETH_CARD_STAT_INC(_c, _stat) QETH_CARD_STAT_ADD(_c, _stat, 1)
+
+#define QETH_TXQ_STAT_ADD(_q, _stat, _val) ((_q)->stats._stat += (_val))
+#define QETH_TXQ_STAT_INC(_q, _stat) QETH_TXQ_STAT_ADD(_q, _stat, 1)
+
+struct qeth_card_stats {
+ u64 rx_bufs;
+ u64 rx_skb_csum;
+ u64 rx_sg_skbs;
+ u64 rx_sg_frags;
+ u64 rx_sg_alloc_page;
+
+ /* rtnl_link_stats64 */
+ u64 rx_packets;
+ u64 rx_bytes;
+ u64 rx_errors;
+ u64 rx_dropped;
+ u64 rx_multicast;
+ u64 tx_errors;
+};
+
+struct qeth_out_q_stats {
+ u64 bufs;
+ u64 bufs_pack;
+ u64 buf_elements;
+ u64 skbs_pack;
+ u64 skbs_sg;
+ u64 skbs_csum;
+ u64 skbs_tso;
+ u64 skbs_linearized;
+ u64 skbs_linearized_fail;
+ u64 tso_bytes;
+ u64 packing_mode_switch;
+
+ /* rtnl_link_stats64 */
+ u64 tx_packets;
+ u64 tx_bytes;
+ u64 tx_errors;
+ u64 tx_dropped;
+};
+
struct qeth_qdio_out_q {
struct qdio_buffer *qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
struct qeth_qdio_out_buffer *bufs[QDIO_MAX_BUFFERS_PER_Q];
struct qdio_outbuf_state *bufstates; /* convenience pointer */
+ struct qeth_out_q_stats stats;
int queue_no;
struct qeth_card *card;
atomic_t state;
@@ -528,7 +519,7 @@ struct qeth_qdio_info {
/* output */
int no_out_queues;
- struct qeth_qdio_out_q **out_qs;
+ struct qeth_qdio_out_q *out_qs[QETH_MAX_QUEUES];
struct qdio_outbuf_state *out_bufstates;
/* priority queueing */
@@ -560,8 +551,6 @@ enum qeth_card_states {
CARD_STATE_DOWN,
CARD_STATE_HARDSETUP,
CARD_STATE_SOFTSETUP,
- CARD_STATE_UP,
- CARD_STATE_RECOVER,
};
/**
@@ -595,8 +584,8 @@ struct qeth_channel;
struct qeth_cmd_buffer {
enum qeth_cmd_buffer_state state;
struct qeth_channel *channel;
+ struct qeth_reply *reply;
unsigned char *data;
- int rc;
void (*callback)(struct qeth_card *card, struct qeth_channel *channel,
struct qeth_cmd_buffer *iob);
};
@@ -673,6 +662,7 @@ struct qeth_card_info {
unsigned short chpid;
__u16 func_level;
char mcl_level[QETH_MCL_LENGTH + 1];
+ u8 open_when_online:1;
int guestlan;
int mac_bits;
enum qeth_card_types type;
@@ -702,7 +692,6 @@ struct qeth_card_options {
struct qeth_vnicc_info vnicc; /* VNICC options */
int fake_broadcast;
enum qeth_discipline_id layer;
- int performance_stats;
int rx_sg_cb;
enum qeth_ipa_isolation_modes isolation;
enum qeth_ipa_isolation_modes prev_isolation;
@@ -742,11 +731,6 @@ struct qeth_discipline {
struct qeth_ipa_cmd *cmd);
};
-struct qeth_vlan_vid {
- struct list_head list;
- unsigned short vid;
-};
-
enum qeth_addr_disposition {
QETH_DISP_ADDR_DELETE = 0,
QETH_DISP_ADDR_DO_NOTHING = 1,
@@ -783,8 +767,7 @@ struct qeth_card {
struct qeth_channel data;
struct net_device *dev;
- struct net_device_stats stats;
-
+ struct qeth_card_stats stats;
struct qeth_card_info info;
struct qeth_token token;
struct qeth_seqno seqno;
@@ -794,8 +777,6 @@ struct qeth_card {
wait_queue_head_t wait_q;
spinlock_t mclock;
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
- struct mutex vid_list_mutex; /* vid_list */
- struct list_head vid_list;
DECLARE_HASHTABLE(mac_htable, 4);
DECLARE_HASHTABLE(ip_htable, 4);
DECLARE_HASHTABLE(ip_mc_htable, 4);
@@ -804,13 +785,11 @@ struct qeth_card {
unsigned long thread_start_mask;
unsigned long thread_allowed_mask;
unsigned long thread_running_mask;
- struct task_struct *recovery_task;
spinlock_t ip_lock;
struct qeth_ipato ipato;
struct list_head cmd_waiter_list;
/* QDIO buffer handling */
struct qeth_qdio_info qdio;
- struct qeth_perf_stats perf_stats;
int read_or_write_problem;
struct qeth_osn_info osn_info;
struct qeth_discipline *discipline;
@@ -827,6 +806,11 @@ struct qeth_card {
struct work_struct close_dev_work;
};
+static inline bool qeth_card_hw_is_reachable(struct qeth_card *card)
+{
+ return card->state == CARD_STATE_SOFTSETUP;
+}
+
struct qeth_trap_id {
__u16 lparnr;
char vmname[8];
@@ -867,11 +851,6 @@ static inline int qeth_get_elements_for_range(addr_t start, addr_t end)
return PFN_UP(end) - PFN_DOWN(start);
}
-static inline int qeth_get_micros(void)
-{
- return (int) (get_tod_clock() >> 12);
-}
-
static inline int qeth_get_ip_version(struct sk_buff *skb)
{
struct vlan_ethhdr *veth = vlan_eth_hdr(skb);
@@ -896,8 +875,7 @@ static inline void qeth_rx_csum(struct qeth_card *card, struct sk_buff *skb,
if ((card->dev->features & NETIF_F_RXCSUM) &&
(flags & QETH_HDR_EXT_CSUM_TRANSP_REQ)) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
- if (card->options.performance_stats)
- card->perf_stats.rx_csum++;
+ QETH_CARD_STAT_INC(card, rx_skb_csum);
} else {
skb->ip_summed = CHECKSUM_NONE;
}
@@ -959,13 +937,14 @@ static inline struct qeth_qdio_out_q *qeth_get_tx_queue(struct qeth_card *card,
extern struct qeth_discipline qeth_l2_discipline;
extern struct qeth_discipline qeth_l3_discipline;
+extern const struct ethtool_ops qeth_ethtool_ops;
+extern const struct ethtool_ops qeth_osn_ethtool_ops;
extern const struct attribute_group *qeth_generic_attr_groups[];
extern const struct attribute_group *qeth_osn_attr_groups[];
extern const struct attribute_group qeth_device_attr_group;
extern const struct attribute_group qeth_device_blkt_group;
extern const struct device_type qeth_generic_devtype;
-int qeth_card_hw_is_reachable(struct qeth_card *);
const char *qeth_get_cardname_short(struct qeth_card *);
int qeth_realloc_buffer_pool(struct qeth_card *, int);
int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id);
@@ -977,11 +956,8 @@ extern struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS];
struct net_device *qeth_clone_netdev(struct net_device *orig);
struct qeth_card *qeth_get_card_by_busid(char *bus_id);
-void qeth_set_recovery_task(struct qeth_card *);
-void qeth_clear_recovery_task(struct qeth_card *);
void qeth_set_allowed_threads(struct qeth_card *, unsigned long , int);
int qeth_threads_running(struct qeth_card *, unsigned long);
-int qeth_wait_for_threads(struct qeth_card *, unsigned long);
int qeth_do_run_thread(struct qeth_card *, unsigned long);
void qeth_clear_thread_start_bit(struct qeth_card *, unsigned long);
void qeth_clear_thread_running_bit(struct qeth_card *, unsigned long);
@@ -1005,38 +981,29 @@ void qeth_clear_working_pool_list(struct qeth_card *);
void qeth_clear_cmd_buffers(struct qeth_channel *);
void qeth_clear_qdio_buffers(struct qeth_card *);
void qeth_setadp_promisc_mode(struct qeth_card *);
-struct net_device_stats *qeth_get_stats(struct net_device *);
int qeth_setadpparms_change_macaddr(struct qeth_card *);
void qeth_tx_timeout(struct net_device *);
void qeth_prepare_control_data(struct qeth_card *, int,
struct qeth_cmd_buffer *);
void qeth_release_buffer(struct qeth_channel *, struct qeth_cmd_buffer *);
-void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob);
+void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
+ u16 cmd_length);
struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *);
int qeth_query_switch_attributes(struct qeth_card *card,
struct qeth_switch_info *sw_info);
-int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *,
- int (*reply_cb)(struct qeth_card *, struct qeth_reply*, unsigned long),
- void *reply_param);
+int qeth_query_card_info(struct qeth_card *card,
+ struct carrier_info *carrier_info);
unsigned int qeth_count_elements(struct sk_buff *skb, unsigned int data_offset);
int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
struct sk_buff *skb, struct qeth_hdr *hdr,
unsigned int offset, unsigned int hd_len,
int elements_needed);
int qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-int qeth_core_get_sset_count(struct net_device *, int);
-void qeth_core_get_ethtool_stats(struct net_device *,
- struct ethtool_stats *, u64 *);
-void qeth_core_get_strings(struct net_device *, u32, u8 *);
-void qeth_core_get_drvinfo