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