2 * Copyright IBM Corp. 2007
3 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
4 * Frank Pavlic <fpavlic@de.ibm.com>,
5 * Thomas Spatzier <tspat@de.ibm.com>,
6 * Frank Blaschka <frank.blaschka@de.ibm.com>
9 #include <linux/slab.h>
10 #include <asm/ebcdic.h>
13 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
14 struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
16 static ssize_t
qeth_l3_dev_route_show(struct qeth_card
*card
,
17 struct qeth_routing_info
*route
, char *buf
)
19 switch (route
->type
) {
21 return sprintf(buf
, "%s\n", "primary router");
22 case SECONDARY_ROUTER
:
23 return sprintf(buf
, "%s\n", "secondary router");
24 case MULTICAST_ROUTER
:
25 if (card
->info
.broadcast_capable
== QETH_BROADCAST_WITHOUT_ECHO
)
26 return sprintf(buf
, "%s\n", "multicast router+");
28 return sprintf(buf
, "%s\n", "multicast router");
29 case PRIMARY_CONNECTOR
:
30 if (card
->info
.broadcast_capable
== QETH_BROADCAST_WITHOUT_ECHO
)
31 return sprintf(buf
, "%s\n", "primary connector+");
33 return sprintf(buf
, "%s\n", "primary connector");
34 case SECONDARY_CONNECTOR
:
35 if (card
->info
.broadcast_capable
== QETH_BROADCAST_WITHOUT_ECHO
)
36 return sprintf(buf
, "%s\n", "secondary connector+");
38 return sprintf(buf
, "%s\n", "secondary connector");
40 return sprintf(buf
, "%s\n", "no");
44 static ssize_t
qeth_l3_dev_route4_show(struct device
*dev
,
45 struct device_attribute
*attr
, char *buf
)
47 struct qeth_card
*card
= dev_get_drvdata(dev
);
52 return qeth_l3_dev_route_show(card
, &card
->options
.route4
, buf
);
55 static ssize_t
qeth_l3_dev_route_store(struct qeth_card
*card
,
56 struct qeth_routing_info
*route
, enum qeth_prot_versions prot
,
57 const char *buf
, size_t count
)
59 enum qeth_routing_types old_route_type
= route
->type
;
63 tmp
= strsep((char **) &buf
, "\n");
64 mutex_lock(&card
->conf_mutex
);
65 if (!strcmp(tmp
, "no_router")) {
66 route
->type
= NO_ROUTER
;
67 } else if (!strcmp(tmp
, "primary_connector")) {
68 route
->type
= PRIMARY_CONNECTOR
;
69 } else if (!strcmp(tmp
, "secondary_connector")) {
70 route
->type
= SECONDARY_CONNECTOR
;
71 } else if (!strcmp(tmp
, "primary_router")) {
72 route
->type
= PRIMARY_ROUTER
;
73 } else if (!strcmp(tmp
, "secondary_router")) {
74 route
->type
= SECONDARY_ROUTER
;
75 } else if (!strcmp(tmp
, "multicast_router")) {
76 route
->type
= MULTICAST_ROUTER
;
81 if (((card
->state
== CARD_STATE_SOFTSETUP
) ||
82 (card
->state
== CARD_STATE_UP
)) &&
83 (old_route_type
!= route
->type
)) {
84 if (prot
== QETH_PROT_IPV4
)
85 rc
= qeth_l3_setrouting_v4(card
);
86 else if (prot
== QETH_PROT_IPV6
)
87 rc
= qeth_l3_setrouting_v6(card
);
91 route
->type
= old_route_type
;
92 mutex_unlock(&card
->conf_mutex
);
93 return rc
? rc
: count
;
96 static ssize_t
qeth_l3_dev_route4_store(struct device
*dev
,
97 struct device_attribute
*attr
, const char *buf
, size_t count
)
99 struct qeth_card
*card
= dev_get_drvdata(dev
);
104 return qeth_l3_dev_route_store(card
, &card
->options
.route4
,
105 QETH_PROT_IPV4
, buf
, count
);
108 static DEVICE_ATTR(route4
, 0644, qeth_l3_dev_route4_show
,
109 qeth_l3_dev_route4_store
);
111 static ssize_t
qeth_l3_dev_route6_show(struct device
*dev
,
112 struct device_attribute
*attr
, char *buf
)
114 struct qeth_card
*card
= dev_get_drvdata(dev
);
119 return qeth_l3_dev_route_show(card
, &card
->options
.route6
, buf
);
122 static ssize_t
qeth_l3_dev_route6_store(struct device
*dev
,
123 struct device_attribute
*attr
, const char *buf
, size_t count
)
125 struct qeth_card
*card
= dev_get_drvdata(dev
);
130 return qeth_l3_dev_route_store(card
, &card
->options
.route6
,
131 QETH_PROT_IPV6
, buf
, count
);
134 static DEVICE_ATTR(route6
, 0644, qeth_l3_dev_route6_show
,
135 qeth_l3_dev_route6_store
);
137 static ssize_t
qeth_l3_dev_fake_broadcast_show(struct device
*dev
,
138 struct device_attribute
*attr
, char *buf
)
140 struct qeth_card
*card
= dev_get_drvdata(dev
);
145 return sprintf(buf
, "%i\n", card
->options
.fake_broadcast
? 1:0);
148 static ssize_t
qeth_l3_dev_fake_broadcast_store(struct device
*dev
,
149 struct device_attribute
*attr
, const char *buf
, size_t count
)
151 struct qeth_card
*card
= dev_get_drvdata(dev
);
158 mutex_lock(&card
->conf_mutex
);
159 if ((card
->state
!= CARD_STATE_DOWN
) &&
160 (card
->state
!= CARD_STATE_RECOVER
)) {
165 i
= simple_strtoul(buf
, &tmp
, 16);
166 if ((i
== 0) || (i
== 1))
167 card
->options
.fake_broadcast
= i
;
171 mutex_unlock(&card
->conf_mutex
);
172 return rc
? rc
: count
;
175 static DEVICE_ATTR(fake_broadcast
, 0644, qeth_l3_dev_fake_broadcast_show
,
176 qeth_l3_dev_fake_broadcast_store
);
178 static ssize_t
qeth_l3_dev_sniffer_show(struct device
*dev
,
179 struct device_attribute
*attr
, char *buf
)
181 struct qeth_card
*card
= dev_get_drvdata(dev
);
186 return sprintf(buf
, "%i\n", card
->options
.sniffer
? 1 : 0);
189 static ssize_t
qeth_l3_dev_sniffer_store(struct device
*dev
,
190 struct device_attribute
*attr
, const char *buf
, size_t count
)
192 struct qeth_card
*card
= dev_get_drvdata(dev
);
199 if (card
->info
.type
!= QETH_CARD_TYPE_IQD
)
201 if (card
->options
.cq
== QETH_CQ_ENABLED
)
204 mutex_lock(&card
->conf_mutex
);
205 if ((card
->state
!= CARD_STATE_DOWN
) &&
206 (card
->state
!= CARD_STATE_RECOVER
)) {
211 rc
= kstrtoul(buf
, 16, &i
);
218 card
->options
.sniffer
= i
;
221 qdio_get_ssqd_desc(CARD_DDEV(card
), &card
->ssqd
);
222 if (card
->ssqd
.qdioac2
& QETH_SNIFF_AVAIL
) {
223 card
->options
.sniffer
= i
;
224 if (card
->qdio
.init_pool
.buf_count
!=
225 QETH_IN_BUF_COUNT_MAX
)
226 qeth_realloc_buffer_pool(card
,
227 QETH_IN_BUF_COUNT_MAX
);
235 mutex_unlock(&card
->conf_mutex
);
236 return rc
? rc
: count
;
239 static DEVICE_ATTR(sniffer
, 0644, qeth_l3_dev_sniffer_show
,
240 qeth_l3_dev_sniffer_store
);
243 static ssize_t
qeth_l3_dev_hsuid_show(struct device
*dev
,
244 struct device_attribute
*attr
, char *buf
)
246 struct qeth_card
*card
= dev_get_drvdata(dev
);
252 if (card
->info
.type
!= QETH_CARD_TYPE_IQD
)
255 if (card
->state
== CARD_STATE_DOWN
)
258 memcpy(tmp_hsuid
, card
->options
.hsuid
, sizeof(tmp_hsuid
));
259 EBCASC(tmp_hsuid
, 8);
260 return sprintf(buf
, "%s\n", tmp_hsuid
);
263 static ssize_t
qeth_l3_dev_hsuid_store(struct device
*dev
,
264 struct device_attribute
*attr
, const char *buf
, size_t count
)
266 struct qeth_card
*card
= dev_get_drvdata(dev
);
267 struct qeth_ipaddr
*addr
;
274 if (card
->info
.type
!= QETH_CARD_TYPE_IQD
)
276 if (card
->state
!= CARD_STATE_DOWN
&&
277 card
->state
!= CARD_STATE_RECOVER
)
279 if (card
->options
.sniffer
)
281 if (card
->options
.cq
== QETH_CQ_NOTAVAILABLE
)
284 tmp
= strsep((char **)&buf
, "\n");
288 if (card
->options
.hsuid
[0]) {
289 /* delete old ip address */
290 addr
= qeth_l3_get_addr_buffer(QETH_PROT_IPV6
);
292 addr
->u
.a6
.addr
.s6_addr32
[0] = 0xfe800000;
293 addr
->u
.a6
.addr
.s6_addr32
[1] = 0x00000000;
294 for (i
= 8; i
< 16; i
++)
295 addr
->u
.a6
.addr
.s6_addr
[i
] =
296 card
->options
.hsuid
[i
- 8];
297 addr
->u
.a6
.pfxlen
= 0;
298 addr
->type
= QETH_IP_TYPE_NORMAL
;
301 if (!qeth_l3_delete_ip(card
, addr
))
303 qeth_l3_set_ip_addr_list(card
);
306 if (strlen(tmp
) == 0) {
307 /* delete ip address only */
308 card
->options
.hsuid
[0] = '\0';
310 memcpy(card
->dev
->perm_addr
, card
->options
.hsuid
, 9);
311 qeth_configure_cq(card
, QETH_CQ_DISABLED
);
315 if (qeth_configure_cq(card
, QETH_CQ_ENABLED
))
318 snprintf(card
->options
.hsuid
, sizeof(card
->options
.hsuid
),
320 ASCEBC(card
->options
.hsuid
, 8);
322 memcpy(card
->dev
->perm_addr
, card
->options
.hsuid
, 9);
324 addr
= qeth_l3_get_addr_buffer(QETH_PROT_IPV6
);
326 addr
->u
.a6
.addr
.s6_addr32
[0] = 0xfe800000;
327 addr
->u
.a6
.addr
.s6_addr32
[1] = 0x00000000;
328 for (i
= 8; i
< 16; i
++)
329 addr
->u
.a6
.addr
.s6_addr
[i
] = card
->options
.hsuid
[i
- 8];
330 addr
->u
.a6
.pfxlen
= 0;
331 addr
->type
= QETH_IP_TYPE_NORMAL
;
334 if (!qeth_l3_add_ip(card
, addr
))
336 qeth_l3_set_ip_addr_list(card
);
341 static DEVICE_ATTR(hsuid
, 0644, qeth_l3_dev_hsuid_show
,
342 qeth_l3_dev_hsuid_store
);
345 static struct attribute
*qeth_l3_device_attrs
[] = {
346 &dev_attr_route4
.attr
,
347 &dev_attr_route6
.attr
,
348 &dev_attr_fake_broadcast
.attr
,
349 &dev_attr_sniffer
.attr
,
350 &dev_attr_hsuid
.attr
,
354 static struct attribute_group qeth_l3_device_attr_group
= {
355 .attrs
= qeth_l3_device_attrs
,
358 static ssize_t
qeth_l3_dev_ipato_enable_show(struct device
*dev
,
359 struct device_attribute
*attr
, char *buf
)
361 struct qeth_card
*card
= dev_get_drvdata(dev
);
366 return sprintf(buf
, "%i\n", card
->ipato
.enabled
? 1:0);
369 static ssize_t
qeth_l3_dev_ipato_enable_store(struct device
*dev
,
370 struct device_attribute
*attr
, const char *buf
, size_t count
)
372 struct qeth_card
*card
= dev_get_drvdata(dev
);
373 struct qeth_ipaddr
*tmpipa
, *t
;
380 mutex_lock(&card
->conf_mutex
);
381 if ((card
->state
!= CARD_STATE_DOWN
) &&
382 (card
->state
!= CARD_STATE_RECOVER
)) {
387 tmp
= strsep((char **) &buf
, "\n");
388 if (!strcmp(tmp
, "toggle")) {
389 card
->ipato
.enabled
= (card
->ipato
.enabled
)? 0 : 1;
390 } else if (!strcmp(tmp
, "1")) {
391 card
->ipato
.enabled
= 1;
392 list_for_each_entry_safe(tmpipa
, t
, card
->ip_tbd_list
, entry
) {
393 if ((tmpipa
->type
== QETH_IP_TYPE_NORMAL
) &&
394 qeth_l3_is_addr_covered_by_ipato(card
, tmpipa
))
396 QETH_IPA_SETIP_TAKEOVER_FLAG
;
399 } else if (!strcmp(tmp
, "0")) {
400 card
->ipato
.enabled
= 0;
401 list_for_each_entry_safe(tmpipa
, t
, card
->ip_tbd_list
, entry
) {
402 if (tmpipa
->set_flags
&
403 QETH_IPA_SETIP_TAKEOVER_FLAG
)
405 ~QETH_IPA_SETIP_TAKEOVER_FLAG
;
410 mutex_unlock(&card
->conf_mutex
);
411 return rc
? rc
: count
;
414 static QETH_DEVICE_ATTR(ipato_enable
, enable
, 0644,
415 qeth_l3_dev_ipato_enable_show
,
416 qeth_l3_dev_ipato_enable_store
);
418 static ssize_t
qeth_l3_dev_ipato_invert4_show(struct device
*dev
,
419 struct device_attribute
*attr
, char *buf
)
421 struct qeth_card
*card
= dev_get_drvdata(dev
);
426 return sprintf(buf
, "%i\n", card
->ipato
.invert4
? 1:0);
429 static ssize_t
qeth_l3_dev_ipato_invert4_store(struct device
*dev
,
430 struct device_attribute
*attr
,
431 const char *buf
, size_t count
)
433 struct qeth_card
*card
= dev_get_drvdata(dev
);
440 mutex_lock(&card
->conf_mutex
);
441 tmp
= strsep((char **) &buf
, "\n");
442 if (!strcmp(tmp
, "toggle")) {
443 card
->ipato
.invert4
= (card
->ipato
.invert4
)? 0 : 1;
444 } else if (!strcmp(tmp
, "1")) {
445 card
->ipato
.invert4
= 1;
446 } else if (!strcmp(tmp
, "0")) {
447 card
->ipato
.invert4
= 0;
450 mutex_unlock(&card
->conf_mutex
);
451 return rc
? rc
: count
;
454 static QETH_DEVICE_ATTR(ipato_invert4
, invert4
, 0644,
455 qeth_l3_dev_ipato_invert4_show
,
456 qeth_l3_dev_ipato_invert4_store
);
458 static ssize_t
qeth_l3_dev_ipato_add_show(char *buf
, struct qeth_card
*card
,
459 enum qeth_prot_versions proto
)
461 struct qeth_ipato_entry
*ipatoe
;
464 int entry_len
; /* length of 1 entry string, differs between v4 and v6 */
467 entry_len
= (proto
== QETH_PROT_IPV4
)? 12 : 40;
468 /* add strlen for "/<mask>\n" */
469 entry_len
+= (proto
== QETH_PROT_IPV4
)? 5 : 6;
470 spin_lock_irqsave(&card
->ip_lock
, flags
);
471 list_for_each_entry(ipatoe
, &card
->ipato
.entries
, entry
) {
472 if (ipatoe
->proto
!= proto
)
474 /* String must not be longer than PAGE_SIZE. So we check if
475 * string length gets near PAGE_SIZE. Then we can savely display
476 * the next IPv6 address (worst case, compared to IPv4) */
477 if ((PAGE_SIZE
- i
) <= entry_len
)
479 qeth_l3_ipaddr_to_string(proto
, ipatoe
->addr
, addr_str
);
480 i
+= snprintf(buf
+ i
, PAGE_SIZE
- i
,
481 "%s/%i\n", addr_str
, ipatoe
->mask_bits
);
483 spin_unlock_irqrestore(&card
->ip_lock
, flags
);
484 i
+= snprintf(buf
+ i
, PAGE_SIZE
- i
, "\n");
489 static ssize_t
qeth_l3_dev_ipato_add4_show(struct device
*dev
,
490 struct device_attribute
*attr
, char *buf
)
492 struct qeth_card
*card
= dev_get_drvdata(dev
);
497 return qeth_l3_dev_ipato_add_show(buf
, card
, QETH_PROT_IPV4
);
500 static int qeth_l3_parse_ipatoe(const char *buf
, enum qeth_prot_versions proto
,
501 u8
*addr
, int *mask_bits
)
503 const char *start
, *end
;
505 char buffer
[40] = {0, };
508 /* get address string */
509 end
= strchr(start
, '/');
510 if (!end
|| (end
- start
>= 40)) {
513 strncpy(buffer
, start
, end
- start
);
514 if (qeth_l3_string_to_ipaddr(buffer
, proto
, addr
)) {
518 *mask_bits
= simple_strtoul(start
, &tmp
, 10);
519 if (!strlen(start
) ||
521 (*mask_bits
> ((proto
== QETH_PROT_IPV4
) ? 32 : 128))) {
527 static ssize_t
qeth_l3_dev_ipato_add_store(const char *buf
, size_t count
,
528 struct qeth_card
*card
, enum qeth_prot_versions proto
)
530 struct qeth_ipato_entry
*ipatoe
;
535 mutex_lock(&card
->conf_mutex
);
536 rc
= qeth_l3_parse_ipatoe(buf
, proto
, addr
, &mask_bits
);
540 ipatoe
= kzalloc(sizeof(struct qeth_ipato_entry
), GFP_KERNEL
);
545 ipatoe
->proto
= proto
;
546 memcpy(ipatoe
->addr
, addr
, (proto
== QETH_PROT_IPV4
)? 4:16);
547 ipatoe
->mask_bits
= mask_bits
;
549 rc
= qeth_l3_add_ipato_entry(card
, ipatoe
);
553 mutex_unlock(&card
->conf_mutex
);
554 return rc
? rc
: count
;
557 static ssize_t
qeth_l3_dev_ipato_add4_store(struct device
*dev
,
558 struct device_attribute
*attr
, const char *buf
, size_t count
)
560 struct qeth_card
*card
= dev_get_drvdata(dev
);
565 return qeth_l3_dev_ipato_add_store(buf
, count
, card
, QETH_PROT_IPV4
);
568 static QETH_DEVICE_ATTR(ipato_add4
, add4
, 0644,
569 qeth_l3_dev_ipato_add4_show
,
570 qeth_l3_dev_ipato_add4_store
);
572 static ssize_t
qeth_l3_dev_ipato_del_store(const char *buf
, size_t count
,
573 struct qeth_card
*card
, enum qeth_prot_versions proto
)
579 mutex_lock(&card
->conf_mutex
);
580 rc
= qeth_l3_parse_ipatoe(buf
, proto
, addr
, &mask_bits
);
582 qeth_l3_del_ipato_entry(card
, proto
, addr
, mask_bits
);
583 mutex_unlock(&card
->conf_mutex
);
584 return rc
? rc
: count
;
587 static ssize_t
qeth_l3_dev_ipato_del4_store(struct device
*dev
,
588 struct device_attribute
*attr
, const char *buf
, size_t count
)
590 struct qeth_card
*card
= dev_get_drvdata(dev
);
595 return qeth_l3_dev_ipato_del_store(buf
, count
, card
, QETH_PROT_IPV4
);
598 static QETH_DEVICE_ATTR(ipato_del4
, del4
, 0200, NULL
,
599 qeth_l3_dev_ipato_del4_store
);
601 static ssize_t
qeth_l3_dev_ipato_invert6_show(struct device
*dev
,
602 struct device_attribute
*attr
, char *buf
)
604 struct qeth_card
*card
= dev_get_drvdata(dev
);
609 return sprintf(buf
, "%i\n", card
->ipato
.invert6
? 1:0);
612 static ssize_t
qeth_l3_dev_ipato_invert6_store(struct device
*dev
,
613 struct device_attribute
*attr
, const char *buf
, size_t count
)
615 struct qeth_card
*card
= dev_get_drvdata(dev
);
622 mutex_lock(&card
->conf_mutex
);
623 tmp
= strsep((char **) &buf
, "\n");
624 if (!strcmp(tmp
, "toggle")) {
625 card
->ipato
.invert6
= (card
->ipato
.invert6
)? 0 : 1;
626 } else if (!strcmp(tmp
, "1")) {
627 card
->ipato
.invert6
= 1;
628 } else if (!strcmp(tmp
, "0")) {
629 card
->ipato
.invert6
= 0;
632 mutex_unlock(&card
->conf_mutex
);
633 return rc
? rc
: count
;
636 static QETH_DEVICE_ATTR(ipato_invert6
, invert6
, 0644,
637 qeth_l3_dev_ipato_invert6_show
,
638 qeth_l3_dev_ipato_invert6_store
);
641 static ssize_t
qeth_l3_dev_ipato_add6_show(struct device
*dev
,
642 struct device_attribute
*attr
, char *buf
)
644 struct qeth_card
*card
= dev_get_drvdata(dev
);
649 return qeth_l3_dev_ipato_add_show(buf
, card
, QETH_PROT_IPV6
);
652 static ssize_t
qeth_l3_dev_ipato_add6_store(struct device
*dev
,
653 struct device_attribute
*attr
, const char *buf
, size_t count
)
655 struct qeth_card
*card
= dev_get_drvdata(dev
);
660 return qeth_l3_dev_ipato_add_store(buf
, count
, card
, QETH_PROT_IPV6
);
663 static QETH_DEVICE_ATTR(ipato_add6
, add6
, 0644,
664 qeth_l3_dev_ipato_add6_show
,
665 qeth_l3_dev_ipato_add6_store
);
667 static ssize_t
qeth_l3_dev_ipato_del6_store(struct device
*dev
,
668 struct device_attribute
*attr
, const char *buf
, size_t count
)
670 struct qeth_card
*card
= dev_get_drvdata(dev
);
675 return qeth_l3_dev_ipato_del_store(buf
, count
, card
, QETH_PROT_IPV6
);
678 static QETH_DEVICE_ATTR(ipato_del6
, del6
, 0200, NULL
,
679 qeth_l3_dev_ipato_del6_store
);
681 static struct attribute
*qeth_ipato_device_attrs
[] = {
682 &dev_attr_ipato_enable
.attr
,
683 &dev_attr_ipato_invert4
.attr
,
684 &dev_attr_ipato_add4
.attr
,
685 &dev_attr_ipato_del4
.attr
,
686 &dev_attr_ipato_invert6
.attr
,
687 &dev_attr_ipato_add6
.attr
,
688 &dev_attr_ipato_del6
.attr
,
692 static struct attribute_group qeth_device_ipato_group
= {
693 .name
= "ipa_takeover",
694 .attrs
= qeth_ipato_device_attrs
,
697 static ssize_t
qeth_l3_dev_vipa_add_show(char *buf
, struct qeth_card
*card
,
698 enum qeth_prot_versions proto
)
700 struct qeth_ipaddr
*ipaddr
;
702 int entry_len
; /* length of 1 entry string, differs between v4 and v6 */
706 entry_len
= (proto
== QETH_PROT_IPV4
)? 12 : 40;
707 entry_len
+= 2; /* \n + terminator */
708 spin_lock_irqsave(&card
->ip_lock
, flags
);
709 list_for_each_entry(ipaddr
, &card
->ip_list
, entry
) {
710 if (ipaddr
->proto
!= proto
)
712 if (ipaddr
->type
!= QETH_IP_TYPE_VIPA
)
714 /* String must not be longer than PAGE_SIZE. So we check if
715 * string length gets near PAGE_SIZE. Then we can savely display
716 * the next IPv6 address (worst case, compared to IPv4) */
717 if ((PAGE_SIZE
- i
) <= entry_len
)
719 qeth_l3_ipaddr_to_string(proto
, (const u8
*)&ipaddr
->u
,
721 i
+= snprintf(buf
+ i
, PAGE_SIZE
- i
, "%s\n", addr_str
);
723 spin_unlock_irqrestore(&card
->ip_lock
, flags
);
724 i
+= snprintf(buf
+ i
, PAGE_SIZE
- i
, "\n");
729 static ssize_t
qeth_l3_dev_vipa_add4_show(struct device
*dev
,
730 struct device_attribute
*attr
, char *buf
)
732 struct qeth_card
*card
= dev_get_drvdata(dev
);
737 return qeth_l3_dev_vipa_add_show(buf
, card
, QETH_PROT_IPV4
);
740 static int qeth_l3_parse_vipae(const char *buf
, enum qeth_prot_versions proto
,
743 if (qeth_l3_string_to_ipaddr(buf
, proto
, addr
)) {
749 static ssize_t
qeth_l3_dev_vipa_add_store(const char *buf
, size_t count
,
750 struct qeth_card
*card
, enum qeth_prot_versions proto
)
755 mutex_lock(&card
->conf_mutex
);
756 rc
= qeth_l3_parse_vipae(buf
, proto
, addr
);
758 rc
= qeth_l3_add_vipa(card
, proto
, addr
);
759 mutex_unlock(&card
->conf_mutex
);
760 return rc
? rc
: count
;
763 static ssize_t
qeth_l3_dev_vipa_add4_store(struct device
*dev
,
764 struct device_attribute
*attr
, const char *buf
, size_t count
)
766 struct qeth_card
*card
= dev_get_drvdata(dev
);
771 return qeth_l3_dev_vipa_add_store(buf
, count
, card
, QETH_PROT_IPV4
);
774 static QETH_DEVICE_ATTR(vipa_add4
, add4
, 0644,
775 qeth_l3_dev_vipa_add4_show
,
776 qeth_l3_dev_vipa_add4_store
);
778 static ssize_t
qeth_l3_dev_vipa_del_store(const char *buf
, size_t count
,
779 struct qeth_card
*card
, enum qeth_prot_versions proto
)
784 mutex_lock(&card
->conf_mutex
);
785 rc
= qeth_l3_parse_vipae(buf
, proto
, addr
);
787 qeth_l3_del_vipa(card
, proto
, addr
);
788 mutex_unlock(&card
->conf_mutex
);
789 return rc
? rc
: count
;
792 static ssize_t
qeth_l3_dev_vipa_del4_store(struct device
*dev
,
793 struct device_attribute
*attr
, const char *buf
, size_t count
)
795 struct qeth_card
*card
= dev_get_drvdata(dev
);
800 return qeth_l3_dev_vipa_del_store(buf
, count
, card
, QETH_PROT_IPV4
);
803 static QETH_DEVICE_ATTR(vipa_del4
, del4
, 0200, NULL
,
804 qeth_l3_dev_vipa_del4_store
);
806 static ssize_t
qeth_l3_dev_vipa_add6_show(struct device
*dev
,
807 struct device_attribute
*attr
, char *buf
)
809 struct qeth_card
*card
= dev_get_drvdata(dev
);
814 return qeth_l3_dev_vipa_add_show(buf
, card
, QETH_PROT_IPV6
);
817 static ssize_t
qeth_l3_dev_vipa_add6_store(struct device
*dev
,
818 struct device_attribute
*attr
, const char *buf
, size_t count
)
820 struct qeth_card
*card
= dev_get_drvdata(dev
);
825 return qeth_l3_dev_vipa_add_store(buf
, count
, card
, QETH_PROT_IPV6
);
828 static QETH_DEVICE_ATTR(vipa_add6
, add6
, 0644,
829 qeth_l3_dev_vipa_add6_show
,
830 qeth_l3_dev_vipa_add6_store
);
832 static ssize_t
qeth_l3_dev_vipa_del6_store(struct device
*dev
,
833 struct device_attribute
*attr
, const char *buf
, size_t count
)
835 struct qeth_card
*card
= dev_get_drvdata(dev
);
840 return qeth_l3_dev_vipa_del_store(buf
, count
, card
, QETH_PROT_IPV6
);
843 static QETH_DEVICE_ATTR(vipa_del6
, del6
, 0200, NULL
,
844 qeth_l3_dev_vipa_del6_store
);
846 static struct attribute
*qeth_vipa_device_attrs
[] = {
847 &dev_attr_vipa_add4
.attr
,
848 &dev_attr_vipa_del4
.attr
,
849 &dev_attr_vipa_add6
.attr
,
850 &dev_attr_vipa_del6
.attr
,
854 static struct attribute_group qeth_device_vipa_group
= {
856 .attrs
= qeth_vipa_device_attrs
,
859 static ssize_t
qeth_l3_dev_rxip_add_show(char *buf
, struct qeth_card
*card
,
860 enum qeth_prot_versions proto
)
862 struct qeth_ipaddr
*ipaddr
;
864 int entry_len
; /* length of 1 entry string, differs between v4 and v6 */
868 entry_len
= (proto
== QETH_PROT_IPV4
)? 12 : 40;
869 entry_len
+= 2; /* \n + terminator */
870 spin_lock_irqsave(&card
->ip_lock
, flags
);
871 list_for_each_entry(ipaddr
, &card
->ip_list
, entry
) {
872 if (ipaddr
->proto
!= proto
)
874 if (ipaddr
->type
!= QETH_IP_TYPE_RXIP
)
876 /* String must not be longer than PAGE_SIZE. So we check if
877 * string length gets near PAGE_SIZE. Then we can savely display
878 * the next IPv6 address (worst case, compared to IPv4) */
879 if ((PAGE_SIZE
- i
) <= entry_len
)
881 qeth_l3_ipaddr_to_string(proto
, (const u8
*)&ipaddr
->u
,
883 i
+= snprintf(buf
+ i
, PAGE_SIZE
- i
, "%s\n", addr_str
);
885 spin_unlock_irqrestore(&card
->ip_lock
, flags
);
886 i
+= snprintf(buf
+ i
, PAGE_SIZE
- i
, "\n");
891 static ssize_t
qeth_l3_dev_rxip_add4_show(struct device
*dev
,
892 struct device_attribute
*attr
, char *buf
)
894 struct qeth_card
*card
= dev_get_drvdata(dev
);
899 return qeth_l3_dev_rxip_add_show(buf
, card
, QETH_PROT_IPV4
);
902 static int qeth_l3_parse_rxipe(const char *buf
, enum qeth_prot_versions proto
,
905 if (qeth_l3_string_to_ipaddr(buf
, proto
, addr
)) {
911 static ssize_t
qeth_l3_dev_rxip_add_store(const char *buf
, size_t count
,
912 struct qeth_card
*card
, enum qeth_prot_versions proto
)
917 mutex_lock(&card
->conf_mutex
);
918 rc
= qeth_l3_parse_rxipe(buf
, proto
, addr
);
920 rc
= qeth_l3_add_rxip(card
, proto
, addr
);
921 mutex_unlock(&card
->conf_mutex
);
922 return rc
? rc
: count
;
925 static ssize_t
qeth_l3_dev_rxip_add4_store(struct device
*dev
,
926 struct device_attribute
*attr
, const char *buf
, size_t count
)
928 struct qeth_card
*card
= dev_get_drvdata(dev
);
933 return qeth_l3_dev_rxip_add_store(buf
, count
, card
, QETH_PROT_IPV4
);
936 static QETH_DEVICE_ATTR(rxip_add4
, add4
, 0644,
937 qeth_l3_dev_rxip_add4_show
,
938 qeth_l3_dev_rxip_add4_store
);
940 static ssize_t
qeth_l3_dev_rxip_del_store(const char *buf
, size_t count
,
941 struct qeth_card
*card
, enum qeth_prot_versions proto
)
946 mutex_lock(&card
->conf_mutex
);
947 rc
= qeth_l3_parse_rxipe(buf
, proto
, addr
);
949 qeth_l3_del_rxip(card
, proto
, addr
);
950 mutex_unlock(&card
->conf_mutex
);
951 return rc
? rc
: count
;
954 static ssize_t
qeth_l3_dev_rxip_del4_store(struct device
*dev
,
955 struct device_attribute
*attr
, const char *buf
, size_t count
)
957 struct qeth_card
*card
= dev_get_drvdata(dev
);
962 return qeth_l3_dev_rxip_del_store(buf
, count
, card
, QETH_PROT_IPV4
);
965 static QETH_DEVICE_ATTR(rxip_del4
, del4
, 0200, NULL
,
966 qeth_l3_dev_rxip_del4_store
);
968 static ssize_t
qeth_l3_dev_rxip_add6_show(struct device
*dev
,
969 struct device_attribute
*attr
, char *buf
)
971 struct qeth_card
*card
= dev_get_drvdata(dev
);
976 return qeth_l3_dev_rxip_add_show(buf
, card
, QETH_PROT_IPV6
);
979 static ssize_t
qeth_l3_dev_rxip_add6_store(struct device
*dev
,
980 struct device_attribute
*attr
, const char *buf
, size_t count
)
982 struct qeth_card
*card
= dev_get_drvdata(dev
);
987 return qeth_l3_dev_rxip_add_store(buf
, count
, card
, QETH_PROT_IPV6
);
990 static QETH_DEVICE_ATTR(rxip_add6
, add6
, 0644,
991 qeth_l3_dev_rxip_add6_show
,
992 qeth_l3_dev_rxip_add6_store
);
994 static ssize_t
qeth_l3_dev_rxip_del6_store(struct device
*dev
,
995 struct device_attribute
*attr
, const char *buf
, size_t count
)
997 struct qeth_card
*card
= dev_get_drvdata(dev
);
1002 return qeth_l3_dev_rxip_del_store(buf
, count
, card
, QETH_PROT_IPV6
);
1005 static QETH_DEVICE_ATTR(rxip_del6
, del6
, 0200, NULL
,
1006 qeth_l3_dev_rxip_del6_store
);
1008 static struct attribute
*qeth_rxip_device_attrs
[] = {
1009 &dev_attr_rxip_add4
.attr
,
1010 &dev_attr_rxip_del4
.attr
,
1011 &dev_attr_rxip_add6
.attr
,
1012 &dev_attr_rxip_del6
.attr
,
1016 static struct attribute_group qeth_device_rxip_group
= {
1018 .attrs
= qeth_rxip_device_attrs
,
1021 int qeth_l3_create_device_attributes(struct device
*dev
)
1025 ret
= sysfs_create_group(&dev
->kobj
, &qeth_l3_device_attr_group
);
1029 ret
= sysfs_create_group(&dev
->kobj
, &qeth_device_ipato_group
);
1031 sysfs_remove_group(&dev
->kobj
, &qeth_l3_device_attr_group
);
1035 ret
= sysfs_create_group(&dev
->kobj
, &qeth_device_vipa_group
);
1037 sysfs_remove_group(&dev
->kobj
, &qeth_l3_device_attr_group
);
1038 sysfs_remove_group(&dev
->kobj
, &qeth_device_ipato_group
);
1042 ret
= sysfs_create_group(&dev
->kobj
, &qeth_device_rxip_group
);
1044 sysfs_remove_group(&dev
->kobj
, &qeth_l3_device_attr_group
);
1045 sysfs_remove_group(&dev
->kobj
, &qeth_device_ipato_group
);
1046 sysfs_remove_group(&dev
->kobj
, &qeth_device_vipa_group
);
1052 void qeth_l3_remove_device_attributes(struct device
*dev
)
1054 sysfs_remove_group(&dev
->kobj
, &qeth_l3_device_attr_group
);
1055 sysfs_remove_group(&dev
->kobj
, &qeth_device_ipato_group
);
1056 sysfs_remove_group(&dev
->kobj
, &qeth_device_vipa_group
);
1057 sysfs_remove_group(&dev
->kobj
, &qeth_device_rxip_group
);