Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
[linux/fpc-iii.git] / drivers / s390 / net / qeth_l3_sys.c
blobfb5318b30e99bfe849602fa127bbf1a1ffe83336
1 /*
2 * drivers/s390/net/qeth_l3_sys.c
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 */
11 #include <linux/slab.h>
13 #include "qeth_l3.h"
15 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
16 struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
18 static const char *qeth_l3_get_checksum_str(struct qeth_card *card)
20 if (card->options.checksum_type == SW_CHECKSUMMING)
21 return "sw";
22 else if (card->options.checksum_type == HW_CHECKSUMMING)
23 return "hw";
24 else
25 return "no";
28 static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
29 struct qeth_routing_info *route, char *buf)
31 switch (route->type) {
32 case PRIMARY_ROUTER:
33 return sprintf(buf, "%s\n", "primary router");
34 case SECONDARY_ROUTER:
35 return sprintf(buf, "%s\n", "secondary router");
36 case MULTICAST_ROUTER:
37 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
38 return sprintf(buf, "%s\n", "multicast router+");
39 else
40 return sprintf(buf, "%s\n", "multicast router");
41 case PRIMARY_CONNECTOR:
42 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
43 return sprintf(buf, "%s\n", "primary connector+");
44 else
45 return sprintf(buf, "%s\n", "primary connector");
46 case SECONDARY_CONNECTOR:
47 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
48 return sprintf(buf, "%s\n", "secondary connector+");
49 else
50 return sprintf(buf, "%s\n", "secondary connector");
51 default:
52 return sprintf(buf, "%s\n", "no");
56 static ssize_t qeth_l3_dev_route4_show(struct device *dev,
57 struct device_attribute *attr, char *buf)
59 struct qeth_card *card = dev_get_drvdata(dev);
61 if (!card)
62 return -EINVAL;
64 return qeth_l3_dev_route_show(card, &card->options.route4, buf);
67 static ssize_t qeth_l3_dev_route_store(struct qeth_card *card,
68 struct qeth_routing_info *route, enum qeth_prot_versions prot,
69 const char *buf, size_t count)
71 enum qeth_routing_types old_route_type = route->type;
72 char *tmp;
73 int rc = 0;
75 tmp = strsep((char **) &buf, "\n");
76 mutex_lock(&card->conf_mutex);
77 if (!strcmp(tmp, "no_router")) {
78 route->type = NO_ROUTER;
79 } else if (!strcmp(tmp, "primary_connector")) {
80 route->type = PRIMARY_CONNECTOR;
81 } else if (!strcmp(tmp, "secondary_connector")) {
82 route->type = SECONDARY_CONNECTOR;
83 } else if (!strcmp(tmp, "primary_router")) {
84 route->type = PRIMARY_ROUTER;
85 } else if (!strcmp(tmp, "secondary_router")) {
86 route->type = SECONDARY_ROUTER;
87 } else if (!strcmp(tmp, "multicast_router")) {
88 route->type = MULTICAST_ROUTER;
89 } else {
90 rc = -EINVAL;
91 goto out;
93 if (((card->state == CARD_STATE_SOFTSETUP) ||
94 (card->state == CARD_STATE_UP)) &&
95 (old_route_type != route->type)) {
96 if (prot == QETH_PROT_IPV4)
97 rc = qeth_l3_setrouting_v4(card);
98 else if (prot == QETH_PROT_IPV6)
99 rc = qeth_l3_setrouting_v6(card);
101 out:
102 mutex_unlock(&card->conf_mutex);
103 return rc ? rc : count;
106 static ssize_t qeth_l3_dev_route4_store(struct device *dev,
107 struct device_attribute *attr, const char *buf, size_t count)
109 struct qeth_card *card = dev_get_drvdata(dev);
111 if (!card)
112 return -EINVAL;
114 return qeth_l3_dev_route_store(card, &card->options.route4,
115 QETH_PROT_IPV4, buf, count);
118 static DEVICE_ATTR(route4, 0644, qeth_l3_dev_route4_show,
119 qeth_l3_dev_route4_store);
121 static ssize_t qeth_l3_dev_route6_show(struct device *dev,
122 struct device_attribute *attr, char *buf)
124 struct qeth_card *card = dev_get_drvdata(dev);
126 if (!card)
127 return -EINVAL;
129 return qeth_l3_dev_route_show(card, &card->options.route6, buf);
132 static ssize_t qeth_l3_dev_route6_store(struct device *dev,
133 struct device_attribute *attr, const char *buf, size_t count)
135 struct qeth_card *card = dev_get_drvdata(dev);
137 if (!card)
138 return -EINVAL;
140 return qeth_l3_dev_route_store(card, &card->options.route6,
141 QETH_PROT_IPV6, buf, count);
144 static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show,
145 qeth_l3_dev_route6_store);
147 static ssize_t qeth_l3_dev_fake_broadcast_show(struct device *dev,
148 struct device_attribute *attr, char *buf)
150 struct qeth_card *card = dev_get_drvdata(dev);
152 if (!card)
153 return -EINVAL;
155 return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
158 static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev,
159 struct device_attribute *attr, const char *buf, size_t count)
161 struct qeth_card *card = dev_get_drvdata(dev);
162 char *tmp;
163 int i, rc = 0;
165 if (!card)
166 return -EINVAL;
168 mutex_lock(&card->conf_mutex);
169 if ((card->state != CARD_STATE_DOWN) &&
170 (card->state != CARD_STATE_RECOVER)) {
171 rc = -EPERM;
172 goto out;
175 i = simple_strtoul(buf, &tmp, 16);
176 if ((i == 0) || (i == 1))
177 card->options.fake_broadcast = i;
178 else
179 rc = -EINVAL;
180 out:
181 mutex_unlock(&card->conf_mutex);
182 return rc ? rc : count;
185 static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show,
186 qeth_l3_dev_fake_broadcast_store);
188 static ssize_t qeth_l3_dev_broadcast_mode_show(struct device *dev,
189 struct device_attribute *attr, char *buf)
191 struct qeth_card *card = dev_get_drvdata(dev);
193 if (!card)
194 return -EINVAL;
196 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
197 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
198 return sprintf(buf, "n/a\n");
200 return sprintf(buf, "%s\n", (card->options.broadcast_mode ==
201 QETH_TR_BROADCAST_ALLRINGS)?
202 "all rings":"local");
205 static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev,
206 struct device_attribute *attr, const char *buf, size_t count)
208 struct qeth_card *card = dev_get_drvdata(dev);
209 char *tmp;
210 int rc = 0;
212 if (!card)
213 return -EINVAL;
215 mutex_lock(&card->conf_mutex);
216 if ((card->state != CARD_STATE_DOWN) &&
217 (card->state != CARD_STATE_RECOVER)) {
218 rc = -EPERM;
219 goto out;
222 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
223 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
224 rc = -EINVAL;
225 goto out;
228 tmp = strsep((char **) &buf, "\n");
230 if (!strcmp(tmp, "local"))
231 card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL;
232 else if (!strcmp(tmp, "all_rings"))
233 card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
234 else
235 rc = -EINVAL;
236 out:
237 mutex_unlock(&card->conf_mutex);
238 return rc ? rc : count;
241 static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show,
242 qeth_l3_dev_broadcast_mode_store);
244 static ssize_t qeth_l3_dev_canonical_macaddr_show(struct device *dev,
245 struct device_attribute *attr, char *buf)
247 struct qeth_card *card = dev_get_drvdata(dev);
249 if (!card)
250 return -EINVAL;
252 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
253 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
254 return sprintf(buf, "n/a\n");
256 return sprintf(buf, "%i\n", (card->options.macaddr_mode ==
257 QETH_TR_MACADDR_CANONICAL)? 1:0);
260 static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev,
261 struct device_attribute *attr, const char *buf, size_t count)
263 struct qeth_card *card = dev_get_drvdata(dev);
264 char *tmp;
265 int i, rc = 0;
267 if (!card)
268 return -EINVAL;
270 mutex_lock(&card->conf_mutex);
271 if ((card->state != CARD_STATE_DOWN) &&
272 (card->state != CARD_STATE_RECOVER)) {
273 rc = -EPERM;
274 goto out;
277 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
278 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
279 rc = -EINVAL;
280 goto out;
283 i = simple_strtoul(buf, &tmp, 16);
284 if ((i == 0) || (i == 1))
285 card->options.macaddr_mode = i?
286 QETH_TR_MACADDR_CANONICAL :
287 QETH_TR_MACADDR_NONCANONICAL;
288 else
289 rc = -EINVAL;
290 out:
291 mutex_unlock(&card->conf_mutex);
292 return rc ? rc : count;
295 static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show,
296 qeth_l3_dev_canonical_macaddr_store);
298 static ssize_t qeth_l3_dev_checksum_show(struct device *dev,
299 struct device_attribute *attr, char *buf)
301 struct qeth_card *card = dev_get_drvdata(dev);
303 if (!card)
304 return -EINVAL;
306 return sprintf(buf, "%s checksumming\n",
307 qeth_l3_get_checksum_str(card));
310 static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
311 struct device_attribute *attr, const char *buf, size_t count)
313 struct qeth_card *card = dev_get_drvdata(dev);
314 enum qeth_checksum_types csum_type;
315 char *tmp;
316 int rc = 0;
318 if (!card)
319 return -EINVAL;
321 mutex_lock(&card->conf_mutex);
322 tmp = strsep((char **) &buf, "\n");
323 if (!strcmp(tmp, "sw_checksumming"))
324 csum_type = SW_CHECKSUMMING;
325 else if (!strcmp(tmp, "hw_checksumming"))
326 csum_type = HW_CHECKSUMMING;
327 else if (!strcmp(tmp, "no_checksumming"))
328 csum_type = NO_CHECKSUMMING;
329 else {
330 rc = -EINVAL;
331 goto out;
334 rc = qeth_l3_set_rx_csum(card, csum_type);
335 out:
336 mutex_unlock(&card->conf_mutex);
337 return rc ? rc : count;
340 static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
341 qeth_l3_dev_checksum_store);
343 static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
344 struct device_attribute *attr, char *buf)
346 struct qeth_card *card = dev_get_drvdata(dev);
348 if (!card)
349 return -EINVAL;
351 return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
354 static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
355 struct device_attribute *attr, const char *buf, size_t count)
357 struct qeth_card *card = dev_get_drvdata(dev);
358 int rc = 0;
359 unsigned long i;
361 if (!card)
362 return -EINVAL;
364 if (card->info.type != QETH_CARD_TYPE_IQD)
365 return -EPERM;
367 mutex_lock(&card->conf_mutex);
368 if ((card->state != CARD_STATE_DOWN) &&
369 (card->state != CARD_STATE_RECOVER)) {
370 rc = -EPERM;
371 goto out;
374 rc = strict_strtoul(buf, 16, &i);
375 if (rc) {
376 rc = -EINVAL;
377 goto out;
379 switch (i) {
380 case 0:
381 card->options.sniffer = i;
382 break;
383 case 1:
384 qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
385 if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
386 card->options.sniffer = i;
387 if (card->qdio.init_pool.buf_count !=
388 QETH_IN_BUF_COUNT_MAX)
389 qeth_realloc_buffer_pool(card,
390 QETH_IN_BUF_COUNT_MAX);
391 break;
392 } else
393 rc = -EPERM;
394 default: /* fall through */
395 rc = -EINVAL;
397 out:
398 mutex_unlock(&card->conf_mutex);
399 return rc ? rc : count;
402 static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
403 qeth_l3_dev_sniffer_store);
405 static ssize_t qeth_l3_dev_large_send_show(struct device *dev,
406 struct device_attribute *attr, char *buf)
408 struct qeth_card *card = dev_get_drvdata(dev);
410 if (!card)
411 return -EINVAL;
413 switch (card->options.large_send) {
414 case QETH_LARGE_SEND_NO:
415 return sprintf(buf, "%s\n", "no");
416 case QETH_LARGE_SEND_TSO:
417 return sprintf(buf, "%s\n", "TSO");
418 default:
419 return sprintf(buf, "%s\n", "N/A");
423 static ssize_t qeth_l3_dev_large_send_store(struct device *dev,
424 struct device_attribute *attr, const char *buf, size_t count)
426 struct qeth_card *card = dev_get_drvdata(dev);
427 enum qeth_large_send_types type;
428 int rc = 0;
429 char *tmp;
431 if (!card)
432 return -EINVAL;
433 tmp = strsep((char **) &buf, "\n");
434 if (!strcmp(tmp, "no"))
435 type = QETH_LARGE_SEND_NO;
436 else if (!strcmp(tmp, "TSO"))
437 type = QETH_LARGE_SEND_TSO;
438 else
439 return -EINVAL;
441 mutex_lock(&card->conf_mutex);
442 if (card->options.large_send != type)
443 rc = qeth_l3_set_large_send(card, type);
444 mutex_unlock(&card->conf_mutex);
445 return rc ? rc : count;
448 static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show,
449 qeth_l3_dev_large_send_store);
451 static struct attribute *qeth_l3_device_attrs[] = {
452 &dev_attr_route4.attr,
453 &dev_attr_route6.attr,
454 &dev_attr_fake_broadcast.attr,
455 &dev_attr_broadcast_mode.attr,
456 &dev_attr_canonical_macaddr.attr,
457 &dev_attr_checksumming.attr,
458 &dev_attr_sniffer.attr,
459 &dev_attr_large_send.attr,
460 NULL,
463 static struct attribute_group qeth_l3_device_attr_group = {
464 .attrs = qeth_l3_device_attrs,
467 static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
468 struct device_attribute *attr, char *buf)
470 struct qeth_card *card = dev_get_drvdata(dev);
472 if (!card)
473 return -EINVAL;
475 return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
478 static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
479 struct device_attribute *attr, const char *buf, size_t count)
481 struct qeth_card *card = dev_get_drvdata(dev);
482 char *tmp;
483 int rc = 0;
485 if (!card)
486 return -EINVAL;
488 mutex_lock(&card->conf_mutex);
489 if ((card->state != CARD_STATE_DOWN) &&
490 (card->state != CARD_STATE_RECOVER)) {
491 rc = -EPERM;
492 goto out;
495 tmp = strsep((char **) &buf, "\n");
496 if (!strcmp(tmp, "toggle")) {
497 card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
498 } else if (!strcmp(tmp, "1")) {
499 card->ipato.enabled = 1;
500 } else if (!strcmp(tmp, "0")) {
501 card->ipato.enabled = 0;
502 } else
503 rc = -EINVAL;
504 out:
505 mutex_unlock(&card->conf_mutex);
506 return rc ? rc : count;
509 static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
510 qeth_l3_dev_ipato_enable_show,
511 qeth_l3_dev_ipato_enable_store);
513 static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
514 struct device_attribute *attr, char *buf)
516 struct qeth_card *card = dev_get_drvdata(dev);
518 if (!card)
519 return -EINVAL;
521 return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
524 static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
525 struct device_attribute *attr,
526 const char *buf, size_t count)
528 struct qeth_card *card = dev_get_drvdata(dev);
529 char *tmp;
530 int rc = 0;
532 if (!card)
533 return -EINVAL;
535 mutex_lock(&card->conf_mutex);
536 tmp = strsep((char **) &buf, "\n");
537 if (!strcmp(tmp, "toggle")) {
538 card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
539 } else if (!strcmp(tmp, "1")) {
540 card->ipato.invert4 = 1;
541 } else if (!strcmp(tmp, "0")) {
542 card->ipato.invert4 = 0;
543 } else
544 rc = -EINVAL;
545 mutex_unlock(&card->conf_mutex);
546 return rc ? rc : count;
549 static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
550 qeth_l3_dev_ipato_invert4_show,
551 qeth_l3_dev_ipato_invert4_store);
553 static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
554 enum qeth_prot_versions proto)
556 struct qeth_ipato_entry *ipatoe;
557 unsigned long flags;
558 char addr_str[40];
559 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
560 int i = 0;
562 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
563 /* add strlen for "/<mask>\n" */
564 entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
565 spin_lock_irqsave(&card->ip_lock, flags);
566 list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
567 if (ipatoe->proto != proto)
568 continue;
569 /* String must not be longer than PAGE_SIZE. So we check if
570 * string length gets near PAGE_SIZE. Then we can savely display
571 * the next IPv6 address (worst case, compared to IPv4) */
572 if ((PAGE_SIZE - i) <= entry_len)
573 break;
574 qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
575 i += snprintf(buf + i, PAGE_SIZE - i,
576 "%s/%i\n", addr_str, ipatoe->mask_bits);
578 spin_unlock_irqrestore(&card->ip_lock, flags);
579 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
581 return i;
584 static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
585 struct device_attribute *attr, char *buf)
587 struct qeth_card *card = dev_get_drvdata(dev);
589 if (!card)
590 return -EINVAL;
592 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
595 static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
596 u8 *addr, int *mask_bits)
598 const char *start, *end;
599 char *tmp;
600 char buffer[40] = {0, };
602 start = buf;
603 /* get address string */
604 end = strchr(start, '/');
605 if (!end || (end - start >= 40)) {
606 return -EINVAL;
608 strncpy(buffer, start, end - start);
609 if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
610 return -EINVAL;
612 start = end + 1;
613 *mask_bits = simple_strtoul(start, &tmp, 10);
614 if (!strlen(start) ||
615 (tmp == start) ||
616 (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
617 return -EINVAL;
619 return 0;
622 static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
623 struct qeth_card *card, enum qeth_prot_versions proto)
625 struct qeth_ipato_entry *ipatoe;
626 u8 addr[16];
627 int mask_bits;
628 int rc = 0;
630 mutex_lock(&card->conf_mutex);
631 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
632 if (rc)
633 goto out;
635 ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
636 if (!ipatoe) {
637 rc = -ENOMEM;
638 goto out;
640 ipatoe->proto = proto;
641 memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
642 ipatoe->mask_bits = mask_bits;
644 rc = qeth_l3_add_ipato_entry(card, ipatoe);
645 if (rc)
646 kfree(ipatoe);
647 out:
648 mutex_unlock(&card->conf_mutex);
649 return rc ? rc : count;
652 static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
653 struct device_attribute *attr, const char *buf, size_t count)
655 struct qeth_card *card = dev_get_drvdata(dev);
657 if (!card)
658 return -EINVAL;
660 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
663 static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
664 qeth_l3_dev_ipato_add4_show,
665 qeth_l3_dev_ipato_add4_store);
667 static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
668 struct qeth_card *card, enum qeth_prot_versions proto)
670 u8 addr[16];
671 int mask_bits;
672 int rc = 0;
674 mutex_lock(&card->conf_mutex);
675 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
676 if (!rc)
677 qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
678 mutex_unlock(&card->conf_mutex);
679 return rc ? rc : count;
682 static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
683 struct device_attribute *attr, const char *buf, size_t count)
685 struct qeth_card *card = dev_get_drvdata(dev);
687 if (!card)
688 return -EINVAL;
690 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
693 static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
694 qeth_l3_dev_ipato_del4_store);
696 static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
697 struct device_attribute *attr, char *buf)
699 struct qeth_card *card = dev_get_drvdata(dev);
701 if (!card)
702 return -EINVAL;
704 return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
707 static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
708 struct device_attribute *attr, const char *buf, size_t count)
710 struct qeth_card *card = dev_get_drvdata(dev);
711 char *tmp;
712 int rc = 0;
714 if (!card)
715 return -EINVAL;
717 mutex_lock(&card->conf_mutex);
718 tmp = strsep((char **) &buf, "\n");
719 if (!strcmp(tmp, "toggle")) {
720 card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
721 } else if (!strcmp(tmp, "1")) {
722 card->ipato.invert6 = 1;
723 } else if (!strcmp(tmp, "0")) {
724 card->ipato.invert6 = 0;
725 } else
726 rc = -EINVAL;
727 mutex_unlock(&card->conf_mutex);
728 return rc ? rc : count;
731 static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
732 qeth_l3_dev_ipato_invert6_show,
733 qeth_l3_dev_ipato_invert6_store);
736 static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
737 struct device_attribute *attr, char *buf)
739 struct qeth_card *card = dev_get_drvdata(dev);
741 if (!card)
742 return -EINVAL;
744 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
747 static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
748 struct device_attribute *attr, const char *buf, size_t count)
750 struct qeth_card *card = dev_get_drvdata(dev);
752 if (!card)
753 return -EINVAL;
755 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
758 static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
759 qeth_l3_dev_ipato_add6_show,
760 qeth_l3_dev_ipato_add6_store);
762 static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
763 struct device_attribute *attr, const char *buf, size_t count)
765 struct qeth_card *card = dev_get_drvdata(dev);
767 if (!card)
768 return -EINVAL;
770 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
773 static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
774 qeth_l3_dev_ipato_del6_store);
776 static struct attribute *qeth_ipato_device_attrs[] = {
777 &dev_attr_ipato_enable.attr,
778 &dev_attr_ipato_invert4.attr,
779 &dev_attr_ipato_add4.attr,
780 &dev_attr_ipato_del4.attr,
781 &dev_attr_ipato_invert6.attr,
782 &dev_attr_ipato_add6.attr,
783 &dev_attr_ipato_del6.attr,
784 NULL,
787 static struct attribute_group qeth_device_ipato_group = {
788 .name = "ipa_takeover",
789 .attrs = qeth_ipato_device_attrs,
792 static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
793 enum qeth_prot_versions proto)
795 struct qeth_ipaddr *ipaddr;
796 char addr_str[40];
797 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
798 unsigned long flags;
799 int i = 0;
801 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
802 entry_len += 2; /* \n + terminator */
803 spin_lock_irqsave(&card->ip_lock, flags);
804 list_for_each_entry(ipaddr, &card->ip_list, entry) {
805 if (ipaddr->proto != proto)
806 continue;
807 if (ipaddr->type != QETH_IP_TYPE_VIPA)
808 continue;
809 /* String must not be longer than PAGE_SIZE. So we check if
810 * string length gets near PAGE_SIZE. Then we can savely display
811 * the next IPv6 address (worst case, compared to IPv4) */
812 if ((PAGE_SIZE - i) <= entry_len)
813 break;
814 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
815 addr_str);
816 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
818 spin_unlock_irqrestore(&card->ip_lock, flags);
819 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
821 return i;
824 static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
825 struct device_attribute *attr, char *buf)
827 struct qeth_card *card = dev_get_drvdata(dev);
829 if (!card)
830 return -EINVAL;
832 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
835 static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
836 u8 *addr)
838 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
839 return -EINVAL;
841 return 0;
844 static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
845 struct qeth_card *card, enum qeth_prot_versions proto)
847 u8 addr[16] = {0, };
848 int rc;
850 mutex_lock(&card->conf_mutex);
851 rc = qeth_l3_parse_vipae(buf, proto, addr);
852 if (!rc)
853 rc = qeth_l3_add_vipa(card, proto, addr);
854 mutex_unlock(&card->conf_mutex);
855 return rc ? rc : count;
858 static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
859 struct device_attribute *attr, const char *buf, size_t count)
861 struct qeth_card *card = dev_get_drvdata(dev);
863 if (!card)
864 return -EINVAL;
866 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
869 static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
870 qeth_l3_dev_vipa_add4_show,
871 qeth_l3_dev_vipa_add4_store);
873 static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
874 struct qeth_card *card, enum qeth_prot_versions proto)
876 u8 addr[16];
877 int rc;
879 mutex_lock(&card->conf_mutex);
880 rc = qeth_l3_parse_vipae(buf, proto, addr);
881 if (!rc)
882 qeth_l3_del_vipa(card, proto, addr);
883 mutex_unlock(&card->conf_mutex);
884 return rc ? rc : count;
887 static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
888 struct device_attribute *attr, const char *buf, size_t count)
890 struct qeth_card *card = dev_get_drvdata(dev);
892 if (!card)
893 return -EINVAL;
895 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
898 static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
899 qeth_l3_dev_vipa_del4_store);
901 static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
902 struct device_attribute *attr, char *buf)
904 struct qeth_card *card = dev_get_drvdata(dev);
906 if (!card)
907 return -EINVAL;
909 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
912 static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
913 struct device_attribute *attr, const char *buf, size_t count)
915 struct qeth_card *card = dev_get_drvdata(dev);
917 if (!card)
918 return -EINVAL;
920 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
923 static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
924 qeth_l3_dev_vipa_add6_show,
925 qeth_l3_dev_vipa_add6_store);
927 static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
928 struct device_attribute *attr, const char *buf, size_t count)
930 struct qeth_card *card = dev_get_drvdata(dev);
932 if (!card)
933 return -EINVAL;
935 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
938 static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
939 qeth_l3_dev_vipa_del6_store);
941 static struct attribute *qeth_vipa_device_attrs[] = {
942 &dev_attr_vipa_add4.attr,
943 &dev_attr_vipa_del4.attr,
944 &dev_attr_vipa_add6.attr,
945 &dev_attr_vipa_del6.attr,
946 NULL,
949 static struct attribute_group qeth_device_vipa_group = {
950 .name = "vipa",
951 .attrs = qeth_vipa_device_attrs,
954 static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
955 enum qeth_prot_versions proto)
957 struct qeth_ipaddr *ipaddr;
958 char addr_str[40];
959 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
960 unsigned long flags;
961 int i = 0;
963 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
964 entry_len += 2; /* \n + terminator */
965 spin_lock_irqsave(&card->ip_lock, flags);
966 list_for_each_entry(ipaddr, &card->ip_list, entry) {
967 if (ipaddr->proto != proto)
968 continue;
969 if (ipaddr->type != QETH_IP_TYPE_RXIP)
970 continue;
971 /* String must not be longer than PAGE_SIZE. So we check if
972 * string length gets near PAGE_SIZE. Then we can savely display
973 * the next IPv6 address (worst case, compared to IPv4) */
974 if ((PAGE_SIZE - i) <= entry_len)
975 break;
976 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
977 addr_str);
978 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
980 spin_unlock_irqrestore(&card->ip_lock, flags);
981 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
983 return i;
986 static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
987 struct device_attribute *attr, char *buf)
989 struct qeth_card *card = dev_get_drvdata(dev);
991 if (!card)
992 return -EINVAL;
994 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
997 static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
998 u8 *addr)
1000 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
1001 return -EINVAL;
1003 return 0;
1006 static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
1007 struct qeth_card *card, enum qeth_prot_versions proto)
1009 u8 addr[16] = {0, };
1010 int rc;
1012 mutex_lock(&card->conf_mutex);
1013 rc = qeth_l3_parse_rxipe(buf, proto, addr);
1014 if (!rc)
1015 rc = qeth_l3_add_rxip(card, proto, addr);
1016 mutex_unlock(&card->conf_mutex);
1017 return rc ? rc : count;
1020 static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
1021 struct device_attribute *attr, const char *buf, size_t count)
1023 struct qeth_card *card = dev_get_drvdata(dev);
1025 if (!card)
1026 return -EINVAL;
1028 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
1031 static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
1032 qeth_l3_dev_rxip_add4_show,
1033 qeth_l3_dev_rxip_add4_store);
1035 static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
1036 struct qeth_card *card, enum qeth_prot_versions proto)
1038 u8 addr[16];
1039 int rc;
1041 mutex_lock(&card->conf_mutex);
1042 rc = qeth_l3_parse_rxipe(buf, proto, addr);
1043 if (!rc)
1044 qeth_l3_del_rxip(card, proto, addr);
1045 mutex_unlock(&card->conf_mutex);
1046 return rc ? rc : count;
1049 static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
1050 struct device_attribute *attr, const char *buf, size_t count)
1052 struct qeth_card *card = dev_get_drvdata(dev);
1054 if (!card)
1055 return -EINVAL;
1057 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
1060 static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
1061 qeth_l3_dev_rxip_del4_store);
1063 static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
1064 struct device_attribute *attr, char *buf)
1066 struct qeth_card *card = dev_get_drvdata(dev);
1068 if (!card)
1069 return -EINVAL;
1071 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
1074 static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
1075 struct device_attribute *attr, const char *buf, size_t count)
1077 struct qeth_card *card = dev_get_drvdata(dev);
1079 if (!card)
1080 return -EINVAL;
1082 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
1085 static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
1086 qeth_l3_dev_rxip_add6_show,
1087 qeth_l3_dev_rxip_add6_store);
1089 static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
1090 struct device_attribute *attr, const char *buf, size_t count)
1092 struct qeth_card *card = dev_get_drvdata(dev);
1094 if (!card)
1095 return -EINVAL;
1097 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
1100 static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
1101 qeth_l3_dev_rxip_del6_store);
1103 static struct attribute *qeth_rxip_device_attrs[] = {
1104 &dev_attr_rxip_add4.attr,
1105 &dev_attr_rxip_del4.attr,
1106 &dev_attr_rxip_add6.attr,
1107 &dev_attr_rxip_del6.attr,
1108 NULL,
1111 static struct attribute_group qeth_device_rxip_group = {
1112 .name = "rxip",
1113 .attrs = qeth_rxip_device_attrs,
1116 int qeth_l3_create_device_attributes(struct device *dev)
1118 int ret;
1120 ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
1121 if (ret)
1122 return ret;
1124 ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
1125 if (ret) {
1126 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1127 return ret;
1130 ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1131 if (ret) {
1132 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1133 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1134 return ret;
1137 ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1138 if (ret) {
1139 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1140 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1141 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1142 return ret;
1144 return 0;
1147 void qeth_l3_remove_device_attributes(struct device *dev)
1149 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1150 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1151 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1152 sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);