]> git.karo-electronics.de Git - linux-beck.git/blob - drivers/s390/net/qeth_core_sys.c
Merge branch 'davinci-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-beck.git] / drivers / s390 / net / qeth_core_sys.c
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 }