perf, x86: Fix key indexing in Pentium-4 PMU
[linux-2.6-block.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, limit;
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         limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt);
134         if (portno > limit)
135                 return -EINVAL;
136
137         card->info.portno = portno;
138         return count;
139 }
140
141 static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);
142
143 static ssize_t qeth_dev_portname_show(struct device *dev,
144                                 struct device_attribute *attr, char *buf)
145 {
146         struct qeth_card *card = dev_get_drvdata(dev);
147         char portname[9] = {0, };
148
149         if (!card)
150                 return -EINVAL;
151
152         if (card->info.portname_required) {
153                 memcpy(portname, card->info.portname + 1, 8);
154                 EBCASC(portname, 8);
155                 return sprintf(buf, "%s\n", portname);
156         } else
157                 return sprintf(buf, "no portname required\n");
158 }
159
160 static ssize_t qeth_dev_portname_store(struct device *dev,
161                 struct device_attribute *attr, const char *buf, size_t count)
162 {
163         struct qeth_card *card = dev_get_drvdata(dev);
164         char *tmp;
165         int i;
166
167         if (!card)
168                 return -EINVAL;
169
170         if ((card->state != CARD_STATE_DOWN) &&
171             (card->state != CARD_STATE_RECOVER))
172                 return -EPERM;
173
174         tmp = strsep((char **) &buf, "\n");
175         if ((strlen(tmp) > 8) || (strlen(tmp) == 0))
176                 return -EINVAL;
177
178         card->info.portname[0] = strlen(tmp);
179         /* for beauty reasons */
180         for (i = 1; i < 9; i++)
181                 card->info.portname[i] = ' ';
182         strcpy(card->info.portname + 1, tmp);
183         ASCEBC(card->info.portname + 1, 8);
184
185         return count;
186 }
187
188 static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show,
189                 qeth_dev_portname_store);
190
191 static ssize_t qeth_dev_prioqing_show(struct device *dev,
192                                 struct device_attribute *attr, char *buf)
193 {
194         struct qeth_card *card = dev_get_drvdata(dev);
195
196         if (!card)
197                 return -EINVAL;
198
199         switch (card->qdio.do_prio_queueing) {
200         case QETH_PRIO_Q_ING_PREC:
201                 return sprintf(buf, "%s\n", "by precedence");
202         case QETH_PRIO_Q_ING_TOS:
203                 return sprintf(buf, "%s\n", "by type of service");
204         default:
205                 return sprintf(buf, "always queue %i\n",
206                                card->qdio.default_out_queue);
207         }
208 }
209
210 static ssize_t qeth_dev_prioqing_store(struct device *dev,
211                 struct device_attribute *attr, const char *buf, size_t count)
212 {
213         struct qeth_card *card = dev_get_drvdata(dev);
214         char *tmp;
215
216         if (!card)
217                 return -EINVAL;
218
219         if ((card->state != CARD_STATE_DOWN) &&
220             (card->state != CARD_STATE_RECOVER))
221                 return -EPERM;
222
223         /* check if 1920 devices are supported ,
224          * if though we have to permit priority queueing
225          */
226         if (card->qdio.no_out_queues == 1) {
227                 card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
228                 return -EPERM;
229         }
230
231         tmp = strsep((char **) &buf, "\n");
232         if (!strcmp(tmp, "prio_queueing_prec"))
233                 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC;
234         else if (!strcmp(tmp, "prio_queueing_tos"))
235                 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS;
236         else if (!strcmp(tmp, "no_prio_queueing:0")) {
237                 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
238                 card->qdio.default_out_queue = 0;
239         } else if (!strcmp(tmp, "no_prio_queueing:1")) {
240                 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
241                 card->qdio.default_out_queue = 1;
242         } else if (!strcmp(tmp, "no_prio_queueing:2")) {
243                 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
244                 card->qdio.default_out_queue = 2;
245         } else if (!strcmp(tmp, "no_prio_queueing:3")) {
246                 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
247                 card->qdio.default_out_queue = 3;
248         } else if (!strcmp(tmp, "no_prio_queueing")) {
249                 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
250                 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
251         } else {
252                 return -EINVAL;
253         }
254         return count;
255 }
256
257 static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show,
258                 qeth_dev_prioqing_store);
259
260 static ssize_t qeth_dev_bufcnt_show(struct device *dev,
261                                 struct device_attribute *attr, char *buf)
262 {
263         struct qeth_card *card = dev_get_drvdata(dev);
264
265         if (!card)
266                 return -EINVAL;
267
268         return sprintf(buf, "%i\n", card->qdio.in_buf_pool.buf_count);
269 }
270
271 static ssize_t qeth_dev_bufcnt_store(struct device *dev,
272                 struct device_attribute *attr, const char *buf, size_t count)
273 {
274         struct qeth_card *card = dev_get_drvdata(dev);
275         char *tmp;
276         int cnt, old_cnt;
277         int rc;
278
279         if (!card)
280                 return -EINVAL;
281
282         if ((card->state != CARD_STATE_DOWN) &&
283             (card->state != CARD_STATE_RECOVER))
284                 return -EPERM;
285
286         old_cnt = card->qdio.in_buf_pool.buf_count;
287         cnt = simple_strtoul(buf, &tmp, 10);
288         cnt = (cnt < QETH_IN_BUF_COUNT_MIN) ? QETH_IN_BUF_COUNT_MIN :
289                 ((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt);
290         if (old_cnt != cnt) {
291                 rc = qeth_realloc_buffer_pool(card, cnt);
292         }
293         return count;
294 }
295
296 static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show,
297                 qeth_dev_bufcnt_store);
298
299 static ssize_t qeth_dev_recover_store(struct device *dev,
300                 struct device_attribute *attr, const char *buf, size_t count)
301 {
302         struct qeth_card *card = dev_get_drvdata(dev);
303         char *tmp;
304         int i;
305
306         if (!card)
307                 return -EINVAL;
308
309         if (card->state != CARD_STATE_UP)
310                 return -EPERM;
311
312         i = simple_strtoul(buf, &tmp, 16);
313         if (i == 1)
314                 qeth_schedule_recovery(card);
315
316         return count;
317 }
318
319 static DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store);
320
321 static ssize_t qeth_dev_performance_stats_show(struct device *dev,
322                                 struct device_attribute *attr, char *buf)
323 {
324         struct qeth_card *card = dev_get_drvdata(dev);
325
326         if (!card)
327                 return -EINVAL;
328
329         return sprintf(buf, "%i\n", card->options.performance_stats ? 1:0);
330 }
331
332 static ssize_t qeth_dev_performance_stats_store(struct device *dev,
333                 struct device_attribute *attr, const char *buf, size_t count)
334 {
335         struct qeth_card *card = dev_get_drvdata(dev);
336         char *tmp;
337         int i;
338
339         if (!card)
340                 return -EINVAL;
341
342         i = simple_strtoul(buf, &tmp, 16);
343         if ((i == 0) || (i == 1)) {
344                 if (i == card->options.performance_stats)
345                         return count;
346                 card->options.performance_stats = i;
347                 if (i == 0)
348                         memset(&card->perf_stats, 0,
349                                 sizeof(struct qeth_perf_stats));
350                 card->perf_stats.initial_rx_packets = card->stats.rx_packets;
351                 card->perf_stats.initial_tx_packets = card->stats.tx_packets;
352         } else {
353                 return -EINVAL;
354         }
355         return count;
356 }
357
358 static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show,
359                    qeth_dev_performance_stats_store);
360
361 static ssize_t qeth_dev_layer2_show(struct device *dev,
362                 struct device_attribute *attr, char *buf)
363 {
364         struct qeth_card *card = dev_get_drvdata(dev);
365
366         if (!card)
367                 return -EINVAL;
368
369         return sprintf(buf, "%i\n", card->options.layer2);
370 }
371
372 static ssize_t qeth_dev_layer2_store(struct device *dev,
373                 struct device_attribute *attr, const char *buf, size_t count)
374 {
375         struct qeth_card *card = dev_get_drvdata(dev);
376         char *tmp;
377         int i, rc;
378         enum qeth_discipline_id newdis;
379
380         if (!card)
381                 return -EINVAL;
382
383         if (((card->state != CARD_STATE_DOWN) &&
384              (card->state != CARD_STATE_RECOVER)))
385                 return -EPERM;
386
387         i = simple_strtoul(buf, &tmp, 16);
388         switch (i) {
389         case 0:
390                 newdis = QETH_DISCIPLINE_LAYER3;
391                 break;
392         case 1:
393                 newdis = QETH_DISCIPLINE_LAYER2;
394                 break;
395         default:
396                 return -EINVAL;
397         }
398
399         if (card->options.layer2 == newdis) {
400                 return count;
401         } else {
402                 if (card->discipline.ccwgdriver) {
403                         card->discipline.ccwgdriver->remove(card->gdev);
404                         qeth_core_free_discipline(card);
405                 }
406         }
407
408         rc = qeth_core_load_discipline(card, newdis);
409         if (rc)
410                 return rc;
411
412         rc = card->discipline.ccwgdriver->probe(card->gdev);
413         if (rc)
414                 return rc;
415         return count;
416 }
417
418 static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
419                    qeth_dev_layer2_store);
420
421 #define ATTR_QETH_ISOLATION_NONE        ("none")
422 #define ATTR_QETH_ISOLATION_FWD         ("forward")
423 #define ATTR_QETH_ISOLATION_DROP        ("drop")
424
425 static ssize_t qeth_dev_isolation_show(struct device *dev,
426                                 struct device_attribute *attr, char *buf)
427 {
428         struct qeth_card *card = dev_get_drvdata(dev);
429
430         if (!card)
431                 return -EINVAL;
432
433         switch (card->options.isolation) {
434         case ISOLATION_MODE_NONE:
435                 return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_NONE);
436         case ISOLATION_MODE_FWD:
437                 return snprintf(buf, 9, "%s\n", ATTR_QETH_ISOLATION_FWD);
438         case ISOLATION_MODE_DROP:
439                 return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_DROP);
440         default:
441                 return snprintf(buf, 5, "%s\n", "N/A");
442         }
443 }
444
445 static ssize_t qeth_dev_isolation_store(struct device *dev,
446                 struct device_attribute *attr, const char *buf, size_t count)
447 {
448         struct qeth_card *card = dev_get_drvdata(dev);
449         enum qeth_ipa_isolation_modes isolation;
450         int rc = 0;
451         char *tmp, *curtoken;
452         curtoken = (char *) buf;
453
454         if (!card) {
455                 rc = -EINVAL;
456                 goto out;
457         }
458
459         /* check for unknown, too, in case we do not yet know who we are */
460         if (card->info.type != QETH_CARD_TYPE_OSAE &&
461             card->info.type != QETH_CARD_TYPE_UNKNOWN) {
462                 rc = -EOPNOTSUPP;
463                 dev_err(&card->gdev->dev, "Adapter does not "
464                         "support QDIO data connection isolation\n");
465                 goto out;
466         }
467
468         /* parse input into isolation mode */
469         tmp = strsep(&curtoken, "\n");
470         if (!strcmp(tmp, ATTR_QETH_ISOLATION_NONE)) {
471                 isolation = ISOLATION_MODE_NONE;
472         } else if (!strcmp(tmp, ATTR_QETH_ISOLATION_FWD)) {
473                 isolation = ISOLATION_MODE_FWD;
474         } else if (!strcmp(tmp, ATTR_QETH_ISOLATION_DROP)) {
475                 isolation = ISOLATION_MODE_DROP;
476         } else {
477                 rc = -EINVAL;
478                 goto out;
479         }
480         rc = count;
481
482         /* defer IP assist if device is offline (until discipline->set_online)*/
483         card->options.isolation = isolation;
484         if (card->state == CARD_STATE_SOFTSETUP ||
485             card->state == CARD_STATE_UP) {
486                 int ipa_rc = qeth_set_access_ctrl_online(card);
487                 if (ipa_rc != 0)
488                         rc = ipa_rc;
489         }
490 out:
491         return rc;
492 }
493
494 static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
495                    qeth_dev_isolation_store);
496
497 static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
498 {
499
500         if (!card)
501                 return -EINVAL;
502
503         return sprintf(buf, "%i\n", value);
504 }
505
506 static ssize_t qeth_dev_blkt_store(struct qeth_card *card,
507                 const char *buf, size_t count, int *value, int max_value)
508 {
509         char *tmp;
510         int i;
511
512         if (!card)
513                 return -EINVAL;
514
515         if ((card->state != CARD_STATE_DOWN) &&
516             (card->state != CARD_STATE_RECOVER))
517                 return -EPERM;
518
519         i = simple_strtoul(buf, &tmp, 10);
520         if (i <= max_value) {
521                 *value = i;
522         } else {
523                 return -EINVAL;
524         }
525         return count;
526 }
527
528 static ssize_t qeth_dev_blkt_total_show(struct device *dev,
529                                 struct device_attribute *attr, char *buf)
530 {
531         struct qeth_card *card = dev_get_drvdata(dev);
532
533         return qeth_dev_blkt_show(buf, card, card->info.blkt.time_total);
534 }
535
536 static ssize_t qeth_dev_blkt_total_store(struct device *dev,
537                 struct device_attribute *attr, const char *buf, size_t count)
538 {
539         struct qeth_card *card = dev_get_drvdata(dev);
540
541         return qeth_dev_blkt_store(card, buf, count,
542                                    &card->info.blkt.time_total, 5000);
543 }
544
545
546
547 static DEVICE_ATTR(total, 0644, qeth_dev_blkt_total_show,
548                    qeth_dev_blkt_total_store);
549
550 static ssize_t qeth_dev_blkt_inter_show(struct device *dev,
551                                 struct device_attribute *attr, char *buf)
552 {
553         struct qeth_card *card = dev_get_drvdata(dev);
554
555         return qeth_dev_blkt_show(buf, card, card->info.blkt.inter_packet);
556 }
557
558 static ssize_t qeth_dev_blkt_inter_store(struct device *dev,
559                 struct device_attribute *attr, const char *buf, size_t count)
560 {
561         struct qeth_card *card = dev_get_drvdata(dev);
562
563         return qeth_dev_blkt_store(card, buf, count,
564                                    &card->info.blkt.inter_packet, 1000);
565 }
566
567 static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,
568                    qeth_dev_blkt_inter_store);
569
570 static ssize_t qeth_dev_blkt_inter_jumbo_show(struct device *dev,
571                                 struct device_attribute *attr, char *buf)
572 {
573         struct qeth_card *card = dev_get_drvdata(dev);
574
575         return qeth_dev_blkt_show(buf, card,
576                                   card->info.blkt.inter_packet_jumbo);
577 }
578
579 static ssize_t qeth_dev_blkt_inter_jumbo_store(struct device *dev,
580                 struct device_attribute *attr, const char *buf, size_t count)
581 {
582         struct qeth_card *card = dev_get_drvdata(dev);
583
584         return qeth_dev_blkt_store(card, buf, count,
585                                    &card->info.blkt.inter_packet_jumbo, 1000);
586 }
587
588 static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show,
589                    qeth_dev_blkt_inter_jumbo_store);
590
591 static struct attribute *qeth_blkt_device_attrs[] = {
592         &dev_attr_total.attr,
593         &dev_attr_inter.attr,
594         &dev_attr_inter_jumbo.attr,
595         NULL,
596 };
597
598 static struct attribute_group qeth_device_blkt_group = {
599         .name = "blkt",
600         .attrs = qeth_blkt_device_attrs,
601 };
602
603 static struct attribute *qeth_device_attrs[] = {
604         &dev_attr_state.attr,
605         &dev_attr_chpid.attr,
606         &dev_attr_if_name.attr,
607         &dev_attr_card_type.attr,
608         &dev_attr_inbuf_size.attr,
609         &dev_attr_portno.attr,
610         &dev_attr_portname.attr,
611         &dev_attr_priority_queueing.attr,
612         &dev_attr_buffer_count.attr,
613         &dev_attr_recover.attr,
614         &dev_attr_performance_stats.attr,
615         &dev_attr_layer2.attr,
616         &dev_attr_isolation.attr,
617         NULL,
618 };
619
620 static struct attribute_group qeth_device_attr_group = {
621         .attrs = qeth_device_attrs,
622 };
623
624 static struct attribute *qeth_osn_device_attrs[] = {
625         &dev_attr_state.attr,
626         &dev_attr_chpid.attr,
627         &dev_attr_if_name.attr,
628         &dev_attr_card_type.attr,
629         &dev_attr_buffer_count.attr,
630         &dev_attr_recover.attr,
631         NULL,
632 };
633
634 static struct attribute_group qeth_osn_device_attr_group = {
635         .attrs = qeth_osn_device_attrs,
636 };
637
638 int qeth_core_create_device_attributes(struct device *dev)
639 {
640         int ret;
641         ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group);
642         if (ret)
643                 return ret;
644         ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group);
645         if (ret)
646                 sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
647
648         return 0;
649 }
650
651 void qeth_core_remove_device_attributes(struct device *dev)
652 {
653         sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
654         sysfs_remove_group(&dev->kobj, &qeth_device_blkt_group);
655 }
656
657 int qeth_core_create_osn_attributes(struct device *dev)
658 {
659         return sysfs_create_group(&dev->kobj, &qeth_osn_device_attr_group);
660 }
661
662 void qeth_core_remove_osn_attributes(struct device *dev)
663 {
664         sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group);
665         return;
666 }