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 return qeth_l3_dev_route_show(card, &card->options.route6, buf);
127 static ssize_t qeth_l3_dev_route6_store(struct device *dev,
128 struct device_attribute *attr, const char *buf, size_t count)
130 struct qeth_card *card = dev_get_drvdata(dev);
135 return qeth_l3_dev_route_store(card, &card->options.route6,
136 QETH_PROT_IPV6, buf, count);
139 static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show,
140 qeth_l3_dev_route6_store);
142 static ssize_t qeth_l3_dev_fake_broadcast_show(struct device *dev,
143 struct device_attribute *attr, char *buf)
145 struct qeth_card *card = dev_get_drvdata(dev);
150 return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
153 static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev,
154 struct device_attribute *attr, const char *buf, size_t count)
156 struct qeth_card *card = dev_get_drvdata(dev);
163 if ((card->state != CARD_STATE_DOWN) &&
164 (card->state != CARD_STATE_RECOVER))
167 i = simple_strtoul(buf, &tmp, 16);
168 if ((i == 0) || (i == 1))
169 card->options.fake_broadcast = i;
176 static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show,
177 qeth_l3_dev_fake_broadcast_store);
179 static ssize_t qeth_l3_dev_broadcast_mode_show(struct device *dev,
180 struct device_attribute *attr, char *buf)
182 struct qeth_card *card = dev_get_drvdata(dev);
187 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
188 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
189 return sprintf(buf, "n/a\n");
191 return sprintf(buf, "%s\n", (card->options.broadcast_mode ==
192 QETH_TR_BROADCAST_ALLRINGS)?
193 "all rings":"local");
196 static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev,
197 struct device_attribute *attr, const char *buf, size_t count)
199 struct qeth_card *card = dev_get_drvdata(dev);
205 if ((card->state != CARD_STATE_DOWN) &&
206 (card->state != CARD_STATE_RECOVER))
209 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
210 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
214 tmp = strsep((char **) &buf, "\n");
216 if (!strcmp(tmp, "local")) {
217 card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL;
219 } else if (!strcmp(tmp, "all_rings")) {
220 card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
228 static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show,
229 qeth_l3_dev_broadcast_mode_store);
231 static ssize_t qeth_l3_dev_canonical_macaddr_show(struct device *dev,
232 struct device_attribute *attr, char *buf)
234 struct qeth_card *card = dev_get_drvdata(dev);
239 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
240 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
241 return sprintf(buf, "n/a\n");
243 return sprintf(buf, "%i\n", (card->options.macaddr_mode ==
244 QETH_TR_MACADDR_CANONICAL)? 1:0);
247 static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev,
248 struct device_attribute *attr, const char *buf, size_t count)
250 struct qeth_card *card = dev_get_drvdata(dev);
257 if ((card->state != CARD_STATE_DOWN) &&
258 (card->state != CARD_STATE_RECOVER))
261 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
262 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
266 i = simple_strtoul(buf, &tmp, 16);
267 if ((i == 0) || (i == 1))
268 card->options.macaddr_mode = i?
269 QETH_TR_MACADDR_CANONICAL :
270 QETH_TR_MACADDR_NONCANONICAL;
277 static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show,
278 qeth_l3_dev_canonical_macaddr_store);
280 static ssize_t qeth_l3_dev_checksum_show(struct device *dev,
281 struct device_attribute *attr, char *buf)
283 struct qeth_card *card = dev_get_drvdata(dev);
288 return sprintf(buf, "%s checksumming\n",
289 qeth_l3_get_checksum_str(card));
292 static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
293 struct device_attribute *attr, const char *buf, size_t count)
295 struct qeth_card *card = dev_get_drvdata(dev);
296 enum qeth_checksum_types csum_type;
303 tmp = strsep((char **) &buf, "\n");
304 if (!strcmp(tmp, "sw_checksumming"))
305 csum_type = SW_CHECKSUMMING;
306 else if (!strcmp(tmp, "hw_checksumming"))
307 csum_type = HW_CHECKSUMMING;
308 else if (!strcmp(tmp, "no_checksumming"))
309 csum_type = NO_CHECKSUMMING;
313 rc = qeth_l3_set_rx_csum(card, csum_type);
319 static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
320 qeth_l3_dev_checksum_store);
322 static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
323 struct device_attribute *attr, char *buf)
325 struct qeth_card *card = dev_get_drvdata(dev);
330 return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
333 static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
334 struct device_attribute *attr, const char *buf, size_t count)
336 struct qeth_card *card = dev_get_drvdata(dev);
343 if (card->info.type != QETH_CARD_TYPE_IQD)
346 if ((card->state != CARD_STATE_DOWN) &&
347 (card->state != CARD_STATE_RECOVER))
350 ret = strict_strtoul(buf, 16, &i);
355 card->options.sniffer = i;
358 ret = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
359 if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
360 card->options.sniffer = i;
361 if (card->qdio.init_pool.buf_count !=
362 QETH_IN_BUF_COUNT_MAX)
363 qeth_realloc_buffer_pool(card,
364 QETH_IN_BUF_COUNT_MAX);
368 default: /* fall through */
374 static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
375 qeth_l3_dev_sniffer_store);
377 static ssize_t qeth_l3_dev_large_send_show(struct device *dev,
378 struct device_attribute *attr, char *buf)
380 struct qeth_card *card = dev_get_drvdata(dev);
385 switch (card->options.large_send) {
386 case QETH_LARGE_SEND_NO:
387 return sprintf(buf, "%s\n", "no");
388 case QETH_LARGE_SEND_TSO:
389 return sprintf(buf, "%s\n", "TSO");
391 return sprintf(buf, "%s\n", "N/A");
395 static ssize_t qeth_l3_dev_large_send_store(struct device *dev,
396 struct device_attribute *attr, const char *buf, size_t count)
398 struct qeth_card *card = dev_get_drvdata(dev);
399 enum qeth_large_send_types type;
405 tmp = strsep((char **) &buf, "\n");
406 if (!strcmp(tmp, "no"))
407 type = QETH_LARGE_SEND_NO;
408 else if (!strcmp(tmp, "TSO"))
409 type = QETH_LARGE_SEND_TSO;
413 if (card->options.large_send == type)
415 rc = qeth_l3_set_large_send(card, type);
421 static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show,
422 qeth_l3_dev_large_send_store);
424 static struct attribute *qeth_l3_device_attrs[] = {
425 &dev_attr_route4.attr,
426 &dev_attr_route6.attr,
427 &dev_attr_fake_broadcast.attr,
428 &dev_attr_broadcast_mode.attr,
429 &dev_attr_canonical_macaddr.attr,
430 &dev_attr_checksumming.attr,
431 &dev_attr_sniffer.attr,
432 &dev_attr_large_send.attr,
436 static struct attribute_group qeth_l3_device_attr_group = {
437 .attrs = qeth_l3_device_attrs,
440 static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
441 struct device_attribute *attr, char *buf)
443 struct qeth_card *card = dev_get_drvdata(dev);
448 return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
451 static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
452 struct device_attribute *attr, const char *buf, size_t count)
454 struct qeth_card *card = dev_get_drvdata(dev);
460 if ((card->state != CARD_STATE_DOWN) &&
461 (card->state != CARD_STATE_RECOVER))
464 tmp = strsep((char **) &buf, "\n");
465 if (!strcmp(tmp, "toggle")) {
466 card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
467 } else if (!strcmp(tmp, "1")) {
468 card->ipato.enabled = 1;
469 } else if (!strcmp(tmp, "0")) {
470 card->ipato.enabled = 0;
477 static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
478 qeth_l3_dev_ipato_enable_show,
479 qeth_l3_dev_ipato_enable_store);
481 static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
482 struct device_attribute *attr, char *buf)
484 struct qeth_card *card = dev_get_drvdata(dev);
489 return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
492 static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
493 struct device_attribute *attr,
494 const char *buf, size_t count)
496 struct qeth_card *card = dev_get_drvdata(dev);
502 tmp = strsep((char **) &buf, "\n");
503 if (!strcmp(tmp, "toggle")) {
504 card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
505 } else if (!strcmp(tmp, "1")) {
506 card->ipato.invert4 = 1;
507 } else if (!strcmp(tmp, "0")) {
508 card->ipato.invert4 = 0;
515 static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
516 qeth_l3_dev_ipato_invert4_show,
517 qeth_l3_dev_ipato_invert4_store);
519 static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
520 enum qeth_prot_versions proto)
522 struct qeth_ipato_entry *ipatoe;
525 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
528 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
529 /* add strlen for "/<mask>\n" */
530 entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
531 spin_lock_irqsave(&card->ip_lock, flags);
532 list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
533 if (ipatoe->proto != proto)
535 /* String must not be longer than PAGE_SIZE. So we check if
536 * string length gets near PAGE_SIZE. Then we can savely display
537 * the next IPv6 address (worst case, compared to IPv4) */
538 if ((PAGE_SIZE - i) <= entry_len)
540 qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
541 i += snprintf(buf + i, PAGE_SIZE - i,
542 "%s/%i\n", addr_str, ipatoe->mask_bits);
544 spin_unlock_irqrestore(&card->ip_lock, flags);
545 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
550 static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
551 struct device_attribute *attr, char *buf)
553 struct qeth_card *card = dev_get_drvdata(dev);
558 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
561 static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
562 u8 *addr, int *mask_bits)
564 const char *start, *end;
566 char buffer[40] = {0, };
569 /* get address string */
570 end = strchr(start, '/');
571 if (!end || (end - start >= 40)) {
574 strncpy(buffer, start, end - start);
575 if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
579 *mask_bits = simple_strtoul(start, &tmp, 10);
580 if (!strlen(start) ||
582 (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
588 static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
589 struct qeth_card *card, enum qeth_prot_versions proto)
591 struct qeth_ipato_entry *ipatoe;
596 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
600 ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
604 ipatoe->proto = proto;
605 memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
606 ipatoe->mask_bits = mask_bits;
608 rc = qeth_l3_add_ipato_entry(card, ipatoe);
617 static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
618 struct device_attribute *attr, const char *buf, size_t count)
620 struct qeth_card *card = dev_get_drvdata(dev);
625 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
628 static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
629 qeth_l3_dev_ipato_add4_show,
630 qeth_l3_dev_ipato_add4_store);
632 static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
633 struct qeth_card *card, enum qeth_prot_versions proto)
639 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
643 qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
648 static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
649 struct device_attribute *attr, const char *buf, size_t count)
651 struct qeth_card *card = dev_get_drvdata(dev);
656 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
659 static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
660 qeth_l3_dev_ipato_del4_store);
662 static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
663 struct device_attribute *attr, char *buf)
665 struct qeth_card *card = dev_get_drvdata(dev);
670 return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
673 static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
674 struct device_attribute *attr, const char *buf, size_t count)
676 struct qeth_card *card = dev_get_drvdata(dev);
682 tmp = strsep((char **) &buf, "\n");
683 if (!strcmp(tmp, "toggle")) {
684 card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
685 } else if (!strcmp(tmp, "1")) {
686 card->ipato.invert6 = 1;
687 } else if (!strcmp(tmp, "0")) {
688 card->ipato.invert6 = 0;
695 static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
696 qeth_l3_dev_ipato_invert6_show,
697 qeth_l3_dev_ipato_invert6_store);
700 static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
701 struct device_attribute *attr, char *buf)
703 struct qeth_card *card = dev_get_drvdata(dev);
708 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
711 static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
712 struct device_attribute *attr, const char *buf, size_t count)
714 struct qeth_card *card = dev_get_drvdata(dev);
719 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
722 static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
723 qeth_l3_dev_ipato_add6_show,
724 qeth_l3_dev_ipato_add6_store);
726 static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
727 struct device_attribute *attr, const char *buf, size_t count)
729 struct qeth_card *card = dev_get_drvdata(dev);
734 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
737 static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
738 qeth_l3_dev_ipato_del6_store);
740 static struct attribute *qeth_ipato_device_attrs[] = {
741 &dev_attr_ipato_enable.attr,
742 &dev_attr_ipato_invert4.attr,
743 &dev_attr_ipato_add4.attr,
744 &dev_attr_ipato_del4.attr,
745 &dev_attr_ipato_invert6.attr,
746 &dev_attr_ipato_add6.attr,
747 &dev_attr_ipato_del6.attr,
751 static struct attribute_group qeth_device_ipato_group = {
752 .name = "ipa_takeover",
753 .attrs = qeth_ipato_device_attrs,
756 static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
757 enum qeth_prot_versions proto)
759 struct qeth_ipaddr *ipaddr;
761 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
765 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
766 entry_len += 2; /* \n + terminator */
767 spin_lock_irqsave(&card->ip_lock, flags);
768 list_for_each_entry(ipaddr, &card->ip_list, entry) {
769 if (ipaddr->proto != proto)
771 if (ipaddr->type != QETH_IP_TYPE_VIPA)
773 /* String must not be longer than PAGE_SIZE. So we check if
774 * string length gets near PAGE_SIZE. Then we can savely display
775 * the next IPv6 address (worst case, compared to IPv4) */
776 if ((PAGE_SIZE - i) <= entry_len)
778 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
780 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
782 spin_unlock_irqrestore(&card->ip_lock, flags);
783 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
788 static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
789 struct device_attribute *attr, char *buf)
791 struct qeth_card *card = dev_get_drvdata(dev);
796 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
799 static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
802 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
808 static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
809 struct qeth_card *card, enum qeth_prot_versions proto)
814 rc = qeth_l3_parse_vipae(buf, proto, addr);
818 rc = qeth_l3_add_vipa(card, proto, addr);
825 static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
826 struct device_attribute *attr, const char *buf, size_t count)
828 struct qeth_card *card = dev_get_drvdata(dev);
833 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
836 static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
837 qeth_l3_dev_vipa_add4_show,
838 qeth_l3_dev_vipa_add4_store);
840 static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
841 struct qeth_card *card, enum qeth_prot_versions proto)
846 rc = qeth_l3_parse_vipae(buf, proto, addr);
850 qeth_l3_del_vipa(card, proto, addr);
855 static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
856 struct device_attribute *attr, const char *buf, size_t count)
858 struct qeth_card *card = dev_get_drvdata(dev);
863 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
866 static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
867 qeth_l3_dev_vipa_del4_store);
869 static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
870 struct device_attribute *attr, char *buf)
872 struct qeth_card *card = dev_get_drvdata(dev);
877 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
880 static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
881 struct device_attribute *attr, const char *buf, size_t count)
883 struct qeth_card *card = dev_get_drvdata(dev);
888 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
891 static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
892 qeth_l3_dev_vipa_add6_show,
893 qeth_l3_dev_vipa_add6_store);
895 static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
896 struct device_attribute *attr, const char *buf, size_t count)
898 struct qeth_card *card = dev_get_drvdata(dev);
903 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
906 static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
907 qeth_l3_dev_vipa_del6_store);
909 static struct attribute *qeth_vipa_device_attrs[] = {
910 &dev_attr_vipa_add4.attr,
911 &dev_attr_vipa_del4.attr,
912 &dev_attr_vipa_add6.attr,
913 &dev_attr_vipa_del6.attr,
917 static struct attribute_group qeth_device_vipa_group = {
919 .attrs = qeth_vipa_device_attrs,
922 static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
923 enum qeth_prot_versions proto)
925 struct qeth_ipaddr *ipaddr;
927 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
931 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
932 entry_len += 2; /* \n + terminator */
933 spin_lock_irqsave(&card->ip_lock, flags);
934 list_for_each_entry(ipaddr, &card->ip_list, entry) {
935 if (ipaddr->proto != proto)
937 if (ipaddr->type != QETH_IP_TYPE_RXIP)
939 /* String must not be longer than PAGE_SIZE. So we check if
940 * string length gets near PAGE_SIZE. Then we can savely display
941 * the next IPv6 address (worst case, compared to IPv4) */
942 if ((PAGE_SIZE - i) <= entry_len)
944 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
946 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
948 spin_unlock_irqrestore(&card->ip_lock, flags);
949 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
954 static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
955 struct device_attribute *attr, char *buf)
957 struct qeth_card *card = dev_get_drvdata(dev);
962 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
965 static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
968 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
974 static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
975 struct qeth_card *card, enum qeth_prot_versions proto)
980 rc = qeth_l3_parse_rxipe(buf, proto, addr);
984 rc = qeth_l3_add_rxip(card, proto, addr);
991 static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
992 struct device_attribute *attr, const char *buf, size_t count)
994 struct qeth_card *card = dev_get_drvdata(dev);
999 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
1002 static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
1003 qeth_l3_dev_rxip_add4_show,
1004 qeth_l3_dev_rxip_add4_store);
1006 static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
1007 struct qeth_card *card, enum qeth_prot_versions proto)
1012 rc = qeth_l3_parse_rxipe(buf, proto, addr);
1016 qeth_l3_del_rxip(card, proto, addr);
1021 static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
1022 struct device_attribute *attr, const char *buf, size_t count)
1024 struct qeth_card *card = dev_get_drvdata(dev);
1029 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
1032 static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
1033 qeth_l3_dev_rxip_del4_store);
1035 static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
1036 struct device_attribute *attr, char *buf)
1038 struct qeth_card *card = dev_get_drvdata(dev);
1043 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
1046 static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
1047 struct device_attribute *attr, const char *buf, size_t count)
1049 struct qeth_card *card = dev_get_drvdata(dev);
1054 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
1057 static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
1058 qeth_l3_dev_rxip_add6_show,
1059 qeth_l3_dev_rxip_add6_store);
1061 static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
1062 struct device_attribute *attr, const char *buf, size_t count)
1064 struct qeth_card *card = dev_get_drvdata(dev);
1069 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
1072 static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
1073 qeth_l3_dev_rxip_del6_store);
1075 static struct attribute *qeth_rxip_device_attrs[] = {
1076 &dev_attr_rxip_add4.attr,
1077 &dev_attr_rxip_del4.attr,
1078 &dev_attr_rxip_add6.attr,
1079 &dev_attr_rxip_del6.attr,
1083 static struct attribute_group qeth_device_rxip_group = {
1085 .attrs = qeth_rxip_device_attrs,
1088 int qeth_l3_create_device_attributes(struct device *dev)
1092 ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
1096 ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
1098 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1102 ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1104 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1105 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1109 ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1111 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1112 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1113 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1119 void qeth_l3_remove_device_attributes(struct device *dev)
1121 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1122 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1123 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1124 sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);