Commit | Line | Data |
---|---|---|
4a71df50 FB |
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) { | |
4a71df50 FB |
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) { | |
4a71df50 FB |
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 { | |
4a71df50 FB |
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); | |
4a71df50 FB |
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 { | |
4a71df50 FB |
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 | ||
7c6a3ed5 | 367 | return sprintf(buf, "%i\n", card->options.layer2); |
4a71df50 FB |
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: | |
4a71df50 FB |
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 | ||
d64ecc22 EL |
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 | ||
4a71df50 FB |
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 { | |
4a71df50 FB |
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, | |
d64ecc22 | 614 | &dev_attr_isolation.attr, |
4a71df50 FB |
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 | } |