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