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