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>
13 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
14 struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
16 static const char *qeth_l3_get_checksum_str(struct qeth_card *card)
18 if (card->options.checksum_type == SW_CHECKSUMMING)
20 else if (card->options.checksum_type == HW_CHECKSUMMING)
26 static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
27 struct qeth_routing_info *route, char *buf)
29 switch (route->type) {
31 return sprintf(buf, "%s\n", "primary router");
32 case SECONDARY_ROUTER:
33 return sprintf(buf, "%s\n", "secondary router");
34 case MULTICAST_ROUTER:
35 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
36 return sprintf(buf, "%s\n", "multicast router+");
38 return sprintf(buf, "%s\n", "multicast router");
39 case PRIMARY_CONNECTOR:
40 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
41 return sprintf(buf, "%s\n", "primary connector+");
43 return sprintf(buf, "%s\n", "primary connector");
44 case SECONDARY_CONNECTOR:
45 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
46 return sprintf(buf, "%s\n", "secondary connector+");
48 return sprintf(buf, "%s\n", "secondary connector");
50 return sprintf(buf, "%s\n", "no");
54 static ssize_t qeth_l3_dev_route4_show(struct device *dev,
55 struct device_attribute *attr, char *buf)
57 struct qeth_card *card = dev_get_drvdata(dev);
62 return qeth_l3_dev_route_show(card, &card->options.route4, buf);
65 static ssize_t qeth_l3_dev_route_store(struct qeth_card *card,
66 struct qeth_routing_info *route, enum qeth_prot_versions prot,
67 const char *buf, size_t count)
69 enum qeth_routing_types old_route_type = route->type;
73 tmp = strsep((char **) &buf, "\n");
75 if (!strcmp(tmp, "no_router")) {
76 route->type = NO_ROUTER;
77 } else if (!strcmp(tmp, "primary_connector")) {
78 route->type = PRIMARY_CONNECTOR;
79 } else if (!strcmp(tmp, "secondary_connector")) {
80 route->type = SECONDARY_CONNECTOR;
81 } else if (!strcmp(tmp, "primary_router")) {
82 route->type = PRIMARY_ROUTER;
83 } else if (!strcmp(tmp, "secondary_router")) {
84 route->type = SECONDARY_ROUTER;
85 } else if (!strcmp(tmp, "multicast_router")) {
86 route->type = MULTICAST_ROUTER;
90 if (((card->state == CARD_STATE_SOFTSETUP) ||
91 (card->state == CARD_STATE_UP)) &&
92 (old_route_type != route->type)) {
93 if (prot == QETH_PROT_IPV4)
94 rc = qeth_l3_setrouting_v4(card);
95 else if (prot == QETH_PROT_IPV6)
96 rc = qeth_l3_setrouting_v6(card);
101 static ssize_t qeth_l3_dev_route4_store(struct device *dev,
102 struct device_attribute *attr, const char *buf, size_t count)
104 struct qeth_card *card = dev_get_drvdata(dev);
109 return qeth_l3_dev_route_store(card, &card->options.route4,
110 QETH_PROT_IPV4, buf, count);
113 static DEVICE_ATTR(route4, 0644, qeth_l3_dev_route4_show,
114 qeth_l3_dev_route4_store);
116 static ssize_t qeth_l3_dev_route6_show(struct device *dev,
117 struct device_attribute *attr, char *buf)
119 struct qeth_card *card = dev_get_drvdata(dev);
124 if (!qeth_is_supported(card, IPA_IPV6))
125 return sprintf(buf, "%s\n", "n/a");
127 return qeth_l3_dev_route_show(card, &card->options.route6, buf);
130 static ssize_t qeth_l3_dev_route6_store(struct device *dev,
131 struct device_attribute *attr, const char *buf, size_t count)
133 struct qeth_card *card = dev_get_drvdata(dev);
138 if (!qeth_is_supported(card, IPA_IPV6)) {
142 return qeth_l3_dev_route_store(card, &card->options.route6,
143 QETH_PROT_IPV6, buf, count);
146 static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show,
147 qeth_l3_dev_route6_store);
149 static ssize_t qeth_l3_dev_fake_broadcast_show(struct device *dev,
150 struct device_attribute *attr, char *buf)
152 struct qeth_card *card = dev_get_drvdata(dev);
157 return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
160 static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev,
161 struct device_attribute *attr, const char *buf, size_t count)
163 struct qeth_card *card = dev_get_drvdata(dev);
170 if ((card->state != CARD_STATE_DOWN) &&
171 (card->state != CARD_STATE_RECOVER))
174 i = simple_strtoul(buf, &tmp, 16);
175 if ((i == 0) || (i == 1))
176 card->options.fake_broadcast = i;
183 static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show,
184 qeth_l3_dev_fake_broadcast_store);
186 static ssize_t qeth_l3_dev_broadcast_mode_show(struct device *dev,
187 struct device_attribute *attr, char *buf)
189 struct qeth_card *card = dev_get_drvdata(dev);
194 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
195 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
196 return sprintf(buf, "n/a\n");
198 return sprintf(buf, "%s\n", (card->options.broadcast_mode ==
199 QETH_TR_BROADCAST_ALLRINGS)?
200 "all rings":"local");
203 static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev,
204 struct device_attribute *attr, const char *buf, size_t count)
206 struct qeth_card *card = dev_get_drvdata(dev);
212 if ((card->state != CARD_STATE_DOWN) &&
213 (card->state != CARD_STATE_RECOVER))
216 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
217 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
221 tmp = strsep((char **) &buf, "\n");
223 if (!strcmp(tmp, "local")) {
224 card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL;
226 } else if (!strcmp(tmp, "all_rings")) {
227 card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
235 static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show,
236 qeth_l3_dev_broadcast_mode_store);
238 static ssize_t qeth_l3_dev_canonical_macaddr_show(struct device *dev,
239 struct device_attribute *attr, char *buf)
241 struct qeth_card *card = dev_get_drvdata(dev);
246 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
247 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
248 return sprintf(buf, "n/a\n");
250 return sprintf(buf, "%i\n", (card->options.macaddr_mode ==
251 QETH_TR_MACADDR_CANONICAL)? 1:0);
254 static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev,
255 struct device_attribute *attr, const char *buf, size_t count)
257 struct qeth_card *card = dev_get_drvdata(dev);
264 if ((card->state != CARD_STATE_DOWN) &&
265 (card->state != CARD_STATE_RECOVER))
268 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
269 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
273 i = simple_strtoul(buf, &tmp, 16);
274 if ((i == 0) || (i == 1))
275 card->options.macaddr_mode = i?
276 QETH_TR_MACADDR_CANONICAL :
277 QETH_TR_MACADDR_NONCANONICAL;
284 static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show,
285 qeth_l3_dev_canonical_macaddr_store);
287 static ssize_t qeth_l3_dev_checksum_show(struct device *dev,
288 struct device_attribute *attr, char *buf)
290 struct qeth_card *card = dev_get_drvdata(dev);
295 return sprintf(buf, "%s checksumming\n",
296 qeth_l3_get_checksum_str(card));
299 static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
300 struct device_attribute *attr, const char *buf, size_t count)
302 struct qeth_card *card = dev_get_drvdata(dev);
308 if ((card->state != CARD_STATE_DOWN) &&
309 (card->state != CARD_STATE_RECOVER))
312 tmp = strsep((char **) &buf, "\n");
313 if (!strcmp(tmp, "sw_checksumming"))
314 card->options.checksum_type = SW_CHECKSUMMING;
315 else if (!strcmp(tmp, "hw_checksumming"))
316 card->options.checksum_type = HW_CHECKSUMMING;
317 else if (!strcmp(tmp, "no_checksumming"))
318 card->options.checksum_type = NO_CHECKSUMMING;
325 static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
326 qeth_l3_dev_checksum_store);
328 static struct attribute *qeth_l3_device_attrs[] = {
329 &dev_attr_route4.attr,
330 &dev_attr_route6.attr,
331 &dev_attr_fake_broadcast.attr,
332 &dev_attr_broadcast_mode.attr,
333 &dev_attr_canonical_macaddr.attr,
334 &dev_attr_checksumming.attr,
338 static struct attribute_group qeth_l3_device_attr_group = {
339 .attrs = qeth_l3_device_attrs,
342 static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
343 struct device_attribute *attr, char *buf)
345 struct qeth_card *card = dev_get_drvdata(dev);
350 return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
353 static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
354 struct device_attribute *attr, const char *buf, size_t count)
356 struct qeth_card *card = dev_get_drvdata(dev);
362 if ((card->state != CARD_STATE_DOWN) &&
363 (card->state != CARD_STATE_RECOVER))
366 tmp = strsep((char **) &buf, "\n");
367 if (!strcmp(tmp, "toggle")) {
368 card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
369 } else if (!strcmp(tmp, "1")) {
370 card->ipato.enabled = 1;
371 } else if (!strcmp(tmp, "0")) {
372 card->ipato.enabled = 0;
379 static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
380 qeth_l3_dev_ipato_enable_show,
381 qeth_l3_dev_ipato_enable_store);
383 static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
384 struct device_attribute *attr, char *buf)
386 struct qeth_card *card = dev_get_drvdata(dev);
391 return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
394 static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
395 struct device_attribute *attr,
396 const char *buf, size_t count)
398 struct qeth_card *card = dev_get_drvdata(dev);
404 tmp = strsep((char **) &buf, "\n");
405 if (!strcmp(tmp, "toggle")) {
406 card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
407 } else if (!strcmp(tmp, "1")) {
408 card->ipato.invert4 = 1;
409 } else if (!strcmp(tmp, "0")) {
410 card->ipato.invert4 = 0;
417 static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
418 qeth_l3_dev_ipato_invert4_show,
419 qeth_l3_dev_ipato_invert4_store);
421 static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
422 enum qeth_prot_versions proto)
424 struct qeth_ipato_entry *ipatoe;
427 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
430 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
431 /* add strlen for "/<mask>\n" */
432 entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
433 spin_lock_irqsave(&card->ip_lock, flags);
434 list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
435 if (ipatoe->proto != proto)
437 /* String must not be longer than PAGE_SIZE. So we check if
438 * string length gets near PAGE_SIZE. Then we can savely display
439 * the next IPv6 address (worst case, compared to IPv4) */
440 if ((PAGE_SIZE - i) <= entry_len)
442 qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
443 i += snprintf(buf + i, PAGE_SIZE - i,
444 "%s/%i\n", addr_str, ipatoe->mask_bits);
446 spin_unlock_irqrestore(&card->ip_lock, flags);
447 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
452 static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
453 struct device_attribute *attr, char *buf)
455 struct qeth_card *card = dev_get_drvdata(dev);
460 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
463 static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
464 u8 *addr, int *mask_bits)
466 const char *start, *end;
468 char buffer[40] = {0, };
471 /* get address string */
472 end = strchr(start, '/');
473 if (!end || (end - start >= 40)) {
476 strncpy(buffer, start, end - start);
477 if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
481 *mask_bits = simple_strtoul(start, &tmp, 10);
482 if (!strlen(start) ||
484 (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
490 static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
491 struct qeth_card *card, enum qeth_prot_versions proto)
493 struct qeth_ipato_entry *ipatoe;
498 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
502 ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
506 ipatoe->proto = proto;
507 memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
508 ipatoe->mask_bits = mask_bits;
510 rc = qeth_l3_add_ipato_entry(card, ipatoe);
519 static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
520 struct device_attribute *attr, const char *buf, size_t count)
522 struct qeth_card *card = dev_get_drvdata(dev);
527 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
530 static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
531 qeth_l3_dev_ipato_add4_show,
532 qeth_l3_dev_ipato_add4_store);
534 static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
535 struct qeth_card *card, enum qeth_prot_versions proto)
541 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
545 qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
550 static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
551 struct device_attribute *attr, const char *buf, size_t count)
553 struct qeth_card *card = dev_get_drvdata(dev);
558 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
561 static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
562 qeth_l3_dev_ipato_del4_store);
564 static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
565 struct device_attribute *attr, char *buf)
567 struct qeth_card *card = dev_get_drvdata(dev);
572 return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
575 static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
576 struct device_attribute *attr, const char *buf, size_t count)
578 struct qeth_card *card = dev_get_drvdata(dev);
584 tmp = strsep((char **) &buf, "\n");
585 if (!strcmp(tmp, "toggle")) {
586 card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
587 } else if (!strcmp(tmp, "1")) {
588 card->ipato.invert6 = 1;
589 } else if (!strcmp(tmp, "0")) {
590 card->ipato.invert6 = 0;
597 static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
598 qeth_l3_dev_ipato_invert6_show,
599 qeth_l3_dev_ipato_invert6_store);
602 static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
603 struct device_attribute *attr, char *buf)
605 struct qeth_card *card = dev_get_drvdata(dev);
610 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
613 static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
614 struct device_attribute *attr, const char *buf, size_t count)
616 struct qeth_card *card = dev_get_drvdata(dev);
621 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
624 static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
625 qeth_l3_dev_ipato_add6_show,
626 qeth_l3_dev_ipato_add6_store);
628 static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
629 struct device_attribute *attr, const char *buf, size_t count)
631 struct qeth_card *card = dev_get_drvdata(dev);
636 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
639 static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
640 qeth_l3_dev_ipato_del6_store);
642 static struct attribute *qeth_ipato_device_attrs[] = {
643 &dev_attr_ipato_enable.attr,
644 &dev_attr_ipato_invert4.attr,
645 &dev_attr_ipato_add4.attr,
646 &dev_attr_ipato_del4.attr,
647 &dev_attr_ipato_invert6.attr,
648 &dev_attr_ipato_add6.attr,
649 &dev_attr_ipato_del6.attr,
653 static struct attribute_group qeth_device_ipato_group = {
654 .name = "ipa_takeover",
655 .attrs = qeth_ipato_device_attrs,
658 static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
659 enum qeth_prot_versions proto)
661 struct qeth_ipaddr *ipaddr;
663 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
667 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
668 entry_len += 2; /* \n + terminator */
669 spin_lock_irqsave(&card->ip_lock, flags);
670 list_for_each_entry(ipaddr, &card->ip_list, entry) {
671 if (ipaddr->proto != proto)
673 if (ipaddr->type != QETH_IP_TYPE_VIPA)
675 /* String must not be longer than PAGE_SIZE. So we check if
676 * string length gets near PAGE_SIZE. Then we can savely display
677 * the next IPv6 address (worst case, compared to IPv4) */
678 if ((PAGE_SIZE - i) <= entry_len)
680 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
682 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
684 spin_unlock_irqrestore(&card->ip_lock, flags);
685 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
690 static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
691 struct device_attribute *attr, char *buf)
693 struct qeth_card *card = dev_get_drvdata(dev);
698 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
701 static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
704 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
710 static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
711 struct qeth_card *card, enum qeth_prot_versions proto)
716 rc = qeth_l3_parse_vipae(buf, proto, addr);
720 rc = qeth_l3_add_vipa(card, proto, addr);
727 static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
728 struct device_attribute *attr, const char *buf, size_t count)
730 struct qeth_card *card = dev_get_drvdata(dev);
735 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
738 static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
739 qeth_l3_dev_vipa_add4_show,
740 qeth_l3_dev_vipa_add4_store);
742 static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
743 struct qeth_card *card, enum qeth_prot_versions proto)
748 rc = qeth_l3_parse_vipae(buf, proto, addr);
752 qeth_l3_del_vipa(card, proto, addr);
757 static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
758 struct device_attribute *attr, const char *buf, size_t count)
760 struct qeth_card *card = dev_get_drvdata(dev);
765 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
768 static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
769 qeth_l3_dev_vipa_del4_store);
771 static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
772 struct device_attribute *attr, char *buf)
774 struct qeth_card *card = dev_get_drvdata(dev);
779 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
782 static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
783 struct device_attribute *attr, const char *buf, size_t count)
785 struct qeth_card *card = dev_get_drvdata(dev);
790 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
793 static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
794 qeth_l3_dev_vipa_add6_show,
795 qeth_l3_dev_vipa_add6_store);
797 static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
798 struct device_attribute *attr, const char *buf, size_t count)
800 struct qeth_card *card = dev_get_drvdata(dev);
805 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
808 static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
809 qeth_l3_dev_vipa_del6_store);
811 static struct attribute *qeth_vipa_device_attrs[] = {
812 &dev_attr_vipa_add4.attr,
813 &dev_attr_vipa_del4.attr,
814 &dev_attr_vipa_add6.attr,
815 &dev_attr_vipa_del6.attr,
819 static struct attribute_group qeth_device_vipa_group = {
821 .attrs = qeth_vipa_device_attrs,
824 static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
825 enum qeth_prot_versions proto)
827 struct qeth_ipaddr *ipaddr;
829 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
833 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
834 entry_len += 2; /* \n + terminator */
835 spin_lock_irqsave(&card->ip_lock, flags);
836 list_for_each_entry(ipaddr, &card->ip_list, entry) {
837 if (ipaddr->proto != proto)
839 if (ipaddr->type != QETH_IP_TYPE_RXIP)
841 /* String must not be longer than PAGE_SIZE. So we check if
842 * string length gets near PAGE_SIZE. Then we can savely display
843 * the next IPv6 address (worst case, compared to IPv4) */
844 if ((PAGE_SIZE - i) <= entry_len)
846 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
848 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
850 spin_unlock_irqrestore(&card->ip_lock, flags);
851 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
856 static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
857 struct device_attribute *attr, char *buf)
859 struct qeth_card *card = dev_get_drvdata(dev);
864 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
867 static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
870 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
876 static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
877 struct qeth_card *card, enum qeth_prot_versions proto)
882 rc = qeth_l3_parse_rxipe(buf, proto, addr);
886 rc = qeth_l3_add_rxip(card, proto, addr);
893 static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
894 struct device_attribute *attr, const char *buf, size_t count)
896 struct qeth_card *card = dev_get_drvdata(dev);
901 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
904 static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
905 qeth_l3_dev_rxip_add4_show,
906 qeth_l3_dev_rxip_add4_store);
908 static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
909 struct qeth_card *card, enum qeth_prot_versions proto)
914 rc = qeth_l3_parse_rxipe(buf, proto, addr);
918 qeth_l3_del_rxip(card, proto, addr);
923 static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
924 struct device_attribute *attr, const char *buf, size_t count)
926 struct qeth_card *card = dev_get_drvdata(dev);
931 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
934 static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
935 qeth_l3_dev_rxip_del4_store);
937 static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
938 struct device_attribute *attr, char *buf)
940 struct qeth_card *card = dev_get_drvdata(dev);
945 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
948 static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
949 struct device_attribute *attr, const char *buf, size_t count)
951 struct qeth_card *card = dev_get_drvdata(dev);
956 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
959 static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
960 qeth_l3_dev_rxip_add6_show,
961 qeth_l3_dev_rxip_add6_store);
963 static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
964 struct device_attribute *attr, const char *buf, size_t count)
966 struct qeth_card *card = dev_get_drvdata(dev);
971 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
974 static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
975 qeth_l3_dev_rxip_del6_store);
977 static struct attribute *qeth_rxip_device_attrs[] = {
978 &dev_attr_rxip_add4.attr,
979 &dev_attr_rxip_del4.attr,
980 &dev_attr_rxip_add6.attr,
981 &dev_attr_rxip_del6.attr,
985 static struct attribute_group qeth_device_rxip_group = {
987 .attrs = qeth_rxip_device_attrs,
990 int qeth_l3_create_device_attributes(struct device *dev)
994 ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
998 ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
1000 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1004 ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1006 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1007 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1011 ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1013 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1014 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1015 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1021 void qeth_l3_remove_device_attributes(struct device *dev)
1023 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1024 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1025 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1026 sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);