PageRenderTime 198ms CodeModel.GetById 12ms app.highlight 144ms RepoModel.GetById 0ms app.codeStats 1ms

/drivers/s390/net/qeth_l3_main.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2
C | 3759 lines | 3251 code | 394 blank | 114 comment | 725 complexity | 0ac3595442969ea8ec7f05d360378290 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

   1/*
   2 *  drivers/s390/net/qeth_l3_main.c
   3 *
   4 *    Copyright IBM Corp. 2007, 2009
   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#define KMSG_COMPONENT "qeth"
  12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  13
  14#include <linux/module.h>
  15#include <linux/moduleparam.h>
  16#include <linux/string.h>
  17#include <linux/errno.h>
  18#include <linux/kernel.h>
  19#include <linux/etherdevice.h>
  20#include <linux/mii.h>
  21#include <linux/ip.h>
  22#include <linux/ipv6.h>
  23#include <linux/inetdevice.h>
  24#include <linux/igmp.h>
  25#include <linux/slab.h>
  26
  27#include <net/ip.h>
  28#include <net/arp.h>
  29#include <net/ip6_checksum.h>
  30
  31#include "qeth_l3.h"
  32
  33
  34static int qeth_l3_set_offline(struct ccwgroup_device *);
  35static int qeth_l3_recover(void *);
  36static int qeth_l3_stop(struct net_device *);
  37static void qeth_l3_set_multicast_list(struct net_device *);
  38static int qeth_l3_neigh_setup(struct net_device *, struct neigh_parms *);
  39static int qeth_l3_register_addr_entry(struct qeth_card *,
  40		struct qeth_ipaddr *);
  41static int qeth_l3_deregister_addr_entry(struct qeth_card *,
  42		struct qeth_ipaddr *);
  43static int __qeth_l3_set_online(struct ccwgroup_device *, int);
  44static int __qeth_l3_set_offline(struct ccwgroup_device *, int);
  45
  46static int qeth_l3_isxdigit(char *buf)
  47{
  48	while (*buf) {
  49		if (!isxdigit(*buf++))
  50			return 0;
  51	}
  52	return 1;
  53}
  54
  55void qeth_l3_ipaddr4_to_string(const __u8 *addr, char *buf)
  56{
  57	sprintf(buf, "%i.%i.%i.%i", addr[0], addr[1], addr[2], addr[3]);
  58}
  59
  60int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr)
  61{
  62	int count = 0, rc = 0;
  63	int in[4];
  64	char c;
  65
  66	rc = sscanf(buf, "%u.%u.%u.%u%c",
  67		    &in[0], &in[1], &in[2], &in[3], &c);
  68	if (rc != 4 && (rc != 5 || c != '\n'))
  69		return -EINVAL;
  70	for (count = 0; count < 4; count++) {
  71		if (in[count] > 255)
  72			return -EINVAL;
  73		addr[count] = in[count];
  74	}
  75	return 0;
  76}
  77
  78void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf)
  79{
  80	sprintf(buf, "%pI6", addr);
  81}
  82
  83int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr)
  84{
  85	const char *end, *end_tmp, *start;
  86	__u16 *in;
  87	char num[5];
  88	int num2, cnt, out, found, save_cnt;
  89	unsigned short in_tmp[8] = {0, };
  90
  91	cnt = out = found = save_cnt = num2 = 0;
  92	end = start = buf;
  93	in = (__u16 *) addr;
  94	memset(in, 0, 16);
  95	while (*end) {
  96		end = strchr(start, ':');
  97		if (end == NULL) {
  98			end = buf + strlen(buf);
  99			end_tmp = strchr(start, '\n');
 100			if (end_tmp != NULL)
 101				end = end_tmp;
 102			out = 1;
 103		}
 104		if ((end - start)) {
 105			memset(num, 0, 5);
 106			if ((end - start) > 4)
 107				return -EINVAL;
 108			memcpy(num, start, end - start);
 109			if (!qeth_l3_isxdigit(num))
 110				return -EINVAL;
 111			sscanf(start, "%x", &num2);
 112			if (found)
 113				in_tmp[save_cnt++] = num2;
 114			else
 115				in[cnt++] = num2;
 116			if (out)
 117				break;
 118		} else {
 119			if (found)
 120				return -EINVAL;
 121			found = 1;
 122		}
 123		start = ++end;
 124	}
 125	if (cnt + save_cnt > 8)
 126		return -EINVAL;
 127	cnt = 7;
 128	while (save_cnt)
 129		in[cnt--] = in_tmp[--save_cnt];
 130	return 0;
 131}
 132
 133void qeth_l3_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr,
 134				char *buf)
 135{
 136	if (proto == QETH_PROT_IPV4)
 137		qeth_l3_ipaddr4_to_string(addr, buf);
 138	else if (proto == QETH_PROT_IPV6)
 139		qeth_l3_ipaddr6_to_string(addr, buf);
 140}
 141
 142int qeth_l3_string_to_ipaddr(const char *buf, enum qeth_prot_versions proto,
 143				__u8 *addr)
 144{
 145	if (proto == QETH_PROT_IPV4)
 146		return qeth_l3_string_to_ipaddr4(buf, addr);
 147	else if (proto == QETH_PROT_IPV6)
 148		return qeth_l3_string_to_ipaddr6(buf, addr);
 149	else
 150		return -EINVAL;
 151}
 152
 153static void qeth_l3_convert_addr_to_bits(u8 *addr, u8 *bits, int len)
 154{
 155	int i, j;
 156	u8 octet;
 157
 158	for (i = 0; i < len; ++i) {
 159		octet = addr[i];
 160		for (j = 7; j >= 0; --j) {
 161			bits[i*8 + j] = octet & 1;
 162			octet >>= 1;
 163		}
 164	}
 165}
 166
 167int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
 168						struct qeth_ipaddr *addr)
 169{
 170	struct qeth_ipato_entry *ipatoe;
 171	u8 addr_bits[128] = {0, };
 172	u8 ipatoe_bits[128] = {0, };
 173	int rc = 0;
 174
 175	if (!card->ipato.enabled)
 176		return 0;
 177
 178	qeth_l3_convert_addr_to_bits((u8 *) &addr->u, addr_bits,
 179				  (addr->proto == QETH_PROT_IPV4)? 4:16);
 180	list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
 181		if (addr->proto != ipatoe->proto)
 182			continue;
 183		qeth_l3_convert_addr_to_bits(ipatoe->addr, ipatoe_bits,
 184					  (ipatoe->proto == QETH_PROT_IPV4) ?
 185					  4 : 16);
 186		if (addr->proto == QETH_PROT_IPV4)
 187			rc = !memcmp(addr_bits, ipatoe_bits,
 188				     min(32, ipatoe->mask_bits));
 189		else
 190			rc = !memcmp(addr_bits, ipatoe_bits,
 191				     min(128, ipatoe->mask_bits));
 192		if (rc)
 193			break;
 194	}
 195	/* invert? */
 196	if ((addr->proto == QETH_PROT_IPV4) && card->ipato.invert4)
 197		rc = !rc;
 198	else if ((addr->proto == QETH_PROT_IPV6) && card->ipato.invert6)
 199		rc = !rc;
 200
 201	return rc;
 202}
 203
 204/*
 205 * Add IP to be added to todo list. If there is already an "add todo"
 206 * in this list we just incremenent the reference count.
 207 * Returns 0 if we  just incremented reference count.
 208 */
 209static int __qeth_l3_insert_ip_todo(struct qeth_card *card,
 210					struct qeth_ipaddr *addr, int add)
 211{
 212	struct qeth_ipaddr *tmp, *t;
 213	int found = 0;
 214
 215	if (card->options.sniffer)
 216		return 0;
 217	list_for_each_entry_safe(tmp, t, card->ip_tbd_list, entry) {
 218		if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
 219		    (tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
 220			return 0;
 221		if ((tmp->proto        == QETH_PROT_IPV4)     &&
 222		    (addr->proto       == QETH_PROT_IPV4)     &&
 223		    (tmp->type         == addr->type)         &&
 224		    (tmp->is_multicast == addr->is_multicast) &&
 225		    (tmp->u.a4.addr    == addr->u.a4.addr)    &&
 226		    (tmp->u.a4.mask    == addr->u.a4.mask)) {
 227			found = 1;
 228			break;
 229		}
 230		if ((tmp->proto        == QETH_PROT_IPV6)      &&
 231		    (addr->proto       == QETH_PROT_IPV6)      &&
 232		    (tmp->type         == addr->type)          &&
 233		    (tmp->is_multicast == addr->is_multicast)  &&
 234		    (tmp->u.a6.pfxlen  == addr->u.a6.pfxlen)   &&
 235		    (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,
 236			    sizeof(struct in6_addr)) == 0)) {
 237			found = 1;
 238			break;
 239		}
 240	}
 241	if (found) {
 242		if (addr->users != 0)
 243			tmp->users += addr->users;
 244		else
 245			tmp->users += add ? 1 : -1;
 246		if (tmp->users == 0) {
 247			list_del(&tmp->entry);
 248			kfree(tmp);
 249		}
 250		return 0;
 251	} else {
 252		if (addr->type == QETH_IP_TYPE_DEL_ALL_MC)
 253			list_add(&addr->entry, card->ip_tbd_list);
 254		else {
 255			if (addr->users == 0)
 256				addr->users += add ? 1 : -1;
 257			if (add && (addr->type == QETH_IP_TYPE_NORMAL) &&
 258			    qeth_l3_is_addr_covered_by_ipato(card, addr)) {
 259				QETH_CARD_TEXT(card, 2, "tkovaddr");
 260				addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
 261			}
 262			list_add_tail(&addr->entry, card->ip_tbd_list);
 263		}
 264		return 1;
 265	}
 266}
 267
 268static int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
 269{
 270	unsigned long flags;
 271	int rc = 0;
 272
 273	QETH_CARD_TEXT(card, 4, "delip");
 274
 275	if (addr->proto == QETH_PROT_IPV4)
 276		QETH_CARD_HEX(card, 4, &addr->u.a4.addr, 4);
 277	else {
 278		QETH_CARD_HEX(card, 4, &addr->u.a6.addr, 8);
 279		QETH_CARD_HEX(card, 4, ((char *)&addr->u.a6.addr) + 8, 8);
 280	}
 281	spin_lock_irqsave(&card->ip_lock, flags);
 282	rc = __qeth_l3_insert_ip_todo(card, addr, 0);
 283	spin_unlock_irqrestore(&card->ip_lock, flags);
 284	return rc;
 285}
 286
 287static int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
 288{
 289	unsigned long flags;
 290	int rc = 0;
 291
 292	QETH_CARD_TEXT(card, 4, "addip");
 293	if (addr->proto == QETH_PROT_IPV4)
 294		QETH_CARD_HEX(card, 4, &addr->u.a4.addr, 4);
 295	else {
 296		QETH_CARD_HEX(card, 4, &addr->u.a6.addr, 8);
 297		QETH_CARD_HEX(card, 4, ((char *)&addr->u.a6.addr) + 8, 8);
 298	}
 299	spin_lock_irqsave(&card->ip_lock, flags);
 300	rc = __qeth_l3_insert_ip_todo(card, addr, 1);
 301	spin_unlock_irqrestore(&card->ip_lock, flags);
 302	return rc;
 303}
 304
 305
 306static struct qeth_ipaddr *qeth_l3_get_addr_buffer(
 307				enum qeth_prot_versions prot)
 308{
 309	struct qeth_ipaddr *addr;
 310
 311	addr = kzalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC);
 312	if (addr == NULL) {
 313		return NULL;
 314	}
 315	addr->type = QETH_IP_TYPE_NORMAL;
 316	addr->proto = prot;
 317	return addr;
 318}
 319
 320static void qeth_l3_delete_mc_addresses(struct qeth_card *card)
 321{
 322	struct qeth_ipaddr *iptodo;
 323	unsigned long flags;
 324
 325	QETH_CARD_TEXT(card, 4, "delmc");
 326	iptodo = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
 327	if (!iptodo) {
 328		QETH_CARD_TEXT(card, 2, "dmcnomem");
 329		return;
 330	}
 331	iptodo->type = QETH_IP_TYPE_DEL_ALL_MC;
 332	spin_lock_irqsave(&card->ip_lock, flags);
 333	if (!__qeth_l3_insert_ip_todo(card, iptodo, 0))
 334		kfree(iptodo);
 335	spin_unlock_irqrestore(&card->ip_lock, flags);
 336}
 337
 338/*
 339 * Add/remove address to/from card's ip list, i.e. try to add or remove
 340 * reference to/from an IP address that is already registered on the card.
 341 * Returns:
 342 *	0  address was on card and its reference count has been adjusted,
 343 *	   but is still > 0, so nothing has to be done
 344 *	   also returns 0 if card was not on card and the todo was to delete
 345 *	   the address -> there is also nothing to be done
 346 *	1  address was not on card and the todo is to add it to the card's ip
 347 *	   list
 348 *	-1 address was on card and its reference count has been decremented
 349 *	   to <= 0 by the todo -> address must be removed from card
 350 */
 351static int __qeth_l3_ref_ip_on_card(struct qeth_card *card,
 352		struct qeth_ipaddr *todo, struct qeth_ipaddr **__addr)
 353{
 354	struct qeth_ipaddr *addr;
 355	int found = 0;
 356
 357	list_for_each_entry(addr, &card->ip_list, entry) {
 358		if ((addr->proto == QETH_PROT_IPV4) &&
 359		    (todo->proto == QETH_PROT_IPV4) &&
 360		    (addr->type == todo->type) &&
 361		    (addr->u.a4.addr == todo->u.a4.addr) &&
 362		    (addr->u.a4.mask == todo->u.a4.mask)) {
 363			found = 1;
 364			break;
 365		}
 366		if ((addr->proto == QETH_PROT_IPV6) &&
 367		    (todo->proto == QETH_PROT_IPV6) &&
 368		    (addr->type == todo->type) &&
 369		    (addr->u.a6.pfxlen == todo->u.a6.pfxlen) &&
 370		    (memcmp(&addr->u.a6.addr, &todo->u.a6.addr,
 371			    sizeof(struct in6_addr)) == 0)) {
 372			found = 1;
 373			break;
 374		}
 375	}
 376	if (found) {
 377		addr->users += todo->users;
 378		if (addr->users <= 0) {
 379			*__addr = addr;
 380			return -1;
 381		} else {
 382			/* for VIPA and RXIP limit refcount to 1 */
 383			if (addr->type != QETH_IP_TYPE_NORMAL)
 384				addr->users = 1;
 385			return 0;
 386		}
 387	}
 388	if (todo->users > 0) {
 389		/* for VIPA and RXIP limit refcount to 1 */
 390		if (todo->type != QETH_IP_TYPE_NORMAL)
 391			todo->users = 1;
 392		return 1;
 393	} else
 394		return 0;
 395}
 396
 397static void __qeth_l3_delete_all_mc(struct qeth_card *card,
 398					unsigned long *flags)
 399{
 400	struct list_head fail_list;
 401	struct qeth_ipaddr *addr, *tmp;
 402	int rc;
 403
 404	INIT_LIST_HEAD(&fail_list);
 405again:
 406	list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) {
 407		if (addr->is_multicast) {
 408			list_del(&addr->entry);
 409			spin_unlock_irqrestore(&card->ip_lock, *flags);
 410			rc = qeth_l3_deregister_addr_entry(card, addr);
 411			spin_lock_irqsave(&card->ip_lock, *flags);
 412			if (!rc || (rc == IPA_RC_MC_ADDR_NOT_FOUND))
 413				kfree(addr);
 414			else
 415				list_add_tail(&addr->entry, &fail_list);
 416			goto again;
 417		}
 418	}
 419	list_splice(&fail_list, &card->ip_list);
 420}
 421
 422static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
 423{
 424	struct list_head *tbd_list;
 425	struct qeth_ipaddr *todo, *addr;
 426	unsigned long flags;
 427	int rc;
 428
 429	QETH_CARD_TEXT(card, 2, "sdiplist");
 430	QETH_CARD_HEX(card, 2, &card, sizeof(void *));
 431
 432	if ((card->state != CARD_STATE_UP &&
 433	     card->state != CARD_STATE_SOFTSETUP) || card->options.sniffer) {
 434		return;
 435	}
 436
 437	spin_lock_irqsave(&card->ip_lock, flags);
 438	tbd_list = card->ip_tbd_list;
 439	card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC);
 440	if (!card->ip_tbd_list) {
 441		QETH_CARD_TEXT(card, 0, "silnomem");
 442		card->ip_tbd_list = tbd_list;
 443		spin_unlock_irqrestore(&card->ip_lock, flags);
 444		return;
 445	} else
 446		INIT_LIST_HEAD(card->ip_tbd_list);
 447
 448	while (!list_empty(tbd_list)) {
 449		todo = list_entry(tbd_list->next, struct qeth_ipaddr, entry);
 450		list_del(&todo->entry);
 451		if (todo->type == QETH_IP_TYPE_DEL_ALL_MC) {
 452			__qeth_l3_delete_all_mc(card, &flags);
 453			kfree(todo);
 454			continue;
 455		}
 456		rc = __qeth_l3_ref_ip_on_card(card, todo, &addr);
 457		if (rc == 0) {
 458			/* nothing to be done; only adjusted refcount */
 459			kfree(todo);
 460		} else if (rc == 1) {
 461			/* new entry to be added to on-card list */
 462			spin_unlock_irqrestore(&card->ip_lock, flags);
 463			rc = qeth_l3_register_addr_entry(card, todo);
 464			spin_lock_irqsave(&card->ip_lock, flags);
 465			if (!rc || (rc == IPA_RC_LAN_OFFLINE))
 466				list_add_tail(&todo->entry, &card->ip_list);
 467			else
 468				kfree(todo);
 469		} else if (rc == -1) {
 470			/* on-card entry to be removed */
 471			list_del_init(&addr->entry);
 472			spin_unlock_irqrestore(&card->ip_lock, flags);
 473			rc = qeth_l3_deregister_addr_entry(card, addr);
 474			spin_lock_irqsave(&card->ip_lock, flags);
 475			if (!rc || (rc == IPA_RC_IP_ADDRESS_NOT_DEFINED))
 476				kfree(addr);
 477			else
 478				list_add_tail(&addr->entry, &card->ip_list);
 479			kfree(todo);
 480		}
 481	}
 482	spin_unlock_irqrestore(&card->ip_lock, flags);
 483	kfree(tbd_list);
 484}
 485
 486static void qeth_l3_clear_ip_list(struct qeth_card *card, int recover)
 487{
 488	struct qeth_ipaddr *addr, *tmp;
 489	unsigned long flags;
 490
 491	QETH_CARD_TEXT(card, 4, "clearip");
 492	if (recover && card->options.sniffer)
 493		return;
 494	spin_lock_irqsave(&card->ip_lock, flags);
 495	/* clear todo list */
 496	list_for_each_entry_safe(addr, tmp, card->ip_tbd_list, entry) {
 497		list_del(&addr->entry);
 498		kfree(addr);
 499	}
 500
 501	while (!list_empty(&card->ip_list)) {
 502		addr = list_entry(card->ip_list.next,
 503				  struct qeth_ipaddr, entry);
 504		list_del_init(&addr->entry);
 505		if (!recover || addr->is_multicast) {
 506			kfree(addr);
 507			continue;
 508		}
 509		list_add_tail(&addr->entry, card->ip_tbd_list);
 510	}
 511	spin_unlock_irqrestore(&card->ip_lock, flags);
 512}
 513
 514static int qeth_l3_address_exists_in_list(struct list_head *list,
 515		struct qeth_ipaddr *addr, int same_type)
 516{
 517	struct qeth_ipaddr *tmp;
 518
 519	list_for_each_entry(tmp, list, entry) {
 520		if ((tmp->proto == QETH_PROT_IPV4) &&
 521		    (addr->proto == QETH_PROT_IPV4) &&
 522		    ((same_type && (tmp->type == addr->type)) ||
 523		    (!same_type && (tmp->type != addr->type))) &&
 524		    (tmp->u.a4.addr == addr->u.a4.addr))
 525			return 1;
 526
 527		if ((tmp->proto == QETH_PROT_IPV6) &&
 528		    (addr->proto == QETH_PROT_IPV6) &&
 529		    ((same_type && (tmp->type == addr->type)) ||
 530		    (!same_type && (tmp->type != addr->type))) &&
 531		    (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,
 532			    sizeof(struct in6_addr)) == 0))
 533			return 1;
 534
 535	}
 536	return 0;
 537}
 538
 539static int qeth_l3_send_setdelmc(struct qeth_card *card,
 540			struct qeth_ipaddr *addr, int ipacmd)
 541{
 542	int rc;
 543	struct qeth_cmd_buffer *iob;
 544	struct qeth_ipa_cmd *cmd;
 545
 546	QETH_CARD_TEXT(card, 4, "setdelmc");
 547
 548	iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
 549	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 550	memcpy(&cmd->data.setdelipm.mac, addr->mac, OSA_ADDR_LEN);
 551	if (addr->proto == QETH_PROT_IPV6)
 552		memcpy(cmd->data.setdelipm.ip6, &addr->u.a6.addr,
 553		       sizeof(struct in6_addr));
 554	else
 555		memcpy(&cmd->data.setdelipm.ip4, &addr->u.a4.addr, 4);
 556
 557	rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
 558
 559	return rc;
 560}
 561
 562static void qeth_l3_fill_netmask(u8 *netmask, unsigned int len)
 563{
 564	int i, j;
 565	for (i = 0; i < 16; i++) {
 566		j = (len) - (i * 8);
 567		if (j >= 8)
 568			netmask[i] = 0xff;
 569		else if (j > 0)
 570			netmask[i] = (u8)(0xFF00 >> j);
 571		else
 572			netmask[i] = 0;
 573	}
 574}
 575
 576static int qeth_l3_send_setdelip(struct qeth_card *card,
 577		struct qeth_ipaddr *addr, int ipacmd, unsigned int flags)
 578{
 579	int rc;
 580	struct qeth_cmd_buffer *iob;
 581	struct qeth_ipa_cmd *cmd;
 582	__u8 netmask[16];
 583
 584	QETH_CARD_TEXT(card, 4, "setdelip");
 585	QETH_CARD_TEXT_(card, 4, "flags%02X", flags);
 586
 587	iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
 588	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 589	if (addr->proto == QETH_PROT_IPV6) {
 590		memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr,
 591		       sizeof(struct in6_addr));
 592		qeth_l3_fill_netmask(netmask, addr->u.a6.pfxlen);
 593		memcpy(cmd->data.setdelip6.mask, netmask,
 594		       sizeof(struct in6_addr));
 595		cmd->data.setdelip6.flags = flags;
 596	} else {
 597		memcpy(cmd->data.setdelip4.ip_addr, &addr->u.a4.addr, 4);
 598		memcpy(cmd->data.setdelip4.mask, &addr->u.a4.mask, 4);
 599		cmd->data.setdelip4.flags = flags;
 600	}
 601
 602	rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
 603
 604	return rc;
 605}
 606
 607static int qeth_l3_send_setrouting(struct qeth_card *card,
 608	enum qeth_routing_types type, enum qeth_prot_versions prot)
 609{
 610	int rc;
 611	struct qeth_ipa_cmd *cmd;
 612	struct qeth_cmd_buffer *iob;
 613
 614	QETH_CARD_TEXT(card, 4, "setroutg");
 615	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot);
 616	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 617	cmd->data.setrtg.type = (type);
 618	rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
 619
 620	return rc;
 621}
 622
 623static void qeth_l3_correct_routing_type(struct qeth_card *card,
 624		enum qeth_routing_types *type, enum qeth_prot_versions prot)
 625{
 626	if (card->info.type == QETH_CARD_TYPE_IQD) {
 627		switch (*type) {
 628		case NO_ROUTER:
 629		case PRIMARY_CONNECTOR:
 630		case SECONDARY_CONNECTOR:
 631		case MULTICAST_ROUTER:
 632			return;
 633		default:
 634			goto out_inval;
 635		}
 636	} else {
 637		switch (*type) {
 638		case NO_ROUTER:
 639		case PRIMARY_ROUTER:
 640		case SECONDARY_ROUTER:
 641			return;
 642		case MULTICAST_ROUTER:
 643			if (qeth_is_ipafunc_supported(card, prot,
 644						      IPA_OSA_MC_ROUTER))
 645				return;
 646		default:
 647			goto out_inval;
 648		}
 649	}
 650out_inval:
 651	*type = NO_ROUTER;
 652}
 653
 654int qeth_l3_setrouting_v4(struct qeth_card *card)
 655{
 656	int rc;
 657
 658	QETH_CARD_TEXT(card, 3, "setrtg4");
 659
 660	qeth_l3_correct_routing_type(card, &card->options.route4.type,
 661				  QETH_PROT_IPV4);
 662
 663	rc = qeth_l3_send_setrouting(card, card->options.route4.type,
 664				  QETH_PROT_IPV4);
 665	if (rc) {
 666		card->options.route4.type = NO_ROUTER;
 667		QETH_DBF_MESSAGE(2, "Error (0x%04x) while setting routing type"
 668			" on %s. Type set to 'no router'.\n", rc,
 669			QETH_CARD_IFNAME(card));
 670	}
 671	return rc;
 672}
 673
 674int qeth_l3_setrouting_v6(struct qeth_card *card)
 675{
 676	int rc = 0;
 677
 678	QETH_CARD_TEXT(card, 3, "setrtg6");
 679#ifdef CONFIG_QETH_IPV6
 680
 681	if (!qeth_is_supported(card, IPA_IPV6))
 682		return 0;
 683	qeth_l3_correct_routing_type(card, &card->options.route6.type,
 684				  QETH_PROT_IPV6);
 685
 686	rc = qeth_l3_send_setrouting(card, card->options.route6.type,
 687				  QETH_PROT_IPV6);
 688	if (rc) {
 689		card->options.route6.type = NO_ROUTER;
 690		QETH_DBF_MESSAGE(2, "Error (0x%04x) while setting routing type"
 691			" on %s. Type set to 'no router'.\n", rc,
 692			QETH_CARD_IFNAME(card));
 693	}
 694#endif
 695	return rc;
 696}
 697
 698/*
 699 * IP address takeover related functions
 700 */
 701static void qeth_l3_clear_ipato_list(struct qeth_card *card)
 702{
 703
 704	struct qeth_ipato_entry *ipatoe, *tmp;
 705	unsigned long flags;
 706
 707	spin_lock_irqsave(&card->ip_lock, flags);
 708	list_for_each_entry_safe(ipatoe, tmp, &card->ipato.entries, entry) {
 709		list_del(&ipatoe->entry);
 710		kfree(ipatoe);
 711	}
 712	spin_unlock_irqrestore(&card->ip_lock, flags);
 713}
 714
 715int qeth_l3_add_ipato_entry(struct qeth_card *card,
 716				struct qeth_ipato_entry *new)
 717{
 718	struct qeth_ipato_entry *ipatoe;
 719	unsigned long flags;
 720	int rc = 0;
 721
 722	QETH_CARD_TEXT(card, 2, "addipato");
 723	spin_lock_irqsave(&card->ip_lock, flags);
 724	list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
 725		if (ipatoe->proto != new->proto)
 726			continue;
 727		if (!memcmp(ipatoe->addr, new->addr,
 728			    (ipatoe->proto == QETH_PROT_IPV4)? 4:16) &&
 729		    (ipatoe->mask_bits == new->mask_bits)) {
 730			rc = -EEXIST;
 731			break;
 732		}
 733	}
 734	if (!rc)
 735		list_add_tail(&new->entry, &card->ipato.entries);
 736
 737	spin_unlock_irqrestore(&card->ip_lock, flags);
 738	return rc;
 739}
 740
 741void qeth_l3_del_ipato_entry(struct qeth_card *card,
 742		enum qeth_prot_versions proto, u8 *addr, int mask_bits)
 743{
 744	struct qeth_ipato_entry *ipatoe, *tmp;
 745	unsigned long flags;
 746
 747	QETH_CARD_TEXT(card, 2, "delipato");
 748	spin_lock_irqsave(&card->ip_lock, flags);
 749	list_for_each_entry_safe(ipatoe, tmp, &card->ipato.entries, entry) {
 750		if (ipatoe->proto != proto)
 751			continue;
 752		if (!memcmp(ipatoe->addr, addr,
 753			    (proto == QETH_PROT_IPV4)? 4:16) &&
 754		    (ipatoe->mask_bits == mask_bits)) {
 755			list_del(&ipatoe->entry);
 756			kfree(ipatoe);
 757		}
 758	}
 759	spin_unlock_irqrestore(&card->ip_lock, flags);
 760}
 761
 762/*
 763 * VIPA related functions
 764 */
 765int qeth_l3_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
 766	      const u8 *addr)
 767{
 768	struct qeth_ipaddr *ipaddr;
 769	unsigned long flags;
 770	int rc = 0;
 771
 772	ipaddr = qeth_l3_get_addr_buffer(proto);
 773	if (ipaddr) {
 774		if (proto == QETH_PROT_IPV4) {
 775			QETH_CARD_TEXT(card, 2, "addvipa4");
 776			memcpy(&ipaddr->u.a4.addr, addr, 4);
 777			ipaddr->u.a4.mask = 0;
 778		} else if (proto == QETH_PROT_IPV6) {
 779			QETH_CARD_TEXT(card, 2, "addvipa6");
 780			memcpy(&ipaddr->u.a6.addr, addr, 16);
 781			ipaddr->u.a6.pfxlen = 0;
 782		}
 783		ipaddr->type = QETH_IP_TYPE_VIPA;
 784		ipaddr->set_flags = QETH_IPA_SETIP_VIPA_FLAG;
 785		ipaddr->del_flags = QETH_IPA_DELIP_VIPA_FLAG;
 786	} else
 787		return -ENOMEM;
 788	spin_lock_irqsave(&card->ip_lock, flags);
 789	if (qeth_l3_address_exists_in_list(&card->ip_list, ipaddr, 0) ||
 790	    qeth_l3_address_exists_in_list(card->ip_tbd_list, ipaddr, 0))
 791		rc = -EEXIST;
 792	spin_unlock_irqrestore(&card->ip_lock, flags);
 793	if (rc) {
 794		return rc;
 795	}
 796	if (!qeth_l3_add_ip(card, ipaddr))
 797		kfree(ipaddr);
 798	qeth_l3_set_ip_addr_list(card);
 799	return rc;
 800}
 801
 802void qeth_l3_del_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
 803	      const u8 *addr)
 804{
 805	struct qeth_ipaddr *ipaddr;
 806
 807	ipaddr = qeth_l3_get_addr_buffer(proto);
 808	if (ipaddr) {
 809		if (proto == QETH_PROT_IPV4) {
 810			QETH_CARD_TEXT(card, 2, "delvipa4");
 811			memcpy(&ipaddr->u.a4.addr, addr, 4);
 812			ipaddr->u.a4.mask = 0;
 813		} else if (proto == QETH_PROT_IPV6) {
 814			QETH_CARD_TEXT(card, 2, "delvipa6");
 815			memcpy(&ipaddr->u.a6.addr, addr, 16);
 816			ipaddr->u.a6.pfxlen = 0;
 817		}
 818		ipaddr->type = QETH_IP_TYPE_VIPA;
 819	} else
 820		return;
 821	if (!qeth_l3_delete_ip(card, ipaddr))
 822		kfree(ipaddr);
 823	qeth_l3_set_ip_addr_list(card);
 824}
 825
 826/*
 827 * proxy ARP related functions
 828 */
 829int qeth_l3_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
 830	      const u8 *addr)
 831{
 832	struct qeth_ipaddr *ipaddr;
 833	unsigned long flags;
 834	int rc = 0;
 835
 836	ipaddr = qeth_l3_get_addr_buffer(proto);
 837	if (ipaddr) {
 838		if (proto == QETH_PROT_IPV4) {
 839			QETH_CARD_TEXT(card, 2, "addrxip4");
 840			memcpy(&ipaddr->u.a4.addr, addr, 4);
 841			ipaddr->u.a4.mask = 0;
 842		} else if (proto == QETH_PROT_IPV6) {
 843			QETH_CARD_TEXT(card, 2, "addrxip6");
 844			memcpy(&ipaddr->u.a6.addr, addr, 16);
 845			ipaddr->u.a6.pfxlen = 0;
 846		}
 847		ipaddr->type = QETH_IP_TYPE_RXIP;
 848		ipaddr->set_flags = QETH_IPA_SETIP_TAKEOVER_FLAG;
 849		ipaddr->del_flags = 0;
 850	} else
 851		return -ENOMEM;
 852	spin_lock_irqsave(&card->ip_lock, flags);
 853	if (qeth_l3_address_exists_in_list(&card->ip_list, ipaddr, 0) ||
 854	    qeth_l3_address_exists_in_list(card->ip_tbd_list, ipaddr, 0))
 855		rc = -EEXIST;
 856	spin_unlock_irqrestore(&card->ip_lock, flags);
 857	if (rc) {
 858		return rc;
 859	}
 860	if (!qeth_l3_add_ip(card, ipaddr))
 861		kfree(ipaddr);
 862	qeth_l3_set_ip_addr_list(card);
 863	return 0;
 864}
 865
 866void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
 867			const u8 *addr)
 868{
 869	struct qeth_ipaddr *ipaddr;
 870
 871	ipaddr = qeth_l3_get_addr_buffer(proto);
 872	if (ipaddr) {
 873		if (proto == QETH_PROT_IPV4) {
 874			QETH_CARD_TEXT(card, 2, "addrxip4");
 875			memcpy(&ipaddr->u.a4.addr, addr, 4);
 876			ipaddr->u.a4.mask = 0;
 877		} else if (proto == QETH_PROT_IPV6) {
 878			QETH_CARD_TEXT(card, 2, "addrxip6");
 879			memcpy(&ipaddr->u.a6.addr, addr, 16);
 880			ipaddr->u.a6.pfxlen = 0;
 881		}
 882		ipaddr->type = QETH_IP_TYPE_RXIP;
 883	} else
 884		return;
 885	if (!qeth_l3_delete_ip(card, ipaddr))
 886		kfree(ipaddr);
 887	qeth_l3_set_ip_addr_list(card);
 888}
 889
 890static int qeth_l3_register_addr_entry(struct qeth_card *card,
 891				struct qeth_ipaddr *addr)
 892{
 893	char buf[50];
 894	int rc = 0;
 895	int cnt = 3;
 896
 897	if (addr->proto == QETH_PROT_IPV4) {
 898		QETH_CARD_TEXT(card, 2, "setaddr4");
 899		QETH_CARD_HEX(card, 3, &addr->u.a4.addr, sizeof(int));
 900	} else if (addr->proto == QETH_PROT_IPV6) {
 901		QETH_CARD_TEXT(card, 2, "setaddr6");
 902		QETH_CARD_HEX(card, 3, &addr->u.a6.addr, 8);
 903		QETH_CARD_HEX(card, 3, ((char *)&addr->u.a6.addr) + 8, 8);
 904	} else {
 905		QETH_CARD_TEXT(card, 2, "setaddr?");
 906		QETH_CARD_HEX(card, 3, addr, sizeof(struct qeth_ipaddr));
 907	}
 908	do {
 909		if (addr->is_multicast)
 910			rc =  qeth_l3_send_setdelmc(card, addr, IPA_CMD_SETIPM);
 911		else
 912			rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_SETIP,
 913					addr->set_flags);
 914		if (rc)
 915			QETH_CARD_TEXT(card, 2, "failed");
 916	} while ((--cnt > 0) && rc);
 917	if (rc) {
 918		QETH_CARD_TEXT(card, 2, "FAILED");
 919		qeth_l3_ipaddr_to_string(addr->proto, (u8 *)&addr->u, buf);
 920		dev_warn(&card->gdev->dev,
 921			"Registering IP address %s failed\n", buf);
 922	}
 923	return rc;
 924}
 925
 926static int qeth_l3_deregister_addr_entry(struct qeth_card *card,
 927						struct qeth_ipaddr *addr)
 928{
 929	int rc = 0;
 930
 931	if (addr->proto == QETH_PROT_IPV4) {
 932		QETH_CARD_TEXT(card, 2, "deladdr4");
 933		QETH_CARD_HEX(card, 3, &addr->u.a4.addr, sizeof(int));
 934	} else if (addr->proto == QETH_PROT_IPV6) {
 935		QETH_CARD_TEXT(card, 2, "deladdr6");
 936		QETH_CARD_HEX(card, 3, &addr->u.a6.addr, 8);
 937		QETH_CARD_HEX(card, 3, ((char *)&addr->u.a6.addr) + 8, 8);
 938	} else {
 939		QETH_CARD_TEXT(card, 2, "deladdr?");
 940		QETH_CARD_HEX(card, 3, addr, sizeof(struct qeth_ipaddr));
 941	}
 942	if (addr->is_multicast)
 943		rc = qeth_l3_send_setdelmc(card, addr, IPA_CMD_DELIPM);
 944	else
 945		rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_DELIP,
 946					addr->del_flags);
 947	if (rc)
 948		QETH_CARD_TEXT(card, 2, "failed");
 949
 950	return rc;
 951}
 952
 953static inline u8 qeth_l3_get_qeth_hdr_flags4(int cast_type)
 954{
 955	if (cast_type == RTN_MULTICAST)
 956		return QETH_CAST_MULTICAST;
 957	if (cast_type == RTN_BROADCAST)
 958		return QETH_CAST_BROADCAST;
 959	return QETH_CAST_UNICAST;
 960}
 961
 962static inline u8 qeth_l3_get_qeth_hdr_flags6(int cast_type)
 963{
 964	u8 ct = QETH_HDR_PASSTHRU | QETH_HDR_IPV6;
 965	if (cast_type == RTN_MULTICAST)
 966		return ct | QETH_CAST_MULTICAST;
 967	if (cast_type == RTN_ANYCAST)
 968		return ct | QETH_CAST_ANYCAST;
 969	if (cast_type == RTN_BROADCAST)
 970		return ct | QETH_CAST_BROADCAST;
 971	return ct | QETH_CAST_UNICAST;
 972}
 973
 974static int qeth_l3_send_setadp_mode(struct qeth_card *card, __u32 command,
 975					__u32 mode)
 976{
 977	int rc;
 978	struct qeth_cmd_buffer *iob;
 979	struct qeth_ipa_cmd *cmd;
 980
 981	QETH_CARD_TEXT(card, 4, "adpmode");
 982
 983	iob = qeth_get_adapter_cmd(card, command,
 984				   sizeof(struct qeth_ipacmd_setadpparms));
 985	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 986	cmd->data.setadapterparms.data.mode = mode;
 987	rc = qeth_send_ipa_cmd(card, iob, qeth_default_setadapterparms_cb,
 988			       NULL);
 989	return rc;
 990}
 991
 992static int qeth_l3_setadapter_hstr(struct qeth_card *card)
 993{
 994	int rc;
 995
 996	QETH_CARD_TEXT(card, 4, "adphstr");
 997
 998	if (qeth_adp_supported(card, IPA_SETADP_SET_BROADCAST_MODE)) {
 999		rc = qeth_l3_send_setadp_mode(card,
1000					IPA_SETADP_SET_BROADCAST_MODE,
1001					card->options.broadcast_mode);
1002		if (rc)
1003			QETH_DBF_MESSAGE(2, "couldn't set broadcast mode on "
1004				   "device %s: x%x\n",
1005				   CARD_BUS_ID(card), rc);
1006		rc = qeth_l3_send_setadp_mode(card,
1007					IPA_SETADP_ALTER_MAC_ADDRESS,
1008					card->options.macaddr_mode);
1009		if (rc)
1010			QETH_DBF_MESSAGE(2, "couldn't set macaddr mode on "
1011				   "device %s: x%x\n", CARD_BUS_ID(card), rc);
1012		return rc;
1013	}
1014	if (card->options.broadcast_mode == QETH_TR_BROADCAST_LOCAL)
1015		QETH_DBF_MESSAGE(2, "set adapter parameters not available "
1016			   "to set broadcast mode, using ALLRINGS "
1017			   "on device %s:\n", CARD_BUS_ID(card));
1018	if (card->options.macaddr_mode == QETH_TR_MACADDR_CANONICAL)
1019		QETH_DBF_MESSAGE(2, "set adapter parameters not available "
1020			   "to set macaddr mode, using NONCANONICAL "
1021			   "on device %s:\n", CARD_BUS_ID(card));
1022	return 0;
1023}
1024
1025static int qeth_l3_setadapter_parms(struct qeth_card *card)
1026{
1027	int rc;
1028
1029	QETH_DBF_TEXT(SETUP, 2, "setadprm");
1030
1031	if (!qeth_is_supported(card, IPA_SETADAPTERPARMS)) {
1032		dev_info(&card->gdev->dev,
1033			"set adapter parameters not supported.\n");
1034		QETH_DBF_TEXT(SETUP, 2, " notsupp");
1035		return 0;
1036	}
1037	rc = qeth_query_setadapterparms(card);
1038	if (rc) {
1039		QETH_DBF_MESSAGE(2, "%s couldn't set adapter parameters: "
1040			"0x%x\n", dev_name(&card->gdev->dev), rc);
1041		return rc;
1042	}
1043	if (qeth_adp_supported(card, IPA_SETADP_ALTER_MAC_ADDRESS)) {
1044		rc = qeth_setadpparms_change_macaddr(card);
1045		if (rc)
1046			dev_warn(&card->gdev->dev, "Reading the adapter MAC"
1047				" address failed\n");
1048	}
1049
1050	if ((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
1051	    (card->info.link_type == QETH_LINK_TYPE_LANE_TR))
1052		rc = qeth_l3_setadapter_hstr(card);
1053
1054	return rc;
1055}
1056
1057static int qeth_l3_default_setassparms_cb(struct qeth_card *card,
1058			struct qeth_reply *reply, unsigned long data)
1059{
1060	struct qeth_ipa_cmd *cmd;
1061
1062	QETH_CARD_TEXT(card, 4, "defadpcb");
1063
1064	cmd = (struct qeth_ipa_cmd *) data;
1065	if (cmd->hdr.return_code == 0) {
1066		cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code;
1067		if (cmd->hdr.prot_version == QETH_PROT_IPV4)
1068			card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
1069		if (cmd->hdr.prot_version == QETH_PROT_IPV6)
1070			card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
1071	}
1072	if (cmd->data.setassparms.hdr.assist_no == IPA_INBOUND_CHECKSUM &&
1073	    cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
1074		card->info.csum_mask = cmd->data.setassparms.data.flags_32bit;
1075		QETH_CARD_TEXT_(card, 3, "csum:%d", card->info.csum_mask);
1076	}
1077	if (cmd->data.setassparms.hdr.assist_no == IPA_OUTBOUND_CHECKSUM &&
1078	    cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
1079		card->info.tx_csum_mask =
1080			cmd->data.setassparms.data.flags_32bit;
1081		QETH_CARD_TEXT_(card, 3, "tcsu:%d", card->info.tx_csum_mask);
1082	}
1083
1084	return 0;
1085}
1086
1087static struct qeth_cmd_buffer *qeth_l3_get_setassparms_cmd(
1088	struct qeth_card *card, enum qeth_ipa_funcs ipa_func, __u16 cmd_code,
1089	__u16 len, enum qeth_prot_versions prot)
1090{
1091	struct qeth_cmd_buffer *iob;
1092	struct qeth_ipa_cmd *cmd;
1093
1094	QETH_CARD_TEXT(card, 4, "getasscm");
1095	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot);
1096
1097	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1098	cmd->data.setassparms.hdr.assist_no = ipa_func;
1099	cmd->data.setassparms.hdr.length = 8 + len;
1100	cmd->data.setassparms.hdr.command_code = cmd_code;
1101	cmd->data.setassparms.hdr.return_code = 0;
1102	cmd->data.setassparms.hdr.seq_no = 0;
1103
1104	return iob;
1105}
1106
1107static int qeth_l3_send_setassparms(struct qeth_card *card,
1108	struct qeth_cmd_buffer *iob, __u16 len, long data,
1109	int (*reply_cb)(struct qeth_card *, struct qeth_reply *,
1110		unsigned long),
1111	void *reply_param)
1112{
1113	int rc;
1114	struct qeth_ipa_cmd *cmd;
1115
1116	QETH_CARD_TEXT(card, 4, "sendassp");
1117
1118	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1119	if (len <= sizeof(__u32))
1120		cmd->data.setassparms.data.flags_32bit = (__u32) data;
1121	else   /* (len > sizeof(__u32)) */
1122		memcpy(&cmd->data.setassparms.data, (void *) data, len);
1123
1124	rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param);
1125	return rc;
1126}
1127
1128#ifdef CONFIG_QETH_IPV6
1129static int qeth_l3_send_simple_setassparms_ipv6(struct qeth_card *card,
1130		enum qeth_ipa_funcs ipa_func, __u16 cmd_code)
1131{
1132	int rc;
1133	struct qeth_cmd_buffer *iob;
1134
1135	QETH_CARD_TEXT(card, 4, "simassp6");
1136	iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code,
1137				       0, QETH_PROT_IPV6);
1138	rc = qeth_l3_send_setassparms(card, iob, 0, 0,
1139				   qeth_l3_default_setassparms_cb, NULL);
1140	return rc;
1141}
1142#endif
1143
1144static int qeth_l3_send_simple_setassparms(struct qeth_card *card,
1145		enum qeth_ipa_funcs ipa_func, __u16 cmd_code, long data)
1146{
1147	int rc;
1148	int length = 0;
1149	struct qeth_cmd_buffer *iob;
1150
1151	QETH_CARD_TEXT(card, 4, "simassp4");
1152	if (data)
1153		length = sizeof(__u32);
1154	iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code,
1155				       length, QETH_PROT_IPV4);
1156	rc = qeth_l3_send_setassparms(card, iob, length, data,
1157				   qeth_l3_default_setassparms_cb, NULL);
1158	return rc;
1159}
1160
1161static int qeth_l3_start_ipa_arp_processing(struct qeth_card *card)
1162{
1163	int rc;
1164
1165	QETH_CARD_TEXT(card, 3, "ipaarp");
1166
1167	if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) {
1168		dev_info(&card->gdev->dev,
1169			"ARP processing not supported on %s!\n",
1170			QETH_CARD_IFNAME(card));
1171		return 0;
1172	}
1173	rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING,
1174					IPA_CMD_ASS_START, 0);
1175	if (rc) {
1176		dev_warn(&card->gdev->dev,
1177			"Starting ARP processing support for %s failed\n",
1178			QETH_CARD_IFNAME(card));
1179	}
1180	return rc;
1181}
1182
1183static int qeth_l3_start_ipa_ip_fragmentation(struct qeth_card *card)
1184{
1185	int rc;
1186
1187	QETH_CARD_TEXT(card, 3, "ipaipfrg");
1188
1189	if (!qeth_is_supported(card, IPA_IP_FRAGMENTATION)) {
1190		dev_info(&card->gdev->dev,
1191			"Hardware IP fragmentation not supported on %s\n",
1192			QETH_CARD_IFNAME(card));
1193		return  -EOPNOTSUPP;
1194	}
1195
1196	rc = qeth_l3_send_simple_setassparms(card, IPA_IP_FRAGMENTATION,
1197					  IPA_CMD_ASS_START, 0);
1198	if (rc) {
1199		dev_warn(&card->gdev->dev,
1200			"Starting IP fragmentation support for %s failed\n",
1201			QETH_CARD_IFNAME(card));
1202	} else
1203		dev_info(&card->gdev->dev,
1204			"Hardware IP fragmentation enabled \n");
1205	return rc;
1206}
1207
1208static int qeth_l3_start_ipa_source_mac(struct qeth_card *card)
1209{
1210	int rc;
1211
1212	QETH_CARD_TEXT(card, 3, "stsrcmac");
1213
1214	if (!qeth_is_supported(card, IPA_SOURCE_MAC)) {
1215		dev_info(&card->gdev->dev,
1216			"Inbound source MAC-address not supported on %s\n",
1217			QETH_CARD_IFNAME(card));
1218		return -EOPNOTSUPP;
1219	}
1220
1221	rc = qeth_l3_send_simple_setassparms(card, IPA_SOURCE_MAC,
1222					  IPA_CMD_ASS_START, 0);
1223	if (rc)
1224		dev_warn(&card->gdev->dev,
1225			"Starting source MAC-address support for %s failed\n",
1226			QETH_CARD_IFNAME(card));
1227	return rc;
1228}
1229
1230static int qeth_l3_start_ipa_vlan(struct qeth_card *card)
1231{
1232	int rc = 0;
1233
1234	QETH_CARD_TEXT(card, 3, "strtvlan");
1235
1236	if (!qeth_is_supported(card, IPA_FULL_VLAN)) {
1237		dev_info(&card->gdev->dev,
1238			"VLAN not supported on %s\n", QETH_CARD_IFNAME(card));
1239		return -EOPNOTSUPP;
1240	}
1241
1242	rc = qeth_l3_send_simple_setassparms(card, IPA_VLAN_PRIO,
1243					  IPA_CMD_ASS_START, 0);
1244	if (rc) {
1245		dev_warn(&card->gdev->dev,
1246			"Starting VLAN support for %s failed\n",
1247			QETH_CARD_IFNAME(card));
1248	} else {
1249		dev_info(&card->gdev->dev, "VLAN enabled\n");
1250	}
1251	return rc;
1252}
1253
1254static int qeth_l3_start_ipa_multicast(struct qeth_card *card)
1255{
1256	int rc;
1257
1258	QETH_CARD_TEXT(card, 3, "stmcast");
1259
1260	if (!qeth_is_supported(card, IPA_MULTICASTING)) {
1261		dev_info(&card->gdev->dev,
1262			"Multicast not supported on %s\n",
1263			QETH_CARD_IFNAME(card));
1264		return -EOPNOTSUPP;
1265	}
1266
1267	rc = qeth_l3_send_simple_setassparms(card, IPA_MULTICASTING,
1268					  IPA_CMD_ASS_START, 0);
1269	if (rc) {
1270		dev_warn(&card->gdev->dev,
1271			"Starting multicast support for %s failed\n",
1272			QETH_CARD_IFNAME(card));
1273	} else {
1274		dev_info(&card->gdev->dev, "Multicast enabled\n");
1275		card->dev->flags |= IFF_MULTICAST;
1276	}
1277	return rc;
1278}
1279
1280#ifdef CONFIG_QETH_IPV6
1281static int qeth_l3_softsetup_ipv6(struct qeth_card *card)
1282{
1283	int rc;
1284
1285	QETH_CARD_TEXT(card, 3, "softipv6");
1286
1287	if (card->info.type == QETH_CARD_TYPE_IQD)
1288		goto out;
1289
1290	rc = qeth_query_ipassists(card, QETH_PROT_IPV6);
1291	if (rc) {
1292		dev_err(&card->gdev->dev,
1293			"Activating IPv6 support for %s failed\n",
1294			QETH_CARD_IFNAME(card));
1295		return rc;
1296	}
1297	rc = qeth_l3_send_simple_setassparms(card, IPA_IPV6,
1298					  IPA_CMD_ASS_START, 3);
1299	if (rc) {
1300		dev_err(&card->gdev->dev,
1301			"Activating IPv6 support for %s failed\n",
1302			QETH_CARD_IFNAME(card));
1303		return rc;
1304	}
1305	rc = qeth_l3_send_simple_setassparms_ipv6(card, IPA_IPV6,
1306					       IPA_CMD_ASS_START);
1307	if (rc) {
1308		dev_err(&card->gdev->dev,
1309			"Activating IPv6 support for %s failed\n",
1310			 QETH_CARD_IFNAME(card));
1311		return rc;
1312	}
1313	rc = qeth_l3_send_simple_setassparms_ipv6(card, IPA_PASSTHRU,
1314					       IPA_CMD_ASS_START);
1315	if (rc) {
1316		dev_warn(&card->gdev->dev,
1317			"Enabling the passthrough mode for %s failed\n",
1318			QETH_CARD_IFNAME(card));
1319		return rc;
1320	}
1321out:
1322	dev_info(&card->gdev->dev, "IPV6 enabled\n");
1323	return 0;
1324}
1325#endif
1326
1327static int qeth_l3_start_ipa_ipv6(struct qeth_card *card)
1328{
1329	int rc = 0;
1330
1331	QETH_CARD_TEXT(card, 3, "strtipv6");
1332
1333	if (!qeth_is_supported(card, IPA_IPV6)) {
1334		dev_info(&card->gdev->dev,
1335			"IPv6 not supported on %s\n", QETH_CARD_IFNAME(card));
1336		return 0;
1337	}
1338#ifdef CONFIG_QETH_IPV6
1339	rc = qeth_l3_softsetup_ipv6(card);
1340#endif
1341	return rc ;
1342}
1343
1344static int qeth_l3_start_ipa_broadcast(struct qeth_card *card)
1345{
1346	int rc;
1347
1348	QETH_CARD_TEXT(card, 3, "stbrdcst");
1349	card->info.broadcast_capable = 0;
1350	if (!qeth_is_supported(card, IPA_FILTERING)) {
1351		dev_info(&card->gdev->dev,
1352			"Broadcast not supported on %s\n",
1353			QETH_CARD_IFNAME(card));
1354		rc = -EOPNOTSUPP;
1355		goto out;
1356	}
1357	rc = qeth_l3_send_simple_setassparms(card, IPA_FILTERING,
1358					  IPA_CMD_ASS_START, 0);
1359	if (rc) {
1360		dev_warn(&card->gdev->dev, "Enabling broadcast filtering for "
1361			"%s failed\n", QETH_CARD_IFNAME(card));
1362		goto out;
1363	}
1364
1365	rc = qeth_l3_send_simple_setassparms(card, IPA_FILTERING,
1366					  IPA_CMD_ASS_CONFIGURE, 1);
1367	if (rc) {
1368		dev_warn(&card->gdev->dev,
1369			"Setting up broadcast filtering for %s failed\n",
1370			QETH_CARD_IFNAME(card));
1371		goto out;
1372	}
1373	card->info.broadcast_capable = QETH_BROADCAST_WITH_ECHO;
1374	dev_info(&card->gdev->dev, "Broadcast enabled\n");
1375	rc = qeth_l3_send_simple_setassparms(card, IPA_FILTERING,
1376					  IPA_CMD_ASS_ENABLE, 1);
1377	if (rc) {
1378		dev_warn(&card->gdev->dev, "Setting up broadcast echo "
1379			"filtering for %s failed\n", QETH_CARD_IFNAME(card));
1380		goto out;
1381	}
1382	card->info.broadcast_capable = QETH_BROADCAST_WITHOUT_ECHO;
1383out:
1384	if (card->info.broadcast_capable)
1385		card->dev->flags |= IFF_BROADCAST;
1386	else
1387		card->dev->flags &= ~IFF_BROADCAST;
1388	return rc;
1389}
1390
1391static int qeth_l3_send_checksum_command(struct qeth_card *card)
1392{
1393	int rc;
1394
1395	rc = qeth_l3_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
1396					  IPA_CMD_ASS_START, 0);
1397	if (rc) {
1398		dev_warn(&card->gdev->dev, "Starting HW checksumming for %s "
1399			"failed, using SW checksumming\n",
1400			QETH_CARD_IFNAME(card));
1401		return rc;
1402	}
1403	rc = qeth_l3_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
1404					  IPA_CMD_ASS_ENABLE,
1405					  card->info.csum_mask);
1406	if (rc) {
1407		dev_warn(&card->gdev->dev, "Enabling HW checksumming for %s "
1408			"failed, using SW checksumming\n",
1409			QETH_CARD_IFNAME(card));
1410		return rc;
1411	}
1412	return 0;
1413}
1414
1415int qeth_l3_set_rx_csum(struct qeth_card *card, int on)
1416{
1417	int rc = 0;
1418
1419	if (on) {
1420		rc = qeth_l3_send_checksum_command(card);
1421		if (rc)
1422			return -EIO;
1423		dev_info(&card->gdev->dev,
1424			"HW Checksumming (inbound) enabled\n");
1425	} else {
1426		rc = qeth_l3_send_simple_setassparms(card,
1427			IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
1428		if (rc)
1429			return -EIO;
1430	}
1431
1432	return 0;
1433}
1434
1435static int qeth_l3_start_ipa_checksum(struct qeth_card *card)
1436{
1437	QETH_CARD_TEXT(card, 3, "strtcsum");
1438
1439	if (card->dev->features & NETIF_F_RXCSUM) {
1440		rtnl_lock();
1441		/* force set_features call */
1442		card->dev->features &= ~NETIF_F_RXCSUM;
1443		netdev_update_features(card->dev);
1444		rtnl_unlock();
1445	}
1446	return 0;
1447}
1448
1449static int qeth_l3_start_ipa_tx_checksum(struct qeth_card *card)
1450{
1451	int rc = 0;
1452
1453	if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
1454		return rc;
1455	rc = qeth_l3_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM,
1456			  IPA_CMD_ASS_START, 0);
1457	if (rc)
1458		goto err_out;
1459	rc = qeth_l3_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM,
1460			  IPA_CMD_ASS_ENABLE, card->info.tx_csum_mask);
1461	if (rc)
1462		goto err_out;
1463	dev_info(&card->gdev->dev, "HW TX Checksumming enabled\n");
1464	return rc;
1465err_out:
1466	dev_warn(&card->gdev->dev, "Enabling HW TX checksumming for %s "
1467		"failed, using SW TX checksumming\n", QETH_CARD_IFNAME(card));
1468	return rc;
1469}
1470
1471static int qeth_l3_start_ipa_tso(struct qeth_card *card)
1472{
1473	int rc;
1474
1475	QETH_CARD_TEXT(card, 3, "sttso");
1476
1477	if (!qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
1478		dev_info(&card->gdev->dev,
1479			"Outbound TSO not supported on %s\n",
1480			QETH_CARD_IFNAME(card));
1481		rc = -EOPNOTSUPP;
1482	} else {
1483		rc = qeth_l3_send_simple_setassparms(card, IPA_OUTBOUND_TSO,
1484						IPA_CMD_ASS_START, 0);
1485		if (rc)
1486			dev_warn(&card->gdev->dev, "Starting outbound TCP "
1487				"segmentation offload for %s failed\n",
1488				QETH_CARD_IFNAME(card));
1489		else
1490			dev_info(&card->gdev->dev,
1491				"Outbound TSO enabled\n");
1492	}
1493	if (rc)
1494		card->dev->features &= ~NETIF_F_TSO;
1495	return rc;
1496}
1497
1498static int qeth_l3_start_ipassists(struct qeth_card *card)
1499{
1500	QETH_CARD_TEXT(card, 3, "strtipas");
1501
1502	qeth_set_access_ctrl_online(card);	/* go on*/
1503	qeth_l3_start_ipa_arp_processing(card);	/* go on*/
1504	qeth_l3_start_ipa_ip_fragmentation(card);	/* go on*/
1505	qeth_l3_start_ipa_source_mac(card);	/* go on*/
1506	qeth_l3_start_ipa_vlan(card);		/* go on*/
1507	qeth_l3_start_ipa_multicast(card);		/* go on*/
1508	qeth_l3_start_ipa_ipv6(card);		/* go on*/
1509	qeth_l3_start_ipa_broadcast(card);		/* go on*/
1510	qeth_l3_start_ipa_checksum(card);		/* go on*/
1511	qeth_l3_start_ipa_tx_checksum(card);
1512	qeth_l3_start_ipa_tso(card);		/* go on*/
1513	return 0;
1514}
1515
1516static int qeth_l3_iqd_read_initial_mac_cb(struct qeth_card *card,
1517		struct qeth_reply *reply, unsigned long data)
1518{
1519	struct qeth_ipa_cmd *cmd;
1520
1521	cmd = (struct qeth_ipa_cmd *) data;
1522	if (cmd->hdr.return_code == 0)
1523		memcpy(card->dev->dev_addr,
1524			cmd->data.create_destroy_addr.unique_id, ETH_ALEN);
1525	else
1526		random_ether_addr(card->dev->dev_addr);
1527
1528	return 0;
1529}
1530
1531static int qeth_l3_iqd_read_initial_mac(struct qeth_card *card)
1532{
1533	int rc = 0;
1534	struct qeth_cmd_buffer *iob;
1535	struct qeth_ipa_cmd *cmd;
1536
1537	QETH_DBF_TEXT(SETUP, 2, "hsrmac");
1538
1539	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR,
1540				     QETH_PROT_IPV6);
1541	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1542	*((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
1543			card->info.unique_id;
1544
1545	rc = qeth_send_ipa_cmd(card, iob, qeth_l3_iqd_read_initial_mac_cb,
1546				NULL);
1547	return rc;
1548}
1549
1550static int qeth_l3_get_unique_id_cb(struct qeth_card *card,
1551		struct qeth_reply *reply, unsigned long data)
1552{
1553	struct qeth_ipa_cmd *cmd;
1554
1555	cmd = (struct qeth_ipa_cmd *) data;
1556	if (cmd->hdr.return_code == 0)
1557		card->info.unique_id = *((__u16 *)
1558				&cmd->data.create_destroy_addr.unique_id[6]);
1559	else {
1560		card->info.unique_id =  UNIQUE_ID_IF_CREATE_ADDR_FAILED |
1561					UNIQUE_ID_NOT_BY_CARD;
1562		dev_warn(&card->gdev->dev, "The network adapter failed to "
1563			"generate a unique ID\n");
1564	}
1565	return 0;
1566}
1567
1568static int qeth_l3_get_unique_id(struct qeth_card *card)
1569{
1570	int rc = 0;
1571	struct qeth_cmd_buffer *iob;
1572	struct qeth_ipa_cmd *cmd;
1573
1574	QETH_DBF_TEXT(SETUP, 2, "guniqeid");
1575
1576	if (!qeth_is_supported(card, IPA_IPV6)) {
1577		card->info.unique_id =  UNIQUE_ID_IF_CREATE_ADDR_FAILED |
1578					UNIQUE_ID_NOT_BY_CARD;
1579		return 0;
1580	}
1581
1582	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR,
1583				     QETH_PROT_IPV6);
1584	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1585	*((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
1586			card->info.unique_id;
1587
1588	rc = qeth_send_ipa_cmd(card, iob, qeth_l3_get_unique_id_cb, NULL);
1589	return rc;
1590}
1591
1592static int
1593qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply,
1594			    unsigned long data)
1595{
1596	struct qeth_ipa_cmd	   *cmd;
1597	__u16 rc;
1598
1599	QETH_DBF_TEXT(SETUP, 2, "diastrcb");
1600
1601	cmd = (struct qeth_ipa_cmd *)data;
1602	rc = cmd->hdr.return_code;
1603	if (rc)
1604		QETH_CARD_TEXT_(card, 2, "dxter%x", rc);
1605	switch (cmd->data.diagass.action) {
1606	case QETH_DIAGS_CMD_TRACE_QUERY:
1607		break;
1608	case QETH_DIAGS_CMD_TRACE_DISABLE:
1609		switch (rc) {
1610		case 0:
1611		case IPA_RC_INVALID_SUBCMD:
1612			card->info.promisc_mode = SET_PROMISC_MODE_OFF;
1613			dev_info(&card->gdev->dev, "The HiperSockets network "
1614				"traffic analyzer is deactivated\n");
1615			break;
1616		default:
1617			break;
1618		}
1619		break;
1620	case QETH_DIAGS_CMD_TRACE_ENABLE:
1621		switch (rc) {
1622		case 0:
1623			card->info.promisc_mode = SET_PROMISC_MODE_ON;
1624			dev_info(&card->gdev->dev, "The HiperSockets network "
1625				"traffic analyzer is activated\n");
1626			break;
1627		case IPA_RC_HARDWARE_AUTH_ERROR:
1628			dev_warn(&card->gdev->dev, "The device is not "
1629				"authorized to run as a HiperSockets network "
1630				"traffic analyzer\n");
1631			break;
1632		case IPA_RC_TRACE_ALREADY_ACTIVE:
1633			dev_warn(&card->gdev->dev, "A HiperSockets "
1634				"network traffic analyzer is already "
1635				"active in the HiperSockets LAN\n");
1636			break;
1637		default:
1638			break;
1639		}
1640		break;
1641	default:
1642		QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n",
1643			cmd->data.diagass.action, QETH_CARD_IFNAME(card));
1644	}
1645
1646	return 0;
1647}
1648
1649static int
1650qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd)
1651{
1652	struct qeth_cmd_buffer *iob;
1653	struct qeth_ipa_cmd    *cmd;
1654
1655	QETH_DBF_TEXT(SETUP, 2, "diagtrac");
1656
1657	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
1658	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1659	cmd->data.diagass.subcmd_len = 16;
1660	cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE;
1661	cmd->data.diagass.type = QETH_DIAGS_TYPE_HIPERSOCKET;
1662	cmd->data.diagass.action = diags_cmd;
1663	return qeth_send_ipa_cmd(card, iob, qeth_diags_trace_cb, NULL);
1664}
1665
1666static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac,
1667				struct net_device *dev)
1668{
1669	if (dev->type == ARPHRD_IEEE802_TR)
1670		ip_tr_mc_map(ipm, mac);
1671	else
1672		ip_eth_mc_map(ipm, mac);
1673}
1674
1675static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev)
1676{
1677	struct qeth_ipaddr *ipm;
1678	struct ip_mc_list *im4;
1679	char buf[MAX_ADDR_LEN];
1680
1681	QETH_CARD_TEXT(card, 4, "addmc");
1682	for (im4 = rcu_dereference(in4_dev->mc_list); im4 != NULL;
1683	     im4 = rcu_dereference(im4->next_rcu)) {
1684		qeth_l3_get_mac_for_ipm(im4->multiaddr, buf, in4_dev->dev);
1685		ipm = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
1686		if (!ipm)
1687			continue;
1688		ipm->u.a4.addr = im4->multiaddr;
1689		memcpy(ipm->mac, buf, OSA_ADDR_LEN);
1690		ipm->is_multicast = 1;
1691		if (!qeth_l3_add_ip(card, ipm))
1692			kfree(ipm);
1693	}
1694}
1695
1696static void qeth_l3_add_vlan_mc(struct qeth_card *card)
1697{
1698	struct in_device *in_dev;
1699	struct vlan_group *vg;
1700	int i;
1701
1702	QETH_CARD_TEXT(card, 4, "addmcvl");
1703	if (!qeth_is_supported(card, IPA_FULL_VLAN) || (card->vlangrp == NULL))
1704		return;
1705
1706	vg = card->vlangrp;
1707	for (i = 0; i < VLAN_N_VID; i++) {
1708		struct net_device *netdev = vlan_group_get_device(vg, i);
1709		if (netdev == NULL ||
1710		    !(netdev->flags & IFF_UP))
1711			continue;
1712		in_dev = in_dev_get(netdev);
1713		if (!in_dev)
1714			continue;
1715		rcu_read_lock();
1716		qeth_l3_add_mc(card, in_dev);
1717		rcu_read_unlock();
1718		in_dev_put(in_dev);
1719	}
1720}
1721
1722static void qeth_l3_add_multicast_ipv4(struct qeth_card *card)
1723{
1724	struct in_device *in4_dev;
1725
1726	QETH_CARD_TEXT(card, 4, "chkmcv4");
1727	in4_dev = in_dev_get(card->dev);
1728	if (in4_dev == NULL)
1729		return;
1730	rcu_read_lock();
1731	qeth_l3_add_mc(card, in4_dev);
1732	qeth_l3_add_vlan_mc(card);
1733	rcu_read_unlock();
1734	in_dev_put(in4_dev);
1735}
1736
1737#ifdef CONFIG_QETH_IPV6
1738static void qeth_l3_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev)
1739{
1740	struct qeth_ipaddr *ipm;
1741	struct ifmcaddr6 *im6;
1742	char buf[MAX_ADDR_LEN];
1743
1744	QETH_CARD_TEXT(card, 4, "addmc6");
1745	for (im6 = in6_dev->mc_list; im6 != NULL; im6 = im6->next) {
1746		ndisc_mc_map(&im6->mca_addr, buf, in6_dev->dev, 0);
1747		ipm = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
1748		if (!ipm)
1749			continue;
1750		ipm->is_multicast = 1;
1751		memcpy(ipm->mac, buf, OSA_ADDR_LEN);
1752		memcpy(&ipm->u.a6.addr, &im6->mca_addr.s6_addr,
1753		       sizeof(struct in6_addr));
1754		if (!qeth_l3_add_ip(card, ipm))
1755			kfree(ipm);
1756	}
1757}
1758
1759static void qeth_l3_add_vlan_mc6(struct qeth_card *card)
1760{
1761	struct inet6_dev *in_dev;
1762	struct vlan_group *vg;
1763	int i;
1764
1765	QETH_CARD_TEXT(card, 4, "admc6vl");
1766	if (!qeth_is_supported(card, IPA_FULL_VLAN) || (card->vlangrp == NULL))
1767		return;
1768
1769	vg = card->vlangrp;
1770	for (i = 0; i < VLAN_N_VID; i++) {
1771		struct net_device *netdev = vlan_group_get_device(vg, i);
1772		if (netdev == NULL ||
1773		    !(netdev->flags & IFF_UP))
1774			continue;
1775		in_dev = in6_dev_get(netdev);
1776		if (!in_dev)
1777			continue;
1778		read_lock_bh(&in_dev->lock);
1779		qeth_l3_add_mc6(card, in_dev);
1780		read_unlock_bh(&in_dev->lock);
1781		in6_dev_put(in_dev);
1782	}
1783}
1784
1785static void qeth_l3_add_multicast_ipv6(struct qeth_card *card)
1786{
1787	struct inet6_dev *in6_dev;
1788
1789	QETH_CARD_TEXT(card, 4, "chkmcv6");
1790	if (!qeth_is_supported(card, IPA_IPV6))
1791		return ;
1792	in6_dev = in6_dev_get(card->dev);
1793	if (in6_dev == NULL)
1794		return;
1795	read_lock_bh(&in6_dev->lock);
1796	qeth_l3_add_mc6(card, in6_dev);
1797	qeth_l3_add_vlan_mc6(card);
1798	read_unlock_bh(&in6_dev->lock);
1799	in6_dev_put(in6_dev);
1800}
1801#endif /* CONFIG_QETH_IPV6 */
1802
1803static void qeth_l3_free_vlan_addresses4(struct qeth_card *card,
1804			unsigned short vid)
1805{
1806	struct in_device *in_dev;
1807	struct in_ifaddr *ifa;
1808	struct qeth_ipaddr *addr;
1809
1810	QETH_CARD_TEXT(card, 4, "frvaddr4");
1811
1812	in_dev = in_dev_get(vlan_group_get_device(card->vlangrp, vid));
1813	if (!in_dev)
1814		return;
1815	for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
1816		addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
1817		if (addr) {
1818			addr->u.a4.addr = ifa->ifa_address;
1819			addr->u.a4.mask = ifa->ifa_mask;
1820			addr->type = QETH_IP_TYPE_NORMAL;
1821			if (!qeth_l3_delete_ip(card, addr))
1822				kfree(addr);
1823		}
1824	}
1825	in_dev_put(in_dev);
1826}
1827
1828static void qeth_l3_free_vlan_addresses6(struct qeth_card *card,
1829			unsigned short vid)
1830{
1831#ifdef CONFIG_QETH_IPV6
1832	struct inet6_dev *in6_dev;
1833	struct inet6_ifaddr *ifa;
1834	struct qeth_ipaddr *addr;
1835
1836	QETH_CARD_TEXT(card, 4, "frvaddr6");
1837
1838	in6_dev = in6_dev_get(vlan_group_get_device(card->vlangrp, vid));
1839	if (!in6_dev)
1840		return;
1841	list_for_each_entry(ifa, &in6_dev->addr_list, if_list) {
1842		addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
1843		if (addr) {
1844			memcpy(&addr->u.a6.addr, &ifa->addr,
1845			       sizeof(struct in6_addr));
1846			addr->u.a6.pfxlen = ifa->prefix_len;
1847			addr->type = QETH_IP_TYPE_NORMAL;
1848			if (!qeth_l3_delete_ip(card, addr))
1849				kfree(addr);
1850		}
1851	}
1852	in6_dev_put(in6_dev);
1853#endif /* CONFIG_QETH_IPV6 */
1854}
1855
1856static void qeth_l3_free_vlan_addresses(struct qeth_card *card,
1857			unsigned short vid)
1858{
1859	if (!card->vlangrp)
1860		return;
1861	qeth_l3_free_vlan_addresses4(card, vid);
1862	qeth_l3_free_vlan_addresses6(card, vid);
1863}
1864
1865static void qeth_l3_vlan_rx_register(struct net_device *dev,
1866			struct vlan_group *grp)
1867{
1868	struct qeth_card *card = dev->ml_priv;
1869	unsigned long flags;
1870
1871	QETH_CARD_TEXT(card, 4, "vlanreg");
1872	spin_lock_irqsave(&card->vlanlock, flags);
1873	card->vlangrp = grp;
1874	spin_unlock_irqrestore(&card->vlanlock, flags);
1875}
1876
1877static void qeth_l3_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
1878{
1879	return;
1880}
1881
1882static void qeth_l3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
1883{
1884	struct qeth_card *card = dev->ml_priv;
1885	unsigned long flags;
1886
1887	QETH_CARD_TEXT_(card, 4, "kid:%d", vid);
1888	if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
1889		QETH_CARD_TEXT(card, 3, "kidREC");
1890		return;
1891	}
1892	spin_lock_irqsave(&card->vlanlock, flags);
1893	/* unregister IP addresses of vlan device */
1894	qeth_l3_free_vlan_addresses(card, vid);
1895	vlan_group_set_device(card->vlangrp, vid, NULL);
1896	spin_unlock_irqrestore(&card->vlanlock, flags);
1897	qeth_l3_set_multicast_list(card->dev);
1898}
1899
1900static inline int qeth_l3_rebuild_skb(struct qeth_card *card,
1901			struct sk_buff *skb, struct qeth_hdr *hdr,
1902			unsigned short *vlan_id)
1903{
1904	__be16 prot;
1905	str

Large files files are truncated, but you can click here to view the full file