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