ASoC: rt5514: make the volume TLV to match the units 0.01dB
[cascardo/linux.git] / drivers / s390 / net / qeth_l3_sys.c
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 #include <linux/slab.h>
10 #include <asm/ebcdic.h>
11 #include <linux/hashtable.h>
12 #include "qeth_l3.h"
13
14 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
15 struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
16
17 static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
18                         struct qeth_routing_info *route, char *buf)
19 {
20         switch (route->type) {
21         case PRIMARY_ROUTER:
22                 return sprintf(buf, "%s\n", "primary router");
23         case SECONDARY_ROUTER:
24                 return sprintf(buf, "%s\n", "secondary router");
25         case MULTICAST_ROUTER:
26                 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
27                         return sprintf(buf, "%s\n", "multicast router+");
28                 else
29                         return sprintf(buf, "%s\n", "multicast router");
30         case PRIMARY_CONNECTOR:
31                 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
32                         return sprintf(buf, "%s\n", "primary connector+");
33                 else
34                         return sprintf(buf, "%s\n", "primary connector");
35         case SECONDARY_CONNECTOR:
36                 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
37                         return sprintf(buf, "%s\n", "secondary connector+");
38                 else
39                         return sprintf(buf, "%s\n", "secondary connector");
40         default:
41                 return sprintf(buf, "%s\n", "no");
42         }
43 }
44
45 static ssize_t qeth_l3_dev_route4_show(struct device *dev,
46                         struct device_attribute *attr, char *buf)
47 {
48         struct qeth_card *card = dev_get_drvdata(dev);
49
50         if (!card)
51                 return -EINVAL;
52
53         return qeth_l3_dev_route_show(card, &card->options.route4, buf);
54 }
55
56 static ssize_t qeth_l3_dev_route_store(struct qeth_card *card,
57                 struct qeth_routing_info *route, enum qeth_prot_versions prot,
58                 const char *buf, size_t count)
59 {
60         enum qeth_routing_types old_route_type = route->type;
61         int rc = 0;
62
63         mutex_lock(&card->conf_mutex);
64         if (sysfs_streq(buf, "no_router")) {
65                 route->type = NO_ROUTER;
66         } else if (sysfs_streq(buf, "primary_connector")) {
67                 route->type = PRIMARY_CONNECTOR;
68         } else if (sysfs_streq(buf, "secondary_connector")) {
69                 route->type = SECONDARY_CONNECTOR;
70         } else if (sysfs_streq(buf, "primary_router")) {
71                 route->type = PRIMARY_ROUTER;
72         } else if (sysfs_streq(buf, "secondary_router")) {
73                 route->type = SECONDARY_ROUTER;
74         } else if (sysfs_streq(buf, "multicast_router")) {
75                 route->type = MULTICAST_ROUTER;
76         } else {
77                 rc = -EINVAL;
78                 goto out;
79         }
80         if (qeth_card_hw_is_reachable(card) &&
81             (old_route_type != route->type)) {
82                 if (prot == QETH_PROT_IPV4)
83                         rc = qeth_l3_setrouting_v4(card);
84                 else if (prot == QETH_PROT_IPV6)
85                         rc = qeth_l3_setrouting_v6(card);
86         }
87 out:
88         if (rc)
89                 route->type = old_route_type;
90         mutex_unlock(&card->conf_mutex);
91         return rc ? rc : count;
92 }
93
94 static ssize_t qeth_l3_dev_route4_store(struct device *dev,
95                 struct device_attribute *attr, const char *buf, size_t count)
96 {
97         struct qeth_card *card = dev_get_drvdata(dev);
98
99         if (!card)
100                 return -EINVAL;
101
102         return qeth_l3_dev_route_store(card, &card->options.route4,
103                                 QETH_PROT_IPV4, buf, count);
104 }
105
106 static DEVICE_ATTR(route4, 0644, qeth_l3_dev_route4_show,
107                         qeth_l3_dev_route4_store);
108
109 static ssize_t qeth_l3_dev_route6_show(struct device *dev,
110                         struct device_attribute *attr, char *buf)
111 {
112         struct qeth_card *card = dev_get_drvdata(dev);
113
114         if (!card)
115                 return -EINVAL;
116
117         return qeth_l3_dev_route_show(card, &card->options.route6, buf);
118 }
119
120 static ssize_t qeth_l3_dev_route6_store(struct device *dev,
121                 struct device_attribute *attr, const char *buf, size_t count)
122 {
123         struct qeth_card *card = dev_get_drvdata(dev);
124
125         if (!card)
126                 return -EINVAL;
127
128         return qeth_l3_dev_route_store(card, &card->options.route6,
129                                 QETH_PROT_IPV6, buf, count);
130 }
131
132 static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show,
133                         qeth_l3_dev_route6_store);
134
135 static ssize_t qeth_l3_dev_fake_broadcast_show(struct device *dev,
136                         struct device_attribute *attr, char *buf)
137 {
138         struct qeth_card *card = dev_get_drvdata(dev);
139
140         if (!card)
141                 return -EINVAL;
142
143         return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
144 }
145
146 static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev,
147                 struct device_attribute *attr, const char *buf, size_t count)
148 {
149         struct qeth_card *card = dev_get_drvdata(dev);
150         char *tmp;
151         int i, rc = 0;
152
153         if (!card)
154                 return -EINVAL;
155
156         mutex_lock(&card->conf_mutex);
157         if ((card->state != CARD_STATE_DOWN) &&
158             (card->state != CARD_STATE_RECOVER)) {
159                 rc = -EPERM;
160                 goto out;
161         }
162
163         i = simple_strtoul(buf, &tmp, 16);
164         if ((i == 0) || (i == 1))
165                 card->options.fake_broadcast = i;
166         else
167                 rc = -EINVAL;
168 out:
169         mutex_unlock(&card->conf_mutex);
170         return rc ? rc : count;
171 }
172
173 static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show,
174                    qeth_l3_dev_fake_broadcast_store);
175
176 static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
177                 struct device_attribute *attr, char *buf)
178 {
179         struct qeth_card *card = dev_get_drvdata(dev);
180
181         if (!card)
182                 return -EINVAL;
183
184         return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
185 }
186
187 static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
188                 struct device_attribute *attr, const char *buf, size_t count)
189 {
190         struct qeth_card *card = dev_get_drvdata(dev);
191         int rc = 0;
192         unsigned long i;
193
194         if (!card)
195                 return -EINVAL;
196
197         if (card->info.type != QETH_CARD_TYPE_IQD)
198                 return -EPERM;
199         if (card->options.cq == QETH_CQ_ENABLED)
200                 return -EPERM;
201
202         mutex_lock(&card->conf_mutex);
203         if ((card->state != CARD_STATE_DOWN) &&
204             (card->state != CARD_STATE_RECOVER)) {
205                 rc = -EPERM;
206                 goto out;
207         }
208
209         rc = kstrtoul(buf, 16, &i);
210         if (rc) {
211                 rc = -EINVAL;
212                 goto out;
213         }
214         switch (i) {
215         case 0:
216                 card->options.sniffer = i;
217                 break;
218         case 1:
219                 qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
220                 if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
221                         card->options.sniffer = i;
222                         if (card->qdio.init_pool.buf_count !=
223                                         QETH_IN_BUF_COUNT_MAX)
224                                 qeth_realloc_buffer_pool(card,
225                                         QETH_IN_BUF_COUNT_MAX);
226                 } else
227                         rc = -EPERM;
228                 break;
229         default:
230                 rc = -EINVAL;
231         }
232 out:
233         mutex_unlock(&card->conf_mutex);
234         return rc ? rc : count;
235 }
236
237 static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
238                 qeth_l3_dev_sniffer_store);
239
240
241 static ssize_t qeth_l3_dev_hsuid_show(struct device *dev,
242                 struct device_attribute *attr, char *buf)
243 {
244         struct qeth_card *card = dev_get_drvdata(dev);
245         char tmp_hsuid[9];
246
247         if (!card)
248                 return -EINVAL;
249
250         if (card->info.type != QETH_CARD_TYPE_IQD)
251                 return -EPERM;
252
253         if (card->state == CARD_STATE_DOWN)
254                 return -EPERM;
255
256         memcpy(tmp_hsuid, card->options.hsuid, sizeof(tmp_hsuid));
257         EBCASC(tmp_hsuid, 8);
258         return sprintf(buf, "%s\n", tmp_hsuid);
259 }
260
261 static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
262                 struct device_attribute *attr, const char *buf, size_t count)
263 {
264         struct qeth_card *card = dev_get_drvdata(dev);
265         struct qeth_ipaddr *addr;
266         char *tmp;
267         int i;
268
269         if (!card)
270                 return -EINVAL;
271
272         if (card->info.type != QETH_CARD_TYPE_IQD)
273                 return -EPERM;
274         if (card->state != CARD_STATE_DOWN &&
275             card->state != CARD_STATE_RECOVER)
276                 return -EPERM;
277         if (card->options.sniffer)
278                 return -EPERM;
279         if (card->options.cq == QETH_CQ_NOTAVAILABLE)
280                 return -EPERM;
281
282         tmp = strsep((char **)&buf, "\n");
283         if (strlen(tmp) > 8)
284                 return -EINVAL;
285
286         if (card->options.hsuid[0]) {
287                 /* delete old ip address */
288                 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
289                 if (!addr)
290                         return -ENOMEM;
291
292                 addr->u.a6.addr.s6_addr32[0] = 0xfe800000;
293                 addr->u.a6.addr.s6_addr32[1] = 0x00000000;
294                 for (i = 8; i < 16; i++)
295                         addr->u.a6.addr.s6_addr[i] =
296                                 card->options.hsuid[i - 8];
297                 addr->u.a6.pfxlen = 0;
298                 addr->type = QETH_IP_TYPE_NORMAL;
299
300                 qeth_l3_delete_ip(card, addr);
301                 kfree(addr);
302         }
303
304         if (strlen(tmp) == 0) {
305                 /* delete ip address only */
306                 card->options.hsuid[0] = '\0';
307                 if (card->dev)
308                         memcpy(card->dev->perm_addr, card->options.hsuid, 9);
309                 qeth_configure_cq(card, QETH_CQ_DISABLED);
310                 return count;
311         }
312
313         if (qeth_configure_cq(card, QETH_CQ_ENABLED))
314                 return -EPERM;
315
316         snprintf(card->options.hsuid, sizeof(card->options.hsuid),
317                  "%-8s", tmp);
318         ASCEBC(card->options.hsuid, 8);
319         if (card->dev)
320                 memcpy(card->dev->perm_addr, card->options.hsuid, 9);
321
322         addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
323         if (addr != NULL) {
324                 addr->u.a6.addr.s6_addr32[0] = 0xfe800000;
325                 addr->u.a6.addr.s6_addr32[1] = 0x00000000;
326                 for (i = 8; i < 16; i++)
327                         addr->u.a6.addr.s6_addr[i] = card->options.hsuid[i - 8];
328                 addr->u.a6.pfxlen = 0;
329                 addr->type = QETH_IP_TYPE_NORMAL;
330         } else
331                 return -ENOMEM;
332         qeth_l3_add_ip(card, addr);
333         kfree(addr);
334
335         return count;
336 }
337
338 static DEVICE_ATTR(hsuid, 0644, qeth_l3_dev_hsuid_show,
339                    qeth_l3_dev_hsuid_store);
340
341
342 static struct attribute *qeth_l3_device_attrs[] = {
343         &dev_attr_route4.attr,
344         &dev_attr_route6.attr,
345         &dev_attr_fake_broadcast.attr,
346         &dev_attr_sniffer.attr,
347         &dev_attr_hsuid.attr,
348         NULL,
349 };
350
351 static struct attribute_group qeth_l3_device_attr_group = {
352         .attrs = qeth_l3_device_attrs,
353 };
354
355 static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
356                         struct device_attribute *attr, char *buf)
357 {
358         struct qeth_card *card = dev_get_drvdata(dev);
359
360         if (!card)
361                 return -EINVAL;
362
363         return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
364 }
365
366 static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
367                 struct device_attribute *attr, const char *buf, size_t count)
368 {
369         struct qeth_card *card = dev_get_drvdata(dev);
370         struct qeth_ipaddr *addr;
371         int i, rc = 0;
372
373         if (!card)
374                 return -EINVAL;
375
376         mutex_lock(&card->conf_mutex);
377         if ((card->state != CARD_STATE_DOWN) &&
378             (card->state != CARD_STATE_RECOVER)) {
379                 rc = -EPERM;
380                 goto out;
381         }
382
383         if (sysfs_streq(buf, "toggle")) {
384                 card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
385         } else if (sysfs_streq(buf, "1")) {
386                 card->ipato.enabled = 1;
387                 hash_for_each(card->ip_htable, i, addr, hnode) {
388                                 if ((addr->type == QETH_IP_TYPE_NORMAL) &&
389                                 qeth_l3_is_addr_covered_by_ipato(card, addr))
390                                         addr->set_flags |=
391                                         QETH_IPA_SETIP_TAKEOVER_FLAG;
392                         }
393         } else if (sysfs_streq(buf, "0")) {
394                 card->ipato.enabled = 0;
395                 hash_for_each(card->ip_htable, i, addr, hnode) {
396                         if (addr->set_flags &
397                         QETH_IPA_SETIP_TAKEOVER_FLAG)
398                                 addr->set_flags &=
399                                 ~QETH_IPA_SETIP_TAKEOVER_FLAG;
400                         }
401         } else
402                 rc = -EINVAL;
403 out:
404         mutex_unlock(&card->conf_mutex);
405         return rc ? rc : count;
406 }
407
408 static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
409                         qeth_l3_dev_ipato_enable_show,
410                         qeth_l3_dev_ipato_enable_store);
411
412 static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
413                                 struct device_attribute *attr, char *buf)
414 {
415         struct qeth_card *card = dev_get_drvdata(dev);
416
417         if (!card)
418                 return -EINVAL;
419
420         return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
421 }
422
423 static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
424                                 struct device_attribute *attr,
425                                 const char *buf, size_t count)
426 {
427         struct qeth_card *card = dev_get_drvdata(dev);
428         int rc = 0;
429
430         if (!card)
431                 return -EINVAL;
432
433         mutex_lock(&card->conf_mutex);
434         if (sysfs_streq(buf, "toggle"))
435                 card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
436         else if (sysfs_streq(buf, "1"))
437                 card->ipato.invert4 = 1;
438         else if (sysfs_streq(buf, "0"))
439                 card->ipato.invert4 = 0;
440         else
441                 rc = -EINVAL;
442         mutex_unlock(&card->conf_mutex);
443         return rc ? rc : count;
444 }
445
446 static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
447                         qeth_l3_dev_ipato_invert4_show,
448                         qeth_l3_dev_ipato_invert4_store);
449
450 static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
451                         enum qeth_prot_versions proto)
452 {
453         struct qeth_ipato_entry *ipatoe;
454         char addr_str[40];
455         int entry_len; /* length of 1 entry string, differs between v4 and v6 */
456         int i = 0;
457
458         entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
459         /* add strlen for "/<mask>\n" */
460         entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
461         spin_lock_bh(&card->ip_lock);
462         list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
463                 if (ipatoe->proto != proto)
464                         continue;
465                 /* String must not be longer than PAGE_SIZE. So we check if
466                  * string length gets near PAGE_SIZE. Then we can savely display
467                  * the next IPv6 address (worst case, compared to IPv4) */
468                 if ((PAGE_SIZE - i) <= entry_len)
469                         break;
470                 qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
471                 i += snprintf(buf + i, PAGE_SIZE - i,
472                               "%s/%i\n", addr_str, ipatoe->mask_bits);
473         }
474         spin_unlock_bh(&card->ip_lock);
475         i += snprintf(buf + i, PAGE_SIZE - i, "\n");
476
477         return i;
478 }
479
480 static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
481                                 struct device_attribute *attr, char *buf)
482 {
483         struct qeth_card *card = dev_get_drvdata(dev);
484
485         if (!card)
486                 return -EINVAL;
487
488         return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
489 }
490
491 static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
492                   u8 *addr, int *mask_bits)
493 {
494         const char *start, *end;
495         char *tmp;
496         char buffer[40] = {0, };
497
498         start = buf;
499         /* get address string */
500         end = strchr(start, '/');
501         if (!end || (end - start >= 40)) {
502                 return -EINVAL;
503         }
504         strncpy(buffer, start, end - start);
505         if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
506                 return -EINVAL;
507         }
508         start = end + 1;
509         *mask_bits = simple_strtoul(start, &tmp, 10);
510         if (!strlen(start) ||
511             (tmp == start) ||
512             (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
513                 return -EINVAL;
514         }
515         return 0;
516 }
517
518 static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
519                          struct qeth_card *card, enum qeth_prot_versions proto)
520 {
521         struct qeth_ipato_entry *ipatoe;
522         u8 addr[16];
523         int mask_bits;
524         int rc = 0;
525
526         mutex_lock(&card->conf_mutex);
527         rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
528         if (rc)
529                 goto out;
530
531         ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
532         if (!ipatoe) {
533                 rc = -ENOMEM;
534                 goto out;
535         }
536         ipatoe->proto = proto;
537         memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
538         ipatoe->mask_bits = mask_bits;
539
540         rc = qeth_l3_add_ipato_entry(card, ipatoe);
541         if (rc)
542                 kfree(ipatoe);
543 out:
544         mutex_unlock(&card->conf_mutex);
545         return rc ? rc : count;
546 }
547
548 static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
549                 struct device_attribute *attr, const char *buf, size_t count)
550 {
551         struct qeth_card *card = dev_get_drvdata(dev);
552
553         if (!card)
554                 return -EINVAL;
555
556         return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
557 }
558
559 static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
560                         qeth_l3_dev_ipato_add4_show,
561                         qeth_l3_dev_ipato_add4_store);
562
563 static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
564                          struct qeth_card *card, enum qeth_prot_versions proto)
565 {
566         u8 addr[16];
567         int mask_bits;
568         int rc = 0;
569
570         mutex_lock(&card->conf_mutex);
571         rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
572         if (!rc)
573                 qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
574         mutex_unlock(&card->conf_mutex);
575         return rc ? rc : count;
576 }
577
578 static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
579                 struct device_attribute *attr, const char *buf, size_t count)
580 {
581         struct qeth_card *card = dev_get_drvdata(dev);
582
583         if (!card)
584                 return -EINVAL;
585
586         return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
587 }
588
589 static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
590                         qeth_l3_dev_ipato_del4_store);
591
592 static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
593                 struct device_attribute *attr, char *buf)
594 {
595         struct qeth_card *card = dev_get_drvdata(dev);
596
597         if (!card)
598                 return -EINVAL;
599
600         return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
601 }
602
603 static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
604                 struct device_attribute *attr, const char *buf, size_t count)
605 {
606         struct qeth_card *card = dev_get_drvdata(dev);
607         int rc = 0;
608
609         if (!card)
610                 return -EINVAL;
611
612         mutex_lock(&card->conf_mutex);
613         if (sysfs_streq(buf, "toggle"))
614                 card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
615         else if (sysfs_streq(buf, "1"))
616                 card->ipato.invert6 = 1;
617         else if (sysfs_streq(buf, "0"))
618                 card->ipato.invert6 = 0;
619         else
620                 rc = -EINVAL;
621         mutex_unlock(&card->conf_mutex);
622         return rc ? rc : count;
623 }
624
625 static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
626                         qeth_l3_dev_ipato_invert6_show,
627                         qeth_l3_dev_ipato_invert6_store);
628
629
630 static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
631                                 struct device_attribute *attr, char *buf)
632 {
633         struct qeth_card *card = dev_get_drvdata(dev);
634
635         if (!card)
636                 return -EINVAL;
637
638         return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
639 }
640
641 static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
642                 struct device_attribute *attr, const char *buf, size_t count)
643 {
644         struct qeth_card *card = dev_get_drvdata(dev);
645
646         if (!card)
647                 return -EINVAL;
648
649         return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
650 }
651
652 static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
653                         qeth_l3_dev_ipato_add6_show,
654                         qeth_l3_dev_ipato_add6_store);
655
656 static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
657                 struct device_attribute *attr, const char *buf, size_t count)
658 {
659         struct qeth_card *card = dev_get_drvdata(dev);
660
661         if (!card)
662                 return -EINVAL;
663
664         return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
665 }
666
667 static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
668                         qeth_l3_dev_ipato_del6_store);
669
670 static struct attribute *qeth_ipato_device_attrs[] = {
671         &dev_attr_ipato_enable.attr,
672         &dev_attr_ipato_invert4.attr,
673         &dev_attr_ipato_add4.attr,
674         &dev_attr_ipato_del4.attr,
675         &dev_attr_ipato_invert6.attr,
676         &dev_attr_ipato_add6.attr,
677         &dev_attr_ipato_del6.attr,
678         NULL,
679 };
680
681 static struct attribute_group qeth_device_ipato_group = {
682         .name = "ipa_takeover",
683         .attrs = qeth_ipato_device_attrs,
684 };
685
686 static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
687                         enum qeth_prot_versions proto)
688 {
689         struct qeth_ipaddr *ipaddr;
690         struct hlist_node  *tmp;
691         char addr_str[40];
692         int entry_len; /* length of 1 entry string, differs between v4 and v6 */
693         int i = 0;
694
695         entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
696         entry_len += 2; /* \n + terminator */
697         spin_lock_bh(&card->ip_lock);
698         hash_for_each_safe(card->ip_htable, i, tmp, ipaddr, hnode) {
699                 if (ipaddr->proto != proto)
700                         continue;
701                 if (ipaddr->type != QETH_IP_TYPE_VIPA)
702                         continue;
703                 /* String must not be longer than PAGE_SIZE. So we check if
704                  * string length gets near PAGE_SIZE. Then we can savely display
705                  * the next IPv6 address (worst case, compared to IPv4) */
706                 if ((PAGE_SIZE - i) <= entry_len)
707                         break;
708                 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
709                         addr_str);
710                 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
711         }
712         spin_unlock_bh(&card->ip_lock);
713         i += snprintf(buf + i, PAGE_SIZE - i, "\n");
714
715         return i;
716 }
717
718 static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
719                         struct device_attribute *attr, char *buf)
720 {
721         struct qeth_card *card = dev_get_drvdata(dev);
722
723         if (!card)
724                 return -EINVAL;
725
726         return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
727 }
728
729 static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
730                  u8 *addr)
731 {
732         if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
733                 return -EINVAL;
734         }
735         return 0;
736 }
737
738 static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
739                         struct qeth_card *card, enum qeth_prot_versions proto)
740 {
741         u8 addr[16] = {0, };
742         int rc;
743
744         mutex_lock(&card->conf_mutex);
745         rc = qeth_l3_parse_vipae(buf, proto, addr);
746         if (!rc)
747                 rc = qeth_l3_add_vipa(card, proto, addr);
748         mutex_unlock(&card->conf_mutex);
749         return rc ? rc : count;
750 }
751
752 static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
753                 struct device_attribute *attr, const char *buf, size_t count)
754 {
755         struct qeth_card *card = dev_get_drvdata(dev);
756
757         if (!card)
758                 return -EINVAL;
759
760         return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
761 }
762
763 static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
764                         qeth_l3_dev_vipa_add4_show,
765                         qeth_l3_dev_vipa_add4_store);
766
767 static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
768                          struct qeth_card *card, enum qeth_prot_versions proto)
769 {
770         u8 addr[16];
771         int rc;
772
773         mutex_lock(&card->conf_mutex);
774         rc = qeth_l3_parse_vipae(buf, proto, addr);
775         if (!rc)
776                 qeth_l3_del_vipa(card, proto, addr);
777         mutex_unlock(&card->conf_mutex);
778         return rc ? rc : count;
779 }
780
781 static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
782                 struct device_attribute *attr, const char *buf, size_t count)
783 {
784         struct qeth_card *card = dev_get_drvdata(dev);
785
786         if (!card)
787                 return -EINVAL;
788
789         return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
790 }
791
792 static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
793                         qeth_l3_dev_vipa_del4_store);
794
795 static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
796                                 struct device_attribute *attr, char *buf)
797 {
798         struct qeth_card *card = dev_get_drvdata(dev);
799
800         if (!card)
801                 return -EINVAL;
802
803         return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
804 }
805
806 static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
807                 struct device_attribute *attr, const char *buf, size_t count)
808 {
809         struct qeth_card *card = dev_get_drvdata(dev);
810
811         if (!card)
812                 return -EINVAL;
813
814         return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
815 }
816
817 static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
818                         qeth_l3_dev_vipa_add6_show,
819                         qeth_l3_dev_vipa_add6_store);
820
821 static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
822                 struct device_attribute *attr, const char *buf, size_t count)
823 {
824         struct qeth_card *card = dev_get_drvdata(dev);
825
826         if (!card)
827                 return -EINVAL;
828
829         return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
830 }
831
832 static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
833                         qeth_l3_dev_vipa_del6_store);
834
835 static struct attribute *qeth_vipa_device_attrs[] = {
836         &dev_attr_vipa_add4.attr,
837         &dev_attr_vipa_del4.attr,
838         &dev_attr_vipa_add6.attr,
839         &dev_attr_vipa_del6.attr,
840         NULL,
841 };
842
843 static struct attribute_group qeth_device_vipa_group = {
844         .name = "vipa",
845         .attrs = qeth_vipa_device_attrs,
846 };
847
848 static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
849                        enum qeth_prot_versions proto)
850 {
851         struct qeth_ipaddr *ipaddr;
852         struct hlist_node *tmp;
853         char addr_str[40];
854         int entry_len; /* length of 1 entry string, differs between v4 and v6 */
855         int i = 0;
856
857         entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
858         entry_len += 2; /* \n + terminator */
859         spin_lock_bh(&card->ip_lock);
860         hash_for_each_safe(card->ip_htable, i, tmp, ipaddr, hnode) {
861                 if (ipaddr->proto != proto)
862                         continue;
863                 if (ipaddr->type != QETH_IP_TYPE_RXIP)
864                         continue;
865                 /* String must not be longer than PAGE_SIZE. So we check if
866                  * string length gets near PAGE_SIZE. Then we can savely display
867                  * the next IPv6 address (worst case, compared to IPv4) */
868                 if ((PAGE_SIZE - i) <= entry_len)
869                         break;
870                 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
871                         addr_str);
872                 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
873         }
874         spin_unlock_bh(&card->ip_lock);
875         i += snprintf(buf + i, PAGE_SIZE - i, "\n");
876
877         return i;
878 }
879
880 static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
881                         struct device_attribute *attr, char *buf)
882 {
883         struct qeth_card *card = dev_get_drvdata(dev);
884
885         if (!card)
886                 return -EINVAL;
887
888         return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
889 }
890
891 static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
892                  u8 *addr)
893 {
894         if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
895                 return -EINVAL;
896         }
897         return 0;
898 }
899
900 static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
901                         struct qeth_card *card, enum qeth_prot_versions proto)
902 {
903         u8 addr[16] = {0, };
904         int rc;
905
906         mutex_lock(&card->conf_mutex);
907         rc = qeth_l3_parse_rxipe(buf, proto, addr);
908         if (!rc)
909                 rc = qeth_l3_add_rxip(card, proto, addr);
910         mutex_unlock(&card->conf_mutex);
911         return rc ? rc : count;
912 }
913
914 static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
915                 struct device_attribute *attr, const char *buf, size_t count)
916 {
917         struct qeth_card *card = dev_get_drvdata(dev);
918
919         if (!card)
920                 return -EINVAL;
921
922         return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
923 }
924
925 static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
926                         qeth_l3_dev_rxip_add4_show,
927                         qeth_l3_dev_rxip_add4_store);
928
929 static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
930                         struct qeth_card *card, enum qeth_prot_versions proto)
931 {
932         u8 addr[16];
933         int rc;
934
935         mutex_lock(&card->conf_mutex);
936         rc = qeth_l3_parse_rxipe(buf, proto, addr);
937         if (!rc)
938                 qeth_l3_del_rxip(card, proto, addr);
939         mutex_unlock(&card->conf_mutex);
940         return rc ? rc : count;
941 }
942
943 static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
944                 struct device_attribute *attr, const char *buf, size_t count)
945 {
946         struct qeth_card *card = dev_get_drvdata(dev);
947
948         if (!card)
949                 return -EINVAL;
950
951         return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
952 }
953
954 static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
955                         qeth_l3_dev_rxip_del4_store);
956
957 static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
958                 struct device_attribute *attr, char *buf)
959 {
960         struct qeth_card *card = dev_get_drvdata(dev);
961
962         if (!card)
963                 return -EINVAL;
964
965         return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
966 }
967
968 static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
969                 struct device_attribute *attr, const char *buf, size_t count)
970 {
971         struct qeth_card *card = dev_get_drvdata(dev);
972
973         if (!card)
974                 return -EINVAL;
975
976         return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
977 }
978
979 static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
980                         qeth_l3_dev_rxip_add6_show,
981                         qeth_l3_dev_rxip_add6_store);
982
983 static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
984                 struct device_attribute *attr, const char *buf, size_t count)
985 {
986         struct qeth_card *card = dev_get_drvdata(dev);
987
988         if (!card)
989                 return -EINVAL;
990
991         return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
992 }
993
994 static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
995                         qeth_l3_dev_rxip_del6_store);
996
997 static struct attribute *qeth_rxip_device_attrs[] = {
998         &dev_attr_rxip_add4.attr,
999         &dev_attr_rxip_del4.attr,
1000         &dev_attr_rxip_add6.attr,
1001         &dev_attr_rxip_del6.attr,
1002         NULL,
1003 };
1004
1005 static struct attribute_group qeth_device_rxip_group = {
1006         .name = "rxip",
1007         .attrs = qeth_rxip_device_attrs,
1008 };
1009
1010 int qeth_l3_create_device_attributes(struct device *dev)
1011 {
1012         int ret;
1013
1014         ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
1015         if (ret)
1016                 return ret;
1017
1018         ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
1019         if (ret) {
1020                 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1021                 return ret;
1022         }
1023
1024         ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1025         if (ret) {
1026                 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1027                 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1028                 return ret;
1029         }
1030
1031         ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1032         if (ret) {
1033                 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1034                 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1035                 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1036                 return ret;
1037         }
1038         return 0;
1039 }
1040
1041 void qeth_l3_remove_device_attributes(struct device *dev)
1042 {
1043         sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1044         sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1045         sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1046         sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
1047 }