[go: nahoru, domu]

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