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