Linux Audio

Check our new training course

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