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