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>
11 #include <linux/slab.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)
22 else if (card->options.checksum_type == HW_CHECKSUMMING)
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) {
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+");
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+");
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+");
50 return sprintf(buf, "%s\n", "secondary connector");
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);
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;
75 tmp = strsep((char **) &buf, "\n");
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;
92 if (((card->state == CARD_STATE_SOFTSETUP) ||
93 (card->state == CARD_STATE_UP)) &&
94 (old_route_type != route->type)) {
95 if (prot == QETH_PROT_IPV4)
96 rc = qeth_l3_setrouting_v4(card);
97 else if (prot == QETH_PROT_IPV6)
98 rc = qeth_l3_setrouting_v6(card);
103 static ssize_t qeth_l3_dev_route4_store(struct device *dev,
104 struct device_attribute *attr, const char *buf, size_t count)
106 struct qeth_card *card = dev_get_drvdata(dev);
111 return qeth_l3_dev_route_store(card, &card->options.route4,
112 QETH_PROT_IPV4, buf, count);
115 static DEVICE_ATTR(route4, 0644, qeth_l3_dev_route4_show,
116 qeth_l3_dev_route4_store);
118 static ssize_t qeth_l3_dev_route6_show(struct device *dev,
119 struct device_attribute *attr, char *buf)
121 struct qeth_card *card = dev_get_drvdata(dev);
126 return qeth_l3_dev_route_show(card, &card->options.route6, buf);
129 static ssize_t qeth_l3_dev_route6_store(struct device *dev,
130 struct device_attribute *attr, const char *buf, size_t count)
132 struct qeth_card *card = dev_get_drvdata(dev);
137 return qeth_l3_dev_route_store(card, &card->options.route6,
138 QETH_PROT_IPV6, buf, count);
141 static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show,
142 qeth_l3_dev_route6_store);
144 static ssize_t qeth_l3_dev_fake_broadcast_show(struct device *dev,
145 struct device_attribute *attr, char *buf)
147 struct qeth_card *card = dev_get_drvdata(dev);
152 return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
155 static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev,
156 struct device_attribute *attr, const char *buf, size_t count)
158 struct qeth_card *card = dev_get_drvdata(dev);
165 if ((card->state != CARD_STATE_DOWN) &&
166 (card->state != CARD_STATE_RECOVER))
169 i = simple_strtoul(buf, &tmp, 16);
170 if ((i == 0) || (i == 1))
171 card->options.fake_broadcast = i;
178 static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show,
179 qeth_l3_dev_fake_broadcast_store);
181 static ssize_t qeth_l3_dev_broadcast_mode_show(struct device *dev,
182 struct device_attribute *attr, char *buf)
184 struct qeth_card *card = dev_get_drvdata(dev);
189 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
190 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
191 return sprintf(buf, "n/a\n");
193 return sprintf(buf, "%s\n", (card->options.broadcast_mode ==
194 QETH_TR_BROADCAST_ALLRINGS)?
195 "all rings":"local");
198 static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev,
199 struct device_attribute *attr, const char *buf, size_t count)
201 struct qeth_card *card = dev_get_drvdata(dev);
207 if ((card->state != CARD_STATE_DOWN) &&
208 (card->state != CARD_STATE_RECOVER))
211 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
212 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
216 tmp = strsep((char **) &buf, "\n");
218 if (!strcmp(tmp, "local")) {
219 card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL;
221 } else if (!strcmp(tmp, "all_rings")) {
222 card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
230 static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show,
231 qeth_l3_dev_broadcast_mode_store);
233 static ssize_t qeth_l3_dev_canonical_macaddr_show(struct device *dev,
234 struct device_attribute *attr, char *buf)
236 struct qeth_card *card = dev_get_drvdata(dev);
241 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
242 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
243 return sprintf(buf, "n/a\n");
245 return sprintf(buf, "%i\n", (card->options.macaddr_mode ==
246 QETH_TR_MACADDR_CANONICAL)? 1:0);
249 static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev,
250 struct device_attribute *attr, const char *buf, size_t count)
252 struct qeth_card *card = dev_get_drvdata(dev);
259 if ((card->state != CARD_STATE_DOWN) &&
260 (card->state != CARD_STATE_RECOVER))
263 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
264 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
268 i = simple_strtoul(buf, &tmp, 16);
269 if ((i == 0) || (i == 1))
270 card->options.macaddr_mode = i?
271 QETH_TR_MACADDR_CANONICAL :
272 QETH_TR_MACADDR_NONCANONICAL;
279 static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show,
280 qeth_l3_dev_canonical_macaddr_store);
282 static ssize_t qeth_l3_dev_checksum_show(struct device *dev,
283 struct device_attribute *attr, char *buf)
285 struct qeth_card *card = dev_get_drvdata(dev);
290 return sprintf(buf, "%s checksumming\n",
291 qeth_l3_get_checksum_str(card));
294 static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
295 struct device_attribute *attr, const char *buf, size_t count)
297 struct qeth_card *card = dev_get_drvdata(dev);
298 enum qeth_checksum_types csum_type;
305 tmp = strsep((char **) &buf, "\n");
306 if (!strcmp(tmp, "sw_checksumming"))
307 csum_type = SW_CHECKSUMMING;
308 else if (!strcmp(tmp, "hw_checksumming"))
309 csum_type = HW_CHECKSUMMING;
310 else if (!strcmp(tmp, "no_checksumming"))
311 csum_type = NO_CHECKSUMMING;
315 rc = qeth_l3_set_rx_csum(card, csum_type);
321 static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
322 qeth_l3_dev_checksum_store);
324 static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
325 struct device_attribute *attr, char *buf)
327 struct qeth_card *card = dev_get_drvdata(dev);
332 return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
335 static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
336 struct device_attribute *attr, const char *buf, size_t count)
338 struct qeth_card *card = dev_get_drvdata(dev);
345 if (card->info.type != QETH_CARD_TYPE_IQD)
348 if ((card->state != CARD_STATE_DOWN) &&
349 (card->state != CARD_STATE_RECOVER))
352 ret = strict_strtoul(buf, 16, &i);
357 card->options.sniffer = i;
360 ret = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
361 if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
362 card->options.sniffer = i;
363 if (card->qdio.init_pool.buf_count !=
364 QETH_IN_BUF_COUNT_MAX)
365 qeth_realloc_buffer_pool(card,
366 QETH_IN_BUF_COUNT_MAX);
370 default: /* fall through */
376 static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
377 qeth_l3_dev_sniffer_store);
379 static ssize_t qeth_l3_dev_large_send_show(struct device *dev,
380 struct device_attribute *attr, char *buf)
382 struct qeth_card *card = dev_get_drvdata(dev);
387 switch (card->options.large_send) {
388 case QETH_LARGE_SEND_NO:
389 return sprintf(buf, "%s\n", "no");
390 case QETH_LARGE_SEND_TSO:
391 return sprintf(buf, "%s\n", "TSO");
393 return sprintf(buf, "%s\n", "N/A");
397 static ssize_t qeth_l3_dev_large_send_store(struct device *dev,
398 struct device_attribute *attr, const char *buf, size_t count)
400 struct qeth_card *card = dev_get_drvdata(dev);
401 enum qeth_large_send_types type;
407 tmp = strsep((char **) &buf, "\n");
408 if (!strcmp(tmp, "no"))
409 type = QETH_LARGE_SEND_NO;
410 else if (!strcmp(tmp, "TSO"))
411 type = QETH_LARGE_SEND_TSO;
415 if (card->options.large_send == type)
417 rc = qeth_l3_set_large_send(card, type);
423 static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show,
424 qeth_l3_dev_large_send_store);
426 static struct attribute *qeth_l3_device_attrs[] = {
427 &dev_attr_route4.attr,
428 &dev_attr_route6.attr,
429 &dev_attr_fake_broadcast.attr,
430 &dev_attr_broadcast_mode.attr,
431 &dev_attr_canonical_macaddr.attr,
432 &dev_attr_checksumming.attr,
433 &dev_attr_sniffer.attr,
434 &dev_attr_large_send.attr,
438 static struct attribute_group qeth_l3_device_attr_group = {
439 .attrs = qeth_l3_device_attrs,
442 static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
443 struct device_attribute *attr, char *buf)
445 struct qeth_card *card = dev_get_drvdata(dev);
450 return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
453 static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
454 struct device_attribute *attr, const char *buf, size_t count)
456 struct qeth_card *card = dev_get_drvdata(dev);
462 if ((card->state != CARD_STATE_DOWN) &&
463 (card->state != CARD_STATE_RECOVER))
466 tmp = strsep((char **) &buf, "\n");
467 if (!strcmp(tmp, "toggle")) {
468 card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
469 } else if (!strcmp(tmp, "1")) {
470 card->ipato.enabled = 1;
471 } else if (!strcmp(tmp, "0")) {
472 card->ipato.enabled = 0;
479 static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
480 qeth_l3_dev_ipato_enable_show,
481 qeth_l3_dev_ipato_enable_store);
483 static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
484 struct device_attribute *attr, char *buf)
486 struct qeth_card *card = dev_get_drvdata(dev);
491 return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
494 static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
495 struct device_attribute *attr,
496 const char *buf, size_t count)
498 struct qeth_card *card = dev_get_drvdata(dev);
504 tmp = strsep((char **) &buf, "\n");
505 if (!strcmp(tmp, "toggle")) {
506 card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
507 } else if (!strcmp(tmp, "1")) {
508 card->ipato.invert4 = 1;
509 } else if (!strcmp(tmp, "0")) {
510 card->ipato.invert4 = 0;
517 static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
518 qeth_l3_dev_ipato_invert4_show,
519 qeth_l3_dev_ipato_invert4_store);
521 static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
522 enum qeth_prot_versions proto)
524 struct qeth_ipato_entry *ipatoe;
527 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
530 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
531 /* add strlen for "/<mask>\n" */
532 entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
533 spin_lock_irqsave(&card->ip_lock, flags);
534 list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
535 if (ipatoe->proto != proto)
537 /* String must not be longer than PAGE_SIZE. So we check if
538 * string length gets near PAGE_SIZE. Then we can savely display
539 * the next IPv6 address (worst case, compared to IPv4) */
540 if ((PAGE_SIZE - i) <= entry_len)
542 qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
543 i += snprintf(buf + i, PAGE_SIZE - i,
544 "%s/%i\n", addr_str, ipatoe->mask_bits);
546 spin_unlock_irqrestore(&card->ip_lock, flags);
547 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
552 static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
553 struct device_attribute *attr, char *buf)
555 struct qeth_card *card = dev_get_drvdata(dev);
560 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
563 static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
564 u8 *addr, int *mask_bits)
566 const char *start, *end;
568 char buffer[40] = {0, };
571 /* get address string */
572 end = strchr(start, '/');
573 if (!end || (end - start >= 40)) {
576 strncpy(buffer, start, end - start);
577 if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
581 *mask_bits = simple_strtoul(start, &tmp, 10);
582 if (!strlen(start) ||
584 (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
590 static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
591 struct qeth_card *card, enum qeth_prot_versions proto)
593 struct qeth_ipato_entry *ipatoe;
598 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
602 ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
606 ipatoe->proto = proto;
607 memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
608 ipatoe->mask_bits = mask_bits;
610 rc = qeth_l3_add_ipato_entry(card, ipatoe);
619 static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
620 struct device_attribute *attr, const char *buf, size_t count)
622 struct qeth_card *card = dev_get_drvdata(dev);
627 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
630 static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
631 qeth_l3_dev_ipato_add4_show,
632 qeth_l3_dev_ipato_add4_store);
634 static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
635 struct qeth_card *card, enum qeth_prot_versions proto)
641 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
645 qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
650 static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
651 struct device_attribute *attr, const char *buf, size_t count)
653 struct qeth_card *card = dev_get_drvdata(dev);
658 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
661 static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
662 qeth_l3_dev_ipato_del4_store);
664 static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
665 struct device_attribute *attr, char *buf)
667 struct qeth_card *card = dev_get_drvdata(dev);
672 return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
675 static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
676 struct device_attribute *attr, const char *buf, size_t count)
678 struct qeth_card *card = dev_get_drvdata(dev);
684 tmp = strsep((char **) &buf, "\n");
685 if (!strcmp(tmp, "toggle")) {
686 card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
687 } else if (!strcmp(tmp, "1")) {
688 card->ipato.invert6 = 1;
689 } else if (!strcmp(tmp, "0")) {
690 card->ipato.invert6 = 0;
697 static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
698 qeth_l3_dev_ipato_invert6_show,
699 qeth_l3_dev_ipato_invert6_store);
702 static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
703 struct device_attribute *attr, char *buf)
705 struct qeth_card *card = dev_get_drvdata(dev);
710 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
713 static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
714 struct device_attribute *attr, const char *buf, size_t count)
716 struct qeth_card *card = dev_get_drvdata(dev);
721 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
724 static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
725 qeth_l3_dev_ipato_add6_show,
726 qeth_l3_dev_ipato_add6_store);
728 static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
729 struct device_attribute *attr, const char *buf, size_t count)
731 struct qeth_card *card = dev_get_drvdata(dev);
736 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
739 static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
740 qeth_l3_dev_ipato_del6_store);
742 static struct attribute *qeth_ipato_device_attrs[] = {
743 &dev_attr_ipato_enable.attr,
744 &dev_attr_ipato_invert4.attr,
745 &dev_attr_ipato_add4.attr,
746 &dev_attr_ipato_del4.attr,
747 &dev_attr_ipato_invert6.attr,
748 &dev_attr_ipato_add6.attr,
749 &dev_attr_ipato_del6.attr,
753 static struct attribute_group qeth_device_ipato_group = {
754 .name = "ipa_takeover",
755 .attrs = qeth_ipato_device_attrs,
758 static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
759 enum qeth_prot_versions proto)
761 struct qeth_ipaddr *ipaddr;
763 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
767 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
768 entry_len += 2; /* \n + terminator */
769 spin_lock_irqsave(&card->ip_lock, flags);
770 list_for_each_entry(ipaddr, &card->ip_list, entry) {
771 if (ipaddr->proto != proto)
773 if (ipaddr->type != QETH_IP_TYPE_VIPA)
775 /* String must not be longer than PAGE_SIZE. So we check if
776 * string length gets near PAGE_SIZE. Then we can savely display
777 * the next IPv6 address (worst case, compared to IPv4) */
778 if ((PAGE_SIZE - i) <= entry_len)
780 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
782 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
784 spin_unlock_irqrestore(&card->ip_lock, flags);
785 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
790 static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
791 struct device_attribute *attr, char *buf)
793 struct qeth_card *card = dev_get_drvdata(dev);
798 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
801 static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
804 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
810 static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
811 struct qeth_card *card, enum qeth_prot_versions proto)
816 rc = qeth_l3_parse_vipae(buf, proto, addr);
820 rc = qeth_l3_add_vipa(card, proto, addr);
827 static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
828 struct device_attribute *attr, const char *buf, size_t count)
830 struct qeth_card *card = dev_get_drvdata(dev);
835 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
838 static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
839 qeth_l3_dev_vipa_add4_show,
840 qeth_l3_dev_vipa_add4_store);
842 static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
843 struct qeth_card *card, enum qeth_prot_versions proto)
848 rc = qeth_l3_parse_vipae(buf, proto, addr);
852 qeth_l3_del_vipa(card, proto, addr);
857 static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
858 struct device_attribute *attr, const char *buf, size_t count)
860 struct qeth_card *card = dev_get_drvdata(dev);
865 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
868 static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
869 qeth_l3_dev_vipa_del4_store);
871 static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
872 struct device_attribute *attr, char *buf)
874 struct qeth_card *card = dev_get_drvdata(dev);
879 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
882 static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
883 struct device_attribute *attr, const char *buf, size_t count)
885 struct qeth_card *card = dev_get_drvdata(dev);
890 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
893 static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
894 qeth_l3_dev_vipa_add6_show,
895 qeth_l3_dev_vipa_add6_store);
897 static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
898 struct device_attribute *attr, const char *buf, size_t count)
900 struct qeth_card *card = dev_get_drvdata(dev);
905 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
908 static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
909 qeth_l3_dev_vipa_del6_store);
911 static struct attribute *qeth_vipa_device_attrs[] = {
912 &dev_attr_vipa_add4.attr,
913 &dev_attr_vipa_del4.attr,
914 &dev_attr_vipa_add6.attr,
915 &dev_attr_vipa_del6.attr,
919 static struct attribute_group qeth_device_vipa_group = {
921 .attrs = qeth_vipa_device_attrs,
924 static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
925 enum qeth_prot_versions proto)
927 struct qeth_ipaddr *ipaddr;
929 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
933 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
934 entry_len += 2; /* \n + terminator */
935 spin_lock_irqsave(&card->ip_lock, flags);
936 list_for_each_entry(ipaddr, &card->ip_list, entry) {
937 if (ipaddr->proto != proto)
939 if (ipaddr->type != QETH_IP_TYPE_RXIP)
941 /* String must not be longer than PAGE_SIZE. So we check if
942 * string length gets near PAGE_SIZE. Then we can savely display
943 * the next IPv6 address (worst case, compared to IPv4) */
944 if ((PAGE_SIZE - i) <= entry_len)
946 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
948 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
950 spin_unlock_irqrestore(&card->ip_lock, flags);
951 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
956 static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
957 struct device_attribute *attr, char *buf)
959 struct qeth_card *card = dev_get_drvdata(dev);
964 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
967 static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
970 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
976 static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
977 struct qeth_card *card, enum qeth_prot_versions proto)
982 rc = qeth_l3_parse_rxipe(buf, proto, addr);
986 rc = qeth_l3_add_rxip(card, proto, addr);
993 static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
994 struct device_attribute *attr, const char *buf, size_t count)
996 struct qeth_card *card = dev_get_drvdata(dev);
1001 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
1004 static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
1005 qeth_l3_dev_rxip_add4_show,
1006 qeth_l3_dev_rxip_add4_store);
1008 static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
1009 struct qeth_card *card, enum qeth_prot_versions proto)
1014 rc = qeth_l3_parse_rxipe(buf, proto, addr);
1018 qeth_l3_del_rxip(card, proto, addr);
1023 static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
1024 struct device_attribute *attr, const char *buf, size_t count)
1026 struct qeth_card *card = dev_get_drvdata(dev);
1031 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
1034 static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
1035 qeth_l3_dev_rxip_del4_store);
1037 static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
1038 struct device_attribute *attr, char *buf)
1040 struct qeth_card *card = dev_get_drvdata(dev);
1045 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
1048 static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
1049 struct device_attribute *attr, const char *buf, size_t count)
1051 struct qeth_card *card = dev_get_drvdata(dev);
1056 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
1059 static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
1060 qeth_l3_dev_rxip_add6_show,
1061 qeth_l3_dev_rxip_add6_store);
1063 static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
1064 struct device_attribute *attr, const char *buf, size_t count)
1066 struct qeth_card *card = dev_get_drvdata(dev);
1071 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
1074 static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
1075 qeth_l3_dev_rxip_del6_store);
1077 static struct attribute *qeth_rxip_device_attrs[] = {
1078 &dev_attr_rxip_add4.attr,
1079 &dev_attr_rxip_del4.attr,
1080 &dev_attr_rxip_add6.attr,
1081 &dev_attr_rxip_del6.attr,
1085 static struct attribute_group qeth_device_rxip_group = {
1087 .attrs = qeth_rxip_device_attrs,
1090 int qeth_l3_create_device_attributes(struct device *dev)
1094 ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
1098 ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
1100 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1104 ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1106 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1107 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1111 ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1113 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1114 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1115 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1121 void qeth_l3_remove_device_attributes(struct device *dev)
1123 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1124 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1125 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1126 sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);