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