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