xref: /openbmc/linux/drivers/s390/net/qeth_core_sys.c (revision 94cdda6b)
1 /*
2  *    Copyright IBM Corp. 2007
3  *    Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
4  *		 Frank Pavlic <fpavlic@de.ibm.com>,
5  *		 Thomas Spatzier <tspat@de.ibm.com>,
6  *		 Frank Blaschka <frank.blaschka@de.ibm.com>
7  */
8 
9 #define KMSG_COMPONENT "qeth"
10 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11 
12 #include <linux/list.h>
13 #include <linux/rwsem.h>
14 #include <asm/ebcdic.h>
15 
16 #include "qeth_core.h"
17 
18 static ssize_t qeth_dev_state_show(struct device *dev,
19 				struct device_attribute *attr, char *buf)
20 {
21 	struct qeth_card *card = dev_get_drvdata(dev);
22 	if (!card)
23 		return -EINVAL;
24 
25 	switch (card->state) {
26 	case CARD_STATE_DOWN:
27 		return sprintf(buf, "DOWN\n");
28 	case CARD_STATE_HARDSETUP:
29 		return sprintf(buf, "HARDSETUP\n");
30 	case CARD_STATE_SOFTSETUP:
31 		return sprintf(buf, "SOFTSETUP\n");
32 	case CARD_STATE_UP:
33 		if (card->lan_online)
34 		return sprintf(buf, "UP (LAN ONLINE)\n");
35 		else
36 			return sprintf(buf, "UP (LAN OFFLINE)\n");
37 	case CARD_STATE_RECOVER:
38 		return sprintf(buf, "RECOVER\n");
39 	default:
40 		return sprintf(buf, "UNKNOWN\n");
41 	}
42 }
43 
44 static DEVICE_ATTR(state, 0444, qeth_dev_state_show, NULL);
45 
46 static ssize_t qeth_dev_chpid_show(struct device *dev,
47 				struct device_attribute *attr, char *buf)
48 {
49 	struct qeth_card *card = dev_get_drvdata(dev);
50 	if (!card)
51 		return -EINVAL;
52 
53 	return sprintf(buf, "%02X\n", card->info.chpid);
54 }
55 
56 static DEVICE_ATTR(chpid, 0444, qeth_dev_chpid_show, NULL);
57 
58 static ssize_t qeth_dev_if_name_show(struct device *dev,
59 				struct device_attribute *attr, char *buf)
60 {
61 	struct qeth_card *card = dev_get_drvdata(dev);
62 	if (!card)
63 		return -EINVAL;
64 	return sprintf(buf, "%s\n", QETH_CARD_IFNAME(card));
65 }
66 
67 static DEVICE_ATTR(if_name, 0444, qeth_dev_if_name_show, NULL);
68 
69 static ssize_t qeth_dev_card_type_show(struct device *dev,
70 				struct device_attribute *attr, char *buf)
71 {
72 	struct qeth_card *card = dev_get_drvdata(dev);
73 	if (!card)
74 		return -EINVAL;
75 
76 	return sprintf(buf, "%s\n", qeth_get_cardname_short(card));
77 }
78 
79 static DEVICE_ATTR(card_type, 0444, qeth_dev_card_type_show, NULL);
80 
81 static inline const char *qeth_get_bufsize_str(struct qeth_card *card)
82 {
83 	if (card->qdio.in_buf_size == 16384)
84 		return "16k";
85 	else if (card->qdio.in_buf_size == 24576)
86 		return "24k";
87 	else if (card->qdio.in_buf_size == 32768)
88 		return "32k";
89 	else if (card->qdio.in_buf_size == 40960)
90 		return "40k";
91 	else
92 		return "64k";
93 }
94 
95 static ssize_t qeth_dev_inbuf_size_show(struct device *dev,
96 				struct device_attribute *attr, char *buf)
97 {
98 	struct qeth_card *card = dev_get_drvdata(dev);
99 	if (!card)
100 		return -EINVAL;
101 
102 	return sprintf(buf, "%s\n", qeth_get_bufsize_str(card));
103 }
104 
105 static DEVICE_ATTR(inbuf_size, 0444, qeth_dev_inbuf_size_show, NULL);
106 
107 static ssize_t qeth_dev_portno_show(struct device *dev,
108 			struct device_attribute *attr, char *buf)
109 {
110 	struct qeth_card *card = dev_get_drvdata(dev);
111 	if (!card)
112 		return -EINVAL;
113 
114 	return sprintf(buf, "%i\n", card->info.portno);
115 }
116 
117 static ssize_t qeth_dev_portno_store(struct device *dev,
118 		struct device_attribute *attr, const char *buf, size_t count)
119 {
120 	struct qeth_card *card = dev_get_drvdata(dev);
121 	char *tmp;
122 	unsigned int portno, limit;
123 	int rc = 0;
124 
125 	if (!card)
126 		return -EINVAL;
127 
128 	mutex_lock(&card->conf_mutex);
129 	if ((card->state != CARD_STATE_DOWN) &&
130 	    (card->state != CARD_STATE_RECOVER)) {
131 		rc = -EPERM;
132 		goto out;
133 	}
134 
135 	portno = simple_strtoul(buf, &tmp, 16);
136 	if (portno > QETH_MAX_PORTNO) {
137 		rc = -EINVAL;
138 		goto out;
139 	}
140 	limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt);
141 	if (portno > limit) {
142 		rc = -EINVAL;
143 		goto out;
144 	}
145 	card->info.portno = portno;
146 out:
147 	mutex_unlock(&card->conf_mutex);
148 	return rc ? rc : count;
149 }
150 
151 static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);
152 
153 static ssize_t qeth_dev_portname_show(struct device *dev,
154 				struct device_attribute *attr, char *buf)
155 {
156 	struct qeth_card *card = dev_get_drvdata(dev);
157 	char portname[9] = {0, };
158 
159 	if (!card)
160 		return -EINVAL;
161 
162 	if (card->info.portname_required) {
163 		memcpy(portname, card->info.portname + 1, 8);
164 		EBCASC(portname, 8);
165 		return sprintf(buf, "%s\n", portname);
166 	} else
167 		return sprintf(buf, "no portname required\n");
168 }
169 
170 static ssize_t qeth_dev_portname_store(struct device *dev,
171 		struct device_attribute *attr, const char *buf, size_t count)
172 {
173 	struct qeth_card *card = dev_get_drvdata(dev);
174 	char *tmp;
175 	int i, rc = 0;
176 
177 	if (!card)
178 		return -EINVAL;
179 
180 	mutex_lock(&card->conf_mutex);
181 	if ((card->state != CARD_STATE_DOWN) &&
182 	    (card->state != CARD_STATE_RECOVER)) {
183 		rc = -EPERM;
184 		goto out;
185 	}
186 
187 	tmp = strsep((char **) &buf, "\n");
188 	if ((strlen(tmp) > 8) || (strlen(tmp) == 0)) {
189 		rc = -EINVAL;
190 		goto out;
191 	}
192 
193 	card->info.portname[0] = strlen(tmp);
194 	/* for beauty reasons */
195 	for (i = 1; i < 9; i++)
196 		card->info.portname[i] = ' ';
197 	strcpy(card->info.portname + 1, tmp);
198 	ASCEBC(card->info.portname + 1, 8);
199 out:
200 	mutex_unlock(&card->conf_mutex);
201 	return rc ? rc : count;
202 }
203 
204 static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show,
205 		qeth_dev_portname_store);
206 
207 static ssize_t qeth_dev_prioqing_show(struct device *dev,
208 				struct device_attribute *attr, char *buf)
209 {
210 	struct qeth_card *card = dev_get_drvdata(dev);
211 
212 	if (!card)
213 		return -EINVAL;
214 
215 	switch (card->qdio.do_prio_queueing) {
216 	case QETH_PRIO_Q_ING_PREC:
217 		return sprintf(buf, "%s\n", "by precedence");
218 	case QETH_PRIO_Q_ING_TOS:
219 		return sprintf(buf, "%s\n", "by type of service");
220 	case QETH_PRIO_Q_ING_SKB:
221 		return sprintf(buf, "%s\n", "by skb-priority");
222 	case QETH_PRIO_Q_ING_VLAN:
223 		return sprintf(buf, "%s\n", "by VLAN headers");
224 	default:
225 		return sprintf(buf, "always queue %i\n",
226 			       card->qdio.default_out_queue);
227 	}
228 }
229 
230 static ssize_t qeth_dev_prioqing_store(struct device *dev,
231 		struct device_attribute *attr, const char *buf, size_t count)
232 {
233 	struct qeth_card *card = dev_get_drvdata(dev);
234 	int rc = 0;
235 
236 	if (!card)
237 		return -EINVAL;
238 
239 	mutex_lock(&card->conf_mutex);
240 	if ((card->state != CARD_STATE_DOWN) &&
241 	    (card->state != CARD_STATE_RECOVER)) {
242 		rc = -EPERM;
243 		goto out;
244 	}
245 
246 	/* check if 1920 devices are supported ,
247 	 * if though we have to permit priority queueing
248 	 */
249 	if (card->qdio.no_out_queues == 1) {
250 		card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
251 		rc = -EPERM;
252 		goto out;
253 	}
254 
255 	if (sysfs_streq(buf, "prio_queueing_prec")) {
256 		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC;
257 		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
258 	} else if (sysfs_streq(buf, "prio_queueing_skb")) {
259 		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_SKB;
260 		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
261 	} else if (sysfs_streq(buf, "prio_queueing_tos")) {
262 		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS;
263 		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
264 	} else if (sysfs_streq(buf, "prio_queueing_vlan")) {
265 		if (!card->options.layer2) {
266 			rc = -ENOTSUPP;
267 			goto out;
268 		}
269 		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_VLAN;
270 		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
271 	} else if (sysfs_streq(buf, "no_prio_queueing:0")) {
272 		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
273 		card->qdio.default_out_queue = 0;
274 	} else if (sysfs_streq(buf, "no_prio_queueing:1")) {
275 		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
276 		card->qdio.default_out_queue = 1;
277 	} else if (sysfs_streq(buf, "no_prio_queueing:2")) {
278 		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
279 		card->qdio.default_out_queue = 2;
280 	} else if (sysfs_streq(buf, "no_prio_queueing:3")) {
281 		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
282 		card->qdio.default_out_queue = 3;
283 	} else if (sysfs_streq(buf, "no_prio_queueing")) {
284 		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
285 		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
286 	} else
287 		rc = -EINVAL;
288 out:
289 	mutex_unlock(&card->conf_mutex);
290 	return rc ? rc : count;
291 }
292 
293 static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show,
294 		qeth_dev_prioqing_store);
295 
296 static ssize_t qeth_dev_bufcnt_show(struct device *dev,
297 				struct device_attribute *attr, char *buf)
298 {
299 	struct qeth_card *card = dev_get_drvdata(dev);
300 
301 	if (!card)
302 		return -EINVAL;
303 
304 	return sprintf(buf, "%i\n", card->qdio.in_buf_pool.buf_count);
305 }
306 
307 static ssize_t qeth_dev_bufcnt_store(struct device *dev,
308 		struct device_attribute *attr, const char *buf, size_t count)
309 {
310 	struct qeth_card *card = dev_get_drvdata(dev);
311 	char *tmp;
312 	int cnt, old_cnt;
313 	int rc = 0;
314 
315 	if (!card)
316 		return -EINVAL;
317 
318 	mutex_lock(&card->conf_mutex);
319 	if ((card->state != CARD_STATE_DOWN) &&
320 	    (card->state != CARD_STATE_RECOVER)) {
321 		rc = -EPERM;
322 		goto out;
323 	}
324 
325 	old_cnt = card->qdio.in_buf_pool.buf_count;
326 	cnt = simple_strtoul(buf, &tmp, 10);
327 	cnt = (cnt < QETH_IN_BUF_COUNT_MIN) ? QETH_IN_BUF_COUNT_MIN :
328 		((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt);
329 	if (old_cnt != cnt) {
330 		rc = qeth_realloc_buffer_pool(card, cnt);
331 	}
332 out:
333 	mutex_unlock(&card->conf_mutex);
334 	return rc ? rc : count;
335 }
336 
337 static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show,
338 		qeth_dev_bufcnt_store);
339 
340 static ssize_t qeth_dev_recover_store(struct device *dev,
341 		struct device_attribute *attr, const char *buf, size_t count)
342 {
343 	struct qeth_card *card = dev_get_drvdata(dev);
344 	char *tmp;
345 	int i;
346 
347 	if (!card)
348 		return -EINVAL;
349 
350 	if (card->state != CARD_STATE_UP)
351 		return -EPERM;
352 
353 	i = simple_strtoul(buf, &tmp, 16);
354 	if (i == 1)
355 		qeth_schedule_recovery(card);
356 
357 	return count;
358 }
359 
360 static DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store);
361 
362 static ssize_t qeth_dev_performance_stats_show(struct device *dev,
363 				struct device_attribute *attr, char *buf)
364 {
365 	struct qeth_card *card = dev_get_drvdata(dev);
366 
367 	if (!card)
368 		return -EINVAL;
369 
370 	return sprintf(buf, "%i\n", card->options.performance_stats ? 1:0);
371 }
372 
373 static ssize_t qeth_dev_performance_stats_store(struct device *dev,
374 		struct device_attribute *attr, const char *buf, size_t count)
375 {
376 	struct qeth_card *card = dev_get_drvdata(dev);
377 	char *tmp;
378 	int i, rc = 0;
379 
380 	if (!card)
381 		return -EINVAL;
382 
383 	mutex_lock(&card->conf_mutex);
384 	i = simple_strtoul(buf, &tmp, 16);
385 	if ((i == 0) || (i == 1)) {
386 		if (i == card->options.performance_stats)
387 			goto out;
388 		card->options.performance_stats = i;
389 		if (i == 0)
390 			memset(&card->perf_stats, 0,
391 				sizeof(struct qeth_perf_stats));
392 		card->perf_stats.initial_rx_packets = card->stats.rx_packets;
393 		card->perf_stats.initial_tx_packets = card->stats.tx_packets;
394 	} else
395 		rc = -EINVAL;
396 out:
397 	mutex_unlock(&card->conf_mutex);
398 	return rc ? rc : count;
399 }
400 
401 static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show,
402 		   qeth_dev_performance_stats_store);
403 
404 static ssize_t qeth_dev_layer2_show(struct device *dev,
405 		struct device_attribute *attr, char *buf)
406 {
407 	struct qeth_card *card = dev_get_drvdata(dev);
408 
409 	if (!card)
410 		return -EINVAL;
411 
412 	return sprintf(buf, "%i\n", card->options.layer2);
413 }
414 
415 static ssize_t qeth_dev_layer2_store(struct device *dev,
416 		struct device_attribute *attr, const char *buf, size_t count)
417 {
418 	struct qeth_card *card = dev_get_drvdata(dev);
419 	char *tmp;
420 	int i, rc = 0;
421 	enum qeth_discipline_id newdis;
422 
423 	if (!card)
424 		return -EINVAL;
425 
426 	mutex_lock(&card->discipline_mutex);
427 	if (card->state != CARD_STATE_DOWN) {
428 		rc = -EPERM;
429 		goto out;
430 	}
431 
432 	i = simple_strtoul(buf, &tmp, 16);
433 	switch (i) {
434 	case 0:
435 		newdis = QETH_DISCIPLINE_LAYER3;
436 		break;
437 	case 1:
438 		newdis = QETH_DISCIPLINE_LAYER2;
439 		break;
440 	default:
441 		rc = -EINVAL;
442 		goto out;
443 	}
444 
445 	if (card->options.layer2 == newdis)
446 		goto out;
447 	else {
448 		card->info.mac_bits  = 0;
449 		if (card->discipline) {
450 			card->discipline->remove(card->gdev);
451 			qeth_core_free_discipline(card);
452 		}
453 	}
454 
455 	rc = qeth_core_load_discipline(card, newdis);
456 	if (rc)
457 		goto out;
458 
459 	rc = card->discipline->setup(card->gdev);
460 out:
461 	mutex_unlock(&card->discipline_mutex);
462 	return rc ? rc : count;
463 }
464 
465 static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
466 		   qeth_dev_layer2_store);
467 
468 #define ATTR_QETH_ISOLATION_NONE	("none")
469 #define ATTR_QETH_ISOLATION_FWD		("forward")
470 #define ATTR_QETH_ISOLATION_DROP	("drop")
471 
472 static ssize_t qeth_dev_isolation_show(struct device *dev,
473 				struct device_attribute *attr, char *buf)
474 {
475 	struct qeth_card *card = dev_get_drvdata(dev);
476 
477 	if (!card)
478 		return -EINVAL;
479 
480 	switch (card->options.isolation) {
481 	case ISOLATION_MODE_NONE:
482 		return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_NONE);
483 	case ISOLATION_MODE_FWD:
484 		return snprintf(buf, 9, "%s\n", ATTR_QETH_ISOLATION_FWD);
485 	case ISOLATION_MODE_DROP:
486 		return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_DROP);
487 	default:
488 		return snprintf(buf, 5, "%s\n", "N/A");
489 	}
490 }
491 
492 static ssize_t qeth_dev_isolation_store(struct device *dev,
493 		struct device_attribute *attr, const char *buf, size_t count)
494 {
495 	struct qeth_card *card = dev_get_drvdata(dev);
496 	enum qeth_ipa_isolation_modes isolation;
497 	int rc = 0;
498 
499 	if (!card)
500 		return -EINVAL;
501 
502 	mutex_lock(&card->conf_mutex);
503 	/* check for unknown, too, in case we do not yet know who we are */
504 	if (card->info.type != QETH_CARD_TYPE_OSD &&
505 	    card->info.type != QETH_CARD_TYPE_OSX &&
506 	    card->info.type != QETH_CARD_TYPE_UNKNOWN) {
507 		rc = -EOPNOTSUPP;
508 		dev_err(&card->gdev->dev, "Adapter does not "
509 			"support QDIO data connection isolation\n");
510 		goto out;
511 	}
512 
513 	/* parse input into isolation mode */
514 	if (sysfs_streq(buf, ATTR_QETH_ISOLATION_NONE)) {
515 		isolation = ISOLATION_MODE_NONE;
516 	} else if (sysfs_streq(buf, ATTR_QETH_ISOLATION_FWD)) {
517 		isolation = ISOLATION_MODE_FWD;
518 	} else if (sysfs_streq(buf, ATTR_QETH_ISOLATION_DROP)) {
519 		isolation = ISOLATION_MODE_DROP;
520 	} else {
521 		rc = -EINVAL;
522 		goto out;
523 	}
524 	rc = count;
525 
526 	/* defer IP assist if device is offline (until discipline->set_online)*/
527 	card->options.prev_isolation = card->options.isolation;
528 	card->options.isolation = isolation;
529 	if (qeth_card_hw_is_reachable(card)) {
530 		int ipa_rc = qeth_set_access_ctrl_online(card, 1);
531 		if (ipa_rc != 0)
532 			rc = ipa_rc;
533 	}
534 out:
535 	mutex_unlock(&card->conf_mutex);
536 	return rc;
537 }
538 
539 static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
540 			qeth_dev_isolation_store);
541 
542 static ssize_t qeth_dev_switch_attrs_show(struct device *dev,
543 				struct device_attribute *attr, char *buf)
544 {
545 	struct qeth_card *card = dev_get_drvdata(dev);
546 	struct qeth_switch_info sw_info;
547 	int	rc = 0;
548 
549 	if (!card)
550 		return -EINVAL;
551 
552 	if (!qeth_card_hw_is_reachable(card))
553 		return sprintf(buf, "n/a\n");
554 
555 	rc = qeth_query_switch_attributes(card, &sw_info);
556 	if (rc)
557 		return rc;
558 
559 	if (!sw_info.capabilities)
560 		rc = sprintf(buf, "unknown");
561 
562 	if (sw_info.capabilities & QETH_SWITCH_FORW_802_1)
563 		rc = sprintf(buf, (sw_info.settings & QETH_SWITCH_FORW_802_1 ?
564 							"[802.1]" : "802.1"));
565 	if (sw_info.capabilities & QETH_SWITCH_FORW_REFL_RELAY)
566 		rc += sprintf(buf + rc,
567 			(sw_info.settings & QETH_SWITCH_FORW_REFL_RELAY ?
568 							" [rr]" : " rr"));
569 	rc += sprintf(buf + rc, "\n");
570 
571 	return rc;
572 }
573 
574 static DEVICE_ATTR(switch_attrs, 0444,
575 		   qeth_dev_switch_attrs_show, NULL);
576 
577 static ssize_t qeth_hw_trap_show(struct device *dev,
578 				struct device_attribute *attr, char *buf)
579 {
580 	struct qeth_card *card = dev_get_drvdata(dev);
581 
582 	if (!card)
583 		return -EINVAL;
584 	if (card->info.hwtrap)
585 		return snprintf(buf, 5, "arm\n");
586 	else
587 		return snprintf(buf, 8, "disarm\n");
588 }
589 
590 static ssize_t qeth_hw_trap_store(struct device *dev,
591 		struct device_attribute *attr, const char *buf, size_t count)
592 {
593 	struct qeth_card *card = dev_get_drvdata(dev);
594 	int rc = 0;
595 	int state = 0;
596 
597 	if (!card)
598 		return -EINVAL;
599 
600 	mutex_lock(&card->conf_mutex);
601 	if (qeth_card_hw_is_reachable(card))
602 		state = 1;
603 
604 	if (sysfs_streq(buf, "arm") && !card->info.hwtrap) {
605 		if (state) {
606 			if (qeth_is_diagass_supported(card,
607 			    QETH_DIAGS_CMD_TRAP)) {
608 				rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM);
609 				if (!rc)
610 					card->info.hwtrap = 1;
611 			} else
612 				rc = -EINVAL;
613 		} else
614 			card->info.hwtrap = 1;
615 	} else if (sysfs_streq(buf, "disarm") && card->info.hwtrap) {
616 		if (state) {
617 			rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
618 			if (!rc)
619 				card->info.hwtrap = 0;
620 		} else
621 			card->info.hwtrap = 0;
622 	} else if (sysfs_streq(buf, "trap") && state && card->info.hwtrap)
623 		rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_CAPTURE);
624 	else
625 		rc = -EINVAL;
626 
627 	mutex_unlock(&card->conf_mutex);
628 	return rc ? rc : count;
629 }
630 
631 static DEVICE_ATTR(hw_trap, 0644, qeth_hw_trap_show,
632 		   qeth_hw_trap_store);
633 
634 static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
635 {
636 
637 	if (!card)
638 		return -EINVAL;
639 
640 	return sprintf(buf, "%i\n", value);
641 }
642 
643 static ssize_t qeth_dev_blkt_store(struct qeth_card *card,
644 		const char *buf, size_t count, int *value, int max_value)
645 {
646 	char *tmp;
647 	int i, rc = 0;
648 
649 	if (!card)
650 		return -EINVAL;
651 
652 	mutex_lock(&card->conf_mutex);
653 	if ((card->state != CARD_STATE_DOWN) &&
654 	    (card->state != CARD_STATE_RECOVER)) {
655 		rc = -EPERM;
656 		goto out;
657 	}
658 	i = simple_strtoul(buf, &tmp, 10);
659 	if (i <= max_value)
660 		*value = i;
661 	else
662 		rc = -EINVAL;
663 out:
664 	mutex_unlock(&card->conf_mutex);
665 	return rc ? rc : count;
666 }
667 
668 static ssize_t qeth_dev_blkt_total_show(struct device *dev,
669 				struct device_attribute *attr, char *buf)
670 {
671 	struct qeth_card *card = dev_get_drvdata(dev);
672 
673 	return qeth_dev_blkt_show(buf, card, card->info.blkt.time_total);
674 }
675 
676 static ssize_t qeth_dev_blkt_total_store(struct device *dev,
677 		struct device_attribute *attr, const char *buf, size_t count)
678 {
679 	struct qeth_card *card = dev_get_drvdata(dev);
680 
681 	return qeth_dev_blkt_store(card, buf, count,
682 				   &card->info.blkt.time_total, 5000);
683 }
684 
685 
686 
687 static DEVICE_ATTR(total, 0644, qeth_dev_blkt_total_show,
688 		   qeth_dev_blkt_total_store);
689 
690 static ssize_t qeth_dev_blkt_inter_show(struct device *dev,
691 				struct device_attribute *attr, char *buf)
692 {
693 	struct qeth_card *card = dev_get_drvdata(dev);
694 
695 	return qeth_dev_blkt_show(buf, card, card->info.blkt.inter_packet);
696 }
697 
698 static ssize_t qeth_dev_blkt_inter_store(struct device *dev,
699 		struct device_attribute *attr, const char *buf, size_t count)
700 {
701 	struct qeth_card *card = dev_get_drvdata(dev);
702 
703 	return qeth_dev_blkt_store(card, buf, count,
704 				   &card->info.blkt.inter_packet, 1000);
705 }
706 
707 static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,
708 		   qeth_dev_blkt_inter_store);
709 
710 static ssize_t qeth_dev_blkt_inter_jumbo_show(struct device *dev,
711 				struct device_attribute *attr, char *buf)
712 {
713 	struct qeth_card *card = dev_get_drvdata(dev);
714 
715 	return qeth_dev_blkt_show(buf, card,
716 				  card->info.blkt.inter_packet_jumbo);
717 }
718 
719 static ssize_t qeth_dev_blkt_inter_jumbo_store(struct device *dev,
720 		struct device_attribute *attr, const char *buf, size_t count)
721 {
722 	struct qeth_card *card = dev_get_drvdata(dev);
723 
724 	return qeth_dev_blkt_store(card, buf, count,
725 				   &card->info.blkt.inter_packet_jumbo, 1000);
726 }
727 
728 static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show,
729 		   qeth_dev_blkt_inter_jumbo_store);
730 
731 static struct attribute *qeth_blkt_device_attrs[] = {
732 	&dev_attr_total.attr,
733 	&dev_attr_inter.attr,
734 	&dev_attr_inter_jumbo.attr,
735 	NULL,
736 };
737 static struct attribute_group qeth_device_blkt_group = {
738 	.name = "blkt",
739 	.attrs = qeth_blkt_device_attrs,
740 };
741 
742 static struct attribute *qeth_device_attrs[] = {
743 	&dev_attr_state.attr,
744 	&dev_attr_chpid.attr,
745 	&dev_attr_if_name.attr,
746 	&dev_attr_card_type.attr,
747 	&dev_attr_inbuf_size.attr,
748 	&dev_attr_portno.attr,
749 	&dev_attr_portname.attr,
750 	&dev_attr_priority_queueing.attr,
751 	&dev_attr_buffer_count.attr,
752 	&dev_attr_recover.attr,
753 	&dev_attr_performance_stats.attr,
754 	&dev_attr_layer2.attr,
755 	&dev_attr_isolation.attr,
756 	&dev_attr_hw_trap.attr,
757 	&dev_attr_switch_attrs.attr,
758 	NULL,
759 };
760 static struct attribute_group qeth_device_attr_group = {
761 	.attrs = qeth_device_attrs,
762 };
763 
764 const struct attribute_group *qeth_generic_attr_groups[] = {
765 	&qeth_device_attr_group,
766 	&qeth_device_blkt_group,
767 	NULL,
768 };
769 
770 static struct attribute *qeth_osn_device_attrs[] = {
771 	&dev_attr_state.attr,
772 	&dev_attr_chpid.attr,
773 	&dev_attr_if_name.attr,
774 	&dev_attr_card_type.attr,
775 	&dev_attr_buffer_count.attr,
776 	&dev_attr_recover.attr,
777 	NULL,
778 };
779 static struct attribute_group qeth_osn_device_attr_group = {
780 	.attrs = qeth_osn_device_attrs,
781 };
782 const struct attribute_group *qeth_osn_attr_groups[] = {
783 	&qeth_osn_device_attr_group,
784 	NULL,
785 };
786