PM / sleep: Asynchronous threads for suspend_noirq
[linux/fpc-iii.git] / drivers / s390 / net / qeth_l3_sys.c
blobadef5f5de118a7ed9b320b3cea07672bc511ec36
1 /*
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>
7 */
9 #include <linux/slab.h>
10 #include <asm/ebcdic.h>
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 ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
17 struct qeth_routing_info *route, char *buf)
19 switch (route->type) {
20 case PRIMARY_ROUTER:
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+");
27 else
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+");
32 else
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+");
37 else
38 return sprintf(buf, "%s\n", "secondary connector");
39 default:
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);
49 if (!card)
50 return -EINVAL;
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;
60 char *tmp;
61 int rc = 0;
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;
77 } else {
78 rc = -EINVAL;
79 goto out;
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);
89 out:
90 if (rc)
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);
101 if (!card)
102 return -EINVAL;
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);
116 if (!card)
117 return -EINVAL;
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);
127 if (!card)
128 return -EINVAL;
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);
142 if (!card)
143 return -EINVAL;
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);
152 char *tmp;
153 int i, rc = 0;
155 if (!card)
156 return -EINVAL;
158 mutex_lock(&card->conf_mutex);
159 if ((card->state != CARD_STATE_DOWN) &&
160 (card->state != CARD_STATE_RECOVER)) {
161 rc = -EPERM;
162 goto out;
165 i = simple_strtoul(buf, &tmp, 16);
166 if ((i == 0) || (i == 1))
167 card->options.fake_broadcast = i;
168 else
169 rc = -EINVAL;
170 out:
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);
183 if (!card)
184 return -EINVAL;
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);
193 int rc = 0;
194 unsigned long i;
196 if (!card)
197 return -EINVAL;
199 if (card->info.type != QETH_CARD_TYPE_IQD)
200 return -EPERM;
201 if (card->options.cq == QETH_CQ_ENABLED)
202 return -EPERM;
204 mutex_lock(&card->conf_mutex);
205 if ((card->state != CARD_STATE_DOWN) &&
206 (card->state != CARD_STATE_RECOVER)) {
207 rc = -EPERM;
208 goto out;
211 rc = kstrtoul(buf, 16, &i);
212 if (rc) {
213 rc = -EINVAL;
214 goto out;
216 switch (i) {
217 case 0:
218 card->options.sniffer = i;
219 break;
220 case 1:
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);
228 } else
229 rc = -EPERM;
230 break;
231 default:
232 rc = -EINVAL;
234 out:
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);
247 char tmp_hsuid[9];
249 if (!card)
250 return -EINVAL;
252 if (card->info.type != QETH_CARD_TYPE_IQD)
253 return -EPERM;
255 if (card->state == CARD_STATE_DOWN)
256 return -EPERM;
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;
268 char *tmp;
269 int i;
271 if (!card)
272 return -EINVAL;
274 if (card->info.type != QETH_CARD_TYPE_IQD)
275 return -EPERM;
276 if (card->state != CARD_STATE_DOWN &&
277 card->state != CARD_STATE_RECOVER)
278 return -EPERM;
279 if (card->options.sniffer)
280 return -EPERM;
281 if (card->options.cq == QETH_CQ_NOTAVAILABLE)
282 return -EPERM;
284 tmp = strsep((char **)&buf, "\n");
285 if (strlen(tmp) > 8)
286 return -EINVAL;
288 if (card->options.hsuid[0]) {
289 /* delete old ip address */
290 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
291 if (addr != NULL) {
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;
299 } else
300 return -ENOMEM;
301 if (!qeth_l3_delete_ip(card, addr))
302 kfree(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';
309 if (card->dev)
310 memcpy(card->dev->perm_addr, card->options.hsuid, 9);
311 qeth_configure_cq(card, QETH_CQ_DISABLED);
312 return count;
315 if (qeth_configure_cq(card, QETH_CQ_ENABLED))
316 return -EPERM;
318 snprintf(card->options.hsuid, sizeof(card->options.hsuid),
319 "%-8s", tmp);
320 ASCEBC(card->options.hsuid, 8);
321 if (card->dev)
322 memcpy(card->dev->perm_addr, card->options.hsuid, 9);
324 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
325 if (addr != NULL) {
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;
332 } else
333 return -ENOMEM;
334 if (!qeth_l3_add_ip(card, addr))
335 kfree(addr);
336 qeth_l3_set_ip_addr_list(card);
338 return count;
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,
351 NULL,
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);
363 if (!card)
364 return -EINVAL;
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;
374 char *tmp;
375 int rc = 0;
377 if (!card)
378 return -EINVAL;
380 mutex_lock(&card->conf_mutex);
381 if ((card->state != CARD_STATE_DOWN) &&
382 (card->state != CARD_STATE_RECOVER)) {
383 rc = -EPERM;
384 goto out;
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))
395 tmpipa->set_flags |=
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)
404 tmpipa->set_flags &=
405 ~QETH_IPA_SETIP_TAKEOVER_FLAG;
407 } else
408 rc = -EINVAL;
409 out:
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);
423 if (!card)
424 return -EINVAL;
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);
434 char *tmp;
435 int rc = 0;
437 if (!card)
438 return -EINVAL;
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;
448 } else
449 rc = -EINVAL;
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;
462 unsigned long flags;
463 char addr_str[40];
464 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
465 int i = 0;
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)
473 continue;
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)
478 break;
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");
486 return i;
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);
494 if (!card)
495 return -EINVAL;
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;
504 char *tmp;
505 char buffer[40] = {0, };
507 start = buf;
508 /* get address string */
509 end = strchr(start, '/');
510 if (!end || (end - start >= 40)) {
511 return -EINVAL;
513 strncpy(buffer, start, end - start);
514 if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
515 return -EINVAL;
517 start = end + 1;
518 *mask_bits = simple_strtoul(start, &tmp, 10);
519 if (!strlen(start) ||
520 (tmp == start) ||
521 (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
522 return -EINVAL;
524 return 0;
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;
531 u8 addr[16];
532 int mask_bits;
533 int rc = 0;
535 mutex_lock(&card->conf_mutex);
536 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
537 if (rc)
538 goto out;
540 ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
541 if (!ipatoe) {
542 rc = -ENOMEM;
543 goto out;
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);
550 if (rc)
551 kfree(ipatoe);
552 out:
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);
562 if (!card)
563 return -EINVAL;
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)
575 u8 addr[16];
576 int mask_bits;
577 int rc = 0;
579 mutex_lock(&card->conf_mutex);
580 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
581 if (!rc)
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);
592 if (!card)
593 return -EINVAL;
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);
606 if (!card)
607 return -EINVAL;
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);
616 char *tmp;
617 int rc = 0;
619 if (!card)
620 return -EINVAL;
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;
630 } else
631 rc = -EINVAL;
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);
646 if (!card)
647 return -EINVAL;
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);
657 if (!card)
658 return -EINVAL;
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);
672 if (!card)
673 return -EINVAL;
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,
689 NULL,
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;
701 char addr_str[40];
702 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
703 unsigned long flags;
704 int i = 0;
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)
711 continue;
712 if (ipaddr->type != QETH_IP_TYPE_VIPA)
713 continue;
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)
718 break;
719 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
720 addr_str);
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");
726 return i;
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);
734 if (!card)
735 return -EINVAL;
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,
741 u8 *addr)
743 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
744 return -EINVAL;
746 return 0;
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)
752 u8 addr[16] = {0, };
753 int rc;
755 mutex_lock(&card->conf_mutex);
756 rc = qeth_l3_parse_vipae(buf, proto, addr);
757 if (!rc)
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);
768 if (!card)
769 return -EINVAL;
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)
781 u8 addr[16];
782 int rc;
784 mutex_lock(&card->conf_mutex);
785 rc = qeth_l3_parse_vipae(buf, proto, addr);
786 if (!rc)
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);
797 if (!card)
798 return -EINVAL;
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);
811 if (!card)
812 return -EINVAL;
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);
822 if (!card)
823 return -EINVAL;
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);
837 if (!card)
838 return -EINVAL;
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,
851 NULL,
854 static struct attribute_group qeth_device_vipa_group = {
855 .name = "vipa",
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;
863 char addr_str[40];
864 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
865 unsigned long flags;
866 int i = 0;
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)
873 continue;
874 if (ipaddr->type != QETH_IP_TYPE_RXIP)
875 continue;
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)
880 break;
881 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
882 addr_str);
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");
888 return i;
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);
896 if (!card)
897 return -EINVAL;
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,
903 u8 *addr)
905 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
906 return -EINVAL;
908 return 0;
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)
914 u8 addr[16] = {0, };
915 int rc;
917 mutex_lock(&card->conf_mutex);
918 rc = qeth_l3_parse_rxipe(buf, proto, addr);
919 if (!rc)
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);
930 if (!card)
931 return -EINVAL;
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)
943 u8 addr[16];
944 int rc;
946 mutex_lock(&card->conf_mutex);
947 rc = qeth_l3_parse_rxipe(buf, proto, addr);
948 if (!rc)
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);
959 if (!card)
960 return -EINVAL;
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);
973 if (!card)
974 return -EINVAL;
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);
984 if (!card)
985 return -EINVAL;
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);
999 if (!card)
1000 return -EINVAL;
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,
1013 NULL,
1016 static struct attribute_group qeth_device_rxip_group = {
1017 .name = "rxip",
1018 .attrs = qeth_rxip_device_attrs,
1021 int qeth_l3_create_device_attributes(struct device *dev)
1023 int ret;
1025 ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
1026 if (ret)
1027 return ret;
1029 ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
1030 if (ret) {
1031 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1032 return ret;
1035 ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1036 if (ret) {
1037 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1038 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1039 return ret;
1042 ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1043 if (ret) {
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);
1047 return ret;
1049 return 0;
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);