14a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka/*
24a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka *    Copyright IBM Corp. 2007
34a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka *    Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
44a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka *		 Frank Pavlic <fpavlic@de.ibm.com>,
54a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka *		 Thomas Spatzier <tspat@de.ibm.com>,
64a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka *		 Frank Blaschka <frank.blaschka@de.ibm.com>
74a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka */
84a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
9fe7a26257a4191de6047f7e1d38832472eb22f85Ursula Braun#define KMSG_COMPONENT "qeth"
10fe7a26257a4191de6047f7e1d38832472eb22f85Ursula Braun#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11fe7a26257a4191de6047f7e1d38832472eb22f85Ursula Braun
124a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka#include <linux/list.h>
134a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka#include <linux/rwsem.h>
144a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka#include <asm/ebcdic.h>
154a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
164a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka#include "qeth_core.h"
174a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
184a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_state_show(struct device *dev,
194a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				struct device_attribute *attr, char *buf)
204a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
214a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
224a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
234a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
244a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
254a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	switch (card->state) {
264a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	case CARD_STATE_DOWN:
274a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return sprintf(buf, "DOWN\n");
284a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	case CARD_STATE_HARDSETUP:
294a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return sprintf(buf, "HARDSETUP\n");
304a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	case CARD_STATE_SOFTSETUP:
314a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return sprintf(buf, "SOFTSETUP\n");
324a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	case CARD_STATE_UP:
334a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		if (card->lan_online)
344a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return sprintf(buf, "UP (LAN ONLINE)\n");
354a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		else
364a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka			return sprintf(buf, "UP (LAN OFFLINE)\n");
374a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	case CARD_STATE_RECOVER:
384a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return sprintf(buf, "RECOVER\n");
394a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	default:
404a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return sprintf(buf, "UNKNOWN\n");
414a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	}
424a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
434a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
444a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(state, 0444, qeth_dev_state_show, NULL);
454a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
464a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_chpid_show(struct device *dev,
474a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				struct device_attribute *attr, char *buf)
484a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
494a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
504a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
514a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
524a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
534a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return sprintf(buf, "%02X\n", card->info.chpid);
544a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
554a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
564a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(chpid, 0444, qeth_dev_chpid_show, NULL);
574a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
584a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_if_name_show(struct device *dev,
594a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				struct device_attribute *attr, char *buf)
604a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
614a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
624a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
634a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
644a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return sprintf(buf, "%s\n", QETH_CARD_IFNAME(card));
654a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
664a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
674a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(if_name, 0444, qeth_dev_if_name_show, NULL);
684a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
694a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_card_type_show(struct device *dev,
704a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				struct device_attribute *attr, char *buf)
714a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
724a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
734a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
744a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
754a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
764a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return sprintf(buf, "%s\n", qeth_get_cardname_short(card));
774a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
784a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
794a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(card_type, 0444, qeth_dev_card_type_show, NULL);
804a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
814a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic inline const char *qeth_get_bufsize_str(struct qeth_card *card)
824a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
834a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (card->qdio.in_buf_size == 16384)
844a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return "16k";
854a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	else if (card->qdio.in_buf_size == 24576)
864a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return "24k";
874a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	else if (card->qdio.in_buf_size == 32768)
884a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return "32k";
894a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	else if (card->qdio.in_buf_size == 40960)
904a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return "40k";
914a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	else
924a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return "64k";
934a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
944a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
954a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_inbuf_size_show(struct device *dev,
964a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				struct device_attribute *attr, char *buf)
974a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
984a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
994a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
1004a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
1014a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1024a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return sprintf(buf, "%s\n", qeth_get_bufsize_str(card));
1034a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
1044a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1054a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(inbuf_size, 0444, qeth_dev_inbuf_size_show, NULL);
1064a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1074a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_portno_show(struct device *dev,
1084a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka			struct device_attribute *attr, char *buf)
1094a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
1104a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
1114a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
1124a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
1134a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1144a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return sprintf(buf, "%i\n", card->info.portno);
1154a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
1164a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1174a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_portno_store(struct device *dev,
1184a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		struct device_attribute *attr, const char *buf, size_t count)
1194a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
1204a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
1214a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	char *tmp;
12276b11f8e270f04851774ff64b16e29e5a43d3a1aUrsula Braun	unsigned int portno, limit;
123c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	int rc = 0;
1244a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1254a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
1264a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
1274a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
128c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_lock(&card->conf_mutex);
1294a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if ((card->state != CARD_STATE_DOWN) &&
130c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	    (card->state != CARD_STATE_RECOVER)) {
131c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EPERM;
132c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
133c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	}
1344a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1354a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	portno = simple_strtoul(buf, &tmp, 16);
136c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	if (portno > QETH_MAX_PORTNO) {
137c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EINVAL;
138c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
139c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	}
14076b11f8e270f04851774ff64b16e29e5a43d3a1aUrsula Braun	limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt);
141c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	if (portno > limit) {
142c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EINVAL;
143c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
144c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	}
1454a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	card->info.portno = portno;
146c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschkaout:
147c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_unlock(&card->conf_mutex);
148c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	return rc ? rc : count;
1494a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
1504a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1514a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);
1524a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1534a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_portname_show(struct device *dev,
1544a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				struct device_attribute *attr, char *buf)
1554a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
1564a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
1574a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	char portname[9] = {0, };
1584a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1594a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
1604a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
1614a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1624a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (card->info.portname_required) {
1634a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		memcpy(portname, card->info.portname + 1, 8);
1644a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		EBCASC(portname, 8);
1654a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return sprintf(buf, "%s\n", portname);
1664a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	} else
1674a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return sprintf(buf, "no portname required\n");
1684a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
1694a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1704a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_portname_store(struct device *dev,
1714a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		struct device_attribute *attr, const char *buf, size_t count)
1724a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
1734a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
1744a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	char *tmp;
175c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	int i, rc = 0;
1764a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1774a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
1784a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
1794a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
180c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_lock(&card->conf_mutex);
1814a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if ((card->state != CARD_STATE_DOWN) &&
182c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	    (card->state != CARD_STATE_RECOVER)) {
183c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EPERM;
184c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
185c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	}
1864a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1874a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	tmp = strsep((char **) &buf, "\n");
188c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	if ((strlen(tmp) > 8) || (strlen(tmp) == 0)) {
189c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EINVAL;
190c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
191c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	}
1924a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
1934a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	card->info.portname[0] = strlen(tmp);
1944a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	/* for beauty reasons */
1954a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	for (i = 1; i < 9; i++)
1964a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->info.portname[i] = ' ';
1974a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	strcpy(card->info.portname + 1, tmp);
1984a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	ASCEBC(card->info.portname + 1, 8);
199c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschkaout:
200c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_unlock(&card->conf_mutex);
201c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	return rc ? rc : count;
2024a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
2034a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
2044a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(portname, 0644, qeth_dev_portname_show,
2054a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		qeth_dev_portname_store);
2064a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
2074a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_prioqing_show(struct device *dev,
2084a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				struct device_attribute *attr, char *buf)
2094a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
2104a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
2114a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
2124a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
2134a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
2144a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
2154a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	switch (card->qdio.do_prio_queueing) {
2164a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	case QETH_PRIO_Q_ING_PREC:
2174a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return sprintf(buf, "%s\n", "by precedence");
2184a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	case QETH_PRIO_Q_ING_TOS:
2194a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return sprintf(buf, "%s\n", "by type of service");
220d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl	case QETH_PRIO_Q_ING_SKB:
221d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl		return sprintf(buf, "%s\n", "by skb-priority");
222d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl	case QETH_PRIO_Q_ING_VLAN:
223d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl		return sprintf(buf, "%s\n", "by VLAN headers");
2244a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	default:
2254a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return sprintf(buf, "always queue %i\n",
2264a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka			       card->qdio.default_out_queue);
2274a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	}
2284a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
2294a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
2304a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_prioqing_store(struct device *dev,
2314a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		struct device_attribute *attr, const char *buf, size_t count)
2324a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
2334a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
2344a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	char *tmp;
235c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	int rc = 0;
2364a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
2374a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
2384a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
2394a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
240c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_lock(&card->conf_mutex);
2414a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if ((card->state != CARD_STATE_DOWN) &&
242c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	    (card->state != CARD_STATE_RECOVER)) {
243c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EPERM;
244c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
245c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	}
2464a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
2474a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	/* check if 1920 devices are supported ,
2484a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	 * if though we have to permit priority queueing
2494a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	 */
2504a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (card->qdio.no_out_queues == 1) {
2514a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
252c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EPERM;
253c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
2544a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	}
2554a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
2564a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	tmp = strsep((char **) &buf, "\n");
2570f8ee7fc5ddee6a326b5ecd4f1ce09e14b65638aStefan Raspl	if (!strcmp(tmp, "prio_queueing_prec")) {
2584a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC;
2590f8ee7fc5ddee6a326b5ecd4f1ce09e14b65638aStefan Raspl		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
260d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl	} else if (!strcmp(tmp, "prio_queueing_skb")) {
261d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_SKB;
262d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
2630f8ee7fc5ddee6a326b5ecd4f1ce09e14b65638aStefan Raspl	} else if (!strcmp(tmp, "prio_queueing_tos")) {
2644a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS;
2650f8ee7fc5ddee6a326b5ecd4f1ce09e14b65638aStefan Raspl		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
266d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl	} else if (!strcmp(tmp, "prio_queueing_vlan")) {
267d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl		if (!card->options.layer2) {
268d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl			rc = -ENOTSUPP;
269d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl			goto out;
270d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl		}
271d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_VLAN;
272d66cb37e96644fcc498d2abe61cd34e4392b9175Stefan Raspl		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
2730f8ee7fc5ddee6a326b5ecd4f1ce09e14b65638aStefan Raspl	} else if (!strcmp(tmp, "no_prio_queueing:0")) {
2744a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
2754a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.default_out_queue = 0;
2764a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	} else if (!strcmp(tmp, "no_prio_queueing:1")) {
2774a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
2784a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.default_out_queue = 1;
2794a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	} else if (!strcmp(tmp, "no_prio_queueing:2")) {
2804a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
2814a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.default_out_queue = 2;
2824a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	} else if (!strcmp(tmp, "no_prio_queueing:3")) {
2834a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
2844a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.default_out_queue = 3;
2854a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	} else if (!strcmp(tmp, "no_prio_queueing")) {
2864a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
2874a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
288c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	} else
289c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EINVAL;
290c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschkaout:
291c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_unlock(&card->conf_mutex);
292c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	return rc ? rc : count;
2934a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
2944a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
2954a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show,
2964a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		qeth_dev_prioqing_store);
2974a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
2984a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_bufcnt_show(struct device *dev,
2994a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				struct device_attribute *attr, char *buf)
3004a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
3014a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
3024a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3034a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
3044a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
3054a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3064a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return sprintf(buf, "%i\n", card->qdio.in_buf_pool.buf_count);
3074a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
3084a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3094a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_bufcnt_store(struct device *dev,
3104a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		struct device_attribute *attr, const char *buf, size_t count)
3114a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
3124a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
3134a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	char *tmp;
3144a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	int cnt, old_cnt;
315c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	int rc = 0;
3164a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3174a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
3184a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
3194a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
320c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_lock(&card->conf_mutex);
3214a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if ((card->state != CARD_STATE_DOWN) &&
322c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	    (card->state != CARD_STATE_RECOVER)) {
323c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EPERM;
324c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
325c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	}
3264a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3274a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	old_cnt = card->qdio.in_buf_pool.buf_count;
3284a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	cnt = simple_strtoul(buf, &tmp, 10);
3294a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	cnt = (cnt < QETH_IN_BUF_COUNT_MIN) ? QETH_IN_BUF_COUNT_MIN :
3304a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt);
3314a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (old_cnt != cnt) {
3324a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		rc = qeth_realloc_buffer_pool(card, cnt);
3334a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	}
334c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschkaout:
335c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_unlock(&card->conf_mutex);
336c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	return rc ? rc : count;
3374a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
3384a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3394a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show,
3404a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		qeth_dev_bufcnt_store);
3414a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3424a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_recover_store(struct device *dev,
3434a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		struct device_attribute *attr, const char *buf, size_t count)
3444a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
3454a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
3464a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	char *tmp;
3474a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	int i;
3484a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3494a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
3504a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
3514a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3524a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (card->state != CARD_STATE_UP)
3534a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EPERM;
3544a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3554a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	i = simple_strtoul(buf, &tmp, 16);
3564a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (i == 1)
3574a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		qeth_schedule_recovery(card);
3584a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3594a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return count;
3604a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
3614a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3624a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store);
3634a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3644a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_performance_stats_show(struct device *dev,
3654a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				struct device_attribute *attr, char *buf)
3664a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
3674a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
3684a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3694a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
3704a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
3714a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3724a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return sprintf(buf, "%i\n", card->options.performance_stats ? 1:0);
3734a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
3744a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3754a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_performance_stats_store(struct device *dev,
3764a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		struct device_attribute *attr, const char *buf, size_t count)
3774a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
3784a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
3794a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	char *tmp;
380c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	int i, rc = 0;
3814a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
3824a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
3834a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
3844a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
385c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_lock(&card->conf_mutex);
3864a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	i = simple_strtoul(buf, &tmp, 16);
3874a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if ((i == 0) || (i == 1)) {
3884a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		if (i == card->options.performance_stats)
389cdac082e051136a021f28d0f63c56e916b541253Joe Perches			goto out;
3904a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->options.performance_stats = i;
3914a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		if (i == 0)
3924a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka			memset(&card->perf_stats, 0,
3934a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				sizeof(struct qeth_perf_stats));
3944a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->perf_stats.initial_rx_packets = card->stats.rx_packets;
3954a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		card->perf_stats.initial_tx_packets = card->stats.tx_packets;
396c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	} else
397c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EINVAL;
398c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschkaout:
399c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_unlock(&card->conf_mutex);
400c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	return rc ? rc : count;
4014a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
4024a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
4034a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show,
4044a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		   qeth_dev_performance_stats_store);
4054a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
4064a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_layer2_show(struct device *dev,
4074a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		struct device_attribute *attr, char *buf)
4084a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
4094a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
4104a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
4114a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
4124a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
4134a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
4147c6a3ed5bd61ec981c8a0d0111cfd435adf3f2b7Ursula Braun	return sprintf(buf, "%i\n", card->options.layer2);
4154a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
4164a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
4174a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_layer2_store(struct device *dev,
4184a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		struct device_attribute *attr, const char *buf, size_t count)
4194a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
4204a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
4214a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	char *tmp;
422c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	int i, rc = 0;
4234a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	enum qeth_discipline_id newdis;
4244a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
4254a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
4264a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
4274a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
4289dc48ccc68b9dfc01c2beee2d4317fb3df3fdce9Ursula Braun	mutex_lock(&card->discipline_mutex);
429c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	if (card->state != CARD_STATE_DOWN) {
430c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EPERM;
431c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
432c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	}
4334a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
4344a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	i = simple_strtoul(buf, &tmp, 16);
4354a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	switch (i) {
4364a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	case 0:
4374a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		newdis = QETH_DISCIPLINE_LAYER3;
4384a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		break;
4394a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	case 1:
4404a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		newdis = QETH_DISCIPLINE_LAYER2;
4414a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		break;
4424a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	default:
443c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EINVAL;
444c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
4454a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	}
4464a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
447c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	if (card->options.layer2 == newdis)
448c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
449c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	else {
45075e0de13631e115768a97131a2d7f5259217512dCarsten Otte		card->info.mac_bits  = 0;
451c041f2d487654eb2f981f517b216cf1efdf3cdf2Sebastian Ott		if (card->discipline) {
452c041f2d487654eb2f981f517b216cf1efdf3cdf2Sebastian Ott			card->discipline->remove(card->gdev);
4534a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka			qeth_core_free_discipline(card);
4544a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		}
4554a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	}
4564a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
4574a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	rc = qeth_core_load_discipline(card, newdis);
4584a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (rc)
459c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
4604a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
461c041f2d487654eb2f981f517b216cf1efdf3cdf2Sebastian Ott	rc = card->discipline->setup(card->gdev);
462c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschkaout:
4639dc48ccc68b9dfc01c2beee2d4317fb3df3fdce9Ursula Braun	mutex_unlock(&card->discipline_mutex);
464c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	return rc ? rc : count;
4654a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
4664a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
4674a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
4684a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		   qeth_dev_layer2_store);
4694a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
470d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck#define ATTR_QETH_ISOLATION_NONE	("none")
471d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck#define ATTR_QETH_ISOLATION_FWD		("forward")
472d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck#define ATTR_QETH_ISOLATION_DROP	("drop")
473d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck
474d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueckstatic ssize_t qeth_dev_isolation_show(struct device *dev,
475d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck				struct device_attribute *attr, char *buf)
476d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck{
477d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	struct qeth_card *card = dev_get_drvdata(dev);
478d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck
479d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	if (!card)
480d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		return -EINVAL;
481d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck
482d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	switch (card->options.isolation) {
483d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	case ISOLATION_MODE_NONE:
484d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_NONE);
485d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	case ISOLATION_MODE_FWD:
486d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		return snprintf(buf, 9, "%s\n", ATTR_QETH_ISOLATION_FWD);
487d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	case ISOLATION_MODE_DROP:
488d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_DROP);
489d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	default:
490d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		return snprintf(buf, 5, "%s\n", "N/A");
491d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	}
492d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck}
493d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck
494d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueckstatic ssize_t qeth_dev_isolation_store(struct device *dev,
495d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		struct device_attribute *attr, const char *buf, size_t count)
496d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck{
497d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	struct qeth_card *card = dev_get_drvdata(dev);
498d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	enum qeth_ipa_isolation_modes isolation;
499d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	int rc = 0;
500d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	char *tmp, *curtoken;
501d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	curtoken = (char *) buf;
502d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck
503c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	if (!card)
504c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		return -EINVAL;
505d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck
506c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_lock(&card->conf_mutex);
507d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	/* check for unknown, too, in case we do not yet know who we are */
5085113fec0984276836cb6f0677f7cb53586ec3451Ursula Braun	if (card->info.type != QETH_CARD_TYPE_OSD &&
5095113fec0984276836cb6f0677f7cb53586ec3451Ursula Braun	    card->info.type != QETH_CARD_TYPE_OSX &&
510d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	    card->info.type != QETH_CARD_TYPE_UNKNOWN) {
511d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		rc = -EOPNOTSUPP;
512d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		dev_err(&card->gdev->dev, "Adapter does not "
513d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck			"support QDIO data connection isolation\n");
514d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		goto out;
515d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	}
516d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck
517d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	/* parse input into isolation mode */
518d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	tmp = strsep(&curtoken, "\n");
519d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	if (!strcmp(tmp, ATTR_QETH_ISOLATION_NONE)) {
520d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		isolation = ISOLATION_MODE_NONE;
521d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	} else if (!strcmp(tmp, ATTR_QETH_ISOLATION_FWD)) {
522d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		isolation = ISOLATION_MODE_FWD;
523d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	} else if (!strcmp(tmp, ATTR_QETH_ISOLATION_DROP)) {
524d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		isolation = ISOLATION_MODE_DROP;
525d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	} else {
526d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		rc = -EINVAL;
527d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		goto out;
528d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	}
529d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	rc = count;
530d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck
531d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	/* defer IP assist if device is offline (until discipline->set_online)*/
5320f54761d167f98dd93cb19a16edbc47bb6574a28Stefan Raspl	card->options.prev_isolation = card->options.isolation;
533d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	card->options.isolation = isolation;
534d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	if (card->state == CARD_STATE_SOFTSETUP ||
535d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	    card->state == CARD_STATE_UP) {
5360f54761d167f98dd93cb19a16edbc47bb6574a28Stefan Raspl		int ipa_rc = qeth_set_access_ctrl_online(card, 1);
537d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck		if (ipa_rc != 0)
538d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck			rc = ipa_rc;
539d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	}
540d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueckout:
541c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_unlock(&card->conf_mutex);
542d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	return rc;
543d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck}
544d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck
545d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueckstatic DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
54645cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl			qeth_dev_isolation_store);
54745cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl
54845cbb2e499cf4686e809206b29377a7e15037bccStefan Rasplstatic ssize_t qeth_dev_switch_attrs_show(struct device *dev,
54945cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl				struct device_attribute *attr, char *buf)
55045cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl{
55145cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	struct qeth_card *card = dev_get_drvdata(dev);
55245cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	struct qeth_switch_info sw_info;
55345cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	int	rc = 0;
55445cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl
55545cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	if (!card)
55645cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl		return -EINVAL;
55745cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl
55845cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	if (card->state != CARD_STATE_SOFTSETUP && card->state != CARD_STATE_UP)
55945cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl		return sprintf(buf, "n/a\n");
56045cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl
56145cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	rc = qeth_query_switch_attributes(card, &sw_info);
56245cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	if (rc)
56345cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl		return rc;
56445cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl
56545cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	if (!sw_info.capabilities)
56645cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl		rc = sprintf(buf, "unknown");
56745cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl
56845cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	if (sw_info.capabilities & QETH_SWITCH_FORW_802_1)
56945cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl		rc = sprintf(buf, (sw_info.settings & QETH_SWITCH_FORW_802_1 ?
57045cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl							"[802.1]" : "802.1"));
57145cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	if (sw_info.capabilities & QETH_SWITCH_FORW_REFL_RELAY)
57245cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl		rc += sprintf(buf + rc,
57345cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl			(sw_info.settings & QETH_SWITCH_FORW_REFL_RELAY ?
57445cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl							" [rr]" : " rr"));
57545cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	rc += sprintf(buf + rc, "\n");
57645cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl
57745cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	return rc;
57845cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl}
57945cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl
58045cbb2e499cf4686e809206b29377a7e15037bccStefan Rasplstatic DEVICE_ATTR(switch_attrs, 0444,
58145cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl		   qeth_dev_switch_attrs_show, NULL);
582d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck
5831da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschkastatic ssize_t qeth_hw_trap_show(struct device *dev,
5841da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka				struct device_attribute *attr, char *buf)
5851da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka{
5861da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
5871da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka
5881da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	if (!card)
5891da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		return -EINVAL;
5901da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	if (card->info.hwtrap)
5911da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		return snprintf(buf, 5, "arm\n");
5921da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	else
5931da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		return snprintf(buf, 8, "disarm\n");
5941da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka}
5951da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka
5961da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschkastatic ssize_t qeth_hw_trap_store(struct device *dev,
5971da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		struct device_attribute *attr, const char *buf, size_t count)
5981da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka{
5991da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
6001da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	int rc = 0;
6011da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	char *tmp, *curtoken;
6021da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	int state = 0;
6031da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	curtoken = (char *)buf;
6041da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka
6051da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	if (!card)
6061da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		return -EINVAL;
6071da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka
6081da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	mutex_lock(&card->conf_mutex);
6091da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	if (card->state == CARD_STATE_SOFTSETUP || card->state == CARD_STATE_UP)
6101da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		state = 1;
6111da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	tmp = strsep(&curtoken, "\n");
6121da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka
6131da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	if (!strcmp(tmp, "arm") && !card->info.hwtrap) {
6141da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		if (state) {
6151da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka			if (qeth_is_diagass_supported(card,
6161da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka			    QETH_DIAGS_CMD_TRAP)) {
6171da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka				rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM);
6181da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka				if (!rc)
6191da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka					card->info.hwtrap = 1;
6201da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka			} else
6211da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka				rc = -EINVAL;
6221da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		} else
6231da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka			card->info.hwtrap = 1;
6241da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	} else if (!strcmp(tmp, "disarm") && card->info.hwtrap) {
6251da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		if (state) {
6261da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka			rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
6271da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka			if (!rc)
6281da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka				card->info.hwtrap = 0;
6291da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		} else
6301da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka			card->info.hwtrap = 0;
6311da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	} else if (!strcmp(tmp, "trap") && state && card->info.hwtrap)
6321da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_CAPTURE);
6331da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	else
6341da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		rc = -EINVAL;
6351da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka
6361da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	mutex_unlock(&card->conf_mutex);
6371da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	return rc ? rc : count;
6381da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka}
6391da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka
6401da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschkastatic DEVICE_ATTR(hw_trap, 0644, qeth_hw_trap_show,
6411da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka		   qeth_hw_trap_store);
6421da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka
6434a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
6444a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
6454a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
6464a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
6474a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
6484a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
6494a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return sprintf(buf, "%i\n", value);
6504a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
6514a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
6524a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_blkt_store(struct qeth_card *card,
6534a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		const char *buf, size_t count, int *value, int max_value)
6544a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
6554a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	char *tmp;
656c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	int i, rc = 0;
6574a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
6584a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if (!card)
6594a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		return -EINVAL;
6604a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
661c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_lock(&card->conf_mutex);
6624a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	if ((card->state != CARD_STATE_DOWN) &&
663c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	    (card->state != CARD_STATE_RECOVER)) {
664c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EPERM;
665c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		goto out;
666c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	}
6674a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	i = simple_strtoul(buf, &tmp, 10);
668c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	if (i <= max_value)
6694a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		*value = i;
670c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	else
671c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka		rc = -EINVAL;
672c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschkaout:
673c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	mutex_unlock(&card->conf_mutex);
674c4949f074332a64baeb2ead6ab9319ca37642f96Frank Blaschka	return rc ? rc : count;
6754a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
6764a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
6774a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_blkt_total_show(struct device *dev,
6784a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				struct device_attribute *attr, char *buf)
6794a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
6804a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
6814a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
6824a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return qeth_dev_blkt_show(buf, card, card->info.blkt.time_total);
6834a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
6844a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
6854a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_blkt_total_store(struct device *dev,
6864a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		struct device_attribute *attr, const char *buf, size_t count)
6874a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
6884a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
6894a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
6904a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return qeth_dev_blkt_store(card, buf, count,
691a60389abaab92213c79790e074ff6bc36ac0ebe5Einar Lueck				   &card->info.blkt.time_total, 5000);
6924a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
6934a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
6944a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
6954a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
6964a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(total, 0644, qeth_dev_blkt_total_show,
6974a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		   qeth_dev_blkt_total_store);
6984a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
6994a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_blkt_inter_show(struct device *dev,
7004a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				struct device_attribute *attr, char *buf)
7014a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
7024a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
7034a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
7044a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return qeth_dev_blkt_show(buf, card, card->info.blkt.inter_packet);
7054a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
7064a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
7074a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_blkt_inter_store(struct device *dev,
7084a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		struct device_attribute *attr, const char *buf, size_t count)
7094a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
7104a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
7114a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
7124a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return qeth_dev_blkt_store(card, buf, count,
713a60389abaab92213c79790e074ff6bc36ac0ebe5Einar Lueck				   &card->info.blkt.inter_packet, 1000);
7144a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
7154a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
7164a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,
7174a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		   qeth_dev_blkt_inter_store);
7184a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
7194a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_blkt_inter_jumbo_show(struct device *dev,
7204a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				struct device_attribute *attr, char *buf)
7214a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
7224a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
7234a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
7244a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return qeth_dev_blkt_show(buf, card,
7254a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka				  card->info.blkt.inter_packet_jumbo);
7264a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
7274a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
7284a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic ssize_t qeth_dev_blkt_inter_jumbo_store(struct device *dev,
7294a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		struct device_attribute *attr, const char *buf, size_t count)
7304a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka{
7314a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	struct qeth_card *card = dev_get_drvdata(dev);
7324a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
7334a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	return qeth_dev_blkt_store(card, buf, count,
734a60389abaab92213c79790e074ff6bc36ac0ebe5Einar Lueck				   &card->info.blkt.inter_packet_jumbo, 1000);
7354a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka}
7364a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
7374a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show,
7384a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka		   qeth_dev_blkt_inter_jumbo_store);
7394a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
7404a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic struct attribute *qeth_blkt_device_attrs[] = {
7414a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_total.attr,
7424a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_inter.attr,
7434a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_inter_jumbo.attr,
7444a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	NULL,
7454a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka};
7464a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic struct attribute_group qeth_device_blkt_group = {
7474a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	.name = "blkt",
7484a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	.attrs = qeth_blkt_device_attrs,
7494a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka};
7504a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
7514a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic struct attribute *qeth_device_attrs[] = {
7524a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_state.attr,
7534a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_chpid.attr,
7544a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_if_name.attr,
7554a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_card_type.attr,
7564a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_inbuf_size.attr,
7574a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_portno.attr,
7584a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_portname.attr,
7594a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_priority_queueing.attr,
7604a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_buffer_count.attr,
7614a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_recover.attr,
7624a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_performance_stats.attr,
7634a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_layer2.attr,
764d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26dEinar Lueck	&dev_attr_isolation.attr,
7651da74b1c10062eff5f67accb3bcb27fa329a55d6Frank Blaschka	&dev_attr_hw_trap.attr,
76645cbb2e499cf4686e809206b29377a7e15037bccStefan Raspl	&dev_attr_switch_attrs.attr,
7674a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	NULL,
7684a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka};
7694a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic struct attribute_group qeth_device_attr_group = {
7704a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	.attrs = qeth_device_attrs,
7714a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka};
7724a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka
773b7169c515bbdc139fadee5a98a866c5dc5bb98afSebastian Ottconst struct attribute_group *qeth_generic_attr_groups[] = {
774b7169c515bbdc139fadee5a98a866c5dc5bb98afSebastian Ott	&qeth_device_attr_group,
775b7169c515bbdc139fadee5a98a866c5dc5bb98afSebastian Ott	&qeth_device_blkt_group,
776b7169c515bbdc139fadee5a98a866c5dc5bb98afSebastian Ott	NULL,
777b7169c515bbdc139fadee5a98a866c5dc5bb98afSebastian Ott};
778b7169c515bbdc139fadee5a98a866c5dc5bb98afSebastian Ott
7794a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic struct attribute *qeth_osn_device_attrs[] = {
7804a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_state.attr,
7814a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_chpid.attr,
7824a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_if_name.attr,
7834a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_card_type.attr,
7844a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_buffer_count.attr,
7854a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	&dev_attr_recover.attr,
7864a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	NULL,
7874a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka};
7884a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschkastatic struct attribute_group qeth_osn_device_attr_group = {
7894a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka	.attrs = qeth_osn_device_attrs,
7904a71df50047f0db65ea09b1be155852e81a45ebaFrank Blaschka};
791b7169c515bbdc139fadee5a98a866c5dc5bb98afSebastian Ottconst struct attribute_group *qeth_osn_attr_groups[] = {
792b7169c515bbdc139fadee5a98a866c5dc5bb98afSebastian Ott	&qeth_osn_device_attr_group,
793b7169c515bbdc139fadee5a98a866c5dc5bb98afSebastian Ott	NULL,
794b7169c515bbdc139fadee5a98a866c5dc5bb98afSebastian Ott};
795