xref: /openbmc/linux/drivers/s390/net/qeth_l3_sys.c (revision 14cc21b6)
1 /*
2  *  drivers/s390/net/qeth_l3_sys.c
3  *
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  */
10 
11 #include "qeth_l3.h"
12 
13 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
14 struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
15 
16 static const char *qeth_l3_get_checksum_str(struct qeth_card *card)
17 {
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";
24 }
25 
26 static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
27 			struct qeth_routing_info *route, char *buf)
28 {
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");
51 	}
52 }
53 
54 static ssize_t qeth_l3_dev_route4_show(struct device *dev,
55 			struct device_attribute *attr, char *buf)
56 {
57 	struct qeth_card *card = dev_get_drvdata(dev);
58 
59 	if (!card)
60 		return -EINVAL;
61 
62 	return qeth_l3_dev_route_show(card, &card->options.route4, buf);
63 }
64 
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)
68 {
69 	enum qeth_routing_types old_route_type = route->type;
70 	char *tmp;
71 	int rc;
72 
73 	tmp = strsep((char **) &buf, "\n");
74 
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;
89 	}
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);
97 	}
98 	return count;
99 }
100 
101 static ssize_t qeth_l3_dev_route4_store(struct device *dev,
102 		struct device_attribute *attr, const char *buf, size_t count)
103 {
104 	struct qeth_card *card = dev_get_drvdata(dev);
105 
106 	if (!card)
107 		return -EINVAL;
108 
109 	return qeth_l3_dev_route_store(card, &card->options.route4,
110 				QETH_PROT_IPV4, buf, count);
111 }
112 
113 static DEVICE_ATTR(route4, 0644, qeth_l3_dev_route4_show,
114 			qeth_l3_dev_route4_store);
115 
116 static ssize_t qeth_l3_dev_route6_show(struct device *dev,
117 			struct device_attribute *attr, char *buf)
118 {
119 	struct qeth_card *card = dev_get_drvdata(dev);
120 
121 	if (!card)
122 		return -EINVAL;
123 
124 	if (!qeth_is_supported(card, IPA_IPV6))
125 		return sprintf(buf, "%s\n", "n/a");
126 
127 	return qeth_l3_dev_route_show(card, &card->options.route6, buf);
128 }
129 
130 static ssize_t qeth_l3_dev_route6_store(struct device *dev,
131 		struct device_attribute *attr, const char *buf, size_t count)
132 {
133 	struct qeth_card *card = dev_get_drvdata(dev);
134 
135 	if (!card)
136 		return -EINVAL;
137 
138 	if (!qeth_is_supported(card, IPA_IPV6)) {
139 		return -ENOTSUPP;
140 	}
141 
142 	return qeth_l3_dev_route_store(card, &card->options.route6,
143 				QETH_PROT_IPV6, buf, count);
144 }
145 
146 static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show,
147 			qeth_l3_dev_route6_store);
148 
149 static ssize_t qeth_l3_dev_fake_broadcast_show(struct device *dev,
150 			struct device_attribute *attr, char *buf)
151 {
152 	struct qeth_card *card = dev_get_drvdata(dev);
153 
154 	if (!card)
155 		return -EINVAL;
156 
157 	return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
158 }
159 
160 static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev,
161 		struct device_attribute *attr, const char *buf, size_t count)
162 {
163 	struct qeth_card *card = dev_get_drvdata(dev);
164 	char *tmp;
165 	int i;
166 
167 	if (!card)
168 		return -EINVAL;
169 
170 	if ((card->state != CARD_STATE_DOWN) &&
171 	    (card->state != CARD_STATE_RECOVER))
172 		return -EPERM;
173 
174 	i = simple_strtoul(buf, &tmp, 16);
175 	if ((i == 0) || (i == 1))
176 		card->options.fake_broadcast = i;
177 	else {
178 		return -EINVAL;
179 	}
180 	return count;
181 }
182 
183 static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show,
184 		   qeth_l3_dev_fake_broadcast_store);
185 
186 static ssize_t qeth_l3_dev_broadcast_mode_show(struct device *dev,
187 				struct device_attribute *attr, char *buf)
188 {
189 	struct qeth_card *card = dev_get_drvdata(dev);
190 
191 	if (!card)
192 		return -EINVAL;
193 
194 	if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
195 	      (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
196 		return sprintf(buf, "n/a\n");
197 
198 	return sprintf(buf, "%s\n", (card->options.broadcast_mode ==
199 				     QETH_TR_BROADCAST_ALLRINGS)?
200 		       "all rings":"local");
201 }
202 
203 static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev,
204 		struct device_attribute *attr, const char *buf, size_t count)
205 {
206 	struct qeth_card *card = dev_get_drvdata(dev);
207 	char *tmp;
208 
209 	if (!card)
210 		return -EINVAL;
211 
212 	if ((card->state != CARD_STATE_DOWN) &&
213 	    (card->state != CARD_STATE_RECOVER))
214 		return -EPERM;
215 
216 	if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
217 	      (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
218 		return -EINVAL;
219 	}
220 
221 	tmp = strsep((char **) &buf, "\n");
222 
223 	if (!strcmp(tmp, "local")) {
224 		card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL;
225 		return count;
226 	} else if (!strcmp(tmp, "all_rings")) {
227 		card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
228 		return count;
229 	} else {
230 		return -EINVAL;
231 	}
232 	return count;
233 }
234 
235 static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show,
236 		   qeth_l3_dev_broadcast_mode_store);
237 
238 static ssize_t qeth_l3_dev_canonical_macaddr_show(struct device *dev,
239 				struct device_attribute *attr, char *buf)
240 {
241 	struct qeth_card *card = dev_get_drvdata(dev);
242 
243 	if (!card)
244 		return -EINVAL;
245 
246 	if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
247 	      (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
248 		return sprintf(buf, "n/a\n");
249 
250 	return sprintf(buf, "%i\n", (card->options.macaddr_mode ==
251 				     QETH_TR_MACADDR_CANONICAL)? 1:0);
252 }
253 
254 static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev,
255 		struct device_attribute *attr, const char *buf, size_t count)
256 {
257 	struct qeth_card *card = dev_get_drvdata(dev);
258 	char *tmp;
259 	int i;
260 
261 	if (!card)
262 		return -EINVAL;
263 
264 	if ((card->state != CARD_STATE_DOWN) &&
265 	    (card->state != CARD_STATE_RECOVER))
266 		return -EPERM;
267 
268 	if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
269 	      (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
270 		return -EINVAL;
271 	}
272 
273 	i = simple_strtoul(buf, &tmp, 16);
274 	if ((i == 0) || (i == 1))
275 		card->options.macaddr_mode = i?
276 			QETH_TR_MACADDR_CANONICAL :
277 			QETH_TR_MACADDR_NONCANONICAL;
278 	else {
279 		return -EINVAL;
280 	}
281 	return count;
282 }
283 
284 static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show,
285 		   qeth_l3_dev_canonical_macaddr_store);
286 
287 static ssize_t qeth_l3_dev_checksum_show(struct device *dev,
288 			struct device_attribute *attr, char *buf)
289 {
290 	struct qeth_card *card = dev_get_drvdata(dev);
291 
292 	if (!card)
293 		return -EINVAL;
294 
295 	return sprintf(buf, "%s checksumming\n",
296 			qeth_l3_get_checksum_str(card));
297 }
298 
299 static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
300 		struct device_attribute *attr, const char *buf, size_t count)
301 {
302 	struct qeth_card *card = dev_get_drvdata(dev);
303 	char *tmp;
304 
305 	if (!card)
306 		return -EINVAL;
307 
308 	if ((card->state != CARD_STATE_DOWN) &&
309 	    (card->state != CARD_STATE_RECOVER))
310 		return -EPERM;
311 
312 	tmp = strsep((char **) &buf, "\n");
313 	if (!strcmp(tmp, "sw_checksumming"))
314 		card->options.checksum_type = SW_CHECKSUMMING;
315 	else if (!strcmp(tmp, "hw_checksumming"))
316 		card->options.checksum_type = HW_CHECKSUMMING;
317 	else if (!strcmp(tmp, "no_checksumming"))
318 		card->options.checksum_type = NO_CHECKSUMMING;
319 	else {
320 		return -EINVAL;
321 	}
322 	return count;
323 }
324 
325 static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
326 		qeth_l3_dev_checksum_store);
327 
328 static struct attribute *qeth_l3_device_attrs[] = {
329 	&dev_attr_route4.attr,
330 	&dev_attr_route6.attr,
331 	&dev_attr_fake_broadcast.attr,
332 	&dev_attr_broadcast_mode.attr,
333 	&dev_attr_canonical_macaddr.attr,
334 	&dev_attr_checksumming.attr,
335 	NULL,
336 };
337 
338 static struct attribute_group qeth_l3_device_attr_group = {
339 	.attrs = qeth_l3_device_attrs,
340 };
341 
342 static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
343 			struct device_attribute *attr, char *buf)
344 {
345 	struct qeth_card *card = dev_get_drvdata(dev);
346 
347 	if (!card)
348 		return -EINVAL;
349 
350 	return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
351 }
352 
353 static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
354 		struct device_attribute *attr, const char *buf, size_t count)
355 {
356 	struct qeth_card *card = dev_get_drvdata(dev);
357 	char *tmp;
358 
359 	if (!card)
360 		return -EINVAL;
361 
362 	if ((card->state != CARD_STATE_DOWN) &&
363 	    (card->state != CARD_STATE_RECOVER))
364 		return -EPERM;
365 
366 	tmp = strsep((char **) &buf, "\n");
367 	if (!strcmp(tmp, "toggle")) {
368 		card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
369 	} else if (!strcmp(tmp, "1")) {
370 		card->ipato.enabled = 1;
371 	} else if (!strcmp(tmp, "0")) {
372 		card->ipato.enabled = 0;
373 	} else {
374 		return -EINVAL;
375 	}
376 	return count;
377 }
378 
379 static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
380 			qeth_l3_dev_ipato_enable_show,
381 			qeth_l3_dev_ipato_enable_store);
382 
383 static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
384 				struct device_attribute *attr, char *buf)
385 {
386 	struct qeth_card *card = dev_get_drvdata(dev);
387 
388 	if (!card)
389 		return -EINVAL;
390 
391 	return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
392 }
393 
394 static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
395 				struct device_attribute *attr,
396 				const char *buf, size_t count)
397 {
398 	struct qeth_card *card = dev_get_drvdata(dev);
399 	char *tmp;
400 
401 	if (!card)
402 		return -EINVAL;
403 
404 	tmp = strsep((char **) &buf, "\n");
405 	if (!strcmp(tmp, "toggle")) {
406 		card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
407 	} else if (!strcmp(tmp, "1")) {
408 		card->ipato.invert4 = 1;
409 	} else if (!strcmp(tmp, "0")) {
410 		card->ipato.invert4 = 0;
411 	} else {
412 		return -EINVAL;
413 	}
414 	return count;
415 }
416 
417 static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
418 			qeth_l3_dev_ipato_invert4_show,
419 			qeth_l3_dev_ipato_invert4_store);
420 
421 static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
422 			enum qeth_prot_versions proto)
423 {
424 	struct qeth_ipato_entry *ipatoe;
425 	unsigned long flags;
426 	char addr_str[40];
427 	int entry_len; /* length of 1 entry string, differs between v4 and v6 */
428 	int i = 0;
429 
430 	entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
431 	/* add strlen for "/<mask>\n" */
432 	entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
433 	spin_lock_irqsave(&card->ip_lock, flags);
434 	list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
435 		if (ipatoe->proto != proto)
436 			continue;
437 		/* String must not be longer than PAGE_SIZE. So we check if
438 		 * string length gets near PAGE_SIZE. Then we can savely display
439 		 * the next IPv6 address (worst case, compared to IPv4) */
440 		if ((PAGE_SIZE - i) <= entry_len)
441 			break;
442 		qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
443 		i += snprintf(buf + i, PAGE_SIZE - i,
444 			      "%s/%i\n", addr_str, ipatoe->mask_bits);
445 	}
446 	spin_unlock_irqrestore(&card->ip_lock, flags);
447 	i += snprintf(buf + i, PAGE_SIZE - i, "\n");
448 
449 	return i;
450 }
451 
452 static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
453 				struct device_attribute *attr, char *buf)
454 {
455 	struct qeth_card *card = dev_get_drvdata(dev);
456 
457 	if (!card)
458 		return -EINVAL;
459 
460 	return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
461 }
462 
463 static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
464 		  u8 *addr, int *mask_bits)
465 {
466 	const char *start, *end;
467 	char *tmp;
468 	char buffer[40] = {0, };
469 
470 	start = buf;
471 	/* get address string */
472 	end = strchr(start, '/');
473 	if (!end || (end - start >= 40)) {
474 		return -EINVAL;
475 	}
476 	strncpy(buffer, start, end - start);
477 	if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
478 		return -EINVAL;
479 	}
480 	start = end + 1;
481 	*mask_bits = simple_strtoul(start, &tmp, 10);
482 	if (!strlen(start) ||
483 	    (tmp == start) ||
484 	    (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
485 		return -EINVAL;
486 	}
487 	return 0;
488 }
489 
490 static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
491 			 struct qeth_card *card, enum qeth_prot_versions proto)
492 {
493 	struct qeth_ipato_entry *ipatoe;
494 	u8 addr[16];
495 	int mask_bits;
496 	int rc;
497 
498 	rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
499 	if (rc)
500 		return rc;
501 
502 	ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
503 	if (!ipatoe) {
504 		return -ENOMEM;
505 	}
506 	ipatoe->proto = proto;
507 	memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
508 	ipatoe->mask_bits = mask_bits;
509 
510 	rc = qeth_l3_add_ipato_entry(card, ipatoe);
511 	if (rc) {
512 		kfree(ipatoe);
513 		return rc;
514 	}
515 
516 	return count;
517 }
518 
519 static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
520 		struct device_attribute *attr, const char *buf, size_t count)
521 {
522 	struct qeth_card *card = dev_get_drvdata(dev);
523 
524 	if (!card)
525 		return -EINVAL;
526 
527 	return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
528 }
529 
530 static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
531 			qeth_l3_dev_ipato_add4_show,
532 			qeth_l3_dev_ipato_add4_store);
533 
534 static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
535 			 struct qeth_card *card, enum qeth_prot_versions proto)
536 {
537 	u8 addr[16];
538 	int mask_bits;
539 	int rc;
540 
541 	rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
542 	if (rc)
543 		return rc;
544 
545 	qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
546 
547 	return count;
548 }
549 
550 static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
551 		struct device_attribute *attr, const char *buf, size_t count)
552 {
553 	struct qeth_card *card = dev_get_drvdata(dev);
554 
555 	if (!card)
556 		return -EINVAL;
557 
558 	return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
559 }
560 
561 static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
562 			qeth_l3_dev_ipato_del4_store);
563 
564 static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
565 		struct device_attribute *attr, char *buf)
566 {
567 	struct qeth_card *card = dev_get_drvdata(dev);
568 
569 	if (!card)
570 		return -EINVAL;
571 
572 	return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
573 }
574 
575 static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
576 		struct device_attribute *attr, const char *buf, size_t count)
577 {
578 	struct qeth_card *card = dev_get_drvdata(dev);
579 	char *tmp;
580 
581 	if (!card)
582 		return -EINVAL;
583 
584 	tmp = strsep((char **) &buf, "\n");
585 	if (!strcmp(tmp, "toggle")) {
586 		card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
587 	} else if (!strcmp(tmp, "1")) {
588 		card->ipato.invert6 = 1;
589 	} else if (!strcmp(tmp, "0")) {
590 		card->ipato.invert6 = 0;
591 	} else {
592 		return -EINVAL;
593 	}
594 	return count;
595 }
596 
597 static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
598 			qeth_l3_dev_ipato_invert6_show,
599 			qeth_l3_dev_ipato_invert6_store);
600 
601 
602 static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
603 				struct device_attribute *attr, char *buf)
604 {
605 	struct qeth_card *card = dev_get_drvdata(dev);
606 
607 	if (!card)
608 		return -EINVAL;
609 
610 	return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
611 }
612 
613 static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
614 		struct device_attribute *attr, const char *buf, size_t count)
615 {
616 	struct qeth_card *card = dev_get_drvdata(dev);
617 
618 	if (!card)
619 		return -EINVAL;
620 
621 	return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
622 }
623 
624 static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
625 			qeth_l3_dev_ipato_add6_show,
626 			qeth_l3_dev_ipato_add6_store);
627 
628 static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
629 		struct device_attribute *attr, const char *buf, size_t count)
630 {
631 	struct qeth_card *card = dev_get_drvdata(dev);
632 
633 	if (!card)
634 		return -EINVAL;
635 
636 	return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
637 }
638 
639 static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
640 			qeth_l3_dev_ipato_del6_store);
641 
642 static struct attribute *qeth_ipato_device_attrs[] = {
643 	&dev_attr_ipato_enable.attr,
644 	&dev_attr_ipato_invert4.attr,
645 	&dev_attr_ipato_add4.attr,
646 	&dev_attr_ipato_del4.attr,
647 	&dev_attr_ipato_invert6.attr,
648 	&dev_attr_ipato_add6.attr,
649 	&dev_attr_ipato_del6.attr,
650 	NULL,
651 };
652 
653 static struct attribute_group qeth_device_ipato_group = {
654 	.name = "ipa_takeover",
655 	.attrs = qeth_ipato_device_attrs,
656 };
657 
658 static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
659 			enum qeth_prot_versions proto)
660 {
661 	struct qeth_ipaddr *ipaddr;
662 	char addr_str[40];
663 	int entry_len; /* length of 1 entry string, differs between v4 and v6 */
664 	unsigned long flags;
665 	int i = 0;
666 
667 	entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
668 	entry_len += 2; /* \n + terminator */
669 	spin_lock_irqsave(&card->ip_lock, flags);
670 	list_for_each_entry(ipaddr, &card->ip_list, entry) {
671 		if (ipaddr->proto != proto)
672 			continue;
673 		if (ipaddr->type != QETH_IP_TYPE_VIPA)
674 			continue;
675 		/* String must not be longer than PAGE_SIZE. So we check if
676 		 * string length gets near PAGE_SIZE. Then we can savely display
677 		 * the next IPv6 address (worst case, compared to IPv4) */
678 		if ((PAGE_SIZE - i) <= entry_len)
679 			break;
680 		qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
681 			addr_str);
682 		i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
683 	}
684 	spin_unlock_irqrestore(&card->ip_lock, flags);
685 	i += snprintf(buf + i, PAGE_SIZE - i, "\n");
686 
687 	return i;
688 }
689 
690 static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
691 			struct device_attribute *attr, char *buf)
692 {
693 	struct qeth_card *card = dev_get_drvdata(dev);
694 
695 	if (!card)
696 		return -EINVAL;
697 
698 	return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
699 }
700 
701 static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
702 		 u8 *addr)
703 {
704 	if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
705 		return -EINVAL;
706 	}
707 	return 0;
708 }
709 
710 static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
711 			struct qeth_card *card, enum qeth_prot_versions proto)
712 {
713 	u8 addr[16] = {0, };
714 	int rc;
715 
716 	rc = qeth_l3_parse_vipae(buf, proto, addr);
717 	if (rc)
718 		return rc;
719 
720 	rc = qeth_l3_add_vipa(card, proto, addr);
721 	if (rc)
722 		return rc;
723 
724 	return count;
725 }
726 
727 static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
728 		struct device_attribute *attr, const char *buf, size_t count)
729 {
730 	struct qeth_card *card = dev_get_drvdata(dev);
731 
732 	if (!card)
733 		return -EINVAL;
734 
735 	return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
736 }
737 
738 static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
739 			qeth_l3_dev_vipa_add4_show,
740 			qeth_l3_dev_vipa_add4_store);
741 
742 static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
743 			 struct qeth_card *card, enum qeth_prot_versions proto)
744 {
745 	u8 addr[16];
746 	int rc;
747 
748 	rc = qeth_l3_parse_vipae(buf, proto, addr);
749 	if (rc)
750 		return rc;
751 
752 	qeth_l3_del_vipa(card, proto, addr);
753 
754 	return count;
755 }
756 
757 static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
758 		struct device_attribute *attr, const char *buf, size_t count)
759 {
760 	struct qeth_card *card = dev_get_drvdata(dev);
761 
762 	if (!card)
763 		return -EINVAL;
764 
765 	return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
766 }
767 
768 static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
769 			qeth_l3_dev_vipa_del4_store);
770 
771 static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
772 				struct device_attribute *attr, char *buf)
773 {
774 	struct qeth_card *card = dev_get_drvdata(dev);
775 
776 	if (!card)
777 		return -EINVAL;
778 
779 	return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
780 }
781 
782 static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
783 		struct device_attribute *attr, const char *buf, size_t count)
784 {
785 	struct qeth_card *card = dev_get_drvdata(dev);
786 
787 	if (!card)
788 		return -EINVAL;
789 
790 	return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
791 }
792 
793 static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
794 			qeth_l3_dev_vipa_add6_show,
795 			qeth_l3_dev_vipa_add6_store);
796 
797 static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
798 		struct device_attribute *attr, const char *buf, size_t count)
799 {
800 	struct qeth_card *card = dev_get_drvdata(dev);
801 
802 	if (!card)
803 		return -EINVAL;
804 
805 	return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
806 }
807 
808 static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
809 			qeth_l3_dev_vipa_del6_store);
810 
811 static struct attribute *qeth_vipa_device_attrs[] = {
812 	&dev_attr_vipa_add4.attr,
813 	&dev_attr_vipa_del4.attr,
814 	&dev_attr_vipa_add6.attr,
815 	&dev_attr_vipa_del6.attr,
816 	NULL,
817 };
818 
819 static struct attribute_group qeth_device_vipa_group = {
820 	.name = "vipa",
821 	.attrs = qeth_vipa_device_attrs,
822 };
823 
824 static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
825 		       enum qeth_prot_versions proto)
826 {
827 	struct qeth_ipaddr *ipaddr;
828 	char addr_str[40];
829 	int entry_len; /* length of 1 entry string, differs between v4 and v6 */
830 	unsigned long flags;
831 	int i = 0;
832 
833 	entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
834 	entry_len += 2; /* \n + terminator */
835 	spin_lock_irqsave(&card->ip_lock, flags);
836 	list_for_each_entry(ipaddr, &card->ip_list, entry) {
837 		if (ipaddr->proto != proto)
838 			continue;
839 		if (ipaddr->type != QETH_IP_TYPE_RXIP)
840 			continue;
841 		/* String must not be longer than PAGE_SIZE. So we check if
842 		 * string length gets near PAGE_SIZE. Then we can savely display
843 		 * the next IPv6 address (worst case, compared to IPv4) */
844 		if ((PAGE_SIZE - i) <= entry_len)
845 			break;
846 		qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
847 			addr_str);
848 		i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
849 	}
850 	spin_unlock_irqrestore(&card->ip_lock, flags);
851 	i += snprintf(buf + i, PAGE_SIZE - i, "\n");
852 
853 	return i;
854 }
855 
856 static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
857 			struct device_attribute *attr, char *buf)
858 {
859 	struct qeth_card *card = dev_get_drvdata(dev);
860 
861 	if (!card)
862 		return -EINVAL;
863 
864 	return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
865 }
866 
867 static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
868 		 u8 *addr)
869 {
870 	if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
871 		return -EINVAL;
872 	}
873 	return 0;
874 }
875 
876 static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
877 			struct qeth_card *card, enum qeth_prot_versions proto)
878 {
879 	u8 addr[16] = {0, };
880 	int rc;
881 
882 	rc = qeth_l3_parse_rxipe(buf, proto, addr);
883 	if (rc)
884 		return rc;
885 
886 	rc = qeth_l3_add_rxip(card, proto, addr);
887 	if (rc)
888 		return rc;
889 
890 	return count;
891 }
892 
893 static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
894 		struct device_attribute *attr, const char *buf, size_t count)
895 {
896 	struct qeth_card *card = dev_get_drvdata(dev);
897 
898 	if (!card)
899 		return -EINVAL;
900 
901 	return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
902 }
903 
904 static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
905 			qeth_l3_dev_rxip_add4_show,
906 			qeth_l3_dev_rxip_add4_store);
907 
908 static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
909 			struct qeth_card *card, enum qeth_prot_versions proto)
910 {
911 	u8 addr[16];
912 	int rc;
913 
914 	rc = qeth_l3_parse_rxipe(buf, proto, addr);
915 	if (rc)
916 		return rc;
917 
918 	qeth_l3_del_rxip(card, proto, addr);
919 
920 	return count;
921 }
922 
923 static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
924 		struct device_attribute *attr, const char *buf, size_t count)
925 {
926 	struct qeth_card *card = dev_get_drvdata(dev);
927 
928 	if (!card)
929 		return -EINVAL;
930 
931 	return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
932 }
933 
934 static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
935 			qeth_l3_dev_rxip_del4_store);
936 
937 static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
938 		struct device_attribute *attr, char *buf)
939 {
940 	struct qeth_card *card = dev_get_drvdata(dev);
941 
942 	if (!card)
943 		return -EINVAL;
944 
945 	return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
946 }
947 
948 static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
949 		struct device_attribute *attr, const char *buf, size_t count)
950 {
951 	struct qeth_card *card = dev_get_drvdata(dev);
952 
953 	if (!card)
954 		return -EINVAL;
955 
956 	return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
957 }
958 
959 static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
960 			qeth_l3_dev_rxip_add6_show,
961 			qeth_l3_dev_rxip_add6_store);
962 
963 static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
964 		struct device_attribute *attr, const char *buf, size_t count)
965 {
966 	struct qeth_card *card = dev_get_drvdata(dev);
967 
968 	if (!card)
969 		return -EINVAL;
970 
971 	return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
972 }
973 
974 static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
975 			qeth_l3_dev_rxip_del6_store);
976 
977 static struct attribute *qeth_rxip_device_attrs[] = {
978 	&dev_attr_rxip_add4.attr,
979 	&dev_attr_rxip_del4.attr,
980 	&dev_attr_rxip_add6.attr,
981 	&dev_attr_rxip_del6.attr,
982 	NULL,
983 };
984 
985 static struct attribute_group qeth_device_rxip_group = {
986 	.name = "rxip",
987 	.attrs = qeth_rxip_device_attrs,
988 };
989 
990 int qeth_l3_create_device_attributes(struct device *dev)
991 {
992 	int ret;
993 
994 	ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
995 	if (ret)
996 		return ret;
997 
998 	ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
999 	if (ret) {
1000 		sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1001 		return ret;
1002 	}
1003 
1004 	ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1005 	if (ret) {
1006 		sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1007 		sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1008 		return ret;
1009 	}
1010 
1011 	ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1012 	if (ret) {
1013 		sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1014 		sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1015 		sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1016 		return ret;
1017 	}
1018 	return 0;
1019 }
1020 
1021 void qeth_l3_remove_device_attributes(struct device *dev)
1022 {
1023 	sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1024 	sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1025 	sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1026 	sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
1027 }
1028