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
);