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