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