]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/s390/net/qeth_l3_sys.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[mv-sheeva.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         enum qeth_checksum_types csum_type;
297         char *tmp;
298         int rc;
299
300         if (!card)
301                 return -EINVAL;
302
303         tmp = strsep((char **) &buf, "\n");
304         if (!strcmp(tmp, "sw_checksumming"))
305                 csum_type = SW_CHECKSUMMING;
306         else if (!strcmp(tmp, "hw_checksumming"))
307                 csum_type = HW_CHECKSUMMING;
308         else if (!strcmp(tmp, "no_checksumming"))
309                 csum_type = NO_CHECKSUMMING;
310         else
311                 return -EINVAL;
312
313         rc = qeth_l3_set_rx_csum(card, csum_type);
314         if (rc)
315                 return rc;
316         return count;
317 }
318
319 static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
320                 qeth_l3_dev_checksum_store);
321
322 static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
323                 struct device_attribute *attr, char *buf)
324 {
325         struct qeth_card *card = dev_get_drvdata(dev);
326
327         if (!card)
328                 return -EINVAL;
329
330         return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
331 }
332
333 static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
334                 struct device_attribute *attr, const char *buf, size_t count)
335 {
336         struct qeth_card *card = dev_get_drvdata(dev);
337         int ret;
338         unsigned long i;
339
340         if (!card)
341                 return -EINVAL;
342
343         if (card->info.type != QETH_CARD_TYPE_IQD)
344                 return -EPERM;
345
346         if ((card->state != CARD_STATE_DOWN) &&
347             (card->state != CARD_STATE_RECOVER))
348                 return -EPERM;
349
350         ret = strict_strtoul(buf, 16, &i);
351         if (ret)
352                 return -EINVAL;
353         switch (i) {
354         case 0:
355                 card->options.sniffer = i;
356                 break;
357         case 1:
358                 ret = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
359                 if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
360                         card->options.sniffer = i;
361                         if (card->qdio.init_pool.buf_count !=
362                                         QETH_IN_BUF_COUNT_MAX)
363                                 qeth_realloc_buffer_pool(card,
364                                         QETH_IN_BUF_COUNT_MAX);
365                         break;
366                 } else
367                         return -EPERM;
368         default:   /* fall through */
369                 return -EINVAL;
370         }
371         return count;
372 }
373
374 static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
375                 qeth_l3_dev_sniffer_store);
376
377 static ssize_t qeth_l3_dev_large_send_show(struct device *dev,
378                                 struct device_attribute *attr, char *buf)
379 {
380         struct qeth_card *card = dev_get_drvdata(dev);
381
382         if (!card)
383                 return -EINVAL;
384
385         switch (card->options.large_send) {
386         case QETH_LARGE_SEND_NO:
387                 return sprintf(buf, "%s\n", "no");
388         case QETH_LARGE_SEND_TSO:
389                 return sprintf(buf, "%s\n", "TSO");
390         default:
391                 return sprintf(buf, "%s\n", "N/A");
392         }
393 }
394
395 static ssize_t qeth_l3_dev_large_send_store(struct device *dev,
396                 struct device_attribute *attr, const char *buf, size_t count)
397 {
398         struct qeth_card *card = dev_get_drvdata(dev);
399         enum qeth_large_send_types type;
400         int rc = 0;
401         char *tmp;
402
403         if (!card)
404                 return -EINVAL;
405         tmp = strsep((char **) &buf, "\n");
406         if (!strcmp(tmp, "no"))
407                 type = QETH_LARGE_SEND_NO;
408         else if (!strcmp(tmp, "TSO"))
409                 type = QETH_LARGE_SEND_TSO;
410         else
411                 return -EINVAL;
412
413         if (card->options.large_send == type)
414                 return count;
415         rc = qeth_l3_set_large_send(card, type);
416         if (rc)
417                 return rc;
418         return count;
419 }
420
421 static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show,
422                    qeth_l3_dev_large_send_store);
423
424 static struct attribute *qeth_l3_device_attrs[] = {
425         &dev_attr_route4.attr,
426         &dev_attr_route6.attr,
427         &dev_attr_fake_broadcast.attr,
428         &dev_attr_broadcast_mode.attr,
429         &dev_attr_canonical_macaddr.attr,
430         &dev_attr_checksumming.attr,
431         &dev_attr_sniffer.attr,
432         &dev_attr_large_send.attr,
433         NULL,
434 };
435
436 static struct attribute_group qeth_l3_device_attr_group = {
437         .attrs = qeth_l3_device_attrs,
438 };
439
440 static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
441                         struct device_attribute *attr, char *buf)
442 {
443         struct qeth_card *card = dev_get_drvdata(dev);
444
445         if (!card)
446                 return -EINVAL;
447
448         return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
449 }
450
451 static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
452                 struct device_attribute *attr, const char *buf, size_t count)
453 {
454         struct qeth_card *card = dev_get_drvdata(dev);
455         char *tmp;
456
457         if (!card)
458                 return -EINVAL;
459
460         if ((card->state != CARD_STATE_DOWN) &&
461             (card->state != CARD_STATE_RECOVER))
462                 return -EPERM;
463
464         tmp = strsep((char **) &buf, "\n");
465         if (!strcmp(tmp, "toggle")) {
466                 card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
467         } else if (!strcmp(tmp, "1")) {
468                 card->ipato.enabled = 1;
469         } else if (!strcmp(tmp, "0")) {
470                 card->ipato.enabled = 0;
471         } else {
472                 return -EINVAL;
473         }
474         return count;
475 }
476
477 static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
478                         qeth_l3_dev_ipato_enable_show,
479                         qeth_l3_dev_ipato_enable_store);
480
481 static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
482                                 struct device_attribute *attr, char *buf)
483 {
484         struct qeth_card *card = dev_get_drvdata(dev);
485
486         if (!card)
487                 return -EINVAL;
488
489         return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
490 }
491
492 static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
493                                 struct device_attribute *attr,
494                                 const char *buf, size_t count)
495 {
496         struct qeth_card *card = dev_get_drvdata(dev);
497         char *tmp;
498
499         if (!card)
500                 return -EINVAL;
501
502         tmp = strsep((char **) &buf, "\n");
503         if (!strcmp(tmp, "toggle")) {
504                 card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
505         } else if (!strcmp(tmp, "1")) {
506                 card->ipato.invert4 = 1;
507         } else if (!strcmp(tmp, "0")) {
508                 card->ipato.invert4 = 0;
509         } else {
510                 return -EINVAL;
511         }
512         return count;
513 }
514
515 static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
516                         qeth_l3_dev_ipato_invert4_show,
517                         qeth_l3_dev_ipato_invert4_store);
518
519 static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
520                         enum qeth_prot_versions proto)
521 {
522         struct qeth_ipato_entry *ipatoe;
523         unsigned long flags;
524         char addr_str[40];
525         int entry_len; /* length of 1 entry string, differs between v4 and v6 */
526         int i = 0;
527
528         entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
529         /* add strlen for "/<mask>\n" */
530         entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
531         spin_lock_irqsave(&card->ip_lock, flags);
532         list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
533                 if (ipatoe->proto != proto)
534                         continue;
535                 /* String must not be longer than PAGE_SIZE. So we check if
536                  * string length gets near PAGE_SIZE. Then we can savely display
537                  * the next IPv6 address (worst case, compared to IPv4) */
538                 if ((PAGE_SIZE - i) <= entry_len)
539                         break;
540                 qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
541                 i += snprintf(buf + i, PAGE_SIZE - i,
542                               "%s/%i\n", addr_str, ipatoe->mask_bits);
543         }
544         spin_unlock_irqrestore(&card->ip_lock, flags);
545         i += snprintf(buf + i, PAGE_SIZE - i, "\n");
546
547         return i;
548 }
549
550 static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
551                                 struct device_attribute *attr, char *buf)
552 {
553         struct qeth_card *card = dev_get_drvdata(dev);
554
555         if (!card)
556                 return -EINVAL;
557
558         return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
559 }
560
561 static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
562                   u8 *addr, int *mask_bits)
563 {
564         const char *start, *end;
565         char *tmp;
566         char buffer[40] = {0, };
567
568         start = buf;
569         /* get address string */
570         end = strchr(start, '/');
571         if (!end || (end - start >= 40)) {
572                 return -EINVAL;
573         }
574         strncpy(buffer, start, end - start);
575         if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
576                 return -EINVAL;
577         }
578         start = end + 1;
579         *mask_bits = simple_strtoul(start, &tmp, 10);
580         if (!strlen(start) ||
581             (tmp == start) ||
582             (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
583                 return -EINVAL;
584         }
585         return 0;
586 }
587
588 static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
589                          struct qeth_card *card, enum qeth_prot_versions proto)
590 {
591         struct qeth_ipato_entry *ipatoe;
592         u8 addr[16];
593         int mask_bits;
594         int rc;
595
596         rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
597         if (rc)
598                 return rc;
599
600         ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
601         if (!ipatoe) {
602                 return -ENOMEM;
603         }
604         ipatoe->proto = proto;
605         memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
606         ipatoe->mask_bits = mask_bits;
607
608         rc = qeth_l3_add_ipato_entry(card, ipatoe);
609         if (rc) {
610                 kfree(ipatoe);
611                 return rc;
612         }
613
614         return count;
615 }
616
617 static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
618                 struct device_attribute *attr, const char *buf, size_t count)
619 {
620         struct qeth_card *card = dev_get_drvdata(dev);
621
622         if (!card)
623                 return -EINVAL;
624
625         return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
626 }
627
628 static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
629                         qeth_l3_dev_ipato_add4_show,
630                         qeth_l3_dev_ipato_add4_store);
631
632 static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
633                          struct qeth_card *card, enum qeth_prot_versions proto)
634 {
635         u8 addr[16];
636         int mask_bits;
637         int rc;
638
639         rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
640         if (rc)
641                 return rc;
642
643         qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
644
645         return count;
646 }
647
648 static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
649                 struct device_attribute *attr, const char *buf, size_t count)
650 {
651         struct qeth_card *card = dev_get_drvdata(dev);
652
653         if (!card)
654                 return -EINVAL;
655
656         return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
657 }
658
659 static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
660                         qeth_l3_dev_ipato_del4_store);
661
662 static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
663                 struct device_attribute *attr, char *buf)
664 {
665         struct qeth_card *card = dev_get_drvdata(dev);
666
667         if (!card)
668                 return -EINVAL;
669
670         return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
671 }
672
673 static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
674                 struct device_attribute *attr, const char *buf, size_t count)
675 {
676         struct qeth_card *card = dev_get_drvdata(dev);
677         char *tmp;
678
679         if (!card)
680                 return -EINVAL;
681
682         tmp = strsep((char **) &buf, "\n");
683         if (!strcmp(tmp, "toggle")) {
684                 card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
685         } else if (!strcmp(tmp, "1")) {
686                 card->ipato.invert6 = 1;
687         } else if (!strcmp(tmp, "0")) {
688                 card->ipato.invert6 = 0;
689         } else {
690                 return -EINVAL;
691         }
692         return count;
693 }
694
695 static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
696                         qeth_l3_dev_ipato_invert6_show,
697                         qeth_l3_dev_ipato_invert6_store);
698
699
700 static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
701                                 struct device_attribute *attr, char *buf)
702 {
703         struct qeth_card *card = dev_get_drvdata(dev);
704
705         if (!card)
706                 return -EINVAL;
707
708         return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
709 }
710
711 static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
712                 struct device_attribute *attr, const char *buf, size_t count)
713 {
714         struct qeth_card *card = dev_get_drvdata(dev);
715
716         if (!card)
717                 return -EINVAL;
718
719         return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
720 }
721
722 static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
723                         qeth_l3_dev_ipato_add6_show,
724                         qeth_l3_dev_ipato_add6_store);
725
726 static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
727                 struct device_attribute *attr, const char *buf, size_t count)
728 {
729         struct qeth_card *card = dev_get_drvdata(dev);
730
731         if (!card)
732                 return -EINVAL;
733
734         return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
735 }
736
737 static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
738                         qeth_l3_dev_ipato_del6_store);
739
740 static struct attribute *qeth_ipato_device_attrs[] = {
741         &dev_attr_ipato_enable.attr,
742         &dev_attr_ipato_invert4.attr,
743         &dev_attr_ipato_add4.attr,
744         &dev_attr_ipato_del4.attr,
745         &dev_attr_ipato_invert6.attr,
746         &dev_attr_ipato_add6.attr,
747         &dev_attr_ipato_del6.attr,
748         NULL,
749 };
750
751 static struct attribute_group qeth_device_ipato_group = {
752         .name = "ipa_takeover",
753         .attrs = qeth_ipato_device_attrs,
754 };
755
756 static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
757                         enum qeth_prot_versions proto)
758 {
759         struct qeth_ipaddr *ipaddr;
760         char addr_str[40];
761         int entry_len; /* length of 1 entry string, differs between v4 and v6 */
762         unsigned long flags;
763         int i = 0;
764
765         entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
766         entry_len += 2; /* \n + terminator */
767         spin_lock_irqsave(&card->ip_lock, flags);
768         list_for_each_entry(ipaddr, &card->ip_list, entry) {
769                 if (ipaddr->proto != proto)
770                         continue;
771                 if (ipaddr->type != QETH_IP_TYPE_VIPA)
772                         continue;
773                 /* String must not be longer than PAGE_SIZE. So we check if
774                  * string length gets near PAGE_SIZE. Then we can savely display
775                  * the next IPv6 address (worst case, compared to IPv4) */
776                 if ((PAGE_SIZE - i) <= entry_len)
777                         break;
778                 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
779                         addr_str);
780                 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
781         }
782         spin_unlock_irqrestore(&card->ip_lock, flags);
783         i += snprintf(buf + i, PAGE_SIZE - i, "\n");
784
785         return i;
786 }
787
788 static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
789                         struct device_attribute *attr, char *buf)
790 {
791         struct qeth_card *card = dev_get_drvdata(dev);
792
793         if (!card)
794                 return -EINVAL;
795
796         return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
797 }
798
799 static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
800                  u8 *addr)
801 {
802         if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
803                 return -EINVAL;
804         }
805         return 0;
806 }
807
808 static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
809                         struct qeth_card *card, enum qeth_prot_versions proto)
810 {
811         u8 addr[16] = {0, };
812         int rc;
813
814         rc = qeth_l3_parse_vipae(buf, proto, addr);
815         if (rc)
816                 return rc;
817
818         rc = qeth_l3_add_vipa(card, proto, addr);
819         if (rc)
820                 return rc;
821
822         return count;
823 }
824
825 static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
826                 struct device_attribute *attr, const char *buf, size_t count)
827 {
828         struct qeth_card *card = dev_get_drvdata(dev);
829
830         if (!card)
831                 return -EINVAL;
832
833         return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
834 }
835
836 static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
837                         qeth_l3_dev_vipa_add4_show,
838                         qeth_l3_dev_vipa_add4_store);
839
840 static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
841                          struct qeth_card *card, enum qeth_prot_versions proto)
842 {
843         u8 addr[16];
844         int rc;
845
846         rc = qeth_l3_parse_vipae(buf, proto, addr);
847         if (rc)
848                 return rc;
849
850         qeth_l3_del_vipa(card, proto, addr);
851
852         return count;
853 }
854
855 static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
856                 struct device_attribute *attr, const char *buf, size_t count)
857 {
858         struct qeth_card *card = dev_get_drvdata(dev);
859
860         if (!card)
861                 return -EINVAL;
862
863         return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
864 }
865
866 static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
867                         qeth_l3_dev_vipa_del4_store);
868
869 static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
870                                 struct device_attribute *attr, char *buf)
871 {
872         struct qeth_card *card = dev_get_drvdata(dev);
873
874         if (!card)
875                 return -EINVAL;
876
877         return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
878 }
879
880 static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
881                 struct device_attribute *attr, const char *buf, size_t count)
882 {
883         struct qeth_card *card = dev_get_drvdata(dev);
884
885         if (!card)
886                 return -EINVAL;
887
888         return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
889 }
890
891 static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
892                         qeth_l3_dev_vipa_add6_show,
893                         qeth_l3_dev_vipa_add6_store);
894
895 static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
896                 struct device_attribute *attr, const char *buf, size_t count)
897 {
898         struct qeth_card *card = dev_get_drvdata(dev);
899
900         if (!card)
901                 return -EINVAL;
902
903         return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
904 }
905
906 static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
907                         qeth_l3_dev_vipa_del6_store);
908
909 static struct attribute *qeth_vipa_device_attrs[] = {
910         &dev_attr_vipa_add4.attr,
911         &dev_attr_vipa_del4.attr,
912         &dev_attr_vipa_add6.attr,
913         &dev_attr_vipa_del6.attr,
914         NULL,
915 };
916
917 static struct attribute_group qeth_device_vipa_group = {
918         .name = "vipa",
919         .attrs = qeth_vipa_device_attrs,
920 };
921
922 static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
923                        enum qeth_prot_versions proto)
924 {
925         struct qeth_ipaddr *ipaddr;
926         char addr_str[40];
927         int entry_len; /* length of 1 entry string, differs between v4 and v6 */
928         unsigned long flags;
929         int i = 0;
930
931         entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
932         entry_len += 2; /* \n + terminator */
933         spin_lock_irqsave(&card->ip_lock, flags);
934         list_for_each_entry(ipaddr, &card->ip_list, entry) {
935                 if (ipaddr->proto != proto)
936                         continue;
937                 if (ipaddr->type != QETH_IP_TYPE_RXIP)
938                         continue;
939                 /* String must not be longer than PAGE_SIZE. So we check if
940                  * string length gets near PAGE_SIZE. Then we can savely display
941                  * the next IPv6 address (worst case, compared to IPv4) */
942                 if ((PAGE_SIZE - i) <= entry_len)
943                         break;
944                 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
945                         addr_str);
946                 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
947         }
948         spin_unlock_irqrestore(&card->ip_lock, flags);
949         i += snprintf(buf + i, PAGE_SIZE - i, "\n");
950
951         return i;
952 }
953
954 static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
955                         struct device_attribute *attr, char *buf)
956 {
957         struct qeth_card *card = dev_get_drvdata(dev);
958
959         if (!card)
960                 return -EINVAL;
961
962         return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
963 }
964
965 static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
966                  u8 *addr)
967 {
968         if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
969                 return -EINVAL;
970         }
971         return 0;
972 }
973
974 static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
975                         struct qeth_card *card, enum qeth_prot_versions proto)
976 {
977         u8 addr[16] = {0, };
978         int rc;
979
980         rc = qeth_l3_parse_rxipe(buf, proto, addr);
981         if (rc)
982                 return rc;
983
984         rc = qeth_l3_add_rxip(card, proto, addr);
985         if (rc)
986                 return rc;
987
988         return count;
989 }
990
991 static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
992                 struct device_attribute *attr, const char *buf, size_t count)
993 {
994         struct qeth_card *card = dev_get_drvdata(dev);
995
996         if (!card)
997                 return -EINVAL;
998
999         return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
1000 }
1001
1002 static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
1003                         qeth_l3_dev_rxip_add4_show,
1004                         qeth_l3_dev_rxip_add4_store);
1005
1006 static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
1007                         struct qeth_card *card, enum qeth_prot_versions proto)
1008 {
1009         u8 addr[16];
1010         int rc;
1011
1012         rc = qeth_l3_parse_rxipe(buf, proto, addr);
1013         if (rc)
1014                 return rc;
1015
1016         qeth_l3_del_rxip(card, proto, addr);
1017
1018         return count;
1019 }
1020
1021 static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
1022                 struct device_attribute *attr, const char *buf, size_t count)
1023 {
1024         struct qeth_card *card = dev_get_drvdata(dev);
1025
1026         if (!card)
1027                 return -EINVAL;
1028
1029         return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
1030 }
1031
1032 static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
1033                         qeth_l3_dev_rxip_del4_store);
1034
1035 static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
1036                 struct device_attribute *attr, char *buf)
1037 {
1038         struct qeth_card *card = dev_get_drvdata(dev);
1039
1040         if (!card)
1041                 return -EINVAL;
1042
1043         return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
1044 }
1045
1046 static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
1047                 struct device_attribute *attr, const char *buf, size_t count)
1048 {
1049         struct qeth_card *card = dev_get_drvdata(dev);
1050
1051         if (!card)
1052                 return -EINVAL;
1053
1054         return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
1055 }
1056
1057 static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
1058                         qeth_l3_dev_rxip_add6_show,
1059                         qeth_l3_dev_rxip_add6_store);
1060
1061 static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
1062                 struct device_attribute *attr, const char *buf, size_t count)
1063 {
1064         struct qeth_card *card = dev_get_drvdata(dev);
1065
1066         if (!card)
1067                 return -EINVAL;
1068
1069         return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
1070 }
1071
1072 static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
1073                         qeth_l3_dev_rxip_del6_store);
1074
1075 static struct attribute *qeth_rxip_device_attrs[] = {
1076         &dev_attr_rxip_add4.attr,
1077         &dev_attr_rxip_del4.attr,
1078         &dev_attr_rxip_add6.attr,
1079         &dev_attr_rxip_del6.attr,
1080         NULL,
1081 };
1082
1083 static struct attribute_group qeth_device_rxip_group = {
1084         .name = "rxip",
1085         .attrs = qeth_rxip_device_attrs,
1086 };
1087
1088 int qeth_l3_create_device_attributes(struct device *dev)
1089 {
1090         int ret;
1091
1092         ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
1093         if (ret)
1094                 return ret;
1095
1096         ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
1097         if (ret) {
1098                 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1099                 return ret;
1100         }
1101
1102         ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1103         if (ret) {
1104                 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1105                 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1106                 return ret;
1107         }
1108
1109         ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1110         if (ret) {
1111                 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1112                 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1113                 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1114                 return ret;
1115         }
1116         return 0;
1117 }
1118
1119 void qeth_l3_remove_device_attributes(struct device *dev)
1120 {
1121         sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1122         sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1123         sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1124         sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
1125 }