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