Linux 2.6.34-rc3
[pohmelfs.git] / drivers / s390 / net / qeth_l3_sys.c
blob3f08b11274aeede53cffa6822738ebd4f5ed1396
1 /*
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>
9 */
11 #include "qeth_l3.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 const char *qeth_l3_get_checksum_str(struct qeth_card *card)
18 if (card->options.checksum_type == SW_CHECKSUMMING)
19 return "sw";
20 else if (card->options.checksum_type == HW_CHECKSUMMING)
21 return "hw";
22 else
23 return "no";
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) {
30 case PRIMARY_ROUTER:
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+");
37 else
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+");
42 else
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+");
47 else
48 return sprintf(buf, "%s\n", "secondary connector");
49 default:
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);
59 if (!card)
60 return -EINVAL;
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;
70 char *tmp;
71 int rc;
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;
87 } else {
88 return -EINVAL;
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);
98 return count;
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);
106 if (!card)
107 return -EINVAL;
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);
121 if (!card)
122 return -EINVAL;
124 return qeth_l3_dev_route_show(card, &card->options.route6, buf);
127 static ssize_t qeth_l3_dev_route6_store(struct device *dev,
128 struct device_attribute *attr, const char *buf, size_t count)
130 struct qeth_card *card = dev_get_drvdata(dev);
132 if (!card)
133 return -EINVAL;
135 return qeth_l3_dev_route_store(card, &card->options.route6,
136 QETH_PROT_IPV6, buf, count);
139 static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show,
140 qeth_l3_dev_route6_store);
142 static ssize_t qeth_l3_dev_fake_broadcast_show(struct device *dev,
143 struct device_attribute *attr, char *buf)
145 struct qeth_card *card = dev_get_drvdata(dev);
147 if (!card)
148 return -EINVAL;
150 return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
153 static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev,
154 struct device_attribute *attr, const char *buf, size_t count)
156 struct qeth_card *card = dev_get_drvdata(dev);
157 char *tmp;
158 int i;
160 if (!card)
161 return -EINVAL;
163 if ((card->state != CARD_STATE_DOWN) &&
164 (card->state != CARD_STATE_RECOVER))
165 return -EPERM;
167 i = simple_strtoul(buf, &tmp, 16);
168 if ((i == 0) || (i == 1))
169 card->options.fake_broadcast = i;
170 else {
171 return -EINVAL;
173 return count;
176 static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show,
177 qeth_l3_dev_fake_broadcast_store);
179 static ssize_t qeth_l3_dev_broadcast_mode_show(struct device *dev,
180 struct device_attribute *attr, char *buf)
182 struct qeth_card *card = dev_get_drvdata(dev);
184 if (!card)
185 return -EINVAL;
187 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
188 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
189 return sprintf(buf, "n/a\n");
191 return sprintf(buf, "%s\n", (card->options.broadcast_mode ==
192 QETH_TR_BROADCAST_ALLRINGS)?
193 "all rings":"local");
196 static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev,
197 struct device_attribute *attr, const char *buf, size_t count)
199 struct qeth_card *card = dev_get_drvdata(dev);
200 char *tmp;
202 if (!card)
203 return -EINVAL;
205 if ((card->state != CARD_STATE_DOWN) &&
206 (card->state != CARD_STATE_RECOVER))
207 return -EPERM;
209 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
210 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
211 return -EINVAL;
214 tmp = strsep((char **) &buf, "\n");
216 if (!strcmp(tmp, "local")) {
217 card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL;
218 return count;
219 } else if (!strcmp(tmp, "all_rings")) {
220 card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
221 return count;
222 } else {
223 return -EINVAL;
225 return count;
228 static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show,
229 qeth_l3_dev_broadcast_mode_store);
231 static ssize_t qeth_l3_dev_canonical_macaddr_show(struct device *dev,
232 struct device_attribute *attr, char *buf)
234 struct qeth_card *card = dev_get_drvdata(dev);
236 if (!card)
237 return -EINVAL;
239 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
240 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
241 return sprintf(buf, "n/a\n");
243 return sprintf(buf, "%i\n", (card->options.macaddr_mode ==
244 QETH_TR_MACADDR_CANONICAL)? 1:0);
247 static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev,
248 struct device_attribute *attr, const char *buf, size_t count)
250 struct qeth_card *card = dev_get_drvdata(dev);
251 char *tmp;
252 int i;
254 if (!card)
255 return -EINVAL;
257 if ((card->state != CARD_STATE_DOWN) &&
258 (card->state != CARD_STATE_RECOVER))
259 return -EPERM;
261 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
262 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
263 return -EINVAL;
266 i = simple_strtoul(buf, &tmp, 16);
267 if ((i == 0) || (i == 1))
268 card->options.macaddr_mode = i?
269 QETH_TR_MACADDR_CANONICAL :
270 QETH_TR_MACADDR_NONCANONICAL;
271 else {
272 return -EINVAL;
274 return count;
277 static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show,
278 qeth_l3_dev_canonical_macaddr_store);
280 static ssize_t qeth_l3_dev_checksum_show(struct device *dev,
281 struct device_attribute *attr, char *buf)
283 struct qeth_card *card = dev_get_drvdata(dev);
285 if (!card)
286 return -EINVAL;
288 return sprintf(buf, "%s checksumming\n",
289 qeth_l3_get_checksum_str(card));
292 static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
293 struct device_attribute *attr, const char *buf, size_t count)
295 struct qeth_card *card = dev_get_drvdata(dev);
296 enum qeth_checksum_types csum_type;
297 char *tmp;
298 int rc;
300 if (!card)
301 return -EINVAL;
303 tmp = strsep((char **) &buf, "\n");
304 if (!strcmp(tmp, "sw_checksumming"))
305 csum_type = SW_CHECKSUMMING;
306 else if (!strcmp(tmp, "hw_checksumming"))
307 csum_type = HW_CHECKSUMMING;
308 else if (!strcmp(tmp, "no_checksumming"))
309 csum_type = NO_CHECKSUMMING;
310 else
311 return -EINVAL;
313 rc = qeth_l3_set_rx_csum(card, csum_type);
314 if (rc)
315 return rc;
316 return count;
319 static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
320 qeth_l3_dev_checksum_store);
322 static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
323 struct device_attribute *attr, char *buf)
325 struct qeth_card *card = dev_get_drvdata(dev);
327 if (!card)
328 return -EINVAL;
330 return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
333 static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
334 struct device_attribute *attr, const char *buf, size_t count)
336 struct qeth_card *card = dev_get_drvdata(dev);
337 int ret;
338 unsigned long i;
340 if (!card)
341 return -EINVAL;
343 if (card->info.type != QETH_CARD_TYPE_IQD)
344 return -EPERM;
346 if ((card->state != CARD_STATE_DOWN) &&
347 (card->state != CARD_STATE_RECOVER))
348 return -EPERM;
350 ret = strict_strtoul(buf, 16, &i);
351 if (ret)
352 return -EINVAL;
353 switch (i) {
354 case 0:
355 card->options.sniffer = i;
356 break;
357 case 1:
358 ret = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
359 if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
360 card->options.sniffer = i;
361 if (card->qdio.init_pool.buf_count !=
362 QETH_IN_BUF_COUNT_MAX)
363 qeth_realloc_buffer_pool(card,
364 QETH_IN_BUF_COUNT_MAX);
365 break;
366 } else
367 return -EPERM;
368 default: /* fall through */
369 return -EINVAL;
371 return count;
374 static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
375 qeth_l3_dev_sniffer_store);
377 static ssize_t qeth_l3_dev_large_send_show(struct device *dev,
378 struct device_attribute *attr, char *buf)
380 struct qeth_card *card = dev_get_drvdata(dev);
382 if (!card)
383 return -EINVAL;
385 switch (card->options.large_send) {
386 case QETH_LARGE_SEND_NO:
387 return sprintf(buf, "%s\n", "no");
388 case QETH_LARGE_SEND_TSO:
389 return sprintf(buf, "%s\n", "TSO");
390 default:
391 return sprintf(buf, "%s\n", "N/A");
395 static ssize_t qeth_l3_dev_large_send_store(struct device *dev,
396 struct device_attribute *attr, const char *buf, size_t count)
398 struct qeth_card *card = dev_get_drvdata(dev);
399 enum qeth_large_send_types type;
400 int rc = 0;
401 char *tmp;
403 if (!card)
404 return -EINVAL;
405 tmp = strsep((char **) &buf, "\n");
406 if (!strcmp(tmp, "no"))
407 type = QETH_LARGE_SEND_NO;
408 else if (!strcmp(tmp, "TSO"))
409 type = QETH_LARGE_SEND_TSO;
410 else
411 return -EINVAL;
413 if (card->options.large_send == type)
414 return count;
415 rc = qeth_l3_set_large_send(card, type);
416 if (rc)
417 return rc;
418 return count;
421 static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show,
422 qeth_l3_dev_large_send_store);
424 static struct attribute *qeth_l3_device_attrs[] = {
425 &dev_attr_route4.attr,
426 &dev_attr_route6.attr,
427 &dev_attr_fake_broadcast.attr,
428 &dev_attr_broadcast_mode.attr,
429 &dev_attr_canonical_macaddr.attr,
430 &dev_attr_checksumming.attr,
431 &dev_attr_sniffer.attr,
432 &dev_attr_large_send.attr,
433 NULL,
436 static struct attribute_group qeth_l3_device_attr_group = {
437 .attrs = qeth_l3_device_attrs,
440 static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
441 struct device_attribute *attr, char *buf)
443 struct qeth_card *card = dev_get_drvdata(dev);
445 if (!card)
446 return -EINVAL;
448 return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
451 static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
452 struct device_attribute *attr, const char *buf, size_t count)
454 struct qeth_card *card = dev_get_drvdata(dev);
455 char *tmp;
457 if (!card)
458 return -EINVAL;
460 if ((card->state != CARD_STATE_DOWN) &&
461 (card->state != CARD_STATE_RECOVER))
462 return -EPERM;
464 tmp = strsep((char **) &buf, "\n");
465 if (!strcmp(tmp, "toggle")) {
466 card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
467 } else if (!strcmp(tmp, "1")) {
468 card->ipato.enabled = 1;
469 } else if (!strcmp(tmp, "0")) {
470 card->ipato.enabled = 0;
471 } else {
472 return -EINVAL;
474 return count;
477 static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
478 qeth_l3_dev_ipato_enable_show,
479 qeth_l3_dev_ipato_enable_store);
481 static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
482 struct device_attribute *attr, char *buf)
484 struct qeth_card *card = dev_get_drvdata(dev);
486 if (!card)
487 return -EINVAL;
489 return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
492 static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
493 struct device_attribute *attr,
494 const char *buf, size_t count)
496 struct qeth_card *card = dev_get_drvdata(dev);
497 char *tmp;
499 if (!card)
500 return -EINVAL;
502 tmp = strsep((char **) &buf, "\n");
503 if (!strcmp(tmp, "toggle")) {
504 card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
505 } else if (!strcmp(tmp, "1")) {
506 card->ipato.invert4 = 1;
507 } else if (!strcmp(tmp, "0")) {
508 card->ipato.invert4 = 0;
509 } else {
510 return -EINVAL;
512 return count;
515 static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
516 qeth_l3_dev_ipato_invert4_show,
517 qeth_l3_dev_ipato_invert4_store);
519 static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
520 enum qeth_prot_versions proto)
522 struct qeth_ipato_entry *ipatoe;
523 unsigned long flags;
524 char addr_str[40];
525 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
526 int i = 0;
528 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
529 /* add strlen for "/<mask>\n" */
530 entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
531 spin_lock_irqsave(&card->ip_lock, flags);
532 list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
533 if (ipatoe->proto != proto)
534 continue;
535 /* String must not be longer than PAGE_SIZE. So we check if
536 * string length gets near PAGE_SIZE. Then we can savely display
537 * the next IPv6 address (worst case, compared to IPv4) */
538 if ((PAGE_SIZE - i) <= entry_len)
539 break;
540 qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
541 i += snprintf(buf + i, PAGE_SIZE - i,
542 "%s/%i\n", addr_str, ipatoe->mask_bits);
544 spin_unlock_irqrestore(&card->ip_lock, flags);
545 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
547 return i;
550 static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
551 struct device_attribute *attr, char *buf)
553 struct qeth_card *card = dev_get_drvdata(dev);
555 if (!card)
556 return -EINVAL;
558 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
561 static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
562 u8 *addr, int *mask_bits)
564 const char *start, *end;
565 char *tmp;
566 char buffer[40] = {0, };
568 start = buf;
569 /* get address string */
570 end = strchr(start, '/');
571 if (!end || (end - start >= 40)) {
572 return -EINVAL;
574 strncpy(buffer, start, end - start);
575 if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
576 return -EINVAL;
578 start = end + 1;
579 *mask_bits = simple_strtoul(start, &tmp, 10);
580 if (!strlen(start) ||
581 (tmp == start) ||
582 (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
583 return -EINVAL;
585 return 0;
588 static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
589 struct qeth_card *card, enum qeth_prot_versions proto)
591 struct qeth_ipato_entry *ipatoe;
592 u8 addr[16];
593 int mask_bits;
594 int rc;
596 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
597 if (rc)
598 return rc;
600 ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
601 if (!ipatoe) {
602 return -ENOMEM;
604 ipatoe->proto = proto;
605 memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
606 ipatoe->mask_bits = mask_bits;
608 rc = qeth_l3_add_ipato_entry(card, ipatoe);
609 if (rc) {
610 kfree(ipatoe);
611 return rc;
614 return count;
617 static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
618 struct device_attribute *attr, const char *buf, size_t count)
620 struct qeth_card *card = dev_get_drvdata(dev);
622 if (!card)
623 return -EINVAL;
625 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
628 static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
629 qeth_l3_dev_ipato_add4_show,
630 qeth_l3_dev_ipato_add4_store);
632 static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
633 struct qeth_card *card, enum qeth_prot_versions proto)
635 u8 addr[16];
636 int mask_bits;
637 int rc;
639 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
640 if (rc)
641 return rc;
643 qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
645 return count;
648 static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
649 struct device_attribute *attr, const char *buf, size_t count)
651 struct qeth_card *card = dev_get_drvdata(dev);
653 if (!card)
654 return -EINVAL;
656 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
659 static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
660 qeth_l3_dev_ipato_del4_store);
662 static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
663 struct device_attribute *attr, char *buf)
665 struct qeth_card *card = dev_get_drvdata(dev);
667 if (!card)
668 return -EINVAL;
670 return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
673 static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
674 struct device_attribute *attr, const char *buf, size_t count)
676 struct qeth_card *card = dev_get_drvdata(dev);
677 char *tmp;
679 if (!card)
680 return -EINVAL;
682 tmp = strsep((char **) &buf, "\n");
683 if (!strcmp(tmp, "toggle")) {
684 card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
685 } else if (!strcmp(tmp, "1")) {
686 card->ipato.invert6 = 1;
687 } else if (!strcmp(tmp, "0")) {
688 card->ipato.invert6 = 0;
689 } else {
690 return -EINVAL;
692 return count;
695 static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
696 qeth_l3_dev_ipato_invert6_show,
697 qeth_l3_dev_ipato_invert6_store);
700 static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
701 struct device_attribute *attr, char *buf)
703 struct qeth_card *card = dev_get_drvdata(dev);
705 if (!card)
706 return -EINVAL;
708 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
711 static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
712 struct device_attribute *attr, const char *buf, size_t count)
714 struct qeth_card *card = dev_get_drvdata(dev);
716 if (!card)
717 return -EINVAL;
719 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
722 static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
723 qeth_l3_dev_ipato_add6_show,
724 qeth_l3_dev_ipato_add6_store);
726 static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
727 struct device_attribute *attr, const char *buf, size_t count)
729 struct qeth_card *card = dev_get_drvdata(dev);
731 if (!card)
732 return -EINVAL;
734 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
737 static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
738 qeth_l3_dev_ipato_del6_store);
740 static struct attribute *qeth_ipato_device_attrs[] = {
741 &dev_attr_ipato_enable.attr,
742 &dev_attr_ipato_invert4.attr,
743 &dev_attr_ipato_add4.attr,
744 &dev_attr_ipato_del4.attr,
745 &dev_attr_ipato_invert6.attr,
746 &dev_attr_ipato_add6.attr,
747 &dev_attr_ipato_del6.attr,
748 NULL,
751 static struct attribute_group qeth_device_ipato_group = {
752 .name = "ipa_takeover",
753 .attrs = qeth_ipato_device_attrs,
756 static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
757 enum qeth_prot_versions proto)
759 struct qeth_ipaddr *ipaddr;
760 char addr_str[40];
761 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
762 unsigned long flags;
763 int i = 0;
765 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
766 entry_len += 2; /* \n + terminator */
767 spin_lock_irqsave(&card->ip_lock, flags);
768 list_for_each_entry(ipaddr, &card->ip_list, entry) {
769 if (ipaddr->proto != proto)
770 continue;
771 if (ipaddr->type != QETH_IP_TYPE_VIPA)
772 continue;
773 /* String must not be longer than PAGE_SIZE. So we check if
774 * string length gets near PAGE_SIZE. Then we can savely display
775 * the next IPv6 address (worst case, compared to IPv4) */
776 if ((PAGE_SIZE - i) <= entry_len)
777 break;
778 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
779 addr_str);
780 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
782 spin_unlock_irqrestore(&card->ip_lock, flags);
783 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
785 return i;
788 static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
789 struct device_attribute *attr, char *buf)
791 struct qeth_card *card = dev_get_drvdata(dev);
793 if (!card)
794 return -EINVAL;
796 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
799 static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
800 u8 *addr)
802 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
803 return -EINVAL;
805 return 0;
808 static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
809 struct qeth_card *card, enum qeth_prot_versions proto)
811 u8 addr[16] = {0, };
812 int rc;
814 rc = qeth_l3_parse_vipae(buf, proto, addr);
815 if (rc)
816 return rc;
818 rc = qeth_l3_add_vipa(card, proto, addr);
819 if (rc)
820 return rc;
822 return count;
825 static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
826 struct device_attribute *attr, const char *buf, size_t count)
828 struct qeth_card *card = dev_get_drvdata(dev);
830 if (!card)
831 return -EINVAL;
833 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
836 static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
837 qeth_l3_dev_vipa_add4_show,
838 qeth_l3_dev_vipa_add4_store);
840 static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
841 struct qeth_card *card, enum qeth_prot_versions proto)
843 u8 addr[16];
844 int rc;
846 rc = qeth_l3_parse_vipae(buf, proto, addr);
847 if (rc)
848 return rc;
850 qeth_l3_del_vipa(card, proto, addr);
852 return count;
855 static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
856 struct device_attribute *attr, const char *buf, size_t count)
858 struct qeth_card *card = dev_get_drvdata(dev);
860 if (!card)
861 return -EINVAL;
863 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
866 static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
867 qeth_l3_dev_vipa_del4_store);
869 static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
870 struct device_attribute *attr, char *buf)
872 struct qeth_card *card = dev_get_drvdata(dev);
874 if (!card)
875 return -EINVAL;
877 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
880 static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
881 struct device_attribute *attr, const char *buf, size_t count)
883 struct qeth_card *card = dev_get_drvdata(dev);
885 if (!card)
886 return -EINVAL;
888 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
891 static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
892 qeth_l3_dev_vipa_add6_show,
893 qeth_l3_dev_vipa_add6_store);
895 static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
896 struct device_attribute *attr, const char *buf, size_t count)
898 struct qeth_card *card = dev_get_drvdata(dev);
900 if (!card)
901 return -EINVAL;
903 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
906 static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
907 qeth_l3_dev_vipa_del6_store);
909 static struct attribute *qeth_vipa_device_attrs[] = {
910 &dev_attr_vipa_add4.attr,
911 &dev_attr_vipa_del4.attr,
912 &dev_attr_vipa_add6.attr,
913 &dev_attr_vipa_del6.attr,
914 NULL,
917 static struct attribute_group qeth_device_vipa_group = {
918 .name = "vipa",
919 .attrs = qeth_vipa_device_attrs,
922 static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
923 enum qeth_prot_versions proto)
925 struct qeth_ipaddr *ipaddr;
926 char addr_str[40];
927 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
928 unsigned long flags;
929 int i = 0;
931 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
932 entry_len += 2; /* \n + terminator */
933 spin_lock_irqsave(&card->ip_lock, flags);
934 list_for_each_entry(ipaddr, &card->ip_list, entry) {
935 if (ipaddr->proto != proto)
936 continue;
937 if (ipaddr->type != QETH_IP_TYPE_RXIP)
938 continue;
939 /* String must not be longer than PAGE_SIZE. So we check if
940 * string length gets near PAGE_SIZE. Then we can savely display
941 * the next IPv6 address (worst case, compared to IPv4) */
942 if ((PAGE_SIZE - i) <= entry_len)
943 break;
944 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
945 addr_str);
946 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
948 spin_unlock_irqrestore(&card->ip_lock, flags);
949 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
951 return i;
954 static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
955 struct device_attribute *attr, char *buf)
957 struct qeth_card *card = dev_get_drvdata(dev);
959 if (!card)
960 return -EINVAL;
962 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
965 static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
966 u8 *addr)
968 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
969 return -EINVAL;
971 return 0;
974 static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
975 struct qeth_card *card, enum qeth_prot_versions proto)
977 u8 addr[16] = {0, };
978 int rc;
980 rc = qeth_l3_parse_rxipe(buf, proto, addr);
981 if (rc)
982 return rc;
984 rc = qeth_l3_add_rxip(card, proto, addr);
985 if (rc)
986 return rc;
988 return count;
991 static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
992 struct device_attribute *attr, const char *buf, size_t count)
994 struct qeth_card *card = dev_get_drvdata(dev);
996 if (!card)
997 return -EINVAL;
999 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
1002 static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
1003 qeth_l3_dev_rxip_add4_show,
1004 qeth_l3_dev_rxip_add4_store);
1006 static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
1007 struct qeth_card *card, enum qeth_prot_versions proto)
1009 u8 addr[16];
1010 int rc;
1012 rc = qeth_l3_parse_rxipe(buf, proto, addr);
1013 if (rc)
1014 return rc;
1016 qeth_l3_del_rxip(card, proto, addr);
1018 return count;
1021 static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
1022 struct device_attribute *attr, const char *buf, size_t count)
1024 struct qeth_card *card = dev_get_drvdata(dev);
1026 if (!card)
1027 return -EINVAL;
1029 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
1032 static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
1033 qeth_l3_dev_rxip_del4_store);
1035 static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
1036 struct device_attribute *attr, char *buf)
1038 struct qeth_card *card = dev_get_drvdata(dev);
1040 if (!card)
1041 return -EINVAL;
1043 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
1046 static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
1047 struct device_attribute *attr, const char *buf, size_t count)
1049 struct qeth_card *card = dev_get_drvdata(dev);
1051 if (!card)
1052 return -EINVAL;
1054 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
1057 static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
1058 qeth_l3_dev_rxip_add6_show,
1059 qeth_l3_dev_rxip_add6_store);
1061 static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
1062 struct device_attribute *attr, const char *buf, size_t count)
1064 struct qeth_card *card = dev_get_drvdata(dev);
1066 if (!card)
1067 return -EINVAL;
1069 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
1072 static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
1073 qeth_l3_dev_rxip_del6_store);
1075 static struct attribute *qeth_rxip_device_attrs[] = {
1076 &dev_attr_rxip_add4.attr,
1077 &dev_attr_rxip_del4.attr,
1078 &dev_attr_rxip_add6.attr,
1079 &dev_attr_rxip_del6.attr,
1080 NULL,
1083 static struct attribute_group qeth_device_rxip_group = {
1084 .name = "rxip",
1085 .attrs = qeth_rxip_device_attrs,
1088 int qeth_l3_create_device_attributes(struct device *dev)
1090 int ret;
1092 ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
1093 if (ret)
1094 return ret;
1096 ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
1097 if (ret) {
1098 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1099 return ret;
1102 ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1103 if (ret) {
1104 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1105 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1106 return ret;
1109 ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1110 if (ret) {
1111 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1112 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1113 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1114 return ret;
1116 return 0;
1119 void qeth_l3_remove_device_attributes(struct device *dev)
1121 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1122 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1123 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1124 sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);