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