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
;
88 PRINT_WARN("Invalid routing type '%s'.\n", tmp
);
91 if (((card
->state
== CARD_STATE_SOFTSETUP
) ||
92 (card
->state
== CARD_STATE_UP
)) &&
93 (old_route_type
!= route
->type
)) {
94 if (prot
== QETH_PROT_IPV4
)
95 rc
= qeth_l3_setrouting_v4(card
);
96 else if (prot
== QETH_PROT_IPV6
)
97 rc
= qeth_l3_setrouting_v6(card
);
102 static ssize_t
qeth_l3_dev_route4_store(struct device
*dev
,
103 struct device_attribute
*attr
, const char *buf
, size_t count
)
105 struct qeth_card
*card
= dev_get_drvdata(dev
);
110 return qeth_l3_dev_route_store(card
, &card
->options
.route4
,
111 QETH_PROT_IPV4
, buf
, count
);
114 static DEVICE_ATTR(route4
, 0644, qeth_l3_dev_route4_show
,
115 qeth_l3_dev_route4_store
);
117 static ssize_t
qeth_l3_dev_route6_show(struct device
*dev
,
118 struct device_attribute
*attr
, char *buf
)
120 struct qeth_card
*card
= dev_get_drvdata(dev
);
125 if (!qeth_is_supported(card
, IPA_IPV6
))
126 return sprintf(buf
, "%s\n", "n/a");
128 return qeth_l3_dev_route_show(card
, &card
->options
.route6
, buf
);
131 static ssize_t
qeth_l3_dev_route6_store(struct device
*dev
,
132 struct device_attribute
*attr
, const char *buf
, size_t count
)
134 struct qeth_card
*card
= dev_get_drvdata(dev
);
139 if (!qeth_is_supported(card
, IPA_IPV6
)) {
140 PRINT_WARN("IPv6 not supported for interface %s.\n"
141 "Routing status no changed.\n",
142 QETH_CARD_IFNAME(card
));
146 return qeth_l3_dev_route_store(card
, &card
->options
.route6
,
147 QETH_PROT_IPV6
, buf
, count
);
150 static DEVICE_ATTR(route6
, 0644, qeth_l3_dev_route6_show
,
151 qeth_l3_dev_route6_store
);
153 static ssize_t
qeth_l3_dev_fake_broadcast_show(struct device
*dev
,
154 struct device_attribute
*attr
, char *buf
)
156 struct qeth_card
*card
= dev_get_drvdata(dev
);
161 return sprintf(buf
, "%i\n", card
->options
.fake_broadcast
? 1:0);
164 static ssize_t
qeth_l3_dev_fake_broadcast_store(struct device
*dev
,
165 struct device_attribute
*attr
, const char *buf
, size_t count
)
167 struct qeth_card
*card
= dev_get_drvdata(dev
);
174 if ((card
->state
!= CARD_STATE_DOWN
) &&
175 (card
->state
!= CARD_STATE_RECOVER
))
178 i
= simple_strtoul(buf
, &tmp
, 16);
179 if ((i
== 0) || (i
== 1))
180 card
->options
.fake_broadcast
= i
;
182 PRINT_WARN("fake_broadcast: write 0 or 1 to this file!\n");
188 static DEVICE_ATTR(fake_broadcast
, 0644, qeth_l3_dev_fake_broadcast_show
,
189 qeth_l3_dev_fake_broadcast_store
);
191 static ssize_t
qeth_l3_dev_broadcast_mode_show(struct device
*dev
,
192 struct device_attribute
*attr
, char *buf
)
194 struct qeth_card
*card
= dev_get_drvdata(dev
);
199 if (!((card
->info
.link_type
== QETH_LINK_TYPE_HSTR
) ||
200 (card
->info
.link_type
== QETH_LINK_TYPE_LANE_TR
)))
201 return sprintf(buf
, "n/a\n");
203 return sprintf(buf
, "%s\n", (card
->options
.broadcast_mode
==
204 QETH_TR_BROADCAST_ALLRINGS
)?
205 "all rings":"local");
208 static ssize_t
qeth_l3_dev_broadcast_mode_store(struct device
*dev
,
209 struct device_attribute
*attr
, const char *buf
, size_t count
)
211 struct qeth_card
*card
= dev_get_drvdata(dev
);
217 if ((card
->state
!= CARD_STATE_DOWN
) &&
218 (card
->state
!= CARD_STATE_RECOVER
))
221 if (!((card
->info
.link_type
== QETH_LINK_TYPE_HSTR
) ||
222 (card
->info
.link_type
== QETH_LINK_TYPE_LANE_TR
))) {
223 PRINT_WARN("Device is not a tokenring device!\n");
227 tmp
= strsep((char **) &buf
, "\n");
229 if (!strcmp(tmp
, "local")) {
230 card
->options
.broadcast_mode
= QETH_TR_BROADCAST_LOCAL
;
232 } else if (!strcmp(tmp
, "all_rings")) {
233 card
->options
.broadcast_mode
= QETH_TR_BROADCAST_ALLRINGS
;
236 PRINT_WARN("broadcast_mode: invalid mode %s!\n",
243 static DEVICE_ATTR(broadcast_mode
, 0644, qeth_l3_dev_broadcast_mode_show
,
244 qeth_l3_dev_broadcast_mode_store
);
246 static ssize_t
qeth_l3_dev_canonical_macaddr_show(struct device
*dev
,
247 struct device_attribute
*attr
, char *buf
)
249 struct qeth_card
*card
= dev_get_drvdata(dev
);
254 if (!((card
->info
.link_type
== QETH_LINK_TYPE_HSTR
) ||
255 (card
->info
.link_type
== QETH_LINK_TYPE_LANE_TR
)))
256 return sprintf(buf
, "n/a\n");
258 return sprintf(buf
, "%i\n", (card
->options
.macaddr_mode
==
259 QETH_TR_MACADDR_CANONICAL
)? 1:0);
262 static ssize_t
qeth_l3_dev_canonical_macaddr_store(struct device
*dev
,
263 struct device_attribute
*attr
, const char *buf
, size_t count
)
265 struct qeth_card
*card
= dev_get_drvdata(dev
);
272 if ((card
->state
!= CARD_STATE_DOWN
) &&
273 (card
->state
!= CARD_STATE_RECOVER
))
276 if (!((card
->info
.link_type
== QETH_LINK_TYPE_HSTR
) ||
277 (card
->info
.link_type
== QETH_LINK_TYPE_LANE_TR
))) {
278 PRINT_WARN("Device is not a tokenring device!\n");
282 i
= simple_strtoul(buf
, &tmp
, 16);
283 if ((i
== 0) || (i
== 1))
284 card
->options
.macaddr_mode
= i
?
285 QETH_TR_MACADDR_CANONICAL
:
286 QETH_TR_MACADDR_NONCANONICAL
;
288 PRINT_WARN("canonical_macaddr: write 0 or 1 to this file!\n");
294 static DEVICE_ATTR(canonical_macaddr
, 0644, qeth_l3_dev_canonical_macaddr_show
,
295 qeth_l3_dev_canonical_macaddr_store
);
297 static ssize_t
qeth_l3_dev_checksum_show(struct device
*dev
,
298 struct device_attribute
*attr
, char *buf
)
300 struct qeth_card
*card
= dev_get_drvdata(dev
);
305 return sprintf(buf
, "%s checksumming\n",
306 qeth_l3_get_checksum_str(card
));
309 static ssize_t
qeth_l3_dev_checksum_store(struct device
*dev
,
310 struct device_attribute
*attr
, const char *buf
, size_t count
)
312 struct qeth_card
*card
= dev_get_drvdata(dev
);
318 if ((card
->state
!= CARD_STATE_DOWN
) &&
319 (card
->state
!= CARD_STATE_RECOVER
))
322 tmp
= strsep((char **) &buf
, "\n");
323 if (!strcmp(tmp
, "sw_checksumming"))
324 card
->options
.checksum_type
= SW_CHECKSUMMING
;
325 else if (!strcmp(tmp
, "hw_checksumming"))
326 card
->options
.checksum_type
= HW_CHECKSUMMING
;
327 else if (!strcmp(tmp
, "no_checksumming"))
328 card
->options
.checksum_type
= NO_CHECKSUMMING
;
330 PRINT_WARN("Unknown checksumming type '%s'\n", tmp
);
336 static DEVICE_ATTR(checksumming
, 0644, qeth_l3_dev_checksum_show
,
337 qeth_l3_dev_checksum_store
);
339 static struct attribute
*qeth_l3_device_attrs
[] = {
340 &dev_attr_route4
.attr
,
341 &dev_attr_route6
.attr
,
342 &dev_attr_fake_broadcast
.attr
,
343 &dev_attr_broadcast_mode
.attr
,
344 &dev_attr_canonical_macaddr
.attr
,
345 &dev_attr_checksumming
.attr
,
349 static struct attribute_group qeth_l3_device_attr_group
= {
350 .attrs
= qeth_l3_device_attrs
,
353 static ssize_t
qeth_l3_dev_ipato_enable_show(struct device
*dev
,
354 struct device_attribute
*attr
, char *buf
)
356 struct qeth_card
*card
= dev_get_drvdata(dev
);
361 return sprintf(buf
, "%i\n", card
->ipato
.enabled
? 1:0);
364 static ssize_t
qeth_l3_dev_ipato_enable_store(struct device
*dev
,
365 struct device_attribute
*attr
, const char *buf
, size_t count
)
367 struct qeth_card
*card
= dev_get_drvdata(dev
);
373 if ((card
->state
!= CARD_STATE_DOWN
) &&
374 (card
->state
!= CARD_STATE_RECOVER
))
377 tmp
= strsep((char **) &buf
, "\n");
378 if (!strcmp(tmp
, "toggle")) {
379 card
->ipato
.enabled
= (card
->ipato
.enabled
)? 0 : 1;
380 } else if (!strcmp(tmp
, "1")) {
381 card
->ipato
.enabled
= 1;
382 } else if (!strcmp(tmp
, "0")) {
383 card
->ipato
.enabled
= 0;
385 PRINT_WARN("ipato_enable: write 0, 1 or 'toggle' to "
392 static QETH_DEVICE_ATTR(ipato_enable
, enable
, 0644,
393 qeth_l3_dev_ipato_enable_show
,
394 qeth_l3_dev_ipato_enable_store
);
396 static ssize_t
qeth_l3_dev_ipato_invert4_show(struct device
*dev
,
397 struct device_attribute
*attr
, char *buf
)
399 struct qeth_card
*card
= dev_get_drvdata(dev
);
404 return sprintf(buf
, "%i\n", card
->ipato
.invert4
? 1:0);
407 static ssize_t
qeth_l3_dev_ipato_invert4_store(struct device
*dev
,
408 struct device_attribute
*attr
,
409 const char *buf
, size_t count
)
411 struct qeth_card
*card
= dev_get_drvdata(dev
);
417 tmp
= strsep((char **) &buf
, "\n");
418 if (!strcmp(tmp
, "toggle")) {
419 card
->ipato
.invert4
= (card
->ipato
.invert4
)? 0 : 1;
420 } else if (!strcmp(tmp
, "1")) {
421 card
->ipato
.invert4
= 1;
422 } else if (!strcmp(tmp
, "0")) {
423 card
->ipato
.invert4
= 0;
425 PRINT_WARN("ipato_invert4: write 0, 1 or 'toggle' to "
432 static QETH_DEVICE_ATTR(ipato_invert4
, invert4
, 0644,
433 qeth_l3_dev_ipato_invert4_show
,
434 qeth_l3_dev_ipato_invert4_store
);
436 static ssize_t
qeth_l3_dev_ipato_add_show(char *buf
, struct qeth_card
*card
,
437 enum qeth_prot_versions proto
)
439 struct qeth_ipato_entry
*ipatoe
;
442 int entry_len
; /* length of 1 entry string, differs between v4 and v6 */
445 entry_len
= (proto
== QETH_PROT_IPV4
)? 12 : 40;
446 /* add strlen for "/<mask>\n" */
447 entry_len
+= (proto
== QETH_PROT_IPV4
)? 5 : 6;
448 spin_lock_irqsave(&card
->ip_lock
, flags
);
449 list_for_each_entry(ipatoe
, &card
->ipato
.entries
, entry
) {
450 if (ipatoe
->proto
!= proto
)
452 /* String must not be longer than PAGE_SIZE. So we check if
453 * string length gets near PAGE_SIZE. Then we can savely display
454 * the next IPv6 address (worst case, compared to IPv4) */
455 if ((PAGE_SIZE
- i
) <= entry_len
)
457 qeth_l3_ipaddr_to_string(proto
, ipatoe
->addr
, addr_str
);
458 i
+= snprintf(buf
+ i
, PAGE_SIZE
- i
,
459 "%s/%i\n", addr_str
, ipatoe
->mask_bits
);
461 spin_unlock_irqrestore(&card
->ip_lock
, flags
);
462 i
+= snprintf(buf
+ i
, PAGE_SIZE
- i
, "\n");
467 static ssize_t
qeth_l3_dev_ipato_add4_show(struct device
*dev
,
468 struct device_attribute
*attr
, char *buf
)
470 struct qeth_card
*card
= dev_get_drvdata(dev
);
475 return qeth_l3_dev_ipato_add_show(buf
, card
, QETH_PROT_IPV4
);
478 static int qeth_l3_parse_ipatoe(const char *buf
, enum qeth_prot_versions proto
,
479 u8
*addr
, int *mask_bits
)
481 const char *start
, *end
;
483 char buffer
[40] = {0, };
486 /* get address string */
487 end
= strchr(start
, '/');
488 if (!end
|| (end
- start
>= 40)) {
489 PRINT_WARN("Invalid format for ipato_addx/delx. "
490 "Use <ip addr>/<mask bits>\n");
493 strncpy(buffer
, start
, end
- start
);
494 if (qeth_l3_string_to_ipaddr(buffer
, proto
, addr
)) {
495 PRINT_WARN("Invalid IP address format!\n");
499 *mask_bits
= simple_strtoul(start
, &tmp
, 10);
500 if (!strlen(start
) ||
502 (*mask_bits
> ((proto
== QETH_PROT_IPV4
) ? 32 : 128))) {
503 PRINT_WARN("Invalid mask bits for ipato_addx/delx !\n");
509 static ssize_t
qeth_l3_dev_ipato_add_store(const char *buf
, size_t count
,
510 struct qeth_card
*card
, enum qeth_prot_versions proto
)
512 struct qeth_ipato_entry
*ipatoe
;
517 rc
= qeth_l3_parse_ipatoe(buf
, proto
, addr
, &mask_bits
);
521 ipatoe
= kzalloc(sizeof(struct qeth_ipato_entry
), GFP_KERNEL
);
523 PRINT_WARN("No memory to allocate ipato entry\n");
526 ipatoe
->proto
= proto
;
527 memcpy(ipatoe
->addr
, addr
, (proto
== QETH_PROT_IPV4
)? 4:16);
528 ipatoe
->mask_bits
= mask_bits
;
530 rc
= qeth_l3_add_ipato_entry(card
, ipatoe
);
539 static ssize_t
qeth_l3_dev_ipato_add4_store(struct device
*dev
,
540 struct device_attribute
*attr
, const char *buf
, size_t count
)
542 struct qeth_card
*card
= dev_get_drvdata(dev
);
547 return qeth_l3_dev_ipato_add_store(buf
, count
, card
, QETH_PROT_IPV4
);
550 static QETH_DEVICE_ATTR(ipato_add4
, add4
, 0644,
551 qeth_l3_dev_ipato_add4_show
,
552 qeth_l3_dev_ipato_add4_store
);
554 static ssize_t
qeth_l3_dev_ipato_del_store(const char *buf
, size_t count
,
555 struct qeth_card
*card
, enum qeth_prot_versions proto
)
561 rc
= qeth_l3_parse_ipatoe(buf
, proto
, addr
, &mask_bits
);
565 qeth_l3_del_ipato_entry(card
, proto
, addr
, mask_bits
);
570 static ssize_t
qeth_l3_dev_ipato_del4_store(struct device
*dev
,
571 struct device_attribute
*attr
, const char *buf
, size_t count
)
573 struct qeth_card
*card
= dev_get_drvdata(dev
);
578 return qeth_l3_dev_ipato_del_store(buf
, count
, card
, QETH_PROT_IPV4
);
581 static QETH_DEVICE_ATTR(ipato_del4
, del4
, 0200, NULL
,
582 qeth_l3_dev_ipato_del4_store
);
584 static ssize_t
qeth_l3_dev_ipato_invert6_show(struct device
*dev
,
585 struct device_attribute
*attr
, char *buf
)
587 struct qeth_card
*card
= dev_get_drvdata(dev
);
592 return sprintf(buf
, "%i\n", card
->ipato
.invert6
? 1:0);
595 static ssize_t
qeth_l3_dev_ipato_invert6_store(struct device
*dev
,
596 struct device_attribute
*attr
, const char *buf
, size_t count
)
598 struct qeth_card
*card
= dev_get_drvdata(dev
);
604 tmp
= strsep((char **) &buf
, "\n");
605 if (!strcmp(tmp
, "toggle")) {
606 card
->ipato
.invert6
= (card
->ipato
.invert6
)? 0 : 1;
607 } else if (!strcmp(tmp
, "1")) {
608 card
->ipato
.invert6
= 1;
609 } else if (!strcmp(tmp
, "0")) {
610 card
->ipato
.invert6
= 0;
612 PRINT_WARN("ipato_invert6: write 0, 1 or 'toggle' to "
619 static QETH_DEVICE_ATTR(ipato_invert6
, invert6
, 0644,
620 qeth_l3_dev_ipato_invert6_show
,
621 qeth_l3_dev_ipato_invert6_store
);
624 static ssize_t
qeth_l3_dev_ipato_add6_show(struct device
*dev
,
625 struct device_attribute
*attr
, char *buf
)
627 struct qeth_card
*card
= dev_get_drvdata(dev
);
632 return qeth_l3_dev_ipato_add_show(buf
, card
, QETH_PROT_IPV6
);
635 static ssize_t
qeth_l3_dev_ipato_add6_store(struct device
*dev
,
636 struct device_attribute
*attr
, const char *buf
, size_t count
)
638 struct qeth_card
*card
= dev_get_drvdata(dev
);
643 return qeth_l3_dev_ipato_add_store(buf
, count
, card
, QETH_PROT_IPV6
);
646 static QETH_DEVICE_ATTR(ipato_add6
, add6
, 0644,
647 qeth_l3_dev_ipato_add6_show
,
648 qeth_l3_dev_ipato_add6_store
);
650 static ssize_t
qeth_l3_dev_ipato_del6_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_IPV6
);
661 static QETH_DEVICE_ATTR(ipato_del6
, del6
, 0200, NULL
,
662 qeth_l3_dev_ipato_del6_store
);
664 static struct attribute
*qeth_ipato_device_attrs
[] = {
665 &dev_attr_ipato_enable
.attr
,
666 &dev_attr_ipato_invert4
.attr
,
667 &dev_attr_ipato_add4
.attr
,
668 &dev_attr_ipato_del4
.attr
,
669 &dev_attr_ipato_invert6
.attr
,
670 &dev_attr_ipato_add6
.attr
,
671 &dev_attr_ipato_del6
.attr
,
675 static struct attribute_group qeth_device_ipato_group
= {
676 .name
= "ipa_takeover",
677 .attrs
= qeth_ipato_device_attrs
,
680 static ssize_t
qeth_l3_dev_vipa_add_show(char *buf
, struct qeth_card
*card
,
681 enum qeth_prot_versions proto
)
683 struct qeth_ipaddr
*ipaddr
;
685 int entry_len
; /* length of 1 entry string, differs between v4 and v6 */
689 entry_len
= (proto
== QETH_PROT_IPV4
)? 12 : 40;
690 entry_len
+= 2; /* \n + terminator */
691 spin_lock_irqsave(&card
->ip_lock
, flags
);
692 list_for_each_entry(ipaddr
, &card
->ip_list
, entry
) {
693 if (ipaddr
->proto
!= proto
)
695 if (ipaddr
->type
!= QETH_IP_TYPE_VIPA
)
697 /* String must not be longer than PAGE_SIZE. So we check if
698 * string length gets near PAGE_SIZE. Then we can savely display
699 * the next IPv6 address (worst case, compared to IPv4) */
700 if ((PAGE_SIZE
- i
) <= entry_len
)
702 qeth_l3_ipaddr_to_string(proto
, (const u8
*)&ipaddr
->u
,
704 i
+= snprintf(buf
+ i
, PAGE_SIZE
- i
, "%s\n", addr_str
);
706 spin_unlock_irqrestore(&card
->ip_lock
, flags
);
707 i
+= snprintf(buf
+ i
, PAGE_SIZE
- i
, "\n");
712 static ssize_t
qeth_l3_dev_vipa_add4_show(struct device
*dev
,
713 struct device_attribute
*attr
, char *buf
)
715 struct qeth_card
*card
= dev_get_drvdata(dev
);
720 return qeth_l3_dev_vipa_add_show(buf
, card
, QETH_PROT_IPV4
);
723 static int qeth_l3_parse_vipae(const char *buf
, enum qeth_prot_versions proto
,
726 if (qeth_l3_string_to_ipaddr(buf
, proto
, addr
)) {
727 PRINT_WARN("Invalid IP address format!\n");
733 static ssize_t
qeth_l3_dev_vipa_add_store(const char *buf
, size_t count
,
734 struct qeth_card
*card
, enum qeth_prot_versions proto
)
739 rc
= qeth_l3_parse_vipae(buf
, proto
, addr
);
743 rc
= qeth_l3_add_vipa(card
, proto
, addr
);
750 static ssize_t
qeth_l3_dev_vipa_add4_store(struct device
*dev
,
751 struct device_attribute
*attr
, const char *buf
, size_t count
)
753 struct qeth_card
*card
= dev_get_drvdata(dev
);
758 return qeth_l3_dev_vipa_add_store(buf
, count
, card
, QETH_PROT_IPV4
);
761 static QETH_DEVICE_ATTR(vipa_add4
, add4
, 0644,
762 qeth_l3_dev_vipa_add4_show
,
763 qeth_l3_dev_vipa_add4_store
);
765 static ssize_t
qeth_l3_dev_vipa_del_store(const char *buf
, size_t count
,
766 struct qeth_card
*card
, enum qeth_prot_versions proto
)
771 rc
= qeth_l3_parse_vipae(buf
, proto
, addr
);
775 qeth_l3_del_vipa(card
, proto
, addr
);
780 static ssize_t
qeth_l3_dev_vipa_del4_store(struct device
*dev
,
781 struct device_attribute
*attr
, const char *buf
, size_t count
)
783 struct qeth_card
*card
= dev_get_drvdata(dev
);
788 return qeth_l3_dev_vipa_del_store(buf
, count
, card
, QETH_PROT_IPV4
);
791 static QETH_DEVICE_ATTR(vipa_del4
, del4
, 0200, NULL
,
792 qeth_l3_dev_vipa_del4_store
);
794 static ssize_t
qeth_l3_dev_vipa_add6_show(struct device
*dev
,
795 struct device_attribute
*attr
, char *buf
)
797 struct qeth_card
*card
= dev_get_drvdata(dev
);
802 return qeth_l3_dev_vipa_add_show(buf
, card
, QETH_PROT_IPV6
);
805 static ssize_t
qeth_l3_dev_vipa_add6_store(struct device
*dev
,
806 struct device_attribute
*attr
, const char *buf
, size_t count
)
808 struct qeth_card
*card
= dev_get_drvdata(dev
);
813 return qeth_l3_dev_vipa_add_store(buf
, count
, card
, QETH_PROT_IPV6
);
816 static QETH_DEVICE_ATTR(vipa_add6
, add6
, 0644,
817 qeth_l3_dev_vipa_add6_show
,
818 qeth_l3_dev_vipa_add6_store
);
820 static ssize_t
qeth_l3_dev_vipa_del6_store(struct device
*dev
,
821 struct device_attribute
*attr
, const char *buf
, size_t count
)
823 struct qeth_card
*card
= dev_get_drvdata(dev
);
828 return qeth_l3_dev_vipa_del_store(buf
, count
, card
, QETH_PROT_IPV6
);
831 static QETH_DEVICE_ATTR(vipa_del6
, del6
, 0200, NULL
,
832 qeth_l3_dev_vipa_del6_store
);
834 static struct attribute
*qeth_vipa_device_attrs
[] = {
835 &dev_attr_vipa_add4
.attr
,
836 &dev_attr_vipa_del4
.attr
,
837 &dev_attr_vipa_add6
.attr
,
838 &dev_attr_vipa_del6
.attr
,
842 static struct attribute_group qeth_device_vipa_group
= {
844 .attrs
= qeth_vipa_device_attrs
,
847 static ssize_t
qeth_l3_dev_rxip_add_show(char *buf
, struct qeth_card
*card
,
848 enum qeth_prot_versions proto
)
850 struct qeth_ipaddr
*ipaddr
;
852 int entry_len
; /* length of 1 entry string, differs between v4 and v6 */
856 entry_len
= (proto
== QETH_PROT_IPV4
)? 12 : 40;
857 entry_len
+= 2; /* \n + terminator */
858 spin_lock_irqsave(&card
->ip_lock
, flags
);
859 list_for_each_entry(ipaddr
, &card
->ip_list
, entry
) {
860 if (ipaddr
->proto
!= proto
)
862 if (ipaddr
->type
!= QETH_IP_TYPE_RXIP
)
864 /* String must not be longer than PAGE_SIZE. So we check if
865 * string length gets near PAGE_SIZE. Then we can savely display
866 * the next IPv6 address (worst case, compared to IPv4) */
867 if ((PAGE_SIZE
- i
) <= entry_len
)
869 qeth_l3_ipaddr_to_string(proto
, (const u8
*)&ipaddr
->u
,
871 i
+= snprintf(buf
+ i
, PAGE_SIZE
- i
, "%s\n", addr_str
);
873 spin_unlock_irqrestore(&card
->ip_lock
, flags
);
874 i
+= snprintf(buf
+ i
, PAGE_SIZE
- i
, "\n");
879 static ssize_t
qeth_l3_dev_rxip_add4_show(struct device
*dev
,
880 struct device_attribute
*attr
, char *buf
)
882 struct qeth_card
*card
= dev_get_drvdata(dev
);
887 return qeth_l3_dev_rxip_add_show(buf
, card
, QETH_PROT_IPV4
);
890 static int qeth_l3_parse_rxipe(const char *buf
, enum qeth_prot_versions proto
,
893 if (qeth_l3_string_to_ipaddr(buf
, proto
, addr
)) {
894 PRINT_WARN("Invalid IP address format!\n");
900 static ssize_t
qeth_l3_dev_rxip_add_store(const char *buf
, size_t count
,
901 struct qeth_card
*card
, enum qeth_prot_versions proto
)
906 rc
= qeth_l3_parse_rxipe(buf
, proto
, addr
);
910 rc
= qeth_l3_add_rxip(card
, proto
, addr
);
917 static ssize_t
qeth_l3_dev_rxip_add4_store(struct device
*dev
,
918 struct device_attribute
*attr
, const char *buf
, size_t count
)
920 struct qeth_card
*card
= dev_get_drvdata(dev
);
925 return qeth_l3_dev_rxip_add_store(buf
, count
, card
, QETH_PROT_IPV4
);
928 static QETH_DEVICE_ATTR(rxip_add4
, add4
, 0644,
929 qeth_l3_dev_rxip_add4_show
,
930 qeth_l3_dev_rxip_add4_store
);
932 static ssize_t
qeth_l3_dev_rxip_del_store(const char *buf
, size_t count
,
933 struct qeth_card
*card
, enum qeth_prot_versions proto
)
938 rc
= qeth_l3_parse_rxipe(buf
, proto
, addr
);
942 qeth_l3_del_rxip(card
, proto
, addr
);
947 static ssize_t
qeth_l3_dev_rxip_del4_store(struct device
*dev
,
948 struct device_attribute
*attr
, const char *buf
, size_t count
)
950 struct qeth_card
*card
= dev_get_drvdata(dev
);
955 return qeth_l3_dev_rxip_del_store(buf
, count
, card
, QETH_PROT_IPV4
);
958 static QETH_DEVICE_ATTR(rxip_del4
, del4
, 0200, NULL
,
959 qeth_l3_dev_rxip_del4_store
);
961 static ssize_t
qeth_l3_dev_rxip_add6_show(struct device
*dev
,
962 struct device_attribute
*attr
, char *buf
)
964 struct qeth_card
*card
= dev_get_drvdata(dev
);
969 return qeth_l3_dev_rxip_add_show(buf
, card
, QETH_PROT_IPV6
);
972 static ssize_t
qeth_l3_dev_rxip_add6_store(struct device
*dev
,
973 struct device_attribute
*attr
, const char *buf
, size_t count
)
975 struct qeth_card
*card
= dev_get_drvdata(dev
);
980 return qeth_l3_dev_rxip_add_store(buf
, count
, card
, QETH_PROT_IPV6
);
983 static QETH_DEVICE_ATTR(rxip_add6
, add6
, 0644,
984 qeth_l3_dev_rxip_add6_show
,
985 qeth_l3_dev_rxip_add6_store
);
987 static ssize_t
qeth_l3_dev_rxip_del6_store(struct device
*dev
,
988 struct device_attribute
*attr
, const char *buf
, size_t count
)
990 struct qeth_card
*card
= dev_get_drvdata(dev
);
995 return qeth_l3_dev_rxip_del_store(buf
, count
, card
, QETH_PROT_IPV6
);
998 static QETH_DEVICE_ATTR(rxip_del6
, del6
, 0200, NULL
,
999 qeth_l3_dev_rxip_del6_store
);
1001 static struct attribute
*qeth_rxip_device_attrs
[] = {
1002 &dev_attr_rxip_add4
.attr
,
1003 &dev_attr_rxip_del4
.attr
,
1004 &dev_attr_rxip_add6
.attr
,
1005 &dev_attr_rxip_del6
.attr
,
1009 static struct attribute_group qeth_device_rxip_group
= {
1011 .attrs
= qeth_rxip_device_attrs
,
1014 int qeth_l3_create_device_attributes(struct device
*dev
)
1018 ret
= sysfs_create_group(&dev
->kobj
, &qeth_l3_device_attr_group
);
1022 ret
= sysfs_create_group(&dev
->kobj
, &qeth_device_ipato_group
);
1024 sysfs_remove_group(&dev
->kobj
, &qeth_l3_device_attr_group
);
1028 ret
= sysfs_create_group(&dev
->kobj
, &qeth_device_vipa_group
);
1030 sysfs_remove_group(&dev
->kobj
, &qeth_l3_device_attr_group
);
1031 sysfs_remove_group(&dev
->kobj
, &qeth_device_ipato_group
);
1035 ret
= sysfs_create_group(&dev
->kobj
, &qeth_device_rxip_group
);
1037 sysfs_remove_group(&dev
->kobj
, &qeth_l3_device_attr_group
);
1038 sysfs_remove_group(&dev
->kobj
, &qeth_device_ipato_group
);
1039 sysfs_remove_group(&dev
->kobj
, &qeth_device_vipa_group
);
1045 void qeth_l3_remove_device_attributes(struct device
*dev
)
1047 sysfs_remove_group(&dev
->kobj
, &qeth_l3_device_attr_group
);
1048 sysfs_remove_group(&dev
->kobj
, &qeth_device_ipato_group
);
1049 sysfs_remove_group(&dev
->kobj
, &qeth_device_vipa_group
);
1050 sysfs_remove_group(&dev
->kobj
, &qeth_device_rxip_group
);