qeth_core_main.c 163.5 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
F
Frank Blaschka 已提交
2
/*
3
 *    Copyright IBM Corp. 2007, 2009
F
Frank Blaschka 已提交
4 5 6 7 8 9
 *    Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
 *		 Frank Pavlic <fpavlic@de.ibm.com>,
 *		 Thomas Spatzier <tspat@de.ibm.com>,
 *		 Frank Blaschka <frank.blaschka@de.ibm.com>
 */

10 11 12
#define KMSG_COMPONENT "qeth"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

13
#include <linux/compat.h>
F
Frank Blaschka 已提交
14 15 16 17 18
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/kernel.h>
19
#include <linux/log2.h>
F
Frank Blaschka 已提交
20 21 22
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/mii.h>
J
Julian Wiedmann 已提交
23
#include <linux/mm.h>
F
Frank Blaschka 已提交
24
#include <linux/kthread.h>
25
#include <linux/slab.h>
26 27 28 29
#include <linux/if_vlan.h>
#include <linux/netdevice.h>
#include <linux/netdev_features.h>
#include <linux/skbuff.h>
30
#include <linux/vmalloc.h>
31

32
#include <net/iucv/af_iucv.h>
33
#include <net/dsfield.h>
F
Frank Blaschka 已提交
34

35
#include <asm/ebcdic.h>
36
#include <asm/chpid.h>
37
#include <asm/io.h>
38
#include <asm/sysinfo.h>
39 40 41
#include <asm/diag.h>
#include <asm/cio.h>
#include <asm/ccwdev.h>
42
#include <asm/cpcmd.h>
F
Frank Blaschka 已提交
43 44 45

#include "qeth_core.h"

46 47 48 49 50
struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = {
	/* define dbf - Name, Pages, Areas, Maxlen, Level, View, Handle */
	/*                   N  P  A    M  L  V                      H  */
	[QETH_DBF_SETUP] = {"qeth_setup",
				8, 1,   8, 5, &debug_hex_ascii_view, NULL},
51 52
	[QETH_DBF_MSG]	 = {"qeth_msg", 8, 1, 11 * sizeof(long), 3,
			    &debug_sprintf_view, NULL},
53 54 55 56
	[QETH_DBF_CTRL]  = {"qeth_control",
		8, 1, QETH_DBF_CTRL_LEN, 5, &debug_hex_ascii_view, NULL},
};
EXPORT_SYMBOL_GPL(qeth_dbf);
F
Frank Blaschka 已提交
57

58 59
struct kmem_cache *qeth_core_header_cache;
EXPORT_SYMBOL_GPL(qeth_core_header_cache);
60
static struct kmem_cache *qeth_qdio_outbuf_cache;
F
Frank Blaschka 已提交
61 62 63 64

static struct device *qeth_core_root_dev;
static struct lock_class_key qdio_out_skb_queue_key;

65 66
static void qeth_issue_next_read_cb(struct qeth_card *card,
				    struct qeth_cmd_buffer *iob);
F
Frank Blaschka 已提交
67 68
static void qeth_free_buffer_pool(struct qeth_card *);
static int qeth_qdio_establish(struct qeth_card *);
69
static void qeth_free_qdio_queues(struct qeth_card *card);
70 71 72 73
static void qeth_notify_skbs(struct qeth_qdio_out_q *queue,
		struct qeth_qdio_out_buffer *buf,
		enum iucv_tx_notify notification);
static void qeth_release_skbs(struct qeth_qdio_out_buffer *buf);
74
static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int);
F
Frank Blaschka 已提交
75

S
Stefan Raspl 已提交
76 77 78 79 80 81 82 83 84
static void qeth_close_dev_handler(struct work_struct *work)
{
	struct qeth_card *card;

	card = container_of(work, struct qeth_card, close_dev_work);
	QETH_CARD_TEXT(card, 2, "cldevhdl");
	ccwgroup_set_offline(card->gdev);
}

J
Julian Wiedmann 已提交
85
static const char *qeth_get_cardname(struct qeth_card *card)
F
Frank Blaschka 已提交
86
{
87
	if (IS_VM_NIC(card)) {
F
Frank Blaschka 已提交
88
		switch (card->info.type) {
89
		case QETH_CARD_TYPE_OSD:
90
			return " Virtual NIC QDIO";
F
Frank Blaschka 已提交
91
		case QETH_CARD_TYPE_IQD:
92
			return " Virtual NIC Hiper";
93
		case QETH_CARD_TYPE_OSM:
94
			return " Virtual NIC QDIO - OSM";
95
		case QETH_CARD_TYPE_OSX:
96
			return " Virtual NIC QDIO - OSX";
F
Frank Blaschka 已提交
97 98 99 100 101
		default:
			return " unknown";
		}
	} else {
		switch (card->info.type) {
102
		case QETH_CARD_TYPE_OSD:
F
Frank Blaschka 已提交
103 104 105 106 107
			return " OSD Express";
		case QETH_CARD_TYPE_IQD:
			return " HiperSockets";
		case QETH_CARD_TYPE_OSN:
			return " OSN QDIO";
108 109 110 111
		case QETH_CARD_TYPE_OSM:
			return " OSM QDIO";
		case QETH_CARD_TYPE_OSX:
			return " OSX QDIO";
F
Frank Blaschka 已提交
112 113 114 115 116 117 118 119 120 121
		default:
			return " unknown";
		}
	}
	return " n/a";
}

/* max length to be returned: 14 */
const char *qeth_get_cardname_short(struct qeth_card *card)
{
122
	if (IS_VM_NIC(card)) {
F
Frank Blaschka 已提交
123
		switch (card->info.type) {
124
		case QETH_CARD_TYPE_OSD:
125
			return "Virt.NIC QDIO";
F
Frank Blaschka 已提交
126
		case QETH_CARD_TYPE_IQD:
127
			return "Virt.NIC Hiper";
128
		case QETH_CARD_TYPE_OSM:
129
			return "Virt.NIC OSM";
130
		case QETH_CARD_TYPE_OSX:
131
			return "Virt.NIC OSX";
F
Frank Blaschka 已提交
132 133 134 135 136
		default:
			return "unknown";
		}
	} else {
		switch (card->info.type) {
137
		case QETH_CARD_TYPE_OSD:
F
Frank Blaschka 已提交
138 139 140 141 142 143 144 145 146
			switch (card->info.link_type) {
			case QETH_LINK_TYPE_FAST_ETH:
				return "OSD_100";
			case QETH_LINK_TYPE_HSTR:
				return "HSTR";
			case QETH_LINK_TYPE_GBIT_ETH:
				return "OSD_1000";
			case QETH_LINK_TYPE_10GBIT_ETH:
				return "OSD_10GIG";
147 148
			case QETH_LINK_TYPE_25GBIT_ETH:
				return "OSD_25GIG";
F
Frank Blaschka 已提交
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
			case QETH_LINK_TYPE_LANE_ETH100:
				return "OSD_FE_LANE";
			case QETH_LINK_TYPE_LANE_TR:
				return "OSD_TR_LANE";
			case QETH_LINK_TYPE_LANE_ETH1000:
				return "OSD_GbE_LANE";
			case QETH_LINK_TYPE_LANE:
				return "OSD_ATM_LANE";
			default:
				return "OSD_Express";
			}
		case QETH_CARD_TYPE_IQD:
			return "HiperSockets";
		case QETH_CARD_TYPE_OSN:
			return "OSN";
164 165 166 167
		case QETH_CARD_TYPE_OSM:
			return "OSM_1000";
		case QETH_CARD_TYPE_OSX:
			return "OSX_10GIG";
F
Frank Blaschka 已提交
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
		default:
			return "unknown";
		}
	}
	return "n/a";
}

void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads,
			 int clear_start_mask)
{
	unsigned long flags;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	card->thread_allowed_mask = threads;
	if (clear_start_mask)
		card->thread_start_mask &= threads;
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	wake_up(&card->wait_q);
}
EXPORT_SYMBOL_GPL(qeth_set_allowed_threads);

int qeth_threads_running(struct qeth_card *card, unsigned long threads)
{
	unsigned long flags;
	int rc = 0;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	rc = (card->thread_running_mask & threads);
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_threads_running);

void qeth_clear_working_pool_list(struct qeth_card *card)
{
	struct qeth_buffer_pool_entry *pool_entry, *tmp;

C
Carsten Otte 已提交
205
	QETH_CARD_TEXT(card, 5, "clwrklst");
F
Frank Blaschka 已提交
206 207 208 209 210 211 212 213 214 215 216 217 218
	list_for_each_entry_safe(pool_entry, tmp,
			    &card->qdio.in_buf_pool.entry_list, list){
			list_del(&pool_entry->list);
	}
}
EXPORT_SYMBOL_GPL(qeth_clear_working_pool_list);

static int qeth_alloc_buffer_pool(struct qeth_card *card)
{
	struct qeth_buffer_pool_entry *pool_entry;
	void *ptr;
	int i, j;

C
Carsten Otte 已提交
219
	QETH_CARD_TEXT(card, 5, "alocpool");
F
Frank Blaschka 已提交
220
	for (i = 0; i < card->qdio.init_pool.buf_count; ++i) {
221
		pool_entry = kzalloc(sizeof(*pool_entry), GFP_KERNEL);
F
Frank Blaschka 已提交
222 223 224 225 226
		if (!pool_entry) {
			qeth_free_buffer_pool(card);
			return -ENOMEM;
		}
		for (j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j) {
227
			ptr = (void *) __get_free_page(GFP_KERNEL);
F
Frank Blaschka 已提交
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
			if (!ptr) {
				while (j > 0)
					free_page((unsigned long)
						  pool_entry->elements[--j]);
				kfree(pool_entry);
				qeth_free_buffer_pool(card);
				return -ENOMEM;
			}
			pool_entry->elements[j] = ptr;
		}
		list_add(&pool_entry->init_list,
			 &card->qdio.init_pool.entry_list);
	}
	return 0;
}

int qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt)
{
C
Carsten Otte 已提交
246
	QETH_CARD_TEXT(card, 2, "realcbp");
F
Frank Blaschka 已提交
247

248
	if (card->state != CARD_STATE_DOWN)
F
Frank Blaschka 已提交
249 250 251 252 253 254 255 256 257
		return -EPERM;

	/* TODO: steel/add buffers from/to a running card's buffer pool (?) */
	qeth_clear_working_pool_list(card);
	qeth_free_buffer_pool(card);
	card->qdio.in_buf_pool.buf_count = bufcnt;
	card->qdio.init_pool.buf_count = bufcnt;
	return qeth_alloc_buffer_pool(card);
}
258
EXPORT_SYMBOL_GPL(qeth_realloc_buffer_pool);
F
Frank Blaschka 已提交
259

S
Sebastian Ott 已提交
260 261
static void qeth_free_qdio_queue(struct qeth_qdio_q *q)
{
262 263 264 265
	if (!q)
		return;

	qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
S
Sebastian Ott 已提交
266 267 268 269 270 271 272 273 274 275 276
	kfree(q);
}

static struct qeth_qdio_q *qeth_alloc_qdio_queue(void)
{
	struct qeth_qdio_q *q = kzalloc(sizeof(*q), GFP_KERNEL);
	int i;

	if (!q)
		return NULL;

277 278 279 280 281
	if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) {
		kfree(q);
		return NULL;
	}

S
Sebastian Ott 已提交
282
	for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i)
283
		q->bufs[i].buffer = q->qdio_bufs[i];
S
Sebastian Ott 已提交
284 285 286 287 288

	QETH_DBF_HEX(SETUP, 2, &q, sizeof(void *));
	return q;
}

J
Julian Wiedmann 已提交
289
static int qeth_cq_init(struct qeth_card *card)
290 291 292 293
{
	int rc;

	if (card->options.cq == QETH_CQ_ENABLED) {
294
		QETH_CARD_TEXT(card, 2, "cqinit");
295 296
		qdio_reset_buffers(card->qdio.c_q->qdio_bufs,
				   QDIO_MAX_BUFFERS_PER_Q);
297 298 299 300 301
		card->qdio.c_q->next_buf_to_init = 127;
		rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT,
			     card->qdio.no_in_queues - 1, 0,
			     127);
		if (rc) {
302
			QETH_CARD_TEXT_(card, 2, "1err%d", rc);
303 304 305 306 307 308 309 310
			goto out;
		}
	}
	rc = 0;
out:
	return rc;
}

J
Julian Wiedmann 已提交
311
static int qeth_alloc_cq(struct qeth_card *card)
312 313 314 315 316 317 318
{
	int rc;

	if (card->options.cq == QETH_CQ_ENABLED) {
		int i;
		struct qdio_outbuf_state *outbuf_states;

319
		QETH_CARD_TEXT(card, 2, "cqon");
S
Sebastian Ott 已提交
320
		card->qdio.c_q = qeth_alloc_qdio_queue();
321 322 323 324 325
		if (!card->qdio.c_q) {
			rc = -1;
			goto kmsg_out;
		}
		card->qdio.no_in_queues = 2;
326
		card->qdio.out_bufstates =
K
Kees Cook 已提交
327 328 329 330
			kcalloc(card->qdio.no_out_queues *
					QDIO_MAX_BUFFERS_PER_Q,
				sizeof(struct qdio_outbuf_state),
				GFP_KERNEL);
331 332 333 334 335 336 337 338 339 340
		outbuf_states = card->qdio.out_bufstates;
		if (outbuf_states == NULL) {
			rc = -1;
			goto free_cq_out;
		}
		for (i = 0; i < card->qdio.no_out_queues; ++i) {
			card->qdio.out_qs[i]->bufstates = outbuf_states;
			outbuf_states += QDIO_MAX_BUFFERS_PER_Q;
		}
	} else {
341
		QETH_CARD_TEXT(card, 2, "nocq");
342 343 344
		card->qdio.c_q = NULL;
		card->qdio.no_in_queues = 1;
	}
345
	QETH_CARD_TEXT_(card, 2, "iqc%d", card->qdio.no_in_queues);
346 347 348 349
	rc = 0;
out:
	return rc;
free_cq_out:
S
Sebastian Ott 已提交
350
	qeth_free_qdio_queue(card->qdio.c_q);
351 352 353 354 355 356
	card->qdio.c_q = NULL;
kmsg_out:
	dev_err(&card->gdev->dev, "Failed to create completion queue\n");
	goto out;
}

J
Julian Wiedmann 已提交
357
static void qeth_free_cq(struct qeth_card *card)
358 359 360
{
	if (card->qdio.c_q) {
		--card->qdio.no_in_queues;
S
Sebastian Ott 已提交
361
		qeth_free_qdio_queue(card->qdio.c_q);
362 363 364 365 366 367
		card->qdio.c_q = NULL;
	}
	kfree(card->qdio.out_bufstates);
	card->qdio.out_bufstates = NULL;
}

J
Julian Wiedmann 已提交
368 369 370
static enum iucv_tx_notify qeth_compute_cq_notification(int sbalf15,
							int delayed)
{
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
	enum iucv_tx_notify n;

	switch (sbalf15) {
	case 0:
		n = delayed ? TX_NOTIFY_DELAYED_OK : TX_NOTIFY_OK;
		break;
	case 4:
	case 16:
	case 17:
	case 18:
		n = delayed ? TX_NOTIFY_DELAYED_UNREACHABLE :
			TX_NOTIFY_UNREACHABLE;
		break;
	default:
		n = delayed ? TX_NOTIFY_DELAYED_GENERALERROR :
			TX_NOTIFY_GENERALERROR;
		break;
	}

	return n;
}

J
Julian Wiedmann 已提交
393 394
static void qeth_cleanup_handled_pending(struct qeth_qdio_out_q *q, int bidx,
					 int forced_cleanup)
395
{
396 397 398
	if (q->card->options.cq != QETH_CQ_ENABLED)
		return;

399 400 401 402 403 404 405 406 407 408 409
	if (q->bufs[bidx]->next_pending != NULL) {
		struct qeth_qdio_out_buffer *head = q->bufs[bidx];
		struct qeth_qdio_out_buffer *c = q->bufs[bidx]->next_pending;

		while (c) {
			if (forced_cleanup ||
			    atomic_read(&c->state) ==
			      QETH_QDIO_BUF_HANDLED_DELAYED) {
				struct qeth_qdio_out_buffer *f = c;
				QETH_CARD_TEXT(f->q->card, 5, "fp");
				QETH_CARD_TEXT_(f->q->card, 5, "%lx", (long) f);
410 411 412 413 414
				/* release here to avoid interleaving between
				   outbound tasklet and inbound tasklet
				   regarding notifications and lifecycle */
				qeth_release_skbs(c);

415
				c = f->next_pending;
S
Stefan Raspl 已提交
416
				WARN_ON_ONCE(head->next_pending != f);
417 418 419 420 421 422 423 424 425
				head->next_pending = c;
				kmem_cache_free(qeth_qdio_outbuf_cache, f);
			} else {
				head = c;
				c = c->next_pending;
			}

		}
	}
426 427 428 429 430 431
	if (forced_cleanup && (atomic_read(&(q->bufs[bidx]->state)) ==
					QETH_QDIO_BUF_HANDLED_DELAYED)) {
		/* for recovery situations */
		qeth_init_qdio_out_buf(q, bidx);
		QETH_CARD_TEXT(q->card, 2, "clprecov");
	}
432 433 434
}


J
Julian Wiedmann 已提交
435 436 437
static void qeth_qdio_handle_aob(struct qeth_card *card,
				 unsigned long phys_aob_addr)
{
438 439
	struct qaob *aob;
	struct qeth_qdio_out_buffer *buffer;
440
	enum iucv_tx_notify notification;
441
	unsigned int i;
442 443 444 445 446 447 448

	aob = (struct qaob *) phys_to_virt(phys_aob_addr);
	QETH_CARD_TEXT(card, 5, "haob");
	QETH_CARD_TEXT_(card, 5, "%lx", phys_aob_addr);
	buffer = (struct qeth_qdio_out_buffer *) aob->user1;
	QETH_CARD_TEXT_(card, 5, "%lx", aob->user1);

449 450 451 452
	if (atomic_cmpxchg(&buffer->state, QETH_QDIO_BUF_PRIMED,
			   QETH_QDIO_BUF_IN_CQ) == QETH_QDIO_BUF_PRIMED) {
		notification = TX_NOTIFY_OK;
	} else {
S
Stefan Raspl 已提交
453 454
		WARN_ON_ONCE(atomic_read(&buffer->state) !=
							QETH_QDIO_BUF_PENDING);
455 456 457 458 459 460 461 462 463 464
		atomic_set(&buffer->state, QETH_QDIO_BUF_IN_CQ);
		notification = TX_NOTIFY_DELAYED_OK;
	}

	if (aob->aorc != 0)  {
		QETH_CARD_TEXT_(card, 2, "aorc%02X", aob->aorc);
		notification = qeth_compute_cq_notification(aob->aorc, 1);
	}
	qeth_notify_skbs(buffer->q, buffer, notification);

465 466 467 468 469 470 471 472 473 474 475
	/* Free dangling allocations. The attached skbs are handled by
	 * qeth_cleanup_handled_pending().
	 */
	for (i = 0;
	     i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card);
	     i++) {
		if (aob->sba[i] && buffer->is_header[i])
			kmem_cache_free(qeth_core_header_cache,
					(void *) aob->sba[i]);
	}
	atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED);
476

477 478 479 480 481 482 483 484 485 486 487
	qdio_release_aob(aob);
}

static inline int qeth_is_cq(struct qeth_card *card, unsigned int queue)
{
	return card->options.cq == QETH_CQ_ENABLED &&
	    card->qdio.c_q != NULL &&
	    queue != 0 &&
	    queue == card->qdio.no_in_queues - 1;
}

488 489
static void qeth_setup_ccw(struct ccw1 *ccw, u8 cmd_code, u8 flags, u32 len,
			   void *data)
490 491
{
	ccw->cmd_code = cmd_code;
492
	ccw->flags = flags | CCW_FLAG_SLI;
493 494 495 496
	ccw->count = len;
	ccw->cda = (__u32) __pa(data);
}

497
static int __qeth_issue_next_read(struct qeth_card *card)
F
Frank Blaschka 已提交
498
{
499 500 501
	struct qeth_cmd_buffer *iob = card->read_cmd;
	struct qeth_channel *channel = iob->channel;
	struct ccw1 *ccw = __ccw_from_cmd(iob);
502
	int rc;
F
Frank Blaschka 已提交
503

C
Carsten Otte 已提交
504
	QETH_CARD_TEXT(card, 5, "issnxrd");
505
	if (channel->state != CH_STATE_UP)
F
Frank Blaschka 已提交
506
		return -EIO;
507

508 509
	memset(iob->data, 0, iob->length);
	qeth_setup_ccw(ccw, CCW_CMD_READ, 0, iob->length, iob->data);
510
	iob->callback = qeth_issue_next_read_cb;
511 512 513
	/* keep the cmd alive after completion: */
	qeth_get_cmd(iob);

C
Carsten Otte 已提交
514
	QETH_CARD_TEXT(card, 6, "noirqpnd");
515
	rc = ccw_device_start(channel->ccwdev, ccw, (addr_t) iob, 0, 0);
F
Frank Blaschka 已提交
516
	if (rc) {
517 518
		QETH_DBF_MESSAGE(2, "error %i on device %x when starting next read ccw!\n",
				 rc, CARD_DEVID(card));
519
		atomic_set(&channel->irq_pending, 0);
520
		qeth_put_cmd(iob);
521
		card->read_or_write_problem = 1;
F
Frank Blaschka 已提交
522 523 524 525 526 527
		qeth_schedule_recovery(card);
		wake_up(&card->wait_q);
	}
	return rc;
}

528 529 530 531 532 533 534 535 536 537 538
static int qeth_issue_next_read(struct qeth_card *card)
{
	int ret;

	spin_lock_irq(get_ccwdev_lock(CARD_RDEV(card)));
	ret = __qeth_issue_next_read(card);
	spin_unlock_irq(get_ccwdev_lock(CARD_RDEV(card)));

	return ret;
}

F
Frank Blaschka 已提交
539 540 541 542
static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
{
	struct qeth_reply *reply;

543
	reply = kzalloc(sizeof(*reply), GFP_KERNEL);
F
Frank Blaschka 已提交
544
	if (reply) {
545
		refcount_set(&reply->refcnt, 1);
546
		init_completion(&reply->received);
547
	}
F
Frank Blaschka 已提交
548 549 550 551 552
	return reply;
}

static void qeth_get_reply(struct qeth_reply *reply)
{
553
	refcount_inc(&reply->refcnt);
F
Frank Blaschka 已提交
554 555 556 557
}

static void qeth_put_reply(struct qeth_reply *reply)
{
558
	if (refcount_dec_and_test(&reply->refcnt))
F
Frank Blaschka 已提交
559 560 561
		kfree(reply);
}

562 563 564 565 566 567 568 569 570 571 572 573 574 575
static void qeth_enqueue_reply(struct qeth_card *card, struct qeth_reply *reply)
{
	spin_lock_irq(&card->lock);
	list_add_tail(&reply->list, &card->cmd_waiter_list);
	spin_unlock_irq(&card->lock);
}

static void qeth_dequeue_reply(struct qeth_card *card, struct qeth_reply *reply)
{
	spin_lock_irq(&card->lock);
	list_del(&reply->list);
	spin_unlock_irq(&card->lock);
}

576
void qeth_notify_reply(struct qeth_reply *reply, int reason)
577
{
578
	reply->rc = reason;
579
	complete(&reply->received);
580
}
581
EXPORT_SYMBOL_GPL(qeth_notify_reply);
582

583
static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc,
F
Frank Blaschka 已提交
584 585
		struct qeth_card *card)
{
586
	const char *ipa_name;
587
	int com = cmd->hdr.command;
F
Frank Blaschka 已提交
588
	ipa_name = qeth_get_ipa_cmd_name(com);
589

590
	if (rc)
591 592 593
		QETH_DBF_MESSAGE(2, "IPA: %s(%#x) for device %x returned %#x \"%s\"\n",
				 ipa_name, com, CARD_DEVID(card), rc,
				 qeth_get_ipa_msg(rc));
594
	else
595 596
		QETH_DBF_MESSAGE(5, "IPA: %s(%#x) for device %x succeeded\n",
				 ipa_name, com, CARD_DEVID(card));
F
Frank Blaschka 已提交
597 598 599
}

static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
600
						struct qeth_ipa_cmd *cmd)
F
Frank Blaschka 已提交
601
{
C
Carsten Otte 已提交
602
	QETH_CARD_TEXT(card, 5, "chkipad");
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619

	if (IS_IPA_REPLY(cmd)) {
		if (cmd->hdr.command != IPA_CMD_SETCCID &&
		    cmd->hdr.command != IPA_CMD_DELCCID &&
		    cmd->hdr.command != IPA_CMD_MODCCID &&
		    cmd->hdr.command != IPA_CMD_SET_DIAG_ASS)
			qeth_issue_ipa_msg(cmd, cmd->hdr.return_code, card);
		return cmd;
	}

	/* handle unsolicited event: */
	switch (cmd->hdr.command) {
	case IPA_CMD_STOPLAN:
		if (cmd->hdr.return_code == IPA_RC_VEPA_TO_VEB_TRANSITION) {
			dev_err(&card->gdev->dev,
				"Interface %s is down because the adjacent port is no longer in reflective relay mode\n",
				QETH_CARD_IFNAME(card));
620
			schedule_work(&card->close_dev_work);
F
Frank Blaschka 已提交
621
		} else {
622 623 624 625
			dev_warn(&card->gdev->dev,
				 "The link for interface %s on CHPID 0x%X failed\n",
				 QETH_CARD_IFNAME(card), card->info.chpid);
			qeth_issue_ipa_msg(cmd, cmd->hdr.return_code, card);
626
			netif_carrier_off(card->dev);
F
Frank Blaschka 已提交
627
		}
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
		return NULL;
	case IPA_CMD_STARTLAN:
		dev_info(&card->gdev->dev,
			 "The link for %s on CHPID 0x%X has been restored\n",
			 QETH_CARD_IFNAME(card), card->info.chpid);
		if (card->info.hwtrap)
			card->info.hwtrap = 2;
		qeth_schedule_recovery(card);
		return NULL;
	case IPA_CMD_SETBRIDGEPORT_IQD:
	case IPA_CMD_SETBRIDGEPORT_OSA:
	case IPA_CMD_ADDRESS_CHANGE_NOTIF:
		if (card->discipline->control_event_handler(card, cmd))
			return cmd;
		return NULL;
	case IPA_CMD_MODCCID:
		return cmd;
	case IPA_CMD_REGISTER_LOCAL_ADDR:
		QETH_CARD_TEXT(card, 3, "irla");
		return NULL;
	case IPA_CMD_UNREGISTER_LOCAL_ADDR:
		QETH_CARD_TEXT(card, 3, "urla");
		return NULL;
	default:
		QETH_DBF_MESSAGE(2, "Received data is IPA but not a reply!\n");
		return cmd;
F
Frank Blaschka 已提交
654 655 656 657 658
	}
}

void qeth_clear_ipacmd_list(struct qeth_card *card)
{
659
	struct qeth_reply *reply;
F
Frank Blaschka 已提交
660 661
	unsigned long flags;

C
Carsten Otte 已提交
662
	QETH_CARD_TEXT(card, 4, "clipalst");
F
Frank Blaschka 已提交
663 664

	spin_lock_irqsave(&card->lock, flags);
665 666
	list_for_each_entry(reply, &card->cmd_waiter_list, list)
		qeth_notify_reply(reply, -EIO);
F
Frank Blaschka 已提交
667 668 669 670
	spin_unlock_irqrestore(&card->lock, flags);
}
EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list);

671 672
static int qeth_check_idx_response(struct qeth_card *card,
	unsigned char *buffer)
F
Frank Blaschka 已提交
673
{
674
	QETH_DBF_HEX(CTRL, 2, buffer, QETH_DBF_CTRL_LEN);
F
Frank Blaschka 已提交
675
	if ((buffer[2] & 0xc0) == 0xc0) {
676
		QETH_DBF_MESSAGE(2, "received an IDX TERMINATE with cause code %#04x\n",
677
				 buffer[4]);
C
Carsten Otte 已提交
678 679 680
		QETH_CARD_TEXT(card, 2, "ckidxres");
		QETH_CARD_TEXT(card, 2, " idxterm");
		QETH_CARD_TEXT_(card, 2, "  rc%d", -EIO);
681 682 683 684 685 686
		if (buffer[4] == 0xf6) {
			dev_err(&card->gdev->dev,
			"The qeth device is not configured "
			"for the OSI layer required by z/VM\n");
			return -EPERM;
		}
F
Frank Blaschka 已提交
687 688 689 690 691
		return -EIO;
	}
	return 0;
}

692
void qeth_put_cmd(struct qeth_cmd_buffer *iob)
693 694 695 696 697 698 699 700
{
	if (refcount_dec_and_test(&iob->ref_count)) {
		if (iob->reply)
			qeth_put_reply(iob->reply);
		kfree(iob->data);
		kfree(iob);
	}
}
701
EXPORT_SYMBOL_GPL(qeth_put_cmd);
F
Frank Blaschka 已提交
702

703 704 705
static void qeth_release_buffer_cb(struct qeth_card *card,
				   struct qeth_cmd_buffer *iob)
{
706
	qeth_put_cmd(iob);
707 708
}

709 710 711 712
static void qeth_cancel_cmd(struct qeth_cmd_buffer *iob, int rc)
{
	struct qeth_reply *reply = iob->reply;

713 714
	if (reply)
		qeth_notify_reply(reply, rc);
715
	qeth_put_cmd(iob);
F
Frank Blaschka 已提交
716 717
}

718 719 720
struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel,
				       unsigned int length, unsigned int ccws,
				       long timeout)
721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737
{
	struct qeth_cmd_buffer *iob;

	if (length > QETH_BUFSIZE)
		return NULL;

	iob = kzalloc(sizeof(*iob), GFP_KERNEL);
	if (!iob)
		return NULL;

	iob->data = kzalloc(ALIGN(length, 8) + ccws * sizeof(struct ccw1),
			    GFP_KERNEL | GFP_DMA);
	if (!iob->data) {
		kfree(iob);
		return NULL;
	}

738
	refcount_set(&iob->ref_count, 1);
739 740 741 742 743
	iob->channel = channel;
	iob->timeout = timeout;
	iob->length = length;
	return iob;
}
744
EXPORT_SYMBOL_GPL(qeth_alloc_cmd);
745

746 747
static void qeth_issue_next_read_cb(struct qeth_card *card,
				    struct qeth_cmd_buffer *iob)
F
Frank Blaschka 已提交
748
{
749
	struct qeth_ipa_cmd *cmd = NULL;
750 751
	struct qeth_reply *reply = NULL;
	struct qeth_reply *r;
F
Frank Blaschka 已提交
752
	unsigned long flags;
753
	int rc = 0;
F
Frank Blaschka 已提交
754

C
Carsten Otte 已提交
755
	QETH_CARD_TEXT(card, 4, "sndctlcb");
756 757 758 759 760
	rc = qeth_check_idx_response(card, iob->data);
	switch (rc) {
	case 0:
		break;
	case -EIO:
F
Frank Blaschka 已提交
761
		qeth_clear_ipacmd_list(card);
762
		qeth_schedule_recovery(card);
763
		/* fall through */
764
	default:
F
Frank Blaschka 已提交
765 766 767
		goto out;
	}

768 769 770
	if (IS_IPA(iob->data)) {
		cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
		cmd = qeth_check_ipa_data(card, cmd);
771 772 773 774 775 776 777 778 779 780 781
		if (!cmd)
			goto out;
		if (IS_OSN(card) && card->osn_info.assist_cb &&
		    cmd->hdr.command != IPA_CMD_STARTLAN) {
			card->osn_info.assist_cb(card->dev, cmd);
			goto out;
		}
	} else {
		/* non-IPA commands should only flow during initialization */
		if (card->state != CARD_STATE_DOWN)
			goto out;
F
Frank Blaschka 已提交
782 783
	}

784
	/* match against pending cmd requests */
F
Frank Blaschka 已提交
785
	spin_lock_irqsave(&card->lock, flags);
786 787 788 789 790
	list_for_each_entry(r, &card->cmd_waiter_list, list) {
		if ((r->seqno == QETH_IDX_COMMAND_SEQNO) ||
		    (cmd && (r->seqno == cmd->hdr.seqno))) {
			reply = r;
			/* take the object outside the lock */
F
Frank Blaschka 已提交
791
			qeth_get_reply(reply);
792
			break;
F
Frank Blaschka 已提交
793 794 795
		}
	}
	spin_unlock_irqrestore(&card->lock, flags);
796 797 798 799

	if (!reply)
		goto out;

800 801 802
	if (!reply->callback) {
		rc = 0;
	} else {
803 804
		if (cmd) {
			reply->offset = (u16)((char *)cmd - (char *)iob->data);
805 806 807 808
			rc = reply->callback(card, reply, (unsigned long)cmd);
		} else {
			rc = reply->callback(card, reply, (unsigned long)iob);
		}
809 810
	}

811 812
	if (rc <= 0)
		qeth_notify_reply(reply, rc);
813 814
	qeth_put_reply(reply);

F
Frank Blaschka 已提交
815 816 817 818
out:
	memcpy(&card->seqno.pdu_hdr_ack,
		QETH_PDU_HEADER_SEQ_NO(iob->data),
		QETH_SEQ_NO_LENGTH);
819
	qeth_put_cmd(iob);
820
	__qeth_issue_next_read(card);
F
Frank Blaschka 已提交
821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856
}

static int qeth_set_thread_start_bit(struct qeth_card *card,
		unsigned long thread)
{
	unsigned long flags;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	if (!(card->thread_allowed_mask & thread) ||
	      (card->thread_start_mask & thread)) {
		spin_unlock_irqrestore(&card->thread_mask_lock, flags);
		return -EPERM;
	}
	card->thread_start_mask |= thread;
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	return 0;
}

void qeth_clear_thread_start_bit(struct qeth_card *card, unsigned long thread)
{
	unsigned long flags;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	card->thread_start_mask &= ~thread;
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	wake_up(&card->wait_q);
}
EXPORT_SYMBOL_GPL(qeth_clear_thread_start_bit);

void qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread)
{
	unsigned long flags;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	card->thread_running_mask &= ~thread;
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
857
	wake_up_all(&card->wait_q);
F
Frank Blaschka 已提交
858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891
}
EXPORT_SYMBOL_GPL(qeth_clear_thread_running_bit);

static int __qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
{
	unsigned long flags;
	int rc = 0;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	if (card->thread_start_mask & thread) {
		if ((card->thread_allowed_mask & thread) &&
		    !(card->thread_running_mask & thread)) {
			rc = 1;
			card->thread_start_mask &= ~thread;
			card->thread_running_mask |= thread;
		} else
			rc = -EPERM;
	}
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	return rc;
}

int qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
{
	int rc = 0;

	wait_event(card->wait_q,
		   (rc = __qeth_do_run_thread(card, thread)) >= 0);
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_do_run_thread);

void qeth_schedule_recovery(struct qeth_card *card)
{
C
Carsten Otte 已提交
892
	QETH_CARD_TEXT(card, 2, "startrec");
F
Frank Blaschka 已提交
893 894 895 896 897
	if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
		schedule_work(&card->kernel_thread_starter);
}
EXPORT_SYMBOL_GPL(qeth_schedule_recovery);

898 899
static int qeth_get_problem(struct qeth_card *card, struct ccw_device *cdev,
			    struct irb *irb)
F
Frank Blaschka 已提交
900 901 902 903 904
{
	int dstat, cstat;
	char *sense;

	sense = (char *) irb->ecw;
905 906
	cstat = irb->scsw.cmd.cstat;
	dstat = irb->scsw.cmd.dstat;
F
Frank Blaschka 已提交
907 908 909 910

	if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK |
		     SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK |
		     SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) {
C
Carsten Otte 已提交
911
		QETH_CARD_TEXT(card, 2, "CGENCHK");
912 913
		dev_warn(&cdev->dev, "The qeth device driver "
			"failed to recover an error on the device\n");
914 915
		QETH_DBF_MESSAGE(2, "check on channel %x with dstat=%#x, cstat=%#x\n",
				 CCW_DEVID(cdev), dstat, cstat);
F
Frank Blaschka 已提交
916 917 918 919 920 921 922 923
		print_hex_dump(KERN_WARNING, "qeth: irb ", DUMP_PREFIX_OFFSET,
				16, 1, irb, 64, 1);
		return 1;
	}

	if (dstat & DEV_STAT_UNIT_CHECK) {
		if (sense[SENSE_RESETTING_EVENT_BYTE] &
		    SENSE_RESETTING_EVENT_FLAG) {
C
Carsten Otte 已提交
924
			QETH_CARD_TEXT(card, 2, "REVIND");
F
Frank Blaschka 已提交
925 926 927 928
			return 1;
		}
		if (sense[SENSE_COMMAND_REJECT_BYTE] &
		    SENSE_COMMAND_REJECT_FLAG) {
C
Carsten Otte 已提交
929
			QETH_CARD_TEXT(card, 2, "CMDREJi");
930
			return 1;
F
Frank Blaschka 已提交
931 932
		}
		if ((sense[2] == 0xaf) && (sense[3] == 0xfe)) {
C
Carsten Otte 已提交
933
			QETH_CARD_TEXT(card, 2, "AFFE");
F
Frank Blaschka 已提交
934 935 936
			return 1;
		}
		if ((!sense[0]) && (!sense[1]) && (!sense[2]) && (!sense[3])) {
C
Carsten Otte 已提交
937
			QETH_CARD_TEXT(card, 2, "ZEROSEN");
F
Frank Blaschka 已提交
938 939
			return 0;
		}
C
Carsten Otte 已提交
940
		QETH_CARD_TEXT(card, 2, "DGENCHK");
F
Frank Blaschka 已提交
941 942 943 944 945
			return 1;
	}
	return 0;
}

946
static int qeth_check_irb_error(struct qeth_card *card, struct ccw_device *cdev,
947
				struct irb *irb)
F
Frank Blaschka 已提交
948
{
949
	if (!IS_ERR(irb))
F
Frank Blaschka 已提交
950 951 952 953
		return 0;

	switch (PTR_ERR(irb)) {
	case -EIO:
954 955
		QETH_DBF_MESSAGE(2, "i/o-error on channel %x\n",
				 CCW_DEVID(cdev));
C
Carsten Otte 已提交
956 957
		QETH_CARD_TEXT(card, 2, "ckirberr");
		QETH_CARD_TEXT_(card, 2, "  rc%d", -EIO);
958
		return -EIO;
F
Frank Blaschka 已提交
959
	case -ETIMEDOUT:
960 961
		dev_warn(&cdev->dev, "A hardware operation timed out"
			" on the device\n");
C
Carsten Otte 已提交
962 963
		QETH_CARD_TEXT(card, 2, "ckirberr");
		QETH_CARD_TEXT_(card, 2, "  rc%d", -ETIMEDOUT);
964
		return -ETIMEDOUT;
F
Frank Blaschka 已提交
965
	default:
966 967
		QETH_DBF_MESSAGE(2, "unknown error %ld on channel %x\n",
				 PTR_ERR(irb), CCW_DEVID(cdev));
C
Carsten Otte 已提交
968 969
		QETH_CARD_TEXT(card, 2, "ckirberr");
		QETH_CARD_TEXT(card, 2, "  rc???");
970
		return PTR_ERR(irb);
F
Frank Blaschka 已提交
971 972 973 974 975 976 977 978
	}
}

static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
		struct irb *irb)
{
	int rc;
	int cstat, dstat;
979
	struct qeth_cmd_buffer *iob = NULL;
980
	struct ccwgroup_device *gdev;
F
Frank Blaschka 已提交
981 982 983
	struct qeth_channel *channel;
	struct qeth_card *card;

984 985 986
	/* while we hold the ccwdev lock, this stays valid: */
	gdev = dev_get_drvdata(&cdev->dev);
	card = dev_get_drvdata(&gdev->dev);
F
Frank Blaschka 已提交
987 988 989
	if (!card)
		return;

C
Carsten Otte 已提交
990 991
	QETH_CARD_TEXT(card, 5, "irq");

F
Frank Blaschka 已提交
992 993
	if (card->read.ccwdev == cdev) {
		channel = &card->read;
C
Carsten Otte 已提交
994
		QETH_CARD_TEXT(card, 5, "read");
F
Frank Blaschka 已提交
995 996
	} else if (card->write.ccwdev == cdev) {
		channel = &card->write;
C
Carsten Otte 已提交
997
		QETH_CARD_TEXT(card, 5, "write");
F
Frank Blaschka 已提交
998 999
	} else {
		channel = &card->data;
C
Carsten Otte 已提交
1000
		QETH_CARD_TEXT(card, 5, "data");
F
Frank Blaschka 已提交
1001
	}
1002 1003 1004 1005

	if (qeth_intparm_is_iob(intparm))
		iob = (struct qeth_cmd_buffer *) __va((addr_t)intparm);

1006
	rc = qeth_check_irb_error(card, cdev, irb);
1007
	if (rc) {
1008 1009
		/* IO was terminated, free its resources. */
		if (iob)
1010
			qeth_cancel_cmd(iob, rc);
1011 1012 1013 1014 1015
		atomic_set(&channel->irq_pending, 0);
		wake_up(&card->wait_q);
		return;
	}

F
Frank Blaschka 已提交
1016 1017
	atomic_set(&channel->irq_pending, 0);

1018
	if (irb->scsw.cmd.fctl & (SCSW_FCTL_CLEAR_FUNC))
F
Frank Blaschka 已提交
1019 1020
		channel->state = CH_STATE_STOPPED;

1021
	if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC))
F
Frank Blaschka 已提交
1022 1023 1024
		channel->state = CH_STATE_HALTED;

	if (intparm == QETH_CLEAR_CHANNEL_PARM) {
C
Carsten Otte 已提交
1025
		QETH_CARD_TEXT(card, 6, "clrchpar");
F
Frank Blaschka 已提交
1026 1027 1028 1029
		/* we don't have to handle this further */
		intparm = 0;
	}
	if (intparm == QETH_HALT_CHANNEL_PARM) {
C
Carsten Otte 已提交
1030
		QETH_CARD_TEXT(card, 6, "hltchpar");
F
Frank Blaschka 已提交
1031 1032 1033
		/* we don't have to handle this further */
		intparm = 0;
	}
1034 1035 1036 1037

	cstat = irb->scsw.cmd.cstat;
	dstat = irb->scsw.cmd.dstat;

F
Frank Blaschka 已提交
1038 1039 1040 1041
	if ((dstat & DEV_STAT_UNIT_EXCEP) ||
	    (dstat & DEV_STAT_UNIT_CHECK) ||
	    (cstat)) {
		if (irb->esw.esw0.erw.cons) {
1042 1043 1044
			dev_warn(&channel->ccwdev->dev,
				"The qeth device driver failed to recover "
				"an error on the device\n");
1045 1046 1047
			QETH_DBF_MESSAGE(2, "sense data available on channel %x: cstat %#X dstat %#X\n",
					 CCW_DEVID(channel->ccwdev), cstat,
					 dstat);
F
Frank Blaschka 已提交
1048 1049 1050 1051 1052
			print_hex_dump(KERN_WARNING, "qeth: irb ",
				DUMP_PREFIX_OFFSET, 16, 1, irb, 32, 1);
			print_hex_dump(KERN_WARNING, "qeth: sense data ",
				DUMP_PREFIX_OFFSET, 16, 1, irb->ecw, 32, 1);
		}
1053

1054
		rc = qeth_get_problem(card, cdev, irb);
F
Frank Blaschka 已提交
1055
		if (rc) {
1056
			card->read_or_write_problem = 1;
1057
			if (iob)
1058
				qeth_cancel_cmd(iob, rc);
1059
			qeth_clear_ipacmd_list(card);
F
Frank Blaschka 已提交
1060 1061 1062 1063 1064
			qeth_schedule_recovery(card);
			goto out;
		}
	}

1065
	if (iob && iob->callback)
1066
		iob->callback(card, iob);
F
Frank Blaschka 已提交
1067 1068 1069 1070 1071 1072

out:
	wake_up(&card->wait_q);
	return;
}

1073
static void qeth_notify_skbs(struct qeth_qdio_out_q *q,
1074
		struct qeth_qdio_out_buffer *buf,
1075
		enum iucv_tx_notify notification)
F
Frank Blaschka 已提交
1076 1077 1078
{
	struct sk_buff *skb;

1079
	skb_queue_walk(&buf->skb_list, skb) {
1080 1081
		QETH_CARD_TEXT_(q->card, 5, "skbn%d", notification);
		QETH_CARD_TEXT_(q->card, 5, "%lx", (long) skb);
1082 1083
		if (skb->protocol == htons(ETH_P_AF_IUCV) && skb->sk)
			iucv_sk(skb->sk)->sk_txnotify(skb, notification);
1084 1085 1086 1087 1088
	}
}

static void qeth_release_skbs(struct qeth_qdio_out_buffer *buf)
{
1089 1090
	struct sk_buff *skb;

1091
	/* release may never happen from within CQ tasklet scope */
S
Stefan Raspl 已提交
1092
	WARN_ON_ONCE(atomic_read(&buf->state) == QETH_QDIO_BUF_IN_CQ);
F
Frank Blaschka 已提交
1093

1094 1095 1096
	if (atomic_read(&buf->state) == QETH_QDIO_BUF_PENDING)
		qeth_notify_skbs(buf->q, buf, TX_NOTIFY_GENERALERROR);

1097 1098
	while ((skb = __skb_dequeue(&buf->skb_list)) != NULL)
		consume_skb(skb);
1099 1100 1101
}

static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
1102
				     struct qeth_qdio_out_buffer *buf)
1103 1104 1105 1106 1107 1108 1109
{
	int i;

	/* is PCI flag set on buffer? */
	if (buf->buffer->element[0].sflags & SBAL_SFLAGS0_PCI_REQ)
		atomic_dec(&queue->set_pci_flags_count);

1110 1111
	qeth_release_skbs(buf);

1112
	for (i = 0; i < queue->max_elements; ++i) {
1113 1114 1115 1116
		if (buf->buffer->element[i].addr && buf->is_header[i])
			kmem_cache_free(qeth_core_header_cache,
				buf->buffer->element[i].addr);
		buf->is_header[i] = 0;
F
Frank Blaschka 已提交
1117
	}
1118

1119
	qeth_scrub_qdio_buffer(buf->buffer, queue->max_elements);
F
Frank Blaschka 已提交
1120
	buf->next_element_to_fill = 0;
1121
	atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
1122 1123
}

1124
static void qeth_drain_output_queue(struct qeth_qdio_out_q *q, bool free)
1125 1126 1127 1128 1129 1130
{
	int j;

	for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
		if (!q->bufs[j])
			continue;
1131
		qeth_cleanup_handled_pending(q, j, 1);
1132
		qeth_clear_output_buffer(q, q->bufs[j]);
1133 1134 1135 1136 1137
		if (free) {
			kmem_cache_free(qeth_qdio_outbuf_cache, q->bufs[j]);
			q->bufs[j] = NULL;
		}
	}
F
Frank Blaschka 已提交
1138 1139
}

1140
void qeth_drain_output_queues(struct qeth_card *card)
F
Frank Blaschka 已提交
1141
{
1142
	int i;
F
Frank Blaschka 已提交
1143

C
Carsten Otte 已提交
1144
	QETH_CARD_TEXT(card, 2, "clearqdbf");
F
Frank Blaschka 已提交
1145
	/* clear outbound buffers to free skbs */
1146
	for (i = 0; i < card->qdio.no_out_queues; ++i) {
1147 1148
		if (card->qdio.out_qs[i])
			qeth_drain_output_queue(card->qdio.out_qs[i], false);
1149
	}
F
Frank Blaschka 已提交
1150
}
1151
EXPORT_SYMBOL_GPL(qeth_drain_output_queues);
F
Frank Blaschka 已提交
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167

static void qeth_free_buffer_pool(struct qeth_card *card)
{
	struct qeth_buffer_pool_entry *pool_entry, *tmp;
	int i = 0;
	list_for_each_entry_safe(pool_entry, tmp,
				 &card->qdio.init_pool.entry_list, init_list){
		for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i)
			free_page((unsigned long)pool_entry->elements[i]);
		list_del(&pool_entry->init_list);
		kfree(pool_entry);
	}
}

static void qeth_clean_channel(struct qeth_channel *channel)
{
1168
	struct ccw_device *cdev = channel->ccwdev;
F
Frank Blaschka 已提交
1169

1170
	QETH_DBF_TEXT(SETUP, 2, "freech");
1171 1172 1173 1174

	spin_lock_irq(get_ccwdev_lock(cdev));
	cdev->handler = NULL;
	spin_unlock_irq(get_ccwdev_lock(cdev));
F
Frank Blaschka 已提交
1175 1176
}

1177
static void qeth_setup_channel(struct qeth_channel *channel)
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190
{
	struct ccw_device *cdev = channel->ccwdev;

	QETH_DBF_TEXT(SETUP, 2, "setupch");

	channel->state = CH_STATE_DOWN;
	atomic_set(&channel->irq_pending, 0);

	spin_lock_irq(get_ccwdev_lock(cdev));
	cdev->handler = qeth_irq;
	spin_unlock_irq(get_ccwdev_lock(cdev));
}

1191
static int qeth_osa_set_output_queues(struct qeth_card *card, bool single)
1192
{
1193
	unsigned int count = single ? 1 : card->dev->num_tx_queues;
1194
	int rc;
1195

1196
	rtnl_lock();
1197
	rc = netif_set_real_num_tx_queues(card->dev, count);
1198
	rtnl_unlock();
1199

1200 1201 1202
	if (rc)
		return rc;

1203
	if (card->qdio.no_out_queues == count)
1204
		return 0;
1205

1206
	if (atomic_read(&card->qdio.state) != QETH_QDIO_UNINITIALIZED)
1207
		qeth_free_qdio_queues(card);
1208 1209 1210 1211 1212 1213

	if (count == 1)
		dev_info(&card->gdev->dev, "Priority Queueing not supported\n");

	card->qdio.default_out_queue = single ? 0 : QETH_DEFAULT_QUEUE;
	card->qdio.no_out_queues = count;
1214
	return 0;
1215 1216
}

1217
static int qeth_update_from_chp_desc(struct qeth_card *card)
F
Frank Blaschka 已提交
1218 1219
{
	struct ccw_device *ccwdev;
1220
	struct channel_path_desc_fmt0 *chp_dsc;
1221
	int rc = 0;
F
Frank Blaschka 已提交
1222

1223
	QETH_CARD_TEXT(card, 2, "chp_desc");
F
Frank Blaschka 已提交
1224 1225

	ccwdev = card->data.ccwdev;
1226 1227
	chp_dsc = ccw_device_get_chp_desc(ccwdev, 0);
	if (!chp_dsc)
1228
		return -ENOMEM;
1229 1230 1231

	card->info.func_level = 0x4100 + chp_dsc->desc;

1232 1233
	if (IS_OSD(card) || IS_OSX(card))
		/* CHPP field bit 6 == 1 -> single queue */
1234
		rc = qeth_osa_set_output_queues(card, chp_dsc->chpp & 0x02);
1235

1236
	kfree(chp_dsc);
1237 1238
	QETH_CARD_TEXT_(card, 2, "nr:%x", card->qdio.no_out_queues);
	QETH_CARD_TEXT_(card, 2, "lvl:%02x", card->info.func_level);
1239
	return rc;
F
Frank Blaschka 已提交
1240 1241 1242 1243
}

static void qeth_init_qdio_info(struct qeth_card *card)
{
1244
	QETH_CARD_TEXT(card, 4, "intqdinf");
F
Frank Blaschka 已提交
1245
	atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
1246 1247 1248
	card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
	card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;

F
Frank Blaschka 已提交
1249
	/* inbound */
1250
	card->qdio.no_in_queues = 1;
F
Frank Blaschka 已提交
1251
	card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT;
1252
	if (IS_IQD(card))
1253 1254 1255
		card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_HSDEFAULT;
	else
		card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_DEFAULT;
F
Frank Blaschka 已提交
1256 1257 1258 1259 1260
	card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count;
	INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
	INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
}

1261
static void qeth_set_initial_options(struct qeth_card *card)
F
Frank Blaschka 已提交
1262 1263 1264 1265
{
	card->options.route4.type = NO_ROUTER;
	card->options.route6.type = NO_ROUTER;
	card->options.rx_sg_cb = QETH_RX_SG_CB;
E
Einar Lueck 已提交
1266
	card->options.isolation = ISOLATION_MODE_NONE;
1267
	card->options.cq = QETH_CQ_DISABLED;
1268
	card->options.layer = QETH_DISCIPLINE_UNDETERMINED;
F
Frank Blaschka 已提交
1269 1270 1271 1272 1273 1274 1275 1276
}

static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
{
	unsigned long flags;
	int rc = 0;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
C
Carsten Otte 已提交
1277
	QETH_CARD_TEXT_(card, 4, "  %02x%02x%02x",
F
Frank Blaschka 已提交
1278 1279 1280 1281 1282 1283 1284 1285 1286 1287
			(u8) card->thread_start_mask,
			(u8) card->thread_allowed_mask,
			(u8) card->thread_running_mask);
	rc = (card->thread_start_mask & thread);
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	return rc;
}

static void qeth_start_kernel_thread(struct work_struct *work)
{
1288
	struct task_struct *ts;
F
Frank Blaschka 已提交
1289 1290
	struct qeth_card *card = container_of(work, struct qeth_card,
					kernel_thread_starter);
C
Carsten Otte 已提交
1291
	QETH_CARD_TEXT(card , 2, "strthrd");
F
Frank Blaschka 已提交
1292 1293 1294 1295

	if (card->read.state != CH_STATE_UP &&
	    card->write.state != CH_STATE_UP)
		return;
1296
	if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) {
1297
		ts = kthread_run(card->discipline->recover, (void *)card,
F
Frank Blaschka 已提交
1298
				"qeth_recover");
1299 1300 1301 1302 1303 1304
		if (IS_ERR(ts)) {
			qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
			qeth_clear_thread_running_bit(card,
				QETH_RECOVER_THREAD);
		}
	}
F
Frank Blaschka 已提交
1305 1306
}

1307
static void qeth_buffer_reclaim_work(struct work_struct *);
1308
static void qeth_setup_card(struct qeth_card *card)
F
Frank Blaschka 已提交
1309
{
1310
	QETH_CARD_TEXT(card, 2, "setupcrd");
F
Frank Blaschka 已提交
1311

1312
	card->info.type = CARD_RDEV(card)->id.driver_info;
F
Frank Blaschka 已提交
1313 1314 1315
	card->state = CARD_STATE_DOWN;
	spin_lock_init(&card->lock);
	spin_lock_init(&card->thread_mask_lock);
1316
	mutex_init(&card->conf_mutex);
1317
	mutex_init(&card->discipline_mutex);
F
Frank Blaschka 已提交
1318 1319 1320
	INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread);
	INIT_LIST_HEAD(&card->cmd_waiter_list);
	init_waitqueue_head(&card->wait_q);
1321
	qeth_set_initial_options(card);
F
Frank Blaschka 已提交
1322 1323 1324
	/* IP address takeover */
	INIT_LIST_HEAD(&card->ipato.entries);
	qeth_init_qdio_info(card);
1325
	INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work);
S
Stefan Raspl 已提交
1326
	INIT_WORK(&card->close_dev_work, qeth_close_dev_handler);
F
Frank Blaschka 已提交
1327 1328
}

1329 1330 1331 1332
static void qeth_core_sl_print(struct seq_file *m, struct service_level *slr)
{
	struct qeth_card *card = container_of(slr, struct qeth_card,
					qeth_service_level);
1333 1334 1335
	if (card->info.mcl_level[0])
		seq_printf(m, "qeth: %s firmware level %s\n",
			CARD_BUS_ID(card), card->info.mcl_level);
1336 1337
}

1338
static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev)
F
Frank Blaschka 已提交
1339 1340 1341
{
	struct qeth_card *card;

1342
	QETH_DBF_TEXT(SETUP, 2, "alloccrd");
1343
	card = kzalloc(sizeof(*card), GFP_KERNEL);
F
Frank Blaschka 已提交
1344
	if (!card)
1345
		goto out;
1346
	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
1347 1348

	card->gdev = gdev;
1349
	dev_set_drvdata(&gdev->dev, card);
1350 1351 1352
	CARD_RDEV(card) = gdev->cdev[0];
	CARD_WDEV(card) = gdev->cdev[1];
	CARD_DDEV(card) = gdev->cdev[2];
1353

1354 1355
	card->event_wq = alloc_ordered_workqueue("%s_event", 0,
						 dev_name(&gdev->dev));
1356 1357
	if (!card->event_wq)
		goto out_wq;
1358 1359 1360 1361

	card->read_cmd = qeth_alloc_cmd(&card->read, QETH_BUFSIZE, 1, 0);
	if (!card->read_cmd)
		goto out_read_cmd;
1362 1363 1364 1365

	qeth_setup_channel(&card->read);
	qeth_setup_channel(&card->write);
	qeth_setup_channel(&card->data);
1366 1367
	card->qeth_service_level.seq_print = qeth_core_sl_print;
	register_service_level(&card->qeth_service_level);
F
Frank Blaschka 已提交
1368
	return card;
1369

1370
out_read_cmd:
1371 1372
	destroy_workqueue(card->event_wq);
out_wq:
1373
	dev_set_drvdata(&gdev->dev, NULL);
1374 1375 1376
	kfree(card);
out:
	return NULL;
F
Frank Blaschka 已提交
1377 1378
}

1379 1380
static int qeth_clear_channel(struct qeth_card *card,
			      struct qeth_channel *channel)
F
Frank Blaschka 已提交
1381 1382 1383
{
	int rc;

C
Carsten Otte 已提交
1384
	QETH_CARD_TEXT(card, 3, "clearch");
J
Julian Wiedmann 已提交
1385
	spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
F
Frank Blaschka 已提交
1386
	rc = ccw_device_clear(channel->ccwdev, QETH_CLEAR_CHANNEL_PARM);
J
Julian Wiedmann 已提交
1387
	spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
F
Frank Blaschka 已提交
1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400

	if (rc)
		return rc;
	rc = wait_event_interruptible_timeout(card->wait_q,
			channel->state == CH_STATE_STOPPED, QETH_TIMEOUT);
	if (rc == -ERESTARTSYS)
		return rc;
	if (channel->state != CH_STATE_STOPPED)
		return -ETIME;
	channel->state = CH_STATE_DOWN;
	return 0;
}

1401 1402
static int qeth_halt_channel(struct qeth_card *card,
			     struct qeth_channel *channel)
F
Frank Blaschka 已提交
1403 1404 1405
{
	int rc;

C
Carsten Otte 已提交
1406
	QETH_CARD_TEXT(card, 3, "haltch");
J
Julian Wiedmann 已提交
1407
	spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
F
Frank Blaschka 已提交
1408
	rc = ccw_device_halt(channel->ccwdev, QETH_HALT_CHANNEL_PARM);
J
Julian Wiedmann 已提交
1409
	spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
F
Frank Blaschka 已提交
1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425

	if (rc)
		return rc;
	rc = wait_event_interruptible_timeout(card->wait_q,
			channel->state == CH_STATE_HALTED, QETH_TIMEOUT);
	if (rc == -ERESTARTSYS)
		return rc;
	if (channel->state != CH_STATE_HALTED)
		return -ETIME;
	return 0;
}

static int qeth_halt_channels(struct qeth_card *card)
{
	int rc1 = 0, rc2 = 0, rc3 = 0;

C
Carsten Otte 已提交
1426
	QETH_CARD_TEXT(card, 3, "haltchs");
1427 1428 1429
	rc1 = qeth_halt_channel(card, &card->read);
	rc2 = qeth_halt_channel(card, &card->write);
	rc3 = qeth_halt_channel(card, &card->data);
F
Frank Blaschka 已提交
1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440
	if (rc1)
		return rc1;
	if (rc2)
		return rc2;
	return rc3;
}

static int qeth_clear_channels(struct qeth_card *card)
{
	int rc1 = 0, rc2 = 0, rc3 = 0;

C
Carsten Otte 已提交
1441
	QETH_CARD_TEXT(card, 3, "clearchs");
1442 1443 1444
	rc1 = qeth_clear_channel(card, &card->read);
	rc2 = qeth_clear_channel(card, &card->write);
	rc3 = qeth_clear_channel(card, &card->data);
F
Frank Blaschka 已提交
1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455
	if (rc1)
		return rc1;
	if (rc2)
		return rc2;
	return rc3;
}

static int qeth_clear_halt_card(struct qeth_card *card, int halt)
{
	int rc = 0;

C
Carsten Otte 已提交
1456
	QETH_CARD_TEXT(card, 3, "clhacrd");
F
Frank Blaschka 已提交
1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468

	if (halt)
		rc = qeth_halt_channels(card);
	if (rc)
		return rc;
	return qeth_clear_channels(card);
}

int qeth_qdio_clear_card(struct qeth_card *card, int use_halt)
{
	int rc = 0;

C
Carsten Otte 已提交
1469
	QETH_CARD_TEXT(card, 3, "qdioclr");
F
Frank Blaschka 已提交
1470 1471 1472
	switch (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ESTABLISHED,
		QETH_QDIO_CLEANING)) {
	case QETH_QDIO_ESTABLISHED:
1473
		if (IS_IQD(card))
J
Jan Glauber 已提交
1474
			rc = qdio_shutdown(CARD_DDEV(card),
F
Frank Blaschka 已提交
1475 1476
				QDIO_FLAG_CLEANUP_USING_HALT);
		else
J
Jan Glauber 已提交
1477
			rc = qdio_shutdown(CARD_DDEV(card),
F
Frank Blaschka 已提交
1478 1479
				QDIO_FLAG_CLEANUP_USING_CLEAR);
		if (rc)
C
Carsten Otte 已提交
1480
			QETH_CARD_TEXT_(card, 3, "1err%d", rc);
F
Frank Blaschka 已提交
1481 1482 1483 1484 1485 1486 1487 1488 1489
		atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
		break;
	case QETH_QDIO_CLEANING:
		return rc;
	default:
		break;
	}
	rc = qeth_clear_halt_card(card, use_halt);
	if (rc)
C
Carsten Otte 已提交
1490
		QETH_CARD_TEXT_(card, 3, "2err%d", rc);
F
Frank Blaschka 已提交
1491 1492 1493 1494 1495
	card->state = CARD_STATE_DOWN;
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_qdio_clear_card);

1496 1497 1498 1499 1500 1501 1502 1503 1504
static enum qeth_discipline_id qeth_vm_detect_layer(struct qeth_card *card)
{
	enum qeth_discipline_id disc = QETH_DISCIPLINE_UNDETERMINED;
	struct diag26c_vnic_resp *response = NULL;
	struct diag26c_vnic_req *request = NULL;
	struct ccw_dev_id id;
	char userid[80];
	int rc = 0;

1505
	QETH_CARD_TEXT(card, 2, "vmlayer");
1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547

	cpcmd("QUERY USERID", userid, sizeof(userid), &rc);
	if (rc)
		goto out;

	request = kzalloc(sizeof(*request), GFP_KERNEL | GFP_DMA);
	response = kzalloc(sizeof(*response), GFP_KERNEL | GFP_DMA);
	if (!request || !response) {
		rc = -ENOMEM;
		goto out;
	}

	ccw_device_get_id(CARD_RDEV(card), &id);
	request->resp_buf_len = sizeof(*response);
	request->resp_version = DIAG26C_VERSION6_VM65918;
	request->req_format = DIAG26C_VNIC_INFO;
	ASCEBC(userid, 8);
	memcpy(&request->sys_name, userid, 8);
	request->devno = id.devno;

	QETH_DBF_HEX(CTRL, 2, request, sizeof(*request));
	rc = diag26c(request, response, DIAG26C_PORT_VNIC);
	QETH_DBF_HEX(CTRL, 2, request, sizeof(*request));
	if (rc)
		goto out;
	QETH_DBF_HEX(CTRL, 2, response, sizeof(*response));

	if (request->resp_buf_len < sizeof(*response) ||
	    response->version != request->resp_version) {
		rc = -EIO;
		goto out;
	}

	if (response->protocol == VNIC_INFO_PROT_L2)
		disc = QETH_DISCIPLINE_LAYER2;
	else if (response->protocol == VNIC_INFO_PROT_L3)
		disc = QETH_DISCIPLINE_LAYER3;

out:
	kfree(response);
	kfree(request);
	if (rc)
1548
		QETH_CARD_TEXT_(card, 2, "err%x", rc);
1549 1550 1551
	return disc;
}

1552 1553 1554
/* Determine whether the device requires a specific layer discipline */
static enum qeth_discipline_id qeth_enforce_discipline(struct qeth_card *card)
{
1555 1556
	enum qeth_discipline_id disc = QETH_DISCIPLINE_UNDETERMINED;

1557
	if (IS_OSM(card) || IS_OSN(card))
1558
		disc = QETH_DISCIPLINE_LAYER2;
1559 1560 1561
	else if (IS_VM_NIC(card))
		disc = IS_IQD(card) ? QETH_DISCIPLINE_LAYER3 :
				      qeth_vm_detect_layer(card);
1562 1563 1564

	switch (disc) {
	case QETH_DISCIPLINE_LAYER2:
1565
		QETH_CARD_TEXT(card, 3, "force l2");
1566 1567
		break;
	case QETH_DISCIPLINE_LAYER3:
1568
		QETH_CARD_TEXT(card, 3, "force l3");
1569 1570
		break;
	default:
1571
		QETH_CARD_TEXT(card, 3, "force no");
1572 1573
	}

1574
	return disc;
1575 1576
}

1577
static void qeth_set_blkt_defaults(struct qeth_card *card)
1578
{
1579
	QETH_CARD_TEXT(card, 2, "cfgblkt");
1580

1581
	if (card->info.use_v1_blkt) {
1582 1583 1584
		card->info.blkt.time_total = 0;
		card->info.blkt.inter_packet = 0;
		card->info.blkt.inter_packet_jumbo = 0;
1585 1586 1587 1588
	} else {
		card->info.blkt.time_total = 250;
		card->info.blkt.inter_packet = 5;
		card->info.blkt.inter_packet_jumbo = 15;
1589
	}
F
Frank Blaschka 已提交
1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602
}

static void qeth_init_tokens(struct qeth_card *card)
{
	card->token.issuer_rm_w = 0x00010103UL;
	card->token.cm_filter_w = 0x00010108UL;
	card->token.cm_connection_w = 0x0001010aUL;
	card->token.ulp_filter_w = 0x0001010bUL;
	card->token.ulp_connection_w = 0x0001010dUL;
}

static void qeth_init_func_level(struct qeth_card *card)
{
1603 1604
	switch (card->info.type) {
	case QETH_CARD_TYPE_IQD:
1605
		card->info.func_level =	QETH_IDX_FUNC_LEVEL_IQD;
1606 1607
		break;
	case QETH_CARD_TYPE_OSD:
1608
	case QETH_CARD_TYPE_OSN:
1609 1610 1611 1612
		card->info.func_level = QETH_IDX_FUNC_LEVEL_OSD;
		break;
	default:
		break;
F
Frank Blaschka 已提交
1613 1614 1615
	}
}

1616
static void qeth_idx_finalize_cmd(struct qeth_card *card,
1617
				  struct qeth_cmd_buffer *iob)
1618 1619 1620 1621 1622 1623 1624
{
	memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data), &card->seqno.trans_hdr,
	       QETH_SEQ_NO_LENGTH);
	if (iob->channel == &card->write)
		card->seqno.trans_hdr++;
}

F
Frank Blaschka 已提交
1625 1626 1627 1628 1629 1630 1631 1632 1633
static int qeth_peer_func_level(int level)
{
	if ((level & 0xff) == 8)
		return (level & 0xff) + 0x400;
	if (((level >> 8) & 3) == 1)
		return (level & 0xff) + 0x200;
	return level;
}

1634
static void qeth_mpc_finalize_cmd(struct qeth_card *card,
1635
				  struct qeth_cmd_buffer *iob)
F
Frank Blaschka 已提交
1636
{
1637
	qeth_idx_finalize_cmd(card, iob);
F
Frank Blaschka 已提交
1638 1639 1640 1641 1642 1643

	memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
	       &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
	card->seqno.pdu_hdr++;
	memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
	       &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
1644 1645 1646

	iob->reply->seqno = QETH_IDX_COMMAND_SEQNO;
	iob->callback = qeth_release_buffer_cb;
F
Frank Blaschka 已提交
1647 1648
}

1649 1650 1651
static struct qeth_cmd_buffer *qeth_mpc_alloc_cmd(struct qeth_card *card,
						  void *data,
						  unsigned int data_length)
1652 1653 1654
{
	struct qeth_cmd_buffer *iob;

1655 1656 1657 1658 1659 1660 1661 1662
	iob = qeth_alloc_cmd(&card->write, data_length, 1, QETH_TIMEOUT);
	if (!iob)
		return NULL;

	memcpy(iob->data, data, data_length);
	qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, data_length,
		       iob->data);
	iob->finalize = qeth_mpc_finalize_cmd;
1663 1664 1665
	return iob;
}

E
Eugene Crosser 已提交
1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679
/**
 * qeth_send_control_data() -	send control command to the card
 * @card:			qeth_card structure pointer
 * @iob:			qeth_cmd_buffer pointer
 * @reply_cb:			callback function pointer
 * @cb_card:			pointer to the qeth_card structure
 * @cb_reply:			pointer to the qeth_reply structure
 * @cb_cmd:			pointer to the original iob for non-IPA
 *				commands, or to the qeth_ipa_cmd structure
 *				for the IPA commands.
 * @reply_param:		private pointer passed to the callback
 *
 * Callback function gets called one or more times, with cb_cmd
 * pointing to the response returned by the hardware. Callback
1680 1681 1682 1683 1684
 * function must return
 *   > 0 if more reply blocks are expected,
 *     0 if the last or only reply block is received, and
 *   < 0 on error.
 * Callback function can get the value of the reply_param pointer from the
E
Eugene Crosser 已提交
1685 1686 1687
 * field 'param' of the structure qeth_reply.
 */

1688
static int qeth_send_control_data(struct qeth_card *card,
1689 1690 1691 1692 1693
				  struct qeth_cmd_buffer *iob,
				  int (*reply_cb)(struct qeth_card *cb_card,
						  struct qeth_reply *cb_reply,
						  unsigned long cb_cmd),
				  void *reply_param)
F
Frank Blaschka 已提交
1694
{
1695
	struct qeth_channel *channel = iob->channel;
1696
	long timeout = iob->timeout;
F
Frank Blaschka 已提交
1697 1698 1699
	int rc;
	struct qeth_reply *reply = NULL;

C
Carsten Otte 已提交
1700
	QETH_CARD_TEXT(card, 2, "sendctl");
F
Frank Blaschka 已提交
1701 1702 1703

	reply = qeth_alloc_reply(card);
	if (!reply) {
1704
		qeth_put_cmd(iob);
F
Frank Blaschka 已提交
1705 1706 1707 1708
		return -ENOMEM;
	}
	reply->callback = reply_cb;
	reply->param = reply_param;
1709

1710
	/* pairs with qeth_put_cmd(): */
1711 1712 1713
	qeth_get_reply(reply);
	iob->reply = reply;

1714 1715 1716 1717 1718
	timeout = wait_event_interruptible_timeout(card->wait_q,
						   qeth_trylock_channel(channel),
						   timeout);
	if (timeout <= 0) {
		qeth_put_reply(reply);
1719
		qeth_put_cmd(iob);
1720 1721
		return (timeout == -ERESTARTSYS) ? -EINTR : -ETIME;
	}
F
Frank Blaschka 已提交
1722

1723
	if (iob->finalize)
1724 1725
		iob->finalize(card, iob);
	QETH_DBF_HEX(CTRL, 2, iob->data, min(iob->length, QETH_DBF_CTRL_LEN));
1726

1727
	qeth_enqueue_reply(card, reply);
1728

C
Carsten Otte 已提交
1729
	QETH_CARD_TEXT(card, 6, "noirqpnd");
J
Julian Wiedmann 已提交
1730
	spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
1731
	rc = ccw_device_start_timeout(channel->ccwdev, __ccw_from_cmd(iob),
1732
				      (addr_t) iob, 0, 0, timeout);
J
Julian Wiedmann 已提交
1733
	spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
F
Frank Blaschka 已提交
1734
	if (rc) {
1735 1736
		QETH_DBF_MESSAGE(2, "qeth_send_control_data on device %x: ccw_device_start rc = %i\n",
				 CARD_DEVID(card), rc);
C
Carsten Otte 已提交
1737
		QETH_CARD_TEXT_(card, 2, " err%d", rc);
1738
		qeth_dequeue_reply(card, reply);
F
Frank Blaschka 已提交
1739
		qeth_put_reply(reply);
1740
		qeth_put_cmd(iob);
1741
		atomic_set(&channel->irq_pending, 0);
F
Frank Blaschka 已提交
1742 1743 1744
		wake_up(&card->wait_q);
		return rc;
	}
1745

1746 1747 1748 1749
	timeout = wait_for_completion_interruptible_timeout(&reply->received,
							    timeout);
	if (timeout <= 0)
		rc = (timeout == -ERESTARTSYS) ? -EINTR : -ETIME;
1750

1751
	qeth_dequeue_reply(card, reply);
1752 1753
	if (!rc)
		rc = reply->rc;
1754 1755
	qeth_put_reply(reply);
	return rc;
F
Frank Blaschka 已提交
1756 1757
}

1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772
static void qeth_read_conf_data_cb(struct qeth_card *card,
				   struct qeth_cmd_buffer *iob)
{
	unsigned char *prcd = iob->data;

	QETH_CARD_TEXT(card, 2, "cfgunit");
	card->info.chpid = prcd[30];
	card->info.unit_addr2 = prcd[31];
	card->info.cula = prcd[63];
	card->info.is_vm_nic = ((prcd[0x10] == _ascebc['V']) &&
				(prcd[0x11] == _ascebc['M']));
	card->info.use_v1_blkt = prcd[74] == 0xF0 && prcd[75] == 0xF0 &&
				 prcd[76] >= 0xF1 && prcd[76] <= 0xF4;

	qeth_notify_reply(iob->reply, 0);
1773
	qeth_put_cmd(iob);
1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794
}

static int qeth_read_conf_data(struct qeth_card *card)
{
	struct qeth_channel *channel = &card->data;
	struct qeth_cmd_buffer *iob;
	struct ciw *ciw;

	/* scan for RCD command in extended SenseID data */
	ciw = ccw_device_get_ciw(channel->ccwdev, CIW_TYPE_RCD);
	if (!ciw || ciw->cmd == 0)
		return -EOPNOTSUPP;

	iob = qeth_alloc_cmd(channel, ciw->count, 1, QETH_RCD_TIMEOUT);
	if (!iob)
		return -ENOMEM;

	iob->callback = qeth_read_conf_data_cb;
	qeth_setup_ccw(__ccw_from_cmd(iob), ciw->cmd, 0, iob->length,
		       iob->data);

1795
	return qeth_send_control_data(card, iob, NULL, NULL);
1796 1797
}

1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811
static int qeth_idx_check_activate_response(struct qeth_card *card,
					    struct qeth_channel *channel,
					    struct qeth_cmd_buffer *iob)
{
	int rc;

	rc = qeth_check_idx_response(card, iob->data);
	if (rc)
		return rc;

	if (QETH_IS_IDX_ACT_POS_REPLY(iob->data))
		return 0;

	/* negative reply: */
1812 1813
	QETH_CARD_TEXT_(card, 2, "idxneg%c",
			QETH_IDX_ACT_CAUSE_CODE(iob->data));
1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831

	switch (QETH_IDX_ACT_CAUSE_CODE(iob->data)) {
	case QETH_IDX_ACT_ERR_EXCL:
		dev_err(&channel->ccwdev->dev,
			"The adapter is used exclusively by another host\n");
		return -EBUSY;
	case QETH_IDX_ACT_ERR_AUTH:
	case QETH_IDX_ACT_ERR_AUTH_USER:
		dev_err(&channel->ccwdev->dev,
			"Setting the device online failed because of insufficient authorization\n");
		return -EPERM;
	default:
		QETH_DBF_MESSAGE(2, "IDX_ACTIVATE on channel %x: negative reply\n",
				 CCW_DEVID(channel->ccwdev));
		return -EIO;
	}
}

1832 1833
static void qeth_idx_activate_read_channel_cb(struct qeth_card *card,
					      struct qeth_cmd_buffer *iob)
1834
{
1835
	struct qeth_channel *channel = iob->channel;
1836 1837 1838
	u16 peer_level;
	int rc;

1839
	QETH_CARD_TEXT(card, 2, "idxrdcb");
1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861

	rc = qeth_idx_check_activate_response(card, channel, iob);
	if (rc)
		goto out;

	memcpy(&peer_level, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
	if (peer_level != qeth_peer_func_level(card->info.func_level)) {
		QETH_DBF_MESSAGE(2, "IDX_ACTIVATE on channel %x: function level mismatch (sent: %#x, received: %#x)\n",
				 CCW_DEVID(channel->ccwdev),
				 card->info.func_level, peer_level);
		rc = -EINVAL;
		goto out;
	}

	memcpy(&card->token.issuer_rm_r,
	       QETH_IDX_ACT_ISSUER_RM_TOKEN(iob->data),
	       QETH_MPC_TOKEN_LENGTH);
	memcpy(&card->info.mcl_level[0],
	       QETH_IDX_REPLY_LEVEL(iob->data), QETH_MCL_LENGTH);

out:
	qeth_notify_reply(iob->reply, rc);
1862
	qeth_put_cmd(iob);
1863 1864
}

1865 1866
static void qeth_idx_activate_write_channel_cb(struct qeth_card *card,
					       struct qeth_cmd_buffer *iob)
1867
{
1868
	struct qeth_channel *channel = iob->channel;
1869 1870 1871
	u16 peer_level;
	int rc;

1872
	QETH_CARD_TEXT(card, 2, "idxwrcb");
1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888

	rc = qeth_idx_check_activate_response(card, channel, iob);
	if (rc)
		goto out;

	memcpy(&peer_level, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
	if ((peer_level & ~0x0100) !=
	    qeth_peer_func_level(card->info.func_level)) {
		QETH_DBF_MESSAGE(2, "IDX_ACTIVATE on channel %x: function level mismatch (sent: %#x, received: %#x)\n",
				 CCW_DEVID(channel->ccwdev),
				 card->info.func_level, peer_level);
		rc = -EINVAL;
	}

out:
	qeth_notify_reply(iob->reply, rc);
1889
	qeth_put_cmd(iob);
1890 1891 1892 1893 1894 1895 1896
}

static void qeth_idx_setup_activate_cmd(struct qeth_card *card,
					struct qeth_cmd_buffer *iob)
{
	u16 addr = (card->info.cula << 8) + card->info.unit_addr2;
	u8 port = ((u8)card->dev->dev_port) | 0x80;
1897
	struct ccw1 *ccw = __ccw_from_cmd(iob);
1898 1899
	struct ccw_dev_id dev_id;

1900 1901 1902
	qeth_setup_ccw(&ccw[0], CCW_CMD_WRITE, CCW_FLAG_CC, IDX_ACTIVATE_SIZE,
		       iob->data);
	qeth_setup_ccw(&ccw[1], CCW_CMD_READ, 0, iob->length, iob->data);
1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920
	ccw_device_get_id(CARD_DDEV(card), &dev_id);
	iob->finalize = qeth_idx_finalize_cmd;

	memcpy(QETH_IDX_ACT_PNO(iob->data), &port, 1);
	memcpy(QETH_IDX_ACT_ISSUER_RM_TOKEN(iob->data),
	       &card->token.issuer_rm_w, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_IDX_ACT_FUNC_LEVEL(iob->data),
	       &card->info.func_level, 2);
	memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(iob->data), &dev_id.devno, 2);
	memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(iob->data), &addr, 2);
}

static int qeth_idx_activate_read_channel(struct qeth_card *card)
{
	struct qeth_channel *channel = &card->read;
	struct qeth_cmd_buffer *iob;
	int rc;

1921
	QETH_CARD_TEXT(card, 2, "idxread");
1922

1923
	iob = qeth_alloc_cmd(channel, QETH_BUFSIZE, 2, QETH_TIMEOUT);
1924 1925 1926 1927 1928
	if (!iob)
		return -ENOMEM;

	memcpy(iob->data, IDX_ACTIVATE_READ, IDX_ACTIVATE_SIZE);
	qeth_idx_setup_activate_cmd(card, iob);
1929
	iob->callback = qeth_idx_activate_read_channel_cb;
1930

1931
	rc = qeth_send_control_data(card, iob, NULL, NULL);
1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944
	if (rc)
		return rc;

	channel->state = CH_STATE_UP;
	return 0;
}

static int qeth_idx_activate_write_channel(struct qeth_card *card)
{
	struct qeth_channel *channel = &card->write;
	struct qeth_cmd_buffer *iob;
	int rc;

1945
	QETH_CARD_TEXT(card, 2, "idxwrite");
1946

1947
	iob = qeth_alloc_cmd(channel, QETH_BUFSIZE, 2, QETH_TIMEOUT);
1948 1949 1950 1951 1952
	if (!iob)
		return -ENOMEM;

	memcpy(iob->data, IDX_ACTIVATE_WRITE, IDX_ACTIVATE_SIZE);
	qeth_idx_setup_activate_cmd(card, iob);
1953
	iob->callback = qeth_idx_activate_write_channel_cb;
1954

1955
	rc = qeth_send_control_data(card, iob, NULL, NULL);
1956 1957 1958 1959 1960 1961 1962
	if (rc)
		return rc;

	channel->state = CH_STATE_UP;
	return 0;
}

F
Frank Blaschka 已提交
1963 1964 1965 1966 1967
static int qeth_cm_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
		unsigned long data)
{
	struct qeth_cmd_buffer *iob;

1968
	QETH_CARD_TEXT(card, 2, "cmenblcb");
F
Frank Blaschka 已提交
1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980

	iob = (struct qeth_cmd_buffer *) data;
	memcpy(&card->token.cm_filter_r,
	       QETH_CM_ENABLE_RESP_FILTER_TOKEN(iob->data),
	       QETH_MPC_TOKEN_LENGTH);
	return 0;
}

static int qeth_cm_enable(struct qeth_card *card)
{
	struct qeth_cmd_buffer *iob;

1981
	QETH_CARD_TEXT(card, 2, "cmenable");
F
Frank Blaschka 已提交
1982

1983
	iob = qeth_mpc_alloc_cmd(card, CM_ENABLE, CM_ENABLE_SIZE);
1984 1985
	if (!iob)
		return -ENOMEM;
1986

F
Frank Blaschka 已提交
1987 1988 1989 1990 1991
	memcpy(QETH_CM_ENABLE_ISSUER_RM_TOKEN(iob->data),
	       &card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_CM_ENABLE_FILTER_TOKEN(iob->data),
	       &card->token.cm_filter_w, QETH_MPC_TOKEN_LENGTH);

1992
	return qeth_send_control_data(card, iob, qeth_cm_enable_cb, NULL);
F
Frank Blaschka 已提交
1993 1994 1995 1996 1997 1998 1999
}

static int qeth_cm_setup_cb(struct qeth_card *card, struct qeth_reply *reply,
		unsigned long data)
{
	struct qeth_cmd_buffer *iob;

2000
	QETH_CARD_TEXT(card, 2, "cmsetpcb");
F
Frank Blaschka 已提交
2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012

	iob = (struct qeth_cmd_buffer *) data;
	memcpy(&card->token.cm_connection_r,
	       QETH_CM_SETUP_RESP_DEST_ADDR(iob->data),
	       QETH_MPC_TOKEN_LENGTH);
	return 0;
}

static int qeth_cm_setup(struct qeth_card *card)
{
	struct qeth_cmd_buffer *iob;

2013
	QETH_CARD_TEXT(card, 2, "cmsetup");
F
Frank Blaschka 已提交
2014

2015
	iob = qeth_mpc_alloc_cmd(card, CM_SETUP, CM_SETUP_SIZE);
2016 2017
	if (!iob)
		return -ENOMEM;
2018

F
Frank Blaschka 已提交
2019 2020 2021 2022 2023 2024
	memcpy(QETH_CM_SETUP_DEST_ADDR(iob->data),
	       &card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_CM_SETUP_CONNECTION_TOKEN(iob->data),
	       &card->token.cm_connection_w, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_CM_SETUP_FILTER_TOKEN(iob->data),
	       &card->token.cm_filter_r, QETH_MPC_TOKEN_LENGTH);
2025
	return qeth_send_control_data(card, iob, qeth_cm_setup_cb, NULL);
F
Frank Blaschka 已提交
2026 2027
}

2028
static int qeth_update_max_mtu(struct qeth_card *card, unsigned int max_mtu)
F
Frank Blaschka 已提交
2029
{
2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048
	struct net_device *dev = card->dev;
	unsigned int new_mtu;

	if (!max_mtu) {
		/* IQD needs accurate max MTU to set up its RX buffers: */
		if (IS_IQD(card))
			return -EINVAL;
		/* tolerate quirky HW: */
		max_mtu = ETH_MAX_MTU;
	}

	rtnl_lock();
	if (IS_IQD(card)) {
		/* move any device with default MTU to new max MTU: */
		new_mtu = (dev->mtu == dev->max_mtu) ? max_mtu : dev->mtu;

		/* adjust RX buffer size to new max MTU: */
		card->qdio.in_buf_size = max_mtu + 2 * PAGE_SIZE;
		if (dev->max_mtu && dev->max_mtu != max_mtu)
2049
			qeth_free_qdio_queues(card);
2050 2051 2052 2053
	} else {
		if (dev->mtu)
			new_mtu = dev->mtu;
		/* default MTUs for first setup: */
2054
		else if (IS_LAYER2(card))
2055 2056 2057
			new_mtu = ETH_DATA_LEN;
		else
			new_mtu = ETH_DATA_LEN - 8; /* allow for LLC + SNAP */
F
Frank Blaschka 已提交
2058
	}
2059 2060 2061 2062 2063

	dev->max_mtu = max_mtu;
	dev->mtu = min(new_mtu, max_mtu);
	rtnl_unlock();
	return 0;
F
Frank Blaschka 已提交
2064 2065
}

J
Julian Wiedmann 已提交
2066
static int qeth_get_mtu_outof_framesize(int framesize)
F
Frank Blaschka 已提交
2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089
{
	switch (framesize) {
	case 0x4000:
		return 8192;
	case 0x6000:
		return 16384;
	case 0xa000:
		return 32768;
	case 0xffff:
		return 57344;
	default:
		return 0;
	}
}

static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
		unsigned long data)
{
	__u16 mtu, framesize;
	__u16 len;
	__u8 link_type;
	struct qeth_cmd_buffer *iob;

2090
	QETH_CARD_TEXT(card, 2, "ulpenacb");
F
Frank Blaschka 已提交
2091 2092 2093 2094 2095

	iob = (struct qeth_cmd_buffer *) data;
	memcpy(&card->token.ulp_filter_r,
	       QETH_ULP_ENABLE_RESP_FILTER_TOKEN(iob->data),
	       QETH_MPC_TOKEN_LENGTH);
2096
	if (IS_IQD(card)) {
F
Frank Blaschka 已提交
2097 2098 2099
		memcpy(&framesize, QETH_ULP_ENABLE_RESP_MAX_MTU(iob->data), 2);
		mtu = qeth_get_mtu_outof_framesize(framesize);
	} else {
2100
		mtu = *(__u16 *)QETH_ULP_ENABLE_RESP_MAX_MTU(iob->data);
F
Frank Blaschka 已提交
2101
	}
2102
	*(u16 *)reply->param = mtu;
F
Frank Blaschka 已提交
2103 2104 2105 2106 2107 2108 2109 2110

	memcpy(&len, QETH_ULP_ENABLE_RESP_DIFINFO_LEN(iob->data), 2);
	if (len >= QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE) {
		memcpy(&link_type,
		       QETH_ULP_ENABLE_RESP_LINK_TYPE(iob->data), 1);
		card->info.link_type = link_type;
	} else
		card->info.link_type = 0;
2111
	QETH_CARD_TEXT_(card, 2, "link%d", card->info.link_type);
F
Frank Blaschka 已提交
2112 2113 2114
	return 0;
}

2115 2116 2117 2118
static u8 qeth_mpc_select_prot_type(struct qeth_card *card)
{
	if (IS_OSN(card))
		return QETH_PROT_OSN2;
2119
	return IS_LAYER2(card) ? QETH_PROT_LAYER2 : QETH_PROT_TCPIP;
2120 2121
}

F
Frank Blaschka 已提交
2122 2123
static int qeth_ulp_enable(struct qeth_card *card)
{
2124
	u8 prot_type = qeth_mpc_select_prot_type(card);
F
Frank Blaschka 已提交
2125
	struct qeth_cmd_buffer *iob;
2126
	u16 max_mtu;
2127
	int rc;
F
Frank Blaschka 已提交
2128

2129
	QETH_CARD_TEXT(card, 2, "ulpenabl");
F
Frank Blaschka 已提交
2130

2131
	iob = qeth_mpc_alloc_cmd(card, ULP_ENABLE, ULP_ENABLE_SIZE);
2132 2133
	if (!iob)
		return -ENOMEM;
F
Frank Blaschka 已提交
2134

2135
	*(QETH_ULP_ENABLE_LINKNUM(iob->data)) = (u8) card->dev->dev_port;
F
Frank Blaschka 已提交
2136 2137 2138 2139 2140
	memcpy(QETH_ULP_ENABLE_PROT_TYPE(iob->data), &prot_type, 1);
	memcpy(QETH_ULP_ENABLE_DEST_ADDR(iob->data),
	       &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_ULP_ENABLE_FILTER_TOKEN(iob->data),
	       &card->token.ulp_filter_w, QETH_MPC_TOKEN_LENGTH);
2141
	rc = qeth_send_control_data(card, iob, qeth_ulp_enable_cb, &max_mtu);
2142 2143 2144
	if (rc)
		return rc;
	return qeth_update_max_mtu(card, max_mtu);
F
Frank Blaschka 已提交
2145 2146 2147 2148 2149 2150 2151
}

static int qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply,
		unsigned long data)
{
	struct qeth_cmd_buffer *iob;

2152
	QETH_CARD_TEXT(card, 2, "ulpstpcb");
F
Frank Blaschka 已提交
2153 2154 2155 2156 2157

	iob = (struct qeth_cmd_buffer *) data;
	memcpy(&card->token.ulp_connection_r,
	       QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(iob->data),
	       QETH_MPC_TOKEN_LENGTH);
2158 2159
	if (!strncmp("00S", QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(iob->data),
		     3)) {
2160
		QETH_CARD_TEXT(card, 2, "olmlimit");
2161 2162
		dev_err(&card->gdev->dev, "A connection could not be "
			"established because of an OLM limit\n");
2163
		return -EMLINK;
2164
	}
S
Stefan Raspl 已提交
2165
	return 0;
F
Frank Blaschka 已提交
2166 2167 2168 2169 2170 2171 2172 2173
}

static int qeth_ulp_setup(struct qeth_card *card)
{
	__u16 temp;
	struct qeth_cmd_buffer *iob;
	struct ccw_dev_id dev_id;

2174
	QETH_CARD_TEXT(card, 2, "ulpsetup");
F
Frank Blaschka 已提交
2175

2176
	iob = qeth_mpc_alloc_cmd(card, ULP_SETUP, ULP_SETUP_SIZE);
2177 2178
	if (!iob)
		return -ENOMEM;
F
Frank Blaschka 已提交
2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190

	memcpy(QETH_ULP_SETUP_DEST_ADDR(iob->data),
	       &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_ULP_SETUP_CONNECTION_TOKEN(iob->data),
	       &card->token.ulp_connection_w, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_ULP_SETUP_FILTER_TOKEN(iob->data),
	       &card->token.ulp_filter_r, QETH_MPC_TOKEN_LENGTH);

	ccw_device_get_id(CARD_DDEV(card), &dev_id);
	memcpy(QETH_ULP_SETUP_CUA(iob->data), &dev_id.devno, 2);
	temp = (card->info.cula << 8) + card->info.unit_addr2;
	memcpy(QETH_ULP_SETUP_REAL_DEVADDR(iob->data), &temp, 2);
2191
	return qeth_send_control_data(card, iob, qeth_ulp_setup_cb, NULL);
F
Frank Blaschka 已提交
2192 2193
}

2194 2195 2196 2197 2198
static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *q, int bidx)
{
	struct qeth_qdio_out_buffer *newbuf;

	newbuf = kmem_cache_zalloc(qeth_qdio_outbuf_cache, GFP_ATOMIC);
2199 2200 2201
	if (!newbuf)
		return -ENOMEM;

2202
	newbuf->buffer = q->qdio_bufs[bidx];
2203 2204 2205 2206 2207 2208
	skb_queue_head_init(&newbuf->skb_list);
	lockdep_set_class(&newbuf->skb_list.lock, &qdio_out_skb_queue_key);
	newbuf->q = q;
	newbuf->next_pending = q->bufs[bidx];
	atomic_set(&newbuf->state, QETH_QDIO_BUF_EMPTY);
	q->bufs[bidx] = newbuf;
2209
	return 0;
2210 2211
}

2212
static void qeth_free_output_queue(struct qeth_qdio_out_q *q)
2213 2214 2215 2216
{
	if (!q)
		return;

2217
	qeth_drain_output_queue(q, true);
2218 2219 2220 2221
	qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
	kfree(q);
}

2222
static struct qeth_qdio_out_q *qeth_alloc_output_queue(void)
2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234
{
	struct qeth_qdio_out_q *q = kzalloc(sizeof(*q), GFP_KERNEL);

	if (!q)
		return NULL;

	if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) {
		kfree(q);
		return NULL;
	}
	return q;
}
2235

2236
static int qeth_alloc_qdio_queues(struct qeth_card *card)
F
Frank Blaschka 已提交
2237 2238 2239
{
	int i, j;

2240
	QETH_CARD_TEXT(card, 2, "allcqdbf");
F
Frank Blaschka 已提交
2241 2242 2243 2244 2245

	if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED,
		QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED)
		return 0;

2246
	QETH_CARD_TEXT(card, 2, "inq");
S
Sebastian Ott 已提交
2247
	card->qdio.in_q = qeth_alloc_qdio_queue();
F
Frank Blaschka 已提交
2248 2249
	if (!card->qdio.in_q)
		goto out_nomem;
S
Sebastian Ott 已提交
2250

F
Frank Blaschka 已提交
2251 2252 2253
	/* inbound buffer pool */
	if (qeth_alloc_buffer_pool(card))
		goto out_freeinq;
2254

F
Frank Blaschka 已提交
2255 2256
	/* outbound */
	for (i = 0; i < card->qdio.no_out_queues; ++i) {
2257
		card->qdio.out_qs[i] = qeth_alloc_output_queue();
F
Frank Blaschka 已提交
2258 2259
		if (!card->qdio.out_qs[i])
			goto out_freeoutq;
2260 2261
		QETH_CARD_TEXT_(card, 2, "outq %i", i);
		QETH_CARD_HEX(card, 2, &card->qdio.out_qs[i], sizeof(void *));
2262
		card->qdio.out_qs[i]->card = card;
F
Frank Blaschka 已提交
2263 2264 2265
		card->qdio.out_qs[i]->queue_no = i;
		/* give outbound qeth_qdio_buffers their qdio_buffers */
		for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
S
Stefan Raspl 已提交
2266
			WARN_ON(card->qdio.out_qs[i]->bufs[j] != NULL);
2267 2268
			if (qeth_init_qdio_out_buf(card->qdio.out_qs[i], j))
				goto out_freeoutqbufs;
F
Frank Blaschka 已提交
2269 2270
		}
	}
2271 2272 2273 2274 2275

	/* completion */
	if (qeth_alloc_cq(card))
		goto out_freeoutq;

F
Frank Blaschka 已提交
2276 2277
	return 0;

2278 2279 2280 2281 2282 2283 2284
out_freeoutqbufs:
	while (j > 0) {
		--j;
		kmem_cache_free(qeth_qdio_outbuf_cache,
				card->qdio.out_qs[i]->bufs[j]);
		card->qdio.out_qs[i]->bufs[j] = NULL;
	}
F
Frank Blaschka 已提交
2285
out_freeoutq:
2286
	while (i > 0) {
2287
		qeth_free_output_queue(card->qdio.out_qs[--i]);
2288 2289
		card->qdio.out_qs[i] = NULL;
	}
F
Frank Blaschka 已提交
2290 2291
	qeth_free_buffer_pool(card);
out_freeinq:
S
Sebastian Ott 已提交
2292
	qeth_free_qdio_queue(card->qdio.in_q);
F
Frank Blaschka 已提交
2293 2294 2295 2296 2297 2298
	card->qdio.in_q = NULL;
out_nomem:
	atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
	return -ENOMEM;
}

2299
static void qeth_free_qdio_queues(struct qeth_card *card)
2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317
{
	int i, j;

	if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
		QETH_QDIO_UNINITIALIZED)
		return;

	qeth_free_cq(card);
	cancel_delayed_work_sync(&card->buffer_reclaim_work);
	for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
		if (card->qdio.in_q->bufs[j].rx_skb)
			dev_kfree_skb_any(card->qdio.in_q->bufs[j].rx_skb);
	}
	qeth_free_qdio_queue(card->qdio.in_q);
	card->qdio.in_q = NULL;
	/* inbound buffer pool */
	qeth_free_buffer_pool(card);
	/* free outbound qdio_qs */
2318 2319 2320
	for (i = 0; i < card->qdio.no_out_queues; i++) {
		qeth_free_output_queue(card->qdio.out_qs[i]);
		card->qdio.out_qs[i] = NULL;
2321 2322 2323
	}
}

F
Frank Blaschka 已提交
2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351
static void qeth_create_qib_param_field(struct qeth_card *card,
		char *param_field)
{

	param_field[0] = _ascebc['P'];
	param_field[1] = _ascebc['C'];
	param_field[2] = _ascebc['I'];
	param_field[3] = _ascebc['T'];
	*((unsigned int *) (&param_field[4])) = QETH_PCI_THRESHOLD_A(card);
	*((unsigned int *) (&param_field[8])) = QETH_PCI_THRESHOLD_B(card);
	*((unsigned int *) (&param_field[12])) = QETH_PCI_TIMER_VALUE(card);
}

static void qeth_create_qib_param_field_blkt(struct qeth_card *card,
		char *param_field)
{
	param_field[16] = _ascebc['B'];
	param_field[17] = _ascebc['L'];
	param_field[18] = _ascebc['K'];
	param_field[19] = _ascebc['T'];
	*((unsigned int *) (&param_field[20])) = card->info.blkt.time_total;
	*((unsigned int *) (&param_field[24])) = card->info.blkt.inter_packet;
	*((unsigned int *) (&param_field[28])) =
		card->info.blkt.inter_packet_jumbo;
}

static int qeth_qdio_activate(struct qeth_card *card)
{
2352
	QETH_CARD_TEXT(card, 3, "qdioact");
J
Jan Glauber 已提交
2353
	return qdio_activate(CARD_DDEV(card));
F
Frank Blaschka 已提交
2354 2355 2356 2357 2358 2359
}

static int qeth_dm_act(struct qeth_card *card)
{
	struct qeth_cmd_buffer *iob;

2360
	QETH_CARD_TEXT(card, 2, "dmact");
F
Frank Blaschka 已提交
2361

2362
	iob = qeth_mpc_alloc_cmd(card, DM_ACT, DM_ACT_SIZE);
2363 2364
	if (!iob)
		return -ENOMEM;
F
Frank Blaschka 已提交
2365 2366 2367 2368 2369

	memcpy(QETH_DM_ACT_DEST_ADDR(iob->data),
	       &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_DM_ACT_CONNECTION_TOKEN(iob->data),
	       &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
2370
	return qeth_send_control_data(card, iob, NULL, NULL);
F
Frank Blaschka 已提交
2371 2372 2373 2374 2375 2376
}

static int qeth_mpc_initialize(struct qeth_card *card)
{
	int rc;

2377
	QETH_CARD_TEXT(card, 2, "mpcinit");
F
Frank Blaschka 已提交
2378 2379 2380

	rc = qeth_issue_next_read(card);
	if (rc) {
2381
		QETH_CARD_TEXT_(card, 2, "1err%d", rc);
F
Frank Blaschka 已提交
2382 2383 2384 2385
		return rc;
	}
	rc = qeth_cm_enable(card);
	if (rc) {
2386
		QETH_CARD_TEXT_(card, 2, "2err%d", rc);
F
Frank Blaschka 已提交
2387 2388 2389 2390
		goto out_qdio;
	}
	rc = qeth_cm_setup(card);
	if (rc) {
2391
		QETH_CARD_TEXT_(card, 2, "3err%d", rc);
F
Frank Blaschka 已提交
2392 2393 2394 2395
		goto out_qdio;
	}
	rc = qeth_ulp_enable(card);
	if (rc) {
2396
		QETH_CARD_TEXT_(card, 2, "4err%d", rc);
F
Frank Blaschka 已提交
2397 2398 2399 2400
		goto out_qdio;
	}
	rc = qeth_ulp_setup(card);
	if (rc) {
2401
		QETH_CARD_TEXT_(card, 2, "5err%d", rc);
F
Frank Blaschka 已提交
2402 2403
		goto out_qdio;
	}
2404
	rc = qeth_alloc_qdio_queues(card);
F
Frank Blaschka 已提交
2405
	if (rc) {
2406
		QETH_CARD_TEXT_(card, 2, "5err%d", rc);
F
Frank Blaschka 已提交
2407 2408 2409 2410
		goto out_qdio;
	}
	rc = qeth_qdio_establish(card);
	if (rc) {
2411
		QETH_CARD_TEXT_(card, 2, "6err%d", rc);
2412
		qeth_free_qdio_queues(card);
F
Frank Blaschka 已提交
2413 2414 2415 2416
		goto out_qdio;
	}
	rc = qeth_qdio_activate(card);
	if (rc) {
2417
		QETH_CARD_TEXT_(card, 2, "7err%d", rc);
F
Frank Blaschka 已提交
2418 2419 2420 2421
		goto out_qdio;
	}
	rc = qeth_dm_act(card);
	if (rc) {
2422
		QETH_CARD_TEXT_(card, 2, "8err%d", rc);
F
Frank Blaschka 已提交
2423 2424 2425 2426 2427
		goto out_qdio;
	}

	return 0;
out_qdio:
2428
	qeth_qdio_clear_card(card, !IS_IQD(card));
2429
	qdio_free(CARD_DDEV(card));
F
Frank Blaschka 已提交
2430 2431 2432 2433 2434 2435
	return rc;
}

void qeth_print_status_message(struct qeth_card *card)
{
	switch (card->info.type) {
2436 2437 2438
	case QETH_CARD_TYPE_OSD:
	case QETH_CARD_TYPE_OSM:
	case QETH_CARD_TYPE_OSX:
F
Frank Blaschka 已提交
2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450
		/* VM will use a non-zero first character
		 * to indicate a HiperSockets like reporting
		 * of the level OSA sets the first character to zero
		 * */
		if (!card->info.mcl_level[0]) {
			sprintf(card->info.mcl_level, "%02x%02x",
				card->info.mcl_level[2],
				card->info.mcl_level[3]);
			break;
		}
		/* fallthrough */
	case QETH_CARD_TYPE_IQD:
2451
		if (IS_VM_NIC(card) || (card->info.mcl_level[0] & 0x80)) {
F
Frank Blaschka 已提交
2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465
			card->info.mcl_level[0] = (char) _ebcasc[(__u8)
				card->info.mcl_level[0]];
			card->info.mcl_level[1] = (char) _ebcasc[(__u8)
				card->info.mcl_level[1]];
			card->info.mcl_level[2] = (char) _ebcasc[(__u8)
				card->info.mcl_level[2]];
			card->info.mcl_level[3] = (char) _ebcasc[(__u8)
				card->info.mcl_level[3]];
			card->info.mcl_level[QETH_MCL_LENGTH] = 0;
		}
		break;
	default:
		memset(&card->info.mcl_level[0], 0, QETH_MCL_LENGTH + 1);
	}
2466 2467 2468 2469 2470 2471 2472
	dev_info(&card->gdev->dev,
		 "Device is a%s card%s%s%s\nwith link type %s.\n",
		 qeth_get_cardname(card),
		 (card->info.mcl_level[0]) ? " (level: " : "",
		 (card->info.mcl_level[0]) ? card->info.mcl_level : "",
		 (card->info.mcl_level[0]) ? ")" : "",
		 qeth_get_cardname_short(card));
F
Frank Blaschka 已提交
2473 2474 2475 2476 2477 2478 2479
}
EXPORT_SYMBOL_GPL(qeth_print_status_message);

static void qeth_initialize_working_pool_list(struct qeth_card *card)
{
	struct qeth_buffer_pool_entry *entry;

C
Carsten Otte 已提交
2480
	QETH_CARD_TEXT(card, 5, "inwrklst");
F
Frank Blaschka 已提交
2481 2482 2483 2484 2485 2486 2487

	list_for_each_entry(entry,
			    &card->qdio.init_pool.entry_list, init_list) {
		qeth_put_buffer_pool_entry(card, entry);
	}
}

J
Julian Wiedmann 已提交
2488 2489
static struct qeth_buffer_pool_entry *qeth_find_free_buffer_pool_entry(
					struct qeth_card *card)
F
Frank Blaschka 已提交
2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518
{
	struct list_head *plh;
	struct qeth_buffer_pool_entry *entry;
	int i, free;
	struct page *page;

	if (list_empty(&card->qdio.in_buf_pool.entry_list))
		return NULL;

	list_for_each(plh, &card->qdio.in_buf_pool.entry_list) {
		entry = list_entry(plh, struct qeth_buffer_pool_entry, list);
		free = 1;
		for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
			if (page_count(virt_to_page(entry->elements[i])) > 1) {
				free = 0;
				break;
			}
		}
		if (free) {
			list_del_init(&entry->list);
			return entry;
		}
	}

	/* no free buffer in pool so take first one and swap pages */
	entry = list_entry(card->qdio.in_buf_pool.entry_list.next,
			struct qeth_buffer_pool_entry, list);
	for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
		if (page_count(virt_to_page(entry->elements[i])) > 1) {
2519
			page = alloc_page(GFP_ATOMIC);
F
Frank Blaschka 已提交
2520 2521 2522 2523 2524
			if (!page) {
				return NULL;
			} else {
				free_page((unsigned long)entry->elements[i]);
				entry->elements[i] = page_address(page);
2525
				QETH_CARD_STAT_INC(card, rx_sg_alloc_page);
F
Frank Blaschka 已提交
2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538
			}
		}
	}
	list_del_init(&entry->list);
	return entry;
}

static int qeth_init_input_buffer(struct qeth_card *card,
		struct qeth_qdio_buffer *buf)
{
	struct qeth_buffer_pool_entry *pool_entry;
	int i;

2539
	if ((card->options.cq == QETH_CQ_ENABLED) && (!buf->rx_skb)) {
2540 2541
		buf->rx_skb = netdev_alloc_skb(card->dev,
					       QETH_RX_PULL_LEN + ETH_HLEN);
2542 2543 2544 2545
		if (!buf->rx_skb)
			return 1;
	}

F
Frank Blaschka 已提交
2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561
	pool_entry = qeth_find_free_buffer_pool_entry(card);
	if (!pool_entry)
		return 1;

	/*
	 * since the buffer is accessed only from the input_tasklet
	 * there shouldn't be a need to synchronize; also, since we use
	 * the QETH_IN_BUF_REQUEUE_THRESHOLD we should never run  out off
	 * buffers
	 */

	buf->pool_entry = pool_entry;
	for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
		buf->buffer->element[i].length = PAGE_SIZE;
		buf->buffer->element[i].addr =  pool_entry->elements[i];
		if (i == QETH_MAX_BUFFER_ELEMENTS(card) - 1)
2562
			buf->buffer->element[i].eflags = SBAL_EFLAGS_LAST_ENTRY;
F
Frank Blaschka 已提交
2563
		else
2564 2565
			buf->buffer->element[i].eflags = 0;
		buf->buffer->element[i].sflags = 0;
F
Frank Blaschka 已提交
2566 2567 2568 2569 2570 2571
	}
	return 0;
}

int qeth_init_qdio_queues(struct qeth_card *card)
{
2572
	unsigned int i;
F
Frank Blaschka 已提交
2573 2574
	int rc;

2575
	QETH_CARD_TEXT(card, 2, "initqdqs");
F
Frank Blaschka 已提交
2576 2577

	/* inbound queue */
2578 2579
	qdio_reset_buffers(card->qdio.in_q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
	memset(&card->rx, 0, sizeof(struct qeth_rx));
F
Frank Blaschka 已提交
2580 2581 2582 2583 2584 2585 2586
	qeth_initialize_working_pool_list(card);
	/*give only as many buffers to hardware as we have buffer pool entries*/
	for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i)
		qeth_init_input_buffer(card, &card->qdio.in_q->bufs[i]);
	card->qdio.in_q->next_buf_to_init =
		card->qdio.in_buf_pool.buf_count - 1;
	rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0,
J
Jan Glauber 已提交
2587
		     card->qdio.in_buf_pool.buf_count - 1);
F
Frank Blaschka 已提交
2588
	if (rc) {
2589
		QETH_CARD_TEXT_(card, 2, "1err%d", rc);
F
Frank Blaschka 已提交
2590 2591
		return rc;
	}
2592 2593 2594 2595 2596 2597 2598

	/* completion */
	rc = qeth_cq_init(card);
	if (rc) {
		return rc;
	}

F
Frank Blaschka 已提交
2599 2600
	/* outbound queue */
	for (i = 0; i < card->qdio.no_out_queues; ++i) {
2601 2602 2603 2604 2605 2606 2607 2608 2609
		struct qeth_qdio_out_q *queue = card->qdio.out_qs[i];

		qdio_reset_buffers(queue->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
		queue->max_elements = QETH_MAX_BUFFER_ELEMENTS(card);
		queue->next_buf_to_fill = 0;
		queue->do_pack = 0;
		atomic_set(&queue->used_buffers, 0);
		atomic_set(&queue->set_pci_flags_count, 0);
		atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
F
Frank Blaschka 已提交
2610 2611 2612 2613 2614
	}
	return 0;
}
EXPORT_SYMBOL_GPL(qeth_init_qdio_queues);

2615
static void qeth_ipa_finalize_cmd(struct qeth_card *card,
2616
				  struct qeth_cmd_buffer *iob)
2617
{
2618
	qeth_mpc_finalize_cmd(card, iob);
2619 2620 2621 2622 2623 2624

	/* override with IPA-specific values: */
	__ipa_cmd(iob)->hdr.seqno = card->seqno.ipa;
	iob->reply->seqno = card->seqno.ipa++;
}

2625 2626
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
			  u16 cmd_length)
2627 2628
{
	u8 prot_type = qeth_mpc_select_prot_type(card);
2629
	u16 total_length = iob->length;
2630

2631 2632
	qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, total_length,
		       iob->data);
2633
	iob->finalize = qeth_ipa_finalize_cmd;
2634

2635
	memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
2636
	memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &total_length, 2);
2637
	memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data), &prot_type, 1);
2638 2639
	memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &cmd_length, 2);
	memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &cmd_length, 2);
2640 2641
	memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
	       &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
2642
	memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &cmd_length, 2);
2643 2644 2645
}
EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd);

2646 2647 2648 2649 2650
struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card,
					   enum qeth_ipa_cmds cmd_code,
					   enum qeth_prot_versions prot,
					   unsigned int data_length)
{
2651
	enum qeth_link_types link_type = card->info.link_type;
2652
	struct qeth_cmd_buffer *iob;
2653
	struct qeth_ipacmd_hdr *hdr;
2654 2655 2656 2657 2658 2659 2660 2661

	data_length += offsetof(struct qeth_ipa_cmd, data);
	iob = qeth_alloc_cmd(&card->write, IPA_PDU_HEADER_SIZE + data_length, 1,
			     QETH_IPA_TIMEOUT);
	if (!iob)
		return NULL;

	qeth_prepare_ipa_cmd(card, iob, data_length);
2662 2663 2664 2665 2666 2667 2668 2669 2670 2671

	hdr = &__ipa_cmd(iob)->hdr;
	hdr->command = cmd_code;
	hdr->initiator = IPA_CMD_INITIATOR_HOST;
	/* hdr->seqno is set by qeth_send_control_data() */
	hdr->adapter_type = (link_type == QETH_LINK_TYPE_HSTR) ? 2 : 1;
	hdr->rel_adapter_no = (u8) card->dev->dev_port;
	hdr->prim_version_no = IS_LAYER2(card) ? 2 : 1;
	hdr->param_count = 1;
	hdr->prot_version = prot;
2672 2673 2674 2675
	return iob;
}
EXPORT_SYMBOL_GPL(qeth_ipa_alloc_cmd);

2676 2677 2678 2679 2680 2681 2682 2683
static int qeth_send_ipa_cmd_cb(struct qeth_card *card,
				struct qeth_reply *reply, unsigned long data)
{
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;

	return (cmd->hdr.return_code) ? -EIO : 0;
}

E
Eugene Crosser 已提交
2684 2685 2686 2687 2688 2689
/**
 * qeth_send_ipa_cmd() - send an IPA command
 *
 * See qeth_send_control_data() for explanation of the arguments.
 */

F
Frank Blaschka 已提交
2690 2691 2692 2693 2694 2695 2696
int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
		int (*reply_cb)(struct qeth_card *, struct qeth_reply*,
			unsigned long),
		void *reply_param)
{
	int rc;

C
Carsten Otte 已提交
2697
	QETH_CARD_TEXT(card, 4, "sendipa");
2698

2699
	if (card->read_or_write_problem) {
2700
		qeth_put_cmd(iob);
2701 2702 2703
		return -EIO;
	}

2704 2705
	if (reply_cb == NULL)
		reply_cb = qeth_send_ipa_cmd_cb;
2706
	rc = qeth_send_control_data(card, iob, reply_cb, reply_param);
2707 2708 2709 2710
	if (rc == -ETIME) {
		qeth_clear_ipacmd_list(card);
		qeth_schedule_recovery(card);
	}
F
Frank Blaschka 已提交
2711 2712 2713 2714
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_send_ipa_cmd);

2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725
static int qeth_send_startlan_cb(struct qeth_card *card,
				 struct qeth_reply *reply, unsigned long data)
{
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;

	if (cmd->hdr.return_code == IPA_RC_LAN_OFFLINE)
		return -ENETDOWN;

	return (cmd->hdr.return_code) ? -EIO : 0;
}

2726
static int qeth_send_startlan(struct qeth_card *card)
F
Frank Blaschka 已提交
2727
{
2728
	struct qeth_cmd_buffer *iob;
F
Frank Blaschka 已提交
2729

2730
	QETH_CARD_TEXT(card, 2, "strtlan");
F
Frank Blaschka 已提交
2731

2732
	iob = qeth_ipa_alloc_cmd(card, IPA_CMD_STARTLAN, QETH_PROT_NONE, 0);
2733 2734
	if (!iob)
		return -ENOMEM;
2735
	return qeth_send_ipa_cmd(card, iob, qeth_send_startlan_cb, NULL);
F
Frank Blaschka 已提交
2736 2737
}

2738
static int qeth_setadpparms_inspect_rc(struct qeth_ipa_cmd *cmd)
F
Frank Blaschka 已提交
2739
{
2740
	if (!cmd->hdr.return_code)
F
Frank Blaschka 已提交
2741 2742
		cmd->hdr.return_code =
			cmd->data.setadapterparms.hdr.return_code;
2743
	return cmd->hdr.return_code;
F
Frank Blaschka 已提交
2744 2745 2746 2747 2748
}

static int qeth_query_setadapterparms_cb(struct qeth_card *card,
		struct qeth_reply *reply, unsigned long data)
{
2749
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
F
Frank Blaschka 已提交
2750

C
Carsten Otte 已提交
2751
	QETH_CARD_TEXT(card, 3, "quyadpcb");
2752
	if (qeth_setadpparms_inspect_rc(cmd))
2753
		return -EIO;
F
Frank Blaschka 已提交
2754

2755
	if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type & 0x7f) {
F
Frank Blaschka 已提交
2756 2757
		card->info.link_type =
		      cmd->data.setadapterparms.data.query_cmds_supp.lan_type;
2758
		QETH_CARD_TEXT_(card, 2, "lnk %d", card->info.link_type);
2759
	}
F
Frank Blaschka 已提交
2760 2761
	card->options.adp.supported_funcs =
		cmd->data.setadapterparms.data.query_cmds_supp.supported_cmds;
2762
	return 0;
F
Frank Blaschka 已提交
2763 2764
}

S
Stefan Raspl 已提交
2765
static struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card,
2766 2767
						    enum qeth_ipa_setadp_cmd adp_cmd,
						    unsigned int data_length)
F
Frank Blaschka 已提交
2768
{
2769
	struct qeth_ipacmd_setadpparms_hdr *hdr;
F
Frank Blaschka 已提交
2770 2771
	struct qeth_cmd_buffer *iob;

2772 2773 2774 2775 2776 2777
	iob = qeth_ipa_alloc_cmd(card, IPA_CMD_SETADAPTERPARMS, QETH_PROT_IPV4,
				 data_length +
				 offsetof(struct qeth_ipacmd_setadpparms,
					  data));
	if (!iob)
		return NULL;
F
Frank Blaschka 已提交
2778

2779 2780 2781 2782 2783
	hdr = &__ipa_cmd(iob)->data.setadapterparms.hdr;
	hdr->cmdlength = sizeof(*hdr) + data_length;
	hdr->command_code = adp_cmd;
	hdr->used_total = 1;
	hdr->seq_no = 1;
F
Frank Blaschka 已提交
2784 2785 2786
	return iob;
}

2787
static int qeth_query_setadapterparms(struct qeth_card *card)
F
Frank Blaschka 已提交
2788 2789 2790 2791
{
	int rc;
	struct qeth_cmd_buffer *iob;

C
Carsten Otte 已提交
2792
	QETH_CARD_TEXT(card, 3, "queryadp");
F
Frank Blaschka 已提交
2793
	iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_COMMANDS_SUPPORTED,
2794
				   SETADP_DATA_SIZEOF(query_cmds_supp));
2795 2796
	if (!iob)
		return -ENOMEM;
F
Frank Blaschka 已提交
2797 2798 2799 2800
	rc = qeth_send_ipa_cmd(card, iob, qeth_query_setadapterparms_cb, NULL);
	return rc;
}

2801 2802 2803 2804 2805
static int qeth_query_ipassists_cb(struct qeth_card *card,
		struct qeth_reply *reply, unsigned long data)
{
	struct qeth_ipa_cmd *cmd;

2806
	QETH_CARD_TEXT(card, 2, "qipasscb");
2807 2808

	cmd = (struct qeth_ipa_cmd *) data;
2809 2810

	switch (cmd->hdr.return_code) {
2811 2812
	case IPA_RC_SUCCESS:
		break;
2813 2814
	case IPA_RC_NOTSUPP:
	case IPA_RC_L2_UNSUPPORTED_CMD:
2815
		QETH_CARD_TEXT(card, 2, "ipaunsup");
2816 2817
		card->options.ipa4.supported_funcs |= IPA_SETADAPTERPARMS;
		card->options.ipa6.supported_funcs |= IPA_SETADAPTERPARMS;
2818
		return -EOPNOTSUPP;
2819
	default:
2820 2821 2822
		QETH_DBF_MESSAGE(1, "IPA_CMD_QIPASSIST on device %x: Unhandled rc=%#x\n",
				 CARD_DEVID(card), cmd->hdr.return_code);
		return -EIO;
2823 2824
	}

2825 2826 2827
	if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
		card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
		card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
2828
	} else if (cmd->hdr.prot_version == QETH_PROT_IPV6) {
2829 2830
		card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
		card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
2831
	} else
2832 2833
		QETH_DBF_MESSAGE(1, "IPA_CMD_QIPASSIST on device %x: Flawed LIC detected\n",
				 CARD_DEVID(card));
2834 2835 2836
	return 0;
}

2837 2838
static int qeth_query_ipassists(struct qeth_card *card,
				enum qeth_prot_versions prot)
2839 2840 2841 2842
{
	int rc;
	struct qeth_cmd_buffer *iob;

2843
	QETH_CARD_TEXT_(card, 2, "qipassi%i", prot);
2844
	iob = qeth_ipa_alloc_cmd(card, IPA_CMD_QIPASSIST, prot, 0);
2845 2846
	if (!iob)
		return -ENOMEM;
2847 2848 2849 2850
	rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL);
	return rc;
}

2851 2852 2853
static int qeth_query_switch_attributes_cb(struct qeth_card *card,
				struct qeth_reply *reply, unsigned long data)
{
2854
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
2855
	struct qeth_query_switch_attributes *attrs;
2856
	struct qeth_switch_info *sw_info;
2857 2858

	QETH_CARD_TEXT(card, 2, "qswiatcb");
2859
	if (qeth_setadpparms_inspect_rc(cmd))
2860
		return -EIO;
2861

2862 2863 2864 2865 2866 2867
	sw_info = (struct qeth_switch_info *)reply->param;
	attrs = &cmd->data.setadapterparms.data.query_switch_attributes;
	sw_info->capabilities = attrs->capabilities;
	sw_info->settings = attrs->settings;
	QETH_CARD_TEXT_(card, 2, "%04x%04x", sw_info->capabilities,
			sw_info->settings);
2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880
	return 0;
}

int qeth_query_switch_attributes(struct qeth_card *card,
				 struct qeth_switch_info *sw_info)
{
	struct qeth_cmd_buffer *iob;

	QETH_CARD_TEXT(card, 2, "qswiattr");
	if (!qeth_adp_supported(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES))
		return -EOPNOTSUPP;
	if (!netif_carrier_ok(card->dev))
		return -ENOMEDIUM;
2881
	iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES, 0);
2882 2883
	if (!iob)
		return -ENOMEM;
2884 2885 2886 2887
	return qeth_send_ipa_cmd(card, iob,
				qeth_query_switch_attributes_cb, sw_info);
}

2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906
struct qeth_cmd_buffer *qeth_get_diag_cmd(struct qeth_card *card,
					  enum qeth_diags_cmds sub_cmd,
					  unsigned int data_length)
{
	struct qeth_ipacmd_diagass *cmd;
	struct qeth_cmd_buffer *iob;

	iob = qeth_ipa_alloc_cmd(card, IPA_CMD_SET_DIAG_ASS, QETH_PROT_NONE,
				 DIAG_HDR_LEN + data_length);
	if (!iob)
		return NULL;

	cmd = &__ipa_cmd(iob)->data.diagass;
	cmd->subcmd_len = DIAG_SUB_HDR_LEN + data_length;
	cmd->subcmd = sub_cmd;
	return iob;
}
EXPORT_SYMBOL_GPL(qeth_get_diag_cmd);

2907 2908 2909
static int qeth_query_setdiagass_cb(struct qeth_card *card,
		struct qeth_reply *reply, unsigned long data)
{
2910 2911
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
	u16 rc = cmd->hdr.return_code;
2912

2913
	if (rc) {
2914
		QETH_CARD_TEXT_(card, 2, "diagq:%x", rc);
2915 2916 2917 2918
		return -EIO;
	}

	card->info.diagass_support = cmd->data.diagass.ext;
2919 2920 2921 2922 2923 2924 2925
	return 0;
}

static int qeth_query_setdiagass(struct qeth_card *card)
{
	struct qeth_cmd_buffer *iob;

2926
	QETH_CARD_TEXT(card, 2, "qdiagass");
2927
	iob = qeth_get_diag_cmd(card, QETH_DIAGS_CMD_QUERY, 0);
2928 2929
	if (!iob)
		return -ENOMEM;
2930 2931 2932 2933 2934 2935 2936 2937 2938
	return qeth_send_ipa_cmd(card, iob, qeth_query_setdiagass_cb, NULL);
}

static void qeth_get_trap_id(struct qeth_card *card, struct qeth_trap_id *tid)
{
	unsigned long info = get_zeroed_page(GFP_KERNEL);
	struct sysinfo_2_2_2 *info222 = (struct sysinfo_2_2_2 *)info;
	struct sysinfo_3_2_2 *info322 = (struct sysinfo_3_2_2 *)info;
	struct ccw_dev_id ccwid;
2939
	int level;
2940 2941 2942 2943 2944 2945 2946

	tid->chpid = card->info.chpid;
	ccw_device_get_id(CARD_RDEV(card), &ccwid);
	tid->ssid = ccwid.ssid;
	tid->devno = ccwid.devno;
	if (!info)
		return;
2947 2948
	level = stsi(NULL, 0, 0, 0);
	if ((level >= 2) && (stsi(info222, 2, 2, 2) == 0))
2949
		tid->lparnr = info222->lpar_number;
2950
	if ((level >= 3) && (stsi(info322, 3, 2, 2) == 0)) {
2951 2952 2953 2954 2955 2956 2957 2958 2959 2960
		EBCASC(info322->vm[0].name, sizeof(info322->vm[0].name));
		memcpy(tid->vmname, info322->vm[0].name, sizeof(tid->vmname));
	}
	free_page(info);
	return;
}

static int qeth_hw_trap_cb(struct qeth_card *card,
		struct qeth_reply *reply, unsigned long data)
{
2961 2962
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
	u16 rc = cmd->hdr.return_code;
2963

2964
	if (rc) {
2965
		QETH_CARD_TEXT_(card, 2, "trapc:%x", rc);
2966 2967
		return -EIO;
	}
2968 2969 2970 2971 2972 2973 2974 2975
	return 0;
}

int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action)
{
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

2976
	QETH_CARD_TEXT(card, 2, "diagtrap");
2977
	iob = qeth_get_diag_cmd(card, QETH_DIAGS_CMD_TRAP, 64);
2978 2979
	if (!iob)
		return -ENOMEM;
2980
	cmd = __ipa_cmd(iob);
2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000
	cmd->data.diagass.type = 1;
	cmd->data.diagass.action = action;
	switch (action) {
	case QETH_DIAGS_TRAP_ARM:
		cmd->data.diagass.options = 0x0003;
		cmd->data.diagass.ext = 0x00010000 +
			sizeof(struct qeth_trap_id);
		qeth_get_trap_id(card,
			(struct qeth_trap_id *)cmd->data.diagass.cdata);
		break;
	case QETH_DIAGS_TRAP_DISARM:
		cmd->data.diagass.options = 0x0001;
		break;
	case QETH_DIAGS_TRAP_CAPTURE:
		break;
	}
	return qeth_send_ipa_cmd(card, iob, qeth_hw_trap_cb, NULL);
}
EXPORT_SYMBOL_GPL(qeth_hw_trap);

3001 3002 3003 3004
static int qeth_check_qdio_errors(struct qeth_card *card,
				  struct qdio_buffer *buf,
				  unsigned int qdio_error,
				  const char *dbftext)
F
Frank Blaschka 已提交
3005
{
J
Jan Glauber 已提交
3006
	if (qdio_error) {
C
Carsten Otte 已提交
3007
		QETH_CARD_TEXT(card, 2, dbftext);
C
Carsten Otte 已提交
3008
		QETH_CARD_TEXT_(card, 2, " F15=%02X",
3009
			       buf->element[15].sflags);
C
Carsten Otte 已提交
3010
		QETH_CARD_TEXT_(card, 2, " F14=%02X",
3011
			       buf->element[14].sflags);
C
Carsten Otte 已提交
3012
		QETH_CARD_TEXT_(card, 2, " qerr=%X", qdio_error);
3013
		if ((buf->element[15].sflags) == 0x12) {
3014
			QETH_CARD_STAT_INC(card, rx_dropped);
3015 3016 3017
			return 0;
		} else
			return 1;
F
Frank Blaschka 已提交
3018 3019 3020 3021
	}
	return 0;
}

3022
static void qeth_queue_input_buffer(struct qeth_card *card, int index)
F
Frank Blaschka 已提交
3023 3024
{
	struct qeth_qdio_q *queue = card->qdio.in_q;
3025
	struct list_head *lh;
F
Frank Blaschka 已提交
3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056
	int count;
	int i;
	int rc;
	int newcount = 0;

	count = (index < queue->next_buf_to_init)?
		card->qdio.in_buf_pool.buf_count -
		(queue->next_buf_to_init - index) :
		card->qdio.in_buf_pool.buf_count -
		(queue->next_buf_to_init + QDIO_MAX_BUFFERS_PER_Q - index);
	/* only requeue at a certain threshold to avoid SIGAs */
	if (count >= QETH_IN_BUF_REQUEUE_THRESHOLD(card)) {
		for (i = queue->next_buf_to_init;
		     i < queue->next_buf_to_init + count; ++i) {
			if (qeth_init_input_buffer(card,
				&queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q])) {
				break;
			} else {
				newcount++;
			}
		}

		if (newcount < count) {
			/* we are in memory shortage so we switch back to
			   traditional skb allocation and drop packages */
			atomic_set(&card->force_alloc_skb, 3);
			count = newcount;
		} else {
			atomic_add_unless(&card->force_alloc_skb, -1, 0);
		}

3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070
		if (!count) {
			i = 0;
			list_for_each(lh, &card->qdio.in_buf_pool.entry_list)
				i++;
			if (i == card->qdio.in_buf_pool.buf_count) {
				QETH_CARD_TEXT(card, 2, "qsarbw");
				card->reclaim_index = index;
				schedule_delayed_work(
					&card->buffer_reclaim_work,
					QETH_RECLAIM_WORK_TIME);
			}
			return;
		}

F
Frank Blaschka 已提交
3071 3072 3073 3074 3075 3076 3077
		/*
		 * according to old code it should be avoided to requeue all
		 * 128 buffers in order to benefit from PCI avoidance.
		 * this function keeps at least one buffer (the buffer at
		 * 'index') un-requeued -> this buffer is the first buffer that
		 * will be requeued the next time
		 */
J
Jan Glauber 已提交
3078 3079
		rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0,
			     queue->next_buf_to_init, count);
F
Frank Blaschka 已提交
3080
		if (rc) {
C
Carsten Otte 已提交
3081
			QETH_CARD_TEXT(card, 2, "qinberr");
F
Frank Blaschka 已提交
3082 3083 3084 3085 3086
		}
		queue->next_buf_to_init = (queue->next_buf_to_init + count) %
					  QDIO_MAX_BUFFERS_PER_Q;
	}
}
3087 3088 3089 3090 3091 3092 3093 3094 3095

static void qeth_buffer_reclaim_work(struct work_struct *work)
{
	struct qeth_card *card = container_of(work, struct qeth_card,
		buffer_reclaim_work.work);

	QETH_CARD_TEXT_(card, 2, "brw:%x", card->reclaim_index);
	qeth_queue_input_buffer(card, card->reclaim_index);
}
F
Frank Blaschka 已提交
3096

3097
static void qeth_handle_send_error(struct qeth_card *card,
J
Jan Glauber 已提交
3098
		struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err)
F
Frank Blaschka 已提交
3099
{
3100
	int sbalf15 = buffer->buffer->element[15].sflags;
F
Frank Blaschka 已提交
3101

C
Carsten Otte 已提交
3102
	QETH_CARD_TEXT(card, 6, "hdsnderr");
3103
	qeth_check_qdio_errors(card, buffer->buffer, qdio_err, "qouterr");
3104 3105

	if (!qdio_err)
3106
		return;
3107 3108

	if ((sbalf15 >= 15) && (sbalf15 <= 31))
3109
		return;
3110

C
Carsten Otte 已提交
3111 3112
	QETH_CARD_TEXT(card, 1, "lnkfail");
	QETH_CARD_TEXT_(card, 1, "%04x %02x",
3113
		       (u16)qdio_err, (u8)sbalf15);
F
Frank Blaschka 已提交
3114 3115
}

3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137
/**
 * qeth_prep_flush_pack_buffer - Prepares flushing of a packing buffer.
 * @queue: queue to check for packing buffer
 *
 * Returns number of buffers that were prepared for flush.
 */
static int qeth_prep_flush_pack_buffer(struct qeth_qdio_out_q *queue)
{
	struct qeth_qdio_out_buffer *buffer;

	buffer = queue->bufs[queue->next_buf_to_fill];
	if ((atomic_read(&buffer->state) == QETH_QDIO_BUF_EMPTY) &&
	    (buffer->next_element_to_fill > 0)) {
		/* it's a packing buffer */
		atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
		queue->next_buf_to_fill =
			(queue->next_buf_to_fill + 1) % QDIO_MAX_BUFFERS_PER_Q;
		return 1;
	}
	return 0;
}

F
Frank Blaschka 已提交
3138 3139 3140 3141 3142 3143 3144 3145 3146 3147
/*
 * Switched to packing state if the number of used buffers on a queue
 * reaches a certain limit.
 */
static void qeth_switch_to_packing_if_needed(struct qeth_qdio_out_q *queue)
{
	if (!queue->do_pack) {
		if (atomic_read(&queue->used_buffers)
		    >= QETH_HIGH_WATERMARK_PACK){
			/* switch non-PACKING -> PACKING */
C
Carsten Otte 已提交
3148
			QETH_CARD_TEXT(queue->card, 6, "np->pack");
3149
			QETH_TXQ_STAT_INC(queue, packing_mode_switch);
F
Frank Blaschka 已提交
3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166
			queue->do_pack = 1;
		}
	}
}

/*
 * Switches from packing to non-packing mode. If there is a packing
 * buffer on the queue this buffer will be prepared to be flushed.
 * In that case 1 is returned to inform the caller. If no buffer
 * has to be flushed, zero is returned.
 */
static int qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
{
	if (queue->do_pack) {
		if (atomic_read(&queue->used_buffers)
		    <= QETH_LOW_WATERMARK_PACK) {
			/* switch PACKING -> non-PACKING */
C
Carsten Otte 已提交
3167
			QETH_CARD_TEXT(queue->card, 6, "pack->np");
3168
			QETH_TXQ_STAT_INC(queue, packing_mode_switch);
F
Frank Blaschka 已提交
3169
			queue->do_pack = 0;
3170
			return qeth_prep_flush_pack_buffer(queue);
F
Frank Blaschka 已提交
3171 3172 3173 3174 3175
		}
	}
	return 0;
}

J
Jan Glauber 已提交
3176 3177
static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
			       int count)
F
Frank Blaschka 已提交
3178 3179 3180 3181 3182 3183 3184
{
	struct qeth_qdio_out_buffer *buf;
	int rc;
	int i;
	unsigned int qdio_flags;

	for (i = index; i < index + count; ++i) {
3185 3186
		int bidx = i % QDIO_MAX_BUFFERS_PER_Q;
		buf = queue->bufs[bidx];
3187 3188
		buf->buffer->element[buf->next_element_to_fill - 1].eflags |=
				SBAL_EFLAGS_LAST_ENTRY;
F
Frank Blaschka 已提交
3189

3190 3191 3192
		if (queue->bufstates)
			queue->bufstates[bidx].user = buf;

3193
		if (IS_IQD(queue->card))
F
Frank Blaschka 已提交
3194 3195 3196 3197 3198 3199 3200 3201 3202 3203
			continue;

		if (!queue->do_pack) {
			if ((atomic_read(&queue->used_buffers) >=
				(QETH_HIGH_WATERMARK_PACK -
				 QETH_WATERMARK_PACK_FUZZ)) &&
			    !atomic_read(&queue->set_pci_flags_count)) {
				/* it's likely that we'll go to packing
				 * mode soon */
				atomic_inc(&queue->set_pci_flags_count);
3204
				buf->buffer->element[0].sflags |= SBAL_SFLAGS0_PCI_REQ;
F
Frank Blaschka 已提交
3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216
			}
		} else {
			if (!atomic_read(&queue->set_pci_flags_count)) {
				/*
				 * there's no outstanding PCI any more, so we
				 * have to request a PCI to be sure the the PCI
				 * will wake at some time in the future then we
				 * can flush packed buffers that might still be
				 * hanging around, which can happen if no
				 * further send was requested by the stack
				 */
				atomic_inc(&queue->set_pci_flags_count);
3217
				buf->buffer->element[0].sflags |= SBAL_SFLAGS0_PCI_REQ;
F
Frank Blaschka 已提交
3218 3219 3220 3221
			}
		}
	}

3222
	QETH_TXQ_STAT_ADD(queue, bufs, count);
F
Frank Blaschka 已提交
3223 3224 3225 3226
	qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
	if (atomic_read(&queue->set_pci_flags_count))
		qdio_flags |= QDIO_FLAG_PCI_OUT;
	rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags,
J
Jan Glauber 已提交
3227
		     queue->queue_no, index, count);
F
Frank Blaschka 已提交
3228
	if (rc) {
3229
		QETH_TXQ_STAT_ADD(queue, tx_errors, count);
3230
		/* ignore temporary SIGA errors without busy condition */
3231
		if (rc == -ENOBUFS)
3232
			return;
C
Carsten Otte 已提交
3233
		QETH_CARD_TEXT(queue->card, 2, "flushbuf");
3234 3235 3236
		QETH_CARD_TEXT_(queue->card, 2, " q%d", queue->queue_no);
		QETH_CARD_TEXT_(queue->card, 2, " idx%d", index);
		QETH_CARD_TEXT_(queue->card, 2, " c%d", count);
C
Carsten Otte 已提交
3237
		QETH_CARD_TEXT_(queue->card, 2, " err%d", rc);
3238

F
Frank Blaschka 已提交
3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271
		/* this must not happen under normal circumstances. if it
		 * happens something is really wrong -> recover */
		qeth_schedule_recovery(queue->card);
		return;
	}
}

static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
{
	int index;
	int flush_cnt = 0;
	int q_was_packing = 0;

	/*
	 * check if weed have to switch to non-packing mode or if
	 * we have to get a pci flag out on the queue
	 */
	if ((atomic_read(&queue->used_buffers) <= QETH_LOW_WATERMARK_PACK) ||
	    !atomic_read(&queue->set_pci_flags_count)) {
		if (atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH) ==
				QETH_OUT_Q_UNLOCKED) {
			/*
			 * If we get in here, there was no action in
			 * do_send_packet. So, we check if there is a
			 * packing buffer to be flushed here.
			 */
			index = queue->next_buf_to_fill;
			q_was_packing = queue->do_pack;
			/* queue->do_pack may change */
			barrier();
			flush_cnt += qeth_switch_to_nonpacking_if_needed(queue);
			if (!flush_cnt &&
			    !atomic_read(&queue->set_pci_flags_count))
3272
				flush_cnt += qeth_prep_flush_pack_buffer(queue);
3273 3274
			if (q_was_packing)
				QETH_TXQ_STAT_ADD(queue, bufs_pack, flush_cnt);
F
Frank Blaschka 已提交
3275
			if (flush_cnt)
J
Jan Glauber 已提交
3276
				qeth_flush_buffers(queue, index, flush_cnt);
F
Frank Blaschka 已提交
3277 3278 3279 3280 3281
			atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
		}
	}
}

3282 3283
static void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
				 unsigned long card_ptr)
3284 3285 3286
{
	struct qeth_card *card = (struct qeth_card *)card_ptr;

3287
	if (card->dev->flags & IFF_UP)
3288 3289 3290
		napi_schedule(&card->napi);
}

3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303
int qeth_configure_cq(struct qeth_card *card, enum qeth_cq cq)
{
	int rc;

	if (card->options.cq ==  QETH_CQ_NOTAVAILABLE) {
		rc = -1;
		goto out;
	} else {
		if (card->options.cq == cq) {
			rc = 0;
			goto out;
		}

3304
		if (card->state != CARD_STATE_DOWN) {
3305 3306 3307 3308
			rc = -1;
			goto out;
		}

3309
		qeth_free_qdio_queues(card);
3310 3311 3312 3313 3314 3315 3316 3317 3318
		card->options.cq = cq;
		rc = 0;
	}
out:
	return rc;

}
EXPORT_SYMBOL_GPL(qeth_configure_cq);

3319 3320 3321 3322
static void qeth_qdio_cq_handler(struct qeth_card *card, unsigned int qdio_err,
				 unsigned int queue, int first_element,
				 int count)
{
3323 3324 3325 3326 3327
	struct qeth_qdio_q *cq = card->qdio.c_q;
	int i;
	int rc;

	if (!qeth_is_cq(card, queue))
3328
		return;
3329 3330 3331 3332 3333 3334

	QETH_CARD_TEXT_(card, 5, "qcqhe%d", first_element);
	QETH_CARD_TEXT_(card, 5, "qcqhc%d", count);
	QETH_CARD_TEXT_(card, 5, "qcqherr%d", qdio_err);

	if (qdio_err) {
3335
		netif_tx_stop_all_queues(card->dev);
3336
		qeth_schedule_recovery(card);
3337
		return;
3338 3339 3340 3341
	}

	for (i = first_element; i < first_element + count; ++i) {
		int bidx = i % QDIO_MAX_BUFFERS_PER_Q;
3342
		struct qdio_buffer *buffer = cq->qdio_bufs[bidx];
3343
		int e = 0;
3344

3345 3346
		while ((e < QDIO_MAX_ELEMENTS_PER_BUFFER) &&
		       buffer->element[e].addr) {
3347 3348 3349 3350 3351 3352
			unsigned long phys_aob_addr;

			phys_aob_addr = (unsigned long) buffer->element[e].addr;
			qeth_qdio_handle_aob(card, phys_aob_addr);
			++e;
		}
3353
		qeth_scrub_qdio_buffer(buffer, QDIO_MAX_ELEMENTS_PER_BUFFER);
3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366
	}
	rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, queue,
		    card->qdio.c_q->next_buf_to_init,
		    count);
	if (rc) {
		dev_warn(&card->gdev->dev,
			"QDIO reported an error, rc=%i\n", rc);
		QETH_CARD_TEXT(card, 2, "qcqherr");
	}
	card->qdio.c_q->next_buf_to_init = (card->qdio.c_q->next_buf_to_init
				   + count) % QDIO_MAX_BUFFERS_PER_Q;
}

3367 3368 3369 3370
static void qeth_qdio_input_handler(struct ccw_device *ccwdev,
				    unsigned int qdio_err, int queue,
				    int first_elem, int count,
				    unsigned long card_ptr)
3371 3372 3373
{
	struct qeth_card *card = (struct qeth_card *)card_ptr;

3374 3375 3376 3377 3378 3379
	QETH_CARD_TEXT_(card, 2, "qihq%d", queue);
	QETH_CARD_TEXT_(card, 2, "qiec%d", qdio_err);

	if (qeth_is_cq(card, queue))
		qeth_qdio_cq_handler(card, qdio_err, queue, first_elem, count);
	else if (qdio_err)
3380 3381 3382
		qeth_schedule_recovery(card);
}

3383 3384 3385 3386
static void qeth_qdio_output_handler(struct ccw_device *ccwdev,
				     unsigned int qdio_error, int __queue,
				     int first_element, int count,
				     unsigned long card_ptr)
F
Frank Blaschka 已提交
3387 3388 3389 3390
{
	struct qeth_card *card        = (struct qeth_card *) card_ptr;
	struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue];
	struct qeth_qdio_out_buffer *buffer;
3391
	struct net_device *dev = card->dev;
3392
	struct netdev_queue *txq;
F
Frank Blaschka 已提交
3393 3394
	int i;

C
Carsten Otte 已提交
3395
	QETH_CARD_TEXT(card, 6, "qdouhdl");
3396
	if (qdio_error & QDIO_ERROR_FATAL) {
C
Carsten Otte 已提交
3397
		QETH_CARD_TEXT(card, 2, "achkcond");
3398
		netif_tx_stop_all_queues(dev);
J
Jan Glauber 已提交
3399 3400
		qeth_schedule_recovery(card);
		return;
F
Frank Blaschka 已提交
3401
	}
3402

F
Frank Blaschka 已提交
3403
	for (i = first_element; i < (first_element + count); ++i) {
3404 3405
		int bidx = i % QDIO_MAX_BUFFERS_PER_Q;
		buffer = queue->bufs[bidx];
3406
		qeth_handle_send_error(card, buffer, qdio_error);
3407 3408 3409 3410

		if (queue->bufstates &&
		    (queue->bufstates[bidx].flags &
		     QDIO_OUTBUF_STATE_FLAG_PENDING) != 0) {
S
Stefan Raspl 已提交
3411
			WARN_ON_ONCE(card->options.cq != QETH_CQ_ENABLED);
3412 3413 3414 3415 3416 3417 3418 3419

			if (atomic_cmpxchg(&buffer->state,
					   QETH_QDIO_BUF_PRIMED,
					   QETH_QDIO_BUF_PENDING) ==
				QETH_QDIO_BUF_PRIMED) {
				qeth_notify_skbs(queue, buffer,
						 TX_NOTIFY_PENDING);
			}
3420
			QETH_CARD_TEXT_(queue->card, 5, "pel%d", bidx);
3421 3422 3423

			/* prepare the queue slot for re-use: */
			qeth_scrub_qdio_buffer(buffer->buffer,
3424
					       queue->max_elements);
3425 3426
			if (qeth_init_qdio_out_buf(queue, bidx)) {
				QETH_CARD_TEXT(card, 2, "outofbuf");
3427
				qeth_schedule_recovery(card);
3428
			}
3429
		} else {
3430 3431 3432 3433 3434 3435 3436 3437
			if (card->options.cq == QETH_CQ_ENABLED) {
				enum iucv_tx_notify n;

				n = qeth_compute_cq_notification(
					buffer->buffer->element[15].sflags, 0);
				qeth_notify_skbs(queue, buffer, n);
			}

3438
			qeth_clear_output_buffer(queue, buffer);
3439 3440
		}
		qeth_cleanup_handled_pending(queue, bidx, 0);
F
Frank Blaschka 已提交
3441 3442 3443
	}
	atomic_sub(count, &queue->used_buffers);
	/* check if we need to do something on this outbound queue */
3444
	if (!IS_IQD(card))
F
Frank Blaschka 已提交
3445 3446
		qeth_check_outbound_queue(queue);

3447 3448 3449 3450 3451 3452 3453 3454 3455
	if (IS_IQD(card))
		__queue = qeth_iqd_translate_txq(dev, __queue);
	txq = netdev_get_tx_queue(dev, __queue);
	/* xmit may have observed the full-condition, but not yet stopped the
	 * txq. In which case the code below won't trigger. So before returning,
	 * xmit will re-check the txq's fill level and wake it up if needed.
	 */
	if (netif_tx_queue_stopped(txq) && !qeth_out_queue_is_full(queue))
		netif_tx_wake_queue(txq);
F
Frank Blaschka 已提交
3456 3457
}

3458 3459 3460
/**
 * Note: Function assumes that we have 4 outbound queues.
 */
3461
int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb)
F
Frank Blaschka 已提交
3462
{
J
Julian Wiedmann 已提交
3463
	struct vlan_ethhdr *veth = vlan_eth_hdr(skb);
3464 3465 3466 3467 3468
	u8 tos;

	switch (card->qdio.do_prio_queueing) {
	case QETH_PRIO_Q_ING_TOS:
	case QETH_PRIO_Q_ING_PREC:
3469
		switch (qeth_get_ip_version(skb)) {
3470 3471 3472 3473 3474 3475 3476 3477
		case 4:
			tos = ipv4_get_dsfield(ip_hdr(skb));
			break;
		case 6:
			tos = ipv6_get_dsfield(ipv6_hdr(skb));
			break;
		default:
			return card->qdio.default_out_queue;
F
Frank Blaschka 已提交
3478
		}
3479
		if (card->qdio.do_prio_queueing == QETH_PRIO_Q_ING_PREC)
J
Julian Wiedmann 已提交
3480
			return ~tos >> 6 & 3;
3481
		if (tos & IPTOS_MINCOST)
J
Julian Wiedmann 已提交
3482
			return 3;
3483 3484 3485 3486 3487 3488
		if (tos & IPTOS_RELIABILITY)
			return 2;
		if (tos & IPTOS_THROUGHPUT)
			return 1;
		if (tos & IPTOS_LOWDELAY)
			return 0;
3489 3490 3491 3492
		break;
	case QETH_PRIO_Q_ING_SKB:
		if (skb->priority > 5)
			return 0;
J
Julian Wiedmann 已提交
3493
		return ~skb->priority >> 1 & 3;
3494
	case QETH_PRIO_Q_ING_VLAN:
J
Julian Wiedmann 已提交
3495 3496 3497
		if (veth->h_vlan_proto == htons(ETH_P_8021Q))
			return ~ntohs(veth->h_vlan_TCI) >>
			       (VLAN_PRIO_SHIFT + 1) & 3;
3498
		break;
F
Frank Blaschka 已提交
3499
	default:
3500
		break;
F
Frank Blaschka 已提交
3501
	}
3502
	return card->qdio.default_out_queue;
F
Frank Blaschka 已提交
3503 3504 3505
}
EXPORT_SYMBOL_GPL(qeth_get_priority_queue);

3506 3507 3508 3509 3510 3511 3512
/**
 * qeth_get_elements_for_frags() -	find number of SBALEs for skb frags.
 * @skb:				SKB address
 *
 * Returns the number of pages, and thus QDIO buffer elements, needed to cover
 * fragmented part of the SKB. Returns zero for linear SKB.
 */
3513
static int qeth_get_elements_for_frags(struct sk_buff *skb)
3514
{
3515
	int cnt, elements = 0;
3516 3517

	for (cnt = 0; cnt < skb_shinfo(skb)->nr_frags; cnt++) {
3518 3519 3520 3521 3522
		struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[cnt];

		elements += qeth_get_elements_for_range(
			(addr_t)skb_frag_address(frag),
			(addr_t)skb_frag_address(frag) + skb_frag_size(frag));
3523 3524 3525 3526
	}
	return elements;
}

3527 3528 3529 3530 3531 3532 3533 3534 3535 3536
/**
 * qeth_count_elements() -	Counts the number of QDIO buffer elements needed
 *				to transmit an skb.
 * @skb:			the skb to operate on.
 * @data_offset:		skip this part of the skb's linear data
 *
 * Returns the number of pages, and thus QDIO buffer elements, needed to map the
 * skb's data (both its linear part and paged fragments).
 */
unsigned int qeth_count_elements(struct sk_buff *skb, unsigned int data_offset)
3537 3538 3539 3540 3541 3542 3543 3544 3545
{
	unsigned int elements = qeth_get_elements_for_frags(skb);
	addr_t end = (addr_t)skb->data + skb_headlen(skb);
	addr_t start = (addr_t)skb->data + data_offset;

	if (start != end)
		elements += qeth_get_elements_for_range(start, end);
	return elements;
}
3546
EXPORT_SYMBOL_GPL(qeth_count_elements);
F
Frank Blaschka 已提交
3547

3548 3549
#define QETH_HDR_CACHE_OBJ_SIZE		(sizeof(struct qeth_hdr_tso) + \
					 MAX_TCP_HEADER)
3550

3551
/**
3552 3553
 * qeth_add_hw_header() - add a HW header to an skb.
 * @skb: skb that the HW header should be added to.
3554 3555
 * @hdr: double pointer to a qeth_hdr. When returning with >= 0,
 *	 it contains a valid pointer to a qeth_hdr.
3556 3557 3558
 * @hdr_len: length of the HW header.
 * @proto_len: length of protocol headers that need to be in same page as the
 *	       HW header.
3559 3560 3561 3562
 *
 * Returns the pushed length. If the header can't be pushed on
 * (eg. because it would cross a page boundary), it is allocated from
 * the cache instead and 0 is returned.
3563
 * The number of needed buffer elements is returned in @elements.
3564 3565
 * Error to create the hdr is indicated by returning with < 0.
 */
3566 3567 3568 3569
static int qeth_add_hw_header(struct qeth_qdio_out_q *queue,
			      struct sk_buff *skb, struct qeth_hdr **hdr,
			      unsigned int hdr_len, unsigned int proto_len,
			      unsigned int *elements)
3570
{
3571
	const unsigned int contiguous = proto_len ? proto_len : 1;
3572
	const unsigned int max_elements = queue->max_elements;
3573 3574 3575 3576 3577 3578
	unsigned int __elements;
	addr_t start, end;
	bool push_ok;
	int rc;

check_layout:
3579
	start = (addr_t)skb->data - hdr_len;
3580 3581
	end = (addr_t)skb->data;

3582
	if (qeth_get_elements_for_range(start, end + contiguous) == 1) {
3583 3584
		/* Push HW header into same page as first protocol header. */
		push_ok = true;
3585 3586 3587 3588 3589
		/* ... but TSO always needs a separate element for headers: */
		if (skb_is_gso(skb))
			__elements = 1 + qeth_count_elements(skb, proto_len);
		else
			__elements = qeth_count_elements(skb, 0);
J
Julian Wiedmann 已提交
3590 3591
	} else if (!proto_len && PAGE_ALIGNED(skb->data)) {
		/* Push HW header into preceding page, flush with skb->data. */
3592
		push_ok = true;
3593
		__elements = 1 + qeth_count_elements(skb, 0);
3594 3595 3596 3597
	} else {
		/* Use header cache, copy protocol headers up. */
		push_ok = false;
		__elements = 1 + qeth_count_elements(skb, proto_len);
3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609
	}

	/* Compress skb to fit into one IO buffer: */
	if (__elements > max_elements) {
		if (!skb_is_nonlinear(skb)) {
			/* Drop it, no easy way of shrinking it further. */
			QETH_DBF_MESSAGE(2, "Dropped an oversized skb (Max Elements=%u / Actual=%u / Length=%u).\n",
					 max_elements, __elements, skb->len);
			return -E2BIG;
		}

		rc = skb_linearize(skb);
3610 3611
		if (rc) {
			QETH_TXQ_STAT_INC(queue, skbs_linearized_fail);
3612
			return rc;
3613
		}
3614

3615
		QETH_TXQ_STAT_INC(queue, skbs_linearized);
3616 3617 3618 3619 3620 3621 3622
		/* Linearization changed the layout, re-evaluate: */
		goto check_layout;
	}

	*elements = __elements;
	/* Add the header: */
	if (push_ok) {
3623 3624
		*hdr = skb_push(skb, hdr_len);
		return hdr_len;
3625 3626
	}
	/* fall back */
3627 3628
	if (hdr_len + proto_len > QETH_HDR_CACHE_OBJ_SIZE)
		return -E2BIG;
3629 3630 3631
	*hdr = kmem_cache_alloc(qeth_core_header_cache, GFP_ATOMIC);
	if (!*hdr)
		return -ENOMEM;
3632 3633
	/* Copy protocol headers behind HW header: */
	skb_copy_from_linear_data(skb, ((char *)*hdr) + hdr_len, proto_len);
3634 3635 3636
	return 0;
}

J
Julian Wiedmann 已提交
3637 3638 3639
static void __qeth_fill_buffer(struct sk_buff *skb,
			       struct qeth_qdio_out_buffer *buf,
			       bool is_first_elem, unsigned int offset)
F
Frank Blaschka 已提交
3640
{
3641 3642
	struct qdio_buffer *buffer = buf->buffer;
	int element = buf->next_element_to_fill;
3643 3644
	int length = skb_headlen(skb) - offset;
	char *data = skb->data + offset;
J
Julian Wiedmann 已提交
3645
	unsigned int elem_length, cnt;
F
Frank Blaschka 已提交
3646

3647
	/* map linear part into buffer element(s) */
F
Frank Blaschka 已提交
3648
	while (length > 0) {
J
Julian Wiedmann 已提交
3649 3650
		elem_length = min_t(unsigned int, length,
				    PAGE_SIZE - offset_in_page(data));
F
Frank Blaschka 已提交
3651 3652

		buffer->element[element].addr = data;
J
Julian Wiedmann 已提交
3653 3654
		buffer->element[element].length = elem_length;
		length -= elem_length;
3655 3656
		if (is_first_elem) {
			is_first_elem = false;
3657 3658
			if (length || skb_is_nonlinear(skb))
				/* skb needs additional elements */
3659
				buffer->element[element].eflags =
3660
					SBAL_EFLAGS_FIRST_FRAG;
F
Frank Blaschka 已提交
3661
			else
3662 3663 3664 3665
				buffer->element[element].eflags = 0;
		} else {
			buffer->element[element].eflags =
				SBAL_EFLAGS_MIDDLE_FRAG;
F
Frank Blaschka 已提交
3666
		}
J
Julian Wiedmann 已提交
3667 3668

		data += elem_length;
F
Frank Blaschka 已提交
3669 3670
		element++;
	}
3671

3672
	/* map page frags into buffer element(s) */
3673
	for (cnt = 0; cnt < skb_shinfo(skb)->nr_frags; cnt++) {
3674 3675 3676 3677
		skb_frag_t *frag = &skb_shinfo(skb)->frags[cnt];

		data = skb_frag_address(frag);
		length = skb_frag_size(frag);
3678
		while (length > 0) {
J
Julian Wiedmann 已提交
3679 3680
			elem_length = min_t(unsigned int, length,
					    PAGE_SIZE - offset_in_page(data));
3681 3682

			buffer->element[element].addr = data;
J
Julian Wiedmann 已提交
3683
			buffer->element[element].length = elem_length;
3684 3685
			buffer->element[element].eflags =
				SBAL_EFLAGS_MIDDLE_FRAG;
J
Julian Wiedmann 已提交
3686 3687 3688

			length -= elem_length;
			data += elem_length;
3689 3690
			element++;
		}
3691 3692
	}

3693 3694
	if (buffer->element[element - 1].eflags)
		buffer->element[element - 1].eflags = SBAL_EFLAGS_LAST_FRAG;
3695
	buf->next_element_to_fill = element;
F
Frank Blaschka 已提交
3696 3697
}

3698 3699 3700 3701 3702 3703 3704 3705 3706
/**
 * qeth_fill_buffer() - map skb into an output buffer
 * @queue:	QDIO queue to submit the buffer on
 * @buf:	buffer to transport the skb
 * @skb:	skb to map into the buffer
 * @hdr:	qeth_hdr for this skb. Either at skb->data, or allocated
 *		from qeth_core_header_cache.
 * @offset:	when mapping the skb, start at skb->data + offset
 * @hd_len:	if > 0, build a dedicated header element of this size
3707
 * flush:	Prepare the buffer to be flushed, regardless of its fill level.
3708
 */
J
Julian Wiedmann 已提交
3709 3710 3711
static int qeth_fill_buffer(struct qeth_qdio_out_q *queue,
			    struct qeth_qdio_out_buffer *buf,
			    struct sk_buff *skb, struct qeth_hdr *hdr,
3712 3713
			    unsigned int offset, unsigned int hd_len,
			    bool flush)
F
Frank Blaschka 已提交
3714
{
3715
	struct qdio_buffer *buffer = buf->buffer;
3716
	bool is_first_elem = true;
F
Frank Blaschka 已提交
3717

3718
	__skb_queue_tail(&buf->skb_list, skb);
F
Frank Blaschka 已提交
3719

3720 3721
	/* build dedicated header element */
	if (hd_len) {
3722
		int element = buf->next_element_to_fill;
3723 3724
		is_first_elem = false;

3725
		buffer->element[element].addr = hdr;
3726
		buffer->element[element].length = hd_len;
3727
		buffer->element[element].eflags = SBAL_EFLAGS_FIRST_FRAG;
3728 3729
		/* remember to free cache-allocated qeth_hdr: */
		buf->is_header[element] = ((void *)hdr != skb->data);
3730 3731 3732
		buf->next_element_to_fill++;
	}

3733
	__qeth_fill_buffer(skb, buf, is_first_elem, offset);
F
Frank Blaschka 已提交
3734 3735

	if (!queue->do_pack) {
C
Carsten Otte 已提交
3736
		QETH_CARD_TEXT(queue->card, 6, "fillbfnp");
F
Frank Blaschka 已提交
3737
	} else {
C
Carsten Otte 已提交
3738
		QETH_CARD_TEXT(queue->card, 6, "fillbfpa");
3739

3740
		QETH_TXQ_STAT_INC(queue, skbs_pack);
3741
		/* If the buffer still has free elements, keep using it. */
3742 3743
		if (!flush &&
		    buf->next_element_to_fill < queue->max_elements)
3744
			return 0;
F
Frank Blaschka 已提交
3745
	}
3746 3747 3748 3749 3750 3751

	/* flush out the buffer */
	atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
	queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
				  QDIO_MAX_BUFFERS_PER_Q;
	return 1;
F
Frank Blaschka 已提交
3752 3753
}

J
Julian Wiedmann 已提交
3754 3755 3756
static int qeth_do_send_packet_fast(struct qeth_qdio_out_q *queue,
				    struct sk_buff *skb, struct qeth_hdr *hdr,
				    unsigned int offset, unsigned int hd_len)
F
Frank Blaschka 已提交
3757
{
3758 3759
	int index = queue->next_buf_to_fill;
	struct qeth_qdio_out_buffer *buffer = queue->bufs[index];
3760 3761
	struct netdev_queue *txq;
	bool stopped = false;
F
Frank Blaschka 已提交
3762

3763 3764
	/* Just a sanity check, the wake/stop logic should ensure that we always
	 * get a free buffer.
F
Frank Blaschka 已提交
3765 3766
	 */
	if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
3767
		return -EBUSY;
3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780

	txq = netdev_get_tx_queue(queue->card->dev, skb_get_queue_mapping(skb));

	if (atomic_inc_return(&queue->used_buffers) >= QDIO_MAX_BUFFERS_PER_Q) {
		/* If a TX completion happens right _here_ and misses to wake
		 * the txq, then our re-check below will catch the race.
		 */
		QETH_TXQ_STAT_INC(queue, stopped);
		netif_tx_stop_queue(txq);
		stopped = true;
	}

	qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len, stopped);
F
Frank Blaschka 已提交
3781
	qeth_flush_buffers(queue, index, 1);
3782 3783 3784

	if (stopped && !qeth_out_queue_is_full(queue))
		netif_tx_start_queue(txq);
F
Frank Blaschka 已提交
3785 3786 3787 3788
	return 0;
}

int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
3789
			struct sk_buff *skb, struct qeth_hdr *hdr,
3790 3791
			unsigned int offset, unsigned int hd_len,
			int elements_needed)
F
Frank Blaschka 已提交
3792 3793
{
	struct qeth_qdio_out_buffer *buffer;
3794 3795
	struct netdev_queue *txq;
	bool stopped = false;
F
Frank Blaschka 已提交
3796 3797 3798 3799 3800 3801 3802 3803 3804 3805
	int start_index;
	int flush_count = 0;
	int do_pack = 0;
	int tmp;
	int rc = 0;

	/* spin until we get the queue ... */
	while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED,
			      QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED);
	start_index = queue->next_buf_to_fill;
3806
	buffer = queue->bufs[queue->next_buf_to_fill];
3807 3808 3809

	/* Just a sanity check, the wake/stop logic should ensure that we always
	 * get a free buffer.
F
Frank Blaschka 已提交
3810 3811 3812 3813 3814
	 */
	if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) {
		atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
		return -EBUSY;
	}
3815 3816 3817

	txq = netdev_get_tx_queue(card->dev, skb_get_queue_mapping(skb));

F
Frank Blaschka 已提交
3818 3819 3820 3821
	/* check if we need to switch packing state of this queue */
	qeth_switch_to_packing_if_needed(queue);
	if (queue->do_pack) {
		do_pack = 1;
F
Frank Blaschka 已提交
3822
		/* does packet fit in current buffer? */
3823 3824
		if (buffer->next_element_to_fill + elements_needed >
		    queue->max_elements) {
F
Frank Blaschka 已提交
3825 3826 3827 3828 3829 3830
			/* ... no -> set state PRIMED */
			atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
			flush_count++;
			queue->next_buf_to_fill =
				(queue->next_buf_to_fill + 1) %
				QDIO_MAX_BUFFERS_PER_Q;
3831
			buffer = queue->bufs[queue->next_buf_to_fill];
3832 3833

			/* We stepped forward, so sanity-check again: */
F
Frank Blaschka 已提交
3834 3835 3836
			if (atomic_read(&buffer->state) !=
			    QETH_QDIO_BUF_EMPTY) {
				qeth_flush_buffers(queue, start_index,
J
Jan Glauber 已提交
3837
							   flush_count);
F
Frank Blaschka 已提交
3838
				atomic_set(&queue->state,
F
Frank Blaschka 已提交
3839
						QETH_OUT_Q_UNLOCKED);
3840 3841
				rc = -EBUSY;
				goto out;
F
Frank Blaschka 已提交
3842 3843 3844
			}
		}
	}
3845

3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857
	if (buffer->next_element_to_fill == 0 &&
	    atomic_inc_return(&queue->used_buffers) >= QDIO_MAX_BUFFERS_PER_Q) {
		/* If a TX completion happens right _here_ and misses to wake
		 * the txq, then our re-check below will catch the race.
		 */
		QETH_TXQ_STAT_INC(queue, stopped);
		netif_tx_stop_queue(txq);
		stopped = true;
	}

	flush_count += qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len,
					stopped);
F
Frank Blaschka 已提交
3858
	if (flush_count)
J
Jan Glauber 已提交
3859
		qeth_flush_buffers(queue, start_index, flush_count);
F
Frank Blaschka 已提交
3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870
	else if (!atomic_read(&queue->set_pci_flags_count))
		atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH);
	/*
	 * queue->state will go from LOCKED -> UNLOCKED or from
	 * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us
	 * (switch packing state or flush buffer to get another pci flag out).
	 * In that case we will enter this loop
	 */
	while (atomic_dec_return(&queue->state)) {
		start_index = queue->next_buf_to_fill;
		/* check if we can go back to non-packing state */
3871
		tmp = qeth_switch_to_nonpacking_if_needed(queue);
F
Frank Blaschka 已提交
3872 3873 3874 3875
		/*
		 * check if we need to flush a packing buffer to get a pci
		 * flag out on the queue
		 */
3876 3877 3878 3879 3880 3881
		if (!tmp && !atomic_read(&queue->set_pci_flags_count))
			tmp = qeth_prep_flush_pack_buffer(queue);
		if (tmp) {
			qeth_flush_buffers(queue, start_index, tmp);
			flush_count += tmp;
		}
F
Frank Blaschka 已提交
3882
	}
3883
out:
F
Frank Blaschka 已提交
3884
	/* at this point the queue is UNLOCKED again */
3885 3886
	if (do_pack)
		QETH_TXQ_STAT_ADD(queue, bufs_pack, flush_count);
F
Frank Blaschka 已提交
3887

3888 3889
	if (stopped && !qeth_out_queue_is_full(queue))
		netif_tx_start_queue(txq);
F
Frank Blaschka 已提交
3890 3891 3892 3893
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_do_send_packet);

J
Julian Wiedmann 已提交
3894 3895 3896
static void qeth_fill_tso_ext(struct qeth_hdr_tso *hdr,
			      unsigned int payload_len, struct sk_buff *skb,
			      unsigned int proto_len)
3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909
{
	struct qeth_hdr_ext_tso *ext = &hdr->ext;

	ext->hdr_tot_len = sizeof(*ext);
	ext->imb_hdr_no = 1;
	ext->hdr_type = 1;
	ext->hdr_version = 1;
	ext->hdr_len = 28;
	ext->payload_len = payload_len;
	ext->mss = skb_shinfo(skb)->gso_size;
	ext->dg_hdr_len = proto_len;
}

3910 3911
int qeth_xmit(struct qeth_card *card, struct sk_buff *skb,
	      struct qeth_qdio_out_q *queue, int ipv, int cast_type,
3912 3913 3914
	      void (*fill_header)(struct qeth_qdio_out_q *queue,
				  struct qeth_hdr *hdr, struct sk_buff *skb,
				  int ipv, int cast_type,
3915 3916
				  unsigned int data_len))
{
3917
	unsigned int proto_len, hw_hdr_len;
3918
	unsigned int frame_len = skb->len;
3919
	bool is_tso = skb_is_gso(skb);
3920 3921 3922 3923 3924 3925 3926
	unsigned int data_offset = 0;
	struct qeth_hdr *hdr = NULL;
	unsigned int hd_len = 0;
	unsigned int elements;
	int push_len, rc;
	bool is_sg;

3927 3928 3929 3930 3931
	if (is_tso) {
		hw_hdr_len = sizeof(struct qeth_hdr_tso);
		proto_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
	} else {
		hw_hdr_len = sizeof(struct qeth_hdr);
J
Julian Wiedmann 已提交
3932
		proto_len = (IS_IQD(card) && IS_LAYER2(card)) ? ETH_HLEN : 0;
3933 3934
	}

3935 3936 3937 3938
	rc = skb_cow_head(skb, hw_hdr_len);
	if (rc)
		return rc;

3939
	push_len = qeth_add_hw_header(queue, skb, &hdr, hw_hdr_len, proto_len,
3940 3941 3942
				      &elements);
	if (push_len < 0)
		return push_len;
3943
	if (is_tso || !push_len) {
3944 3945
		/* HW header needs its own buffer element. */
		hd_len = hw_hdr_len + proto_len;
3946
		data_offset = push_len + proto_len;
3947
	}
3948
	memset(hdr, 0, hw_hdr_len);
3949
	fill_header(queue, hdr, skb, ipv, cast_type, frame_len);
3950 3951 3952
	if (is_tso)
		qeth_fill_tso_ext((struct qeth_hdr_tso *) hdr,
				  frame_len - proto_len, skb, proto_len);
3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965

	is_sg = skb_is_nonlinear(skb);
	if (IS_IQD(card)) {
		rc = qeth_do_send_packet_fast(queue, skb, hdr, data_offset,
					      hd_len);
	} else {
		/* TODO: drop skb_orphan() once TX completion is fast enough */
		skb_orphan(skb);
		rc = qeth_do_send_packet(card, queue, skb, hdr, data_offset,
					 hd_len, elements);
	}

	if (!rc) {
3966 3967 3968 3969 3970 3971
		QETH_TXQ_STAT_ADD(queue, buf_elements, elements);
		if (is_sg)
			QETH_TXQ_STAT_INC(queue, skbs_sg);
		if (is_tso) {
			QETH_TXQ_STAT_INC(queue, skbs_tso);
			QETH_TXQ_STAT_ADD(queue, tso_bytes, frame_len);
3972 3973 3974 3975 3976 3977 3978 3979 3980
		}
	} else {
		if (!push_len)
			kmem_cache_free(qeth_core_header_cache, hdr);
	}
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_xmit);

F
Frank Blaschka 已提交
3981 3982 3983
static int qeth_setadp_promisc_mode_cb(struct qeth_card *card,
		struct qeth_reply *reply, unsigned long data)
{
3984
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
F
Frank Blaschka 已提交
3985 3986
	struct qeth_ipacmd_setadpparms *setparms;

C
Carsten Otte 已提交
3987
	QETH_CARD_TEXT(card, 4, "prmadpcb");
F
Frank Blaschka 已提交
3988 3989

	setparms = &(cmd->data.setadapterparms);
3990
	if (qeth_setadpparms_inspect_rc(cmd)) {
3991
		QETH_CARD_TEXT_(card, 4, "prmrc%x", cmd->hdr.return_code);
F
Frank Blaschka 已提交
3992 3993 3994
		setparms->data.mode = SET_PROMISC_MODE_OFF;
	}
	card->info.promisc_mode = setparms->data.mode;
3995
	return (cmd->hdr.return_code) ? -EIO : 0;
F
Frank Blaschka 已提交
3996 3997 3998 3999 4000 4001 4002 4003 4004
}

void qeth_setadp_promisc_mode(struct qeth_card *card)
{
	enum qeth_ipa_promisc_modes mode;
	struct net_device *dev = card->dev;
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

C
Carsten Otte 已提交
4005
	QETH_CARD_TEXT(card, 4, "setprom");
F
Frank Blaschka 已提交
4006 4007 4008 4009 4010 4011 4012 4013 4014

	if (((dev->flags & IFF_PROMISC) &&
	     (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
	    (!(dev->flags & IFF_PROMISC) &&
	     (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
		return;
	mode = SET_PROMISC_MODE_OFF;
	if (dev->flags & IFF_PROMISC)
		mode = SET_PROMISC_MODE_ON;
C
Carsten Otte 已提交
4015
	QETH_CARD_TEXT_(card, 4, "mode:%x", mode);
F
Frank Blaschka 已提交
4016 4017

	iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE,
4018
				   SETADP_DATA_SIZEOF(mode));
4019 4020
	if (!iob)
		return;
4021
	cmd = __ipa_cmd(iob);
F
Frank Blaschka 已提交
4022 4023 4024 4025 4026 4027 4028 4029
	cmd->data.setadapterparms.data.mode = mode;
	qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL);
}
EXPORT_SYMBOL_GPL(qeth_setadp_promisc_mode);

static int qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
		struct qeth_reply *reply, unsigned long data)
{
4030
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
4031
	struct qeth_ipacmd_setadpparms *adp_cmd;
F
Frank Blaschka 已提交
4032

C
Carsten Otte 已提交
4033
	QETH_CARD_TEXT(card, 4, "chgmaccb");
4034
	if (qeth_setadpparms_inspect_rc(cmd))
4035
		return -EIO;
F
Frank Blaschka 已提交
4036

4037
	adp_cmd = &cmd->data.setadapterparms;
4038 4039 4040
	if (!is_valid_ether_addr(adp_cmd->data.change_addr.addr))
		return -EADDRNOTAVAIL;

4041 4042
	if (IS_LAYER2(card) && IS_OSD(card) && !IS_VM_NIC(card) &&
	    !(adp_cmd->hdr.flags & QETH_SETADP_FLAGS_VIRTUAL_MAC))
4043
		return -EADDRNOTAVAIL;
4044 4045

	ether_addr_copy(card->dev->dev_addr, adp_cmd->data.change_addr.addr);
F
Frank Blaschka 已提交
4046 4047 4048 4049 4050 4051 4052 4053 4054
	return 0;
}

int qeth_setadpparms_change_macaddr(struct qeth_card *card)
{
	int rc;
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

C
Carsten Otte 已提交
4055
	QETH_CARD_TEXT(card, 4, "chgmac");
F
Frank Blaschka 已提交
4056 4057

	iob = qeth_get_adapter_cmd(card, IPA_SETADP_ALTER_MAC_ADDRESS,
4058
				   SETADP_DATA_SIZEOF(change_addr));
4059 4060
	if (!iob)
		return -ENOMEM;
4061
	cmd = __ipa_cmd(iob);
F
Frank Blaschka 已提交
4062
	cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC;
4063 4064 4065
	cmd->data.setadapterparms.data.change_addr.addr_size = ETH_ALEN;
	ether_addr_copy(cmd->data.setadapterparms.data.change_addr.addr,
			card->dev->dev_addr);
F
Frank Blaschka 已提交
4066 4067 4068 4069 4070 4071
	rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_change_macaddr_cb,
			       NULL);
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_setadpparms_change_macaddr);

E
Einar Lueck 已提交
4072 4073 4074
static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
		struct qeth_reply *reply, unsigned long data)
{
4075
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
E
Einar Lueck 已提交
4076
	struct qeth_set_access_ctrl *access_ctrl_req;
S
Stefan Raspl 已提交
4077
	int fallback = *(int *)reply->param;
E
Einar Lueck 已提交
4078

C
Carsten Otte 已提交
4079
	QETH_CARD_TEXT(card, 4, "setaccb");
4080
	if (cmd->hdr.return_code)
4081
		return -EIO;
4082
	qeth_setadpparms_inspect_rc(cmd);
E
Einar Lueck 已提交
4083 4084

	access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
4085 4086
	QETH_CARD_TEXT_(card, 2, "rc=%d",
			cmd->data.setadapterparms.hdr.return_code);
S
Stefan Raspl 已提交
4087 4088
	if (cmd->data.setadapterparms.hdr.return_code !=
						SET_ACCESS_CTRL_RC_SUCCESS)
4089 4090 4091
		QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%#x) on device %x: %#x\n",
				 access_ctrl_req->subcmd_code, CARD_DEVID(card),
				 cmd->data.setadapterparms.hdr.return_code);
E
Einar Lueck 已提交
4092 4093 4094 4095 4096 4097 4098 4099 4100 4101
	switch (cmd->data.setadapterparms.hdr.return_code) {
	case SET_ACCESS_CTRL_RC_SUCCESS:
		if (card->options.isolation == ISOLATION_MODE_NONE) {
			dev_info(&card->gdev->dev,
			    "QDIO data connection isolation is deactivated\n");
		} else {
			dev_info(&card->gdev->dev,
			    "QDIO data connection isolation is activated\n");
		}
		break;
S
Stefan Raspl 已提交
4102
	case SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED:
4103 4104
		QETH_DBF_MESSAGE(2, "QDIO data connection isolation on device %x already deactivated\n",
				 CARD_DEVID(card));
S
Stefan Raspl 已提交
4105 4106 4107 4108
		if (fallback)
			card->options.isolation = card->options.prev_isolation;
		break;
	case SET_ACCESS_CTRL_RC_ALREADY_ISOLATED:
4109 4110
		QETH_DBF_MESSAGE(2, "QDIO data connection isolation on device %x already activated\n",
				 CARD_DEVID(card));
S
Stefan Raspl 已提交
4111 4112 4113
		if (fallback)
			card->options.isolation = card->options.prev_isolation;
		break;
E
Einar Lueck 已提交
4114 4115 4116 4117 4118 4119 4120 4121
	case SET_ACCESS_CTRL_RC_NOT_SUPPORTED:
		dev_err(&card->gdev->dev, "Adapter does not "
			"support QDIO data connection isolation\n");
		break;
	case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER:
		dev_err(&card->gdev->dev,
			"Adapter is dedicated. "
			"QDIO data connection isolation not supported\n");
S
Stefan Raspl 已提交
4122 4123
		if (fallback)
			card->options.isolation = card->options.prev_isolation;
E
Einar Lueck 已提交
4124 4125 4126 4127
		break;
	case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF:
		dev_err(&card->gdev->dev,
			"TSO does not permit QDIO data connection isolation\n");
S
Stefan Raspl 已提交
4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145
		if (fallback)
			card->options.isolation = card->options.prev_isolation;
		break;
	case SET_ACCESS_CTRL_RC_REFLREL_UNSUPPORTED:
		dev_err(&card->gdev->dev, "The adjacent switch port does not "
			"support reflective relay mode\n");
		if (fallback)
			card->options.isolation = card->options.prev_isolation;
		break;
	case SET_ACCESS_CTRL_RC_REFLREL_FAILED:
		dev_err(&card->gdev->dev, "The reflective relay mode cannot be "
					"enabled at the adjacent switch port");
		if (fallback)
			card->options.isolation = card->options.prev_isolation;
		break;
	case SET_ACCESS_CTRL_RC_REFLREL_DEACT_FAILED:
		dev_warn(&card->gdev->dev, "Turning off reflective relay mode "
					"at the adjacent switch failed\n");
E
Einar Lueck 已提交
4146 4147 4148
		break;
	default:
		/* this should never happen */
S
Stefan Raspl 已提交
4149 4150
		if (fallback)
			card->options.isolation = card->options.prev_isolation;
E
Einar Lueck 已提交
4151 4152
		break;
	}
4153
	return (cmd->hdr.return_code) ? -EIO : 0;
E
Einar Lueck 已提交
4154 4155 4156
}

static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
S
Stefan Raspl 已提交
4157
		enum qeth_ipa_isolation_modes isolation, int fallback)
E
Einar Lueck 已提交
4158 4159 4160 4161 4162 4163
{
	int rc;
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;
	struct qeth_set_access_ctrl *access_ctrl_req;

C
Carsten Otte 已提交
4164
	QETH_CARD_TEXT(card, 4, "setacctl");
E
Einar Lueck 已提交
4165 4166

	iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL,
4167
				   SETADP_DATA_SIZEOF(set_access_ctrl));
4168 4169
	if (!iob)
		return -ENOMEM;
4170
	cmd = __ipa_cmd(iob);
E
Einar Lueck 已提交
4171 4172 4173 4174
	access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
	access_ctrl_req->subcmd_code = isolation;

	rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_set_access_ctrl_cb,
S
Stefan Raspl 已提交
4175
			       &fallback);
4176
	QETH_CARD_TEXT_(card, 2, "rc=%d", rc);
E
Einar Lueck 已提交
4177 4178 4179
	return rc;
}

S
Stefan Raspl 已提交
4180
int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback)
E
Einar Lueck 已提交
4181 4182 4183
{
	int rc = 0;

C
Carsten Otte 已提交
4184
	QETH_CARD_TEXT(card, 4, "setactlo");
E
Einar Lueck 已提交
4185

4186 4187
	if ((IS_OSD(card) || IS_OSX(card)) &&
	    qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) {
E
Einar Lueck 已提交
4188
		rc = qeth_setadpparms_set_access_ctrl(card,
S
Stefan Raspl 已提交
4189
			card->options.isolation, fallback);
E
Einar Lueck 已提交
4190
		if (rc) {
4191 4192
			QETH_DBF_MESSAGE(3, "IPA(SET_ACCESS_CTRL(%d) on device %x: sent failed\n",
					 rc, CARD_DEVID(card));
S
Stefan Raspl 已提交
4193
			rc = -EOPNOTSUPP;
E
Einar Lueck 已提交
4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205
		}
	} else if (card->options.isolation != ISOLATION_MODE_NONE) {
		card->options.isolation = ISOLATION_MODE_NONE;

		dev_err(&card->gdev->dev, "Adapter does not "
			"support QDIO data connection isolation\n");
		rc = -EOPNOTSUPP;
	}
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_set_access_ctrl_online);

F
Frank Blaschka 已提交
4206 4207 4208 4209
void qeth_tx_timeout(struct net_device *dev)
{
	struct qeth_card *card;

4210
	card = dev->ml_priv;
C
Carsten Otte 已提交
4211
	QETH_CARD_TEXT(card, 4, "txtimeo");
F
Frank Blaschka 已提交
4212 4213 4214 4215
	qeth_schedule_recovery(card);
}
EXPORT_SYMBOL_GPL(qeth_tx_timeout);

4216
static int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
F
Frank Blaschka 已提交
4217
{
4218
	struct qeth_card *card = dev->ml_priv;
F
Frank Blaschka 已提交
4219 4220 4221 4222 4223 4224 4225
	int rc = 0;

	switch (regnum) {
	case MII_BMCR: /* Basic mode control register */
		rc = BMCR_FULLDPLX;
		if ((card->info.link_type != QETH_LINK_TYPE_GBIT_ETH) &&
		    (card->info.link_type != QETH_LINK_TYPE_OSN) &&
4226 4227
		    (card->info.link_type != QETH_LINK_TYPE_10GBIT_ETH) &&
		    (card->info.link_type != QETH_LINK_TYPE_25GBIT_ETH))
F
Frank Blaschka 已提交
4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286
			rc |= BMCR_SPEED100;
		break;
	case MII_BMSR: /* Basic mode status register */
		rc = BMSR_ERCAP | BMSR_ANEGCOMPLETE | BMSR_LSTATUS |
		     BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | BMSR_100FULL |
		     BMSR_100BASE4;
		break;
	case MII_PHYSID1: /* PHYS ID 1 */
		rc = (dev->dev_addr[0] << 16) | (dev->dev_addr[1] << 8) |
		     dev->dev_addr[2];
		rc = (rc >> 5) & 0xFFFF;
		break;
	case MII_PHYSID2: /* PHYS ID 2 */
		rc = (dev->dev_addr[2] << 10) & 0xFFFF;
		break;
	case MII_ADVERTISE: /* Advertisement control reg */
		rc = ADVERTISE_ALL;
		break;
	case MII_LPA: /* Link partner ability reg */
		rc = LPA_10HALF | LPA_10FULL | LPA_100HALF | LPA_100FULL |
		     LPA_100BASE4 | LPA_LPACK;
		break;
	case MII_EXPANSION: /* Expansion register */
		break;
	case MII_DCOUNTER: /* disconnect counter */
		break;
	case MII_FCSCOUNTER: /* false carrier counter */
		break;
	case MII_NWAYTEST: /* N-way auto-neg test register */
		break;
	case MII_RERRCOUNTER: /* rx error counter */
		rc = card->stats.rx_errors;
		break;
	case MII_SREVISION: /* silicon revision */
		break;
	case MII_RESV1: /* reserved 1 */
		break;
	case MII_LBRERROR: /* loopback, rx, bypass error */
		break;
	case MII_PHYADDR: /* physical address */
		break;
	case MII_RESV2: /* reserved 2 */
		break;
	case MII_TPISTATUS: /* TPI status for 10mbps */
		break;
	case MII_NCONFIG: /* network interface config */
		break;
	default:
		break;
	}
	return rc;
}

static int qeth_snmp_command_cb(struct qeth_card *card,
		struct qeth_reply *reply, unsigned long sdata)
{
	struct qeth_ipa_cmd *cmd;
	struct qeth_arp_query_info *qinfo;
	unsigned char *data;
4287
	void *snmp_data;
F
Frank Blaschka 已提交
4288 4289
	__u16 data_len;

C
Carsten Otte 已提交
4290
	QETH_CARD_TEXT(card, 3, "snpcmdcb");
F
Frank Blaschka 已提交
4291 4292 4293 4294 4295 4296

	cmd = (struct qeth_ipa_cmd *) sdata;
	data = (unsigned char *)((char *)cmd - reply->offset);
	qinfo = (struct qeth_arp_query_info *) reply->param;

	if (cmd->hdr.return_code) {
4297
		QETH_CARD_TEXT_(card, 4, "scer1%x", cmd->hdr.return_code);
4298
		return -EIO;
F
Frank Blaschka 已提交
4299 4300 4301 4302
	}
	if (cmd->data.setadapterparms.hdr.return_code) {
		cmd->hdr.return_code =
			cmd->data.setadapterparms.hdr.return_code;
4303
		QETH_CARD_TEXT_(card, 4, "scer2%x", cmd->hdr.return_code);
4304
		return -EIO;
F
Frank Blaschka 已提交
4305 4306
	}
	data_len = *((__u16 *)QETH_IPA_PDU_LEN_PDU1(data));
4307 4308 4309 4310 4311 4312 4313 4314 4315
	if (cmd->data.setadapterparms.hdr.seq_no == 1) {
		snmp_data = &cmd->data.setadapterparms.data.snmp;
		data_len -= offsetof(struct qeth_ipa_cmd,
				     data.setadapterparms.data.snmp);
	} else {
		snmp_data = &cmd->data.setadapterparms.data.snmp.request;
		data_len -= offsetof(struct qeth_ipa_cmd,
				     data.setadapterparms.data.snmp.request);
	}
F
Frank Blaschka 已提交
4316 4317 4318

	/* check if there is enough room in userspace */
	if ((qinfo->udata_len - qinfo->udata_offset) < data_len) {
4319 4320
		QETH_CARD_TEXT_(card, 4, "scer3%i", -ENOSPC);
		return -ENOSPC;
F
Frank Blaschka 已提交
4321
	}
C
Carsten Otte 已提交
4322
	QETH_CARD_TEXT_(card, 4, "snore%i",
F
Frank Blaschka 已提交
4323
		       cmd->data.setadapterparms.hdr.used_total);
C
Carsten Otte 已提交
4324
	QETH_CARD_TEXT_(card, 4, "sseqn%i",
F
Frank Blaschka 已提交
4325 4326
		cmd->data.setadapterparms.hdr.seq_no);
	/*copy entries to user buffer*/
4327
	memcpy(qinfo->udata + qinfo->udata_offset, snmp_data, data_len);
F
Frank Blaschka 已提交
4328
	qinfo->udata_offset += data_len;
4329

F
Frank Blaschka 已提交
4330
	/* check if all replies received ... */
C
Carsten Otte 已提交
4331
		QETH_CARD_TEXT_(card, 4, "srtot%i",
F
Frank Blaschka 已提交
4332
			       cmd->data.setadapterparms.hdr.used_total);
C
Carsten Otte 已提交
4333
		QETH_CARD_TEXT_(card, 4, "srseq%i",
F
Frank Blaschka 已提交
4334 4335 4336 4337 4338 4339 4340
			       cmd->data.setadapterparms.hdr.seq_no);
	if (cmd->data.setadapterparms.hdr.seq_no <
	    cmd->data.setadapterparms.hdr.used_total)
		return 1;
	return 0;
}

4341
static int qeth_snmp_command(struct qeth_card *card, char __user *udata)
F
Frank Blaschka 已提交
4342 4343 4344 4345
{
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;
	struct qeth_snmp_ureq *ureq;
4346
	unsigned int req_len;
F
Frank Blaschka 已提交
4347 4348 4349
	struct qeth_arp_query_info qinfo = {0, };
	int rc = 0;

C
Carsten Otte 已提交
4350
	QETH_CARD_TEXT(card, 3, "snmpcmd");
F
Frank Blaschka 已提交
4351

4352
	if (IS_VM_NIC(card))
F
Frank Blaschka 已提交
4353 4354 4355
		return -EOPNOTSUPP;

	if ((!qeth_adp_supported(card, IPA_SETADP_SET_SNMP_CONTROL)) &&
4356
	    IS_LAYER3(card))
F
Frank Blaschka 已提交
4357
		return -EOPNOTSUPP;
4358

F
Frank Blaschka 已提交
4359 4360 4361
	/* skip 4 bytes (data_len struct member) to get req_len */
	if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int)))
		return -EFAULT;
4362 4363 4364
	if (req_len + offsetof(struct qeth_ipacmd_setadpparms, data) +
	    offsetof(struct qeth_ipa_cmd, data) + IPA_PDU_HEADER_SIZE >
	    QETH_BUFSIZE)
4365
		return -EINVAL;
4366 4367
	ureq = memdup_user(udata, req_len + sizeof(struct qeth_snmp_ureq_hdr));
	if (IS_ERR(ureq)) {
C
Carsten Otte 已提交
4368
		QETH_CARD_TEXT(card, 2, "snmpnome");
4369
		return PTR_ERR(ureq);
F
Frank Blaschka 已提交
4370 4371 4372 4373 4374 4375 4376 4377 4378
	}
	qinfo.udata_len = ureq->hdr.data_len;
	qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL);
	if (!qinfo.udata) {
		kfree(ureq);
		return -ENOMEM;
	}
	qinfo.udata_offset = sizeof(struct qeth_snmp_ureq_hdr);

4379
	iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, req_len);
4380 4381 4382 4383
	if (!iob) {
		rc = -ENOMEM;
		goto out;
	}
4384

4385
	cmd = __ipa_cmd(iob);
F
Frank Blaschka 已提交
4386
	memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len);
4387
	rc = qeth_send_ipa_cmd(card, iob, qeth_snmp_command_cb, &qinfo);
F
Frank Blaschka 已提交
4388
	if (rc)
4389 4390
		QETH_DBF_MESSAGE(2, "SNMP command failed on device %x: (%#x)\n",
				 CARD_DEVID(card), rc);
F
Frank Blaschka 已提交
4391 4392 4393 4394
	else {
		if (copy_to_user(udata, qinfo.udata, qinfo.udata_len))
			rc = -EFAULT;
	}
4395
out:
F
Frank Blaschka 已提交
4396 4397 4398 4399 4400
	kfree(ureq);
	kfree(qinfo.udata);
	return rc;
}

4401 4402 4403
static int qeth_setadpparms_query_oat_cb(struct qeth_card *card,
		struct qeth_reply *reply, unsigned long data)
{
4404
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *)data;
4405 4406 4407 4408 4409
	struct qeth_qoat_priv *priv;
	char *resdata;
	int resdatalen;

	QETH_CARD_TEXT(card, 3, "qoatcb");
4410
	if (qeth_setadpparms_inspect_rc(cmd))
4411
		return -EIO;
4412 4413 4414 4415 4416

	priv = (struct qeth_qoat_priv *)reply->param;
	resdatalen = cmd->data.setadapterparms.hdr.cmdlength;
	resdata = (char *)data + 28;

4417 4418
	if (resdatalen > (priv->buffer_len - priv->response_len))
		return -ENOSPC;
4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429

	memcpy((priv->buffer + priv->response_len), resdata,
		resdatalen);
	priv->response_len += resdatalen;

	if (cmd->data.setadapterparms.hdr.seq_no <
	    cmd->data.setadapterparms.hdr.used_total)
		return 1;
	return 0;
}

4430
static int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454
{
	int rc = 0;
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;
	struct qeth_query_oat *oat_req;
	struct qeth_query_oat_data oat_data;
	struct qeth_qoat_priv priv;
	void __user *tmp;

	QETH_CARD_TEXT(card, 3, "qoatcmd");

	if (!qeth_adp_supported(card, IPA_SETADP_QUERY_OAT)) {
		rc = -EOPNOTSUPP;
		goto out;
	}

	if (copy_from_user(&oat_data, udata,
	    sizeof(struct qeth_query_oat_data))) {
			rc = -EFAULT;
			goto out;
	}

	priv.buffer_len = oat_data.buffer_len;
	priv.response_len = 0;
4455
	priv.buffer = vzalloc(oat_data.buffer_len);
4456 4457 4458 4459 4460 4461
	if (!priv.buffer) {
		rc = -ENOMEM;
		goto out;
	}

	iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT,
4462
				   SETADP_DATA_SIZEOF(query_oat));
4463 4464 4465 4466
	if (!iob) {
		rc = -ENOMEM;
		goto out_free;
	}
4467
	cmd = __ipa_cmd(iob);
4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489
	oat_req = &cmd->data.setadapterparms.data.query_oat;
	oat_req->subcmd_code = oat_data.command;

	rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_query_oat_cb,
			       &priv);
	if (!rc) {
		if (is_compat_task())
			tmp = compat_ptr(oat_data.ptr);
		else
			tmp = (void __user *)(unsigned long)oat_data.ptr;

		if (copy_to_user(tmp, priv.buffer,
		    priv.response_len)) {
			rc = -EFAULT;
			goto out_free;
		}

		oat_data.response_len = priv.response_len;

		if (copy_to_user(udata, &oat_data,
		    sizeof(struct qeth_query_oat_data)))
			rc = -EFAULT;
4490
	}
4491 4492

out_free:
4493
	vfree(priv.buffer);
4494 4495 4496 4497
out:
	return rc;
}

4498 4499
static int qeth_query_card_info_cb(struct qeth_card *card,
				   struct qeth_reply *reply, unsigned long data)
E
Eugene Crosser 已提交
4500
{
4501 4502
	struct carrier_info *carrier_info = (struct carrier_info *)reply->param;
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *)data;
E
Eugene Crosser 已提交
4503 4504 4505
	struct qeth_query_card_info *card_info;

	QETH_CARD_TEXT(card, 2, "qcrdincb");
4506
	if (qeth_setadpparms_inspect_rc(cmd))
4507
		return -EIO;
E
Eugene Crosser 已提交
4508

4509 4510 4511 4512
	card_info = &cmd->data.setadapterparms.data.card_info;
	carrier_info->card_type = card_info->card_type;
	carrier_info->port_mode = card_info->port_mode;
	carrier_info->port_speed = card_info->port_speed;
E
Eugene Crosser 已提交
4513 4514 4515
	return 0;
}

4516 4517
int qeth_query_card_info(struct qeth_card *card,
			 struct carrier_info *carrier_info)
E
Eugene Crosser 已提交
4518 4519 4520 4521 4522 4523
{
	struct qeth_cmd_buffer *iob;

	QETH_CARD_TEXT(card, 2, "qcrdinfo");
	if (!qeth_adp_supported(card, IPA_SETADP_QUERY_CARD_INFO))
		return -EOPNOTSUPP;
4524
	iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_CARD_INFO, 0);
4525 4526
	if (!iob)
		return -ENOMEM;
E
Eugene Crosser 已提交
4527 4528 4529 4530
	return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb,
					(void *)carrier_info);
}

4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545
/**
 * qeth_vm_request_mac() - Request a hypervisor-managed MAC address
 * @card: pointer to a qeth_card
 *
 * Returns
 *	0, if a MAC address has been set for the card's netdevice
 *	a return code, for various error conditions
 */
int qeth_vm_request_mac(struct qeth_card *card)
{
	struct diag26c_mac_resp *response;
	struct diag26c_mac_req *request;
	struct ccw_dev_id id;
	int rc;

4546
	QETH_CARD_TEXT(card, 2, "vmreqmac");
4547 4548 4549 4550 4551 4552 4553 4554

	request = kzalloc(sizeof(*request), GFP_KERNEL | GFP_DMA);
	response = kzalloc(sizeof(*response), GFP_KERNEL | GFP_DMA);
	if (!request || !response) {
		rc = -ENOMEM;
		goto out;
	}

4555
	ccw_device_get_id(CARD_DDEV(card), &id);
4556 4557 4558 4559 4560
	request->resp_buf_len = sizeof(*response);
	request->resp_version = DIAG26C_VERSION2;
	request->op_code = DIAG26C_GET_MAC;
	request->devno = id.devno;

4561
	QETH_DBF_HEX(CTRL, 2, request, sizeof(*request));
4562
	rc = diag26c(request, response, DIAG26C_MAC_SERVICES);
4563
	QETH_DBF_HEX(CTRL, 2, request, sizeof(*request));
4564 4565
	if (rc)
		goto out;
4566
	QETH_DBF_HEX(CTRL, 2, response, sizeof(*response));
4567 4568 4569 4570

	if (request->resp_buf_len < sizeof(*response) ||
	    response->version != request->resp_version) {
		rc = -EIO;
4571 4572 4573
		QETH_CARD_TEXT(card, 2, "badresp");
		QETH_CARD_HEX(card, 2, &request->resp_buf_len,
			      sizeof(request->resp_buf_len));
4574 4575
	} else if (!is_valid_ether_addr(response->mac)) {
		rc = -EINVAL;
4576 4577
		QETH_CARD_TEXT(card, 2, "badmac");
		QETH_CARD_HEX(card, 2, response->mac, ETH_ALEN);
4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588
	} else {
		ether_addr_copy(card->dev->dev_addr, response->mac);
	}

out:
	kfree(response);
	kfree(request);
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_vm_request_mac);

4589 4590 4591 4592 4593 4594
static void qeth_determine_capabilities(struct qeth_card *card)
{
	int rc;
	struct ccw_device *ddev;
	int ddev_offline = 0;

4595
	QETH_CARD_TEXT(card, 2, "detcapab");
4596 4597 4598 4599 4600
	ddev = CARD_DDEV(card);
	if (!ddev->online) {
		ddev_offline = 1;
		rc = ccw_device_set_online(ddev);
		if (rc) {
4601
			QETH_CARD_TEXT_(card, 2, "3err%d", rc);
4602 4603 4604 4605
			goto out;
		}
	}

4606
	rc = qeth_read_conf_data(card);
4607
	if (rc) {
4608 4609
		QETH_DBF_MESSAGE(2, "qeth_read_conf_data on device %x returned %i\n",
				 CARD_DEVID(card), rc);
4610
		QETH_CARD_TEXT_(card, 2, "5err%d", rc);
4611 4612 4613 4614 4615
		goto out_offline;
	}

	rc = qdio_get_ssqd_desc(ddev, &card->ssqd);
	if (rc)
4616
		QETH_CARD_TEXT_(card, 2, "6err%d", rc);
4617

4618 4619 4620 4621 4622
	QETH_CARD_TEXT_(card, 2, "qfmt%d", card->ssqd.qfmt);
	QETH_CARD_TEXT_(card, 2, "ac1:%02x", card->ssqd.qdioac1);
	QETH_CARD_TEXT_(card, 2, "ac2:%04x", card->ssqd.qdioac2);
	QETH_CARD_TEXT_(card, 2, "ac3:%04x", card->ssqd.qdioac3);
	QETH_CARD_TEXT_(card, 2, "icnt%d", card->ssqd.icnt);
4623 4624 4625 4626 4627 4628 4629 4630 4631 4632
	if (!((card->ssqd.qfmt != QDIO_IQDIO_QFMT) ||
	    ((card->ssqd.qdioac1 & CHSC_AC1_INITIATE_INPUTQ) == 0) ||
	    ((card->ssqd.qdioac3 & CHSC_AC3_FORMAT2_CQ_AVAILABLE) == 0))) {
		dev_info(&card->gdev->dev,
			"Completion Queueing supported\n");
	} else {
		card->options.cq = QETH_CQ_NOTAVAILABLE;
	}


4633 4634 4635 4636 4637 4638 4639
out_offline:
	if (ddev_offline == 1)
		ccw_device_set_offline(ddev);
out:
	return;
}

J
Julian Wiedmann 已提交
4640 4641 4642 4643 4644 4645
static void qeth_qdio_establish_cq(struct qeth_card *card,
				   struct qdio_buffer **in_sbal_ptrs,
				   void (**queue_start_poll)
					(struct ccw_device *, int,
					 unsigned long))
{
4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659
	int i;

	if (card->options.cq == QETH_CQ_ENABLED) {
		int offset = QDIO_MAX_BUFFERS_PER_Q *
			     (card->qdio.no_in_queues - 1);
		for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) {
			in_sbal_ptrs[offset + i] = (struct qdio_buffer *)
				virt_to_phys(card->qdio.c_q->bufs[i].buffer);
		}

		queue_start_poll[card->qdio.no_in_queues - 1] = NULL;
	}
}

F
Frank Blaschka 已提交
4660 4661 4662 4663 4664
static int qeth_qdio_establish(struct qeth_card *card)
{
	struct qdio_initialize init_data;
	char *qib_param_field;
	struct qdio_buffer **in_sbal_ptrs;
4665
	void (**queue_start_poll) (struct ccw_device *, int, unsigned long);
F
Frank Blaschka 已提交
4666 4667 4668 4669
	struct qdio_buffer **out_sbal_ptrs;
	int i, j, k;
	int rc = 0;

4670
	QETH_CARD_TEXT(card, 2, "qdioest");
F
Frank Blaschka 已提交
4671

K
Kees Cook 已提交
4672 4673
	qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q,
				  GFP_KERNEL);
4674 4675 4676 4677
	if (!qib_param_field) {
		rc =  -ENOMEM;
		goto out_free_nothing;
	}
F
Frank Blaschka 已提交
4678 4679 4680 4681

	qeth_create_qib_param_field(card, qib_param_field);
	qeth_create_qib_param_field_blkt(card, qib_param_field);

K
Kees Cook 已提交
4682 4683
	in_sbal_ptrs = kcalloc(card->qdio.no_in_queues * QDIO_MAX_BUFFERS_PER_Q,
			       sizeof(void *),
F
Frank Blaschka 已提交
4684 4685
			       GFP_KERNEL);
	if (!in_sbal_ptrs) {
4686 4687
		rc = -ENOMEM;
		goto out_free_qib_param;
F
Frank Blaschka 已提交
4688
	}
4689
	for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) {
F
Frank Blaschka 已提交
4690 4691
		in_sbal_ptrs[i] = (struct qdio_buffer *)
			virt_to_phys(card->qdio.in_q->bufs[i].buffer);
4692
	}
F
Frank Blaschka 已提交
4693

K
Kees Cook 已提交
4694
	queue_start_poll = kcalloc(card->qdio.no_in_queues, sizeof(void *),
4695
				   GFP_KERNEL);
4696 4697 4698 4699
	if (!queue_start_poll) {
		rc = -ENOMEM;
		goto out_free_in_sbals;
	}
4700
	for (i = 0; i < card->qdio.no_in_queues; ++i)
4701
		queue_start_poll[i] = qeth_qdio_start_poll;
4702 4703

	qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll);
4704

F
Frank Blaschka 已提交
4705
	out_sbal_ptrs =
K
Kees Cook 已提交
4706 4707 4708
		kcalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q,
			sizeof(void *),
			GFP_KERNEL);
F
Frank Blaschka 已提交
4709
	if (!out_sbal_ptrs) {
4710 4711
		rc = -ENOMEM;
		goto out_free_queue_start_poll;
F
Frank Blaschka 已提交
4712 4713 4714 4715
	}
	for (i = 0, k = 0; i < card->qdio.no_out_queues; ++i)
		for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j, ++k) {
			out_sbal_ptrs[k] = (struct qdio_buffer *)virt_to_phys(
4716
				card->qdio.out_qs[i]->bufs[j]->buffer);
F
Frank Blaschka 已提交
4717 4718 4719 4720
		}

	memset(&init_data, 0, sizeof(struct qdio_initialize));
	init_data.cdev                   = CARD_DDEV(card);
4721 4722
	init_data.q_format		 = IS_IQD(card) ? QDIO_IQDIO_QFMT :
							  QDIO_QETH_QFMT;
F
Frank Blaschka 已提交
4723 4724
	init_data.qib_param_field_format = 0;
	init_data.qib_param_field        = qib_param_field;
4725
	init_data.no_input_qs            = card->qdio.no_in_queues;
F
Frank Blaschka 已提交
4726
	init_data.no_output_qs           = card->qdio.no_out_queues;
4727 4728
	init_data.input_handler		 = qeth_qdio_input_handler;
	init_data.output_handler	 = qeth_qdio_output_handler;
4729
	init_data.queue_start_poll_array = queue_start_poll;
F
Frank Blaschka 已提交
4730
	init_data.int_parm               = (unsigned long) card;
4731 4732
	init_data.input_sbal_addr_array  = in_sbal_ptrs;
	init_data.output_sbal_addr_array = out_sbal_ptrs;
4733
	init_data.output_sbal_state_array = card->qdio.out_bufstates;
4734
	init_data.scan_threshold	 = IS_IQD(card) ? 1 : 32;
F
Frank Blaschka 已提交
4735 4736 4737

	if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
		QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) {
J
Jan Glauber 已提交
4738 4739 4740 4741 4742 4743 4744
		rc = qdio_allocate(&init_data);
		if (rc) {
			atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
			goto out;
		}
		rc = qdio_establish(&init_data);
		if (rc) {
F
Frank Blaschka 已提交
4745
			atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
J
Jan Glauber 已提交
4746 4747
			qdio_free(CARD_DDEV(card));
		}
F
Frank Blaschka 已提交
4748
	}
4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759

	switch (card->options.cq) {
	case QETH_CQ_ENABLED:
		dev_info(&card->gdev->dev, "Completion Queue support enabled");
		break;
	case QETH_CQ_DISABLED:
		dev_info(&card->gdev->dev, "Completion Queue support disabled");
		break;
	default:
		break;
	}
J
Jan Glauber 已提交
4760
out:
F
Frank Blaschka 已提交
4761
	kfree(out_sbal_ptrs);
4762 4763 4764
out_free_queue_start_poll:
	kfree(queue_start_poll);
out_free_in_sbals:
F
Frank Blaschka 已提交
4765
	kfree(in_sbal_ptrs);
4766
out_free_qib_param:
F
Frank Blaschka 已提交
4767
	kfree(qib_param_field);
4768
out_free_nothing:
F
Frank Blaschka 已提交
4769 4770 4771 4772 4773
	return rc;
}

static void qeth_core_free_card(struct qeth_card *card)
{
4774
	QETH_CARD_TEXT(card, 2, "freecrd");
F
Frank Blaschka 已提交
4775 4776
	qeth_clean_channel(&card->read);
	qeth_clean_channel(&card->write);
4777
	qeth_clean_channel(&card->data);
4778
	qeth_put_cmd(card->read_cmd);
4779
	destroy_workqueue(card->event_wq);
4780
	qeth_free_qdio_queues(card);
4781
	unregister_service_level(&card->qeth_service_level);
4782
	dev_set_drvdata(&card->gdev->dev, NULL);
F
Frank Blaschka 已提交
4783 4784 4785
	kfree(card);
}

4786 4787 4788
void qeth_trace_features(struct qeth_card *card)
{
	QETH_CARD_TEXT(card, 2, "features");
4789 4790 4791 4792 4793
	QETH_CARD_HEX(card, 2, &card->options.ipa4, sizeof(card->options.ipa4));
	QETH_CARD_HEX(card, 2, &card->options.ipa6, sizeof(card->options.ipa6));
	QETH_CARD_HEX(card, 2, &card->options.adp, sizeof(card->options.adp));
	QETH_CARD_HEX(card, 2, &card->info.diagass_support,
		      sizeof(card->info.diagass_support));
4794 4795 4796
}
EXPORT_SYMBOL_GPL(qeth_trace_features);

F
Frank Blaschka 已提交
4797
static struct ccw_device_id qeth_ids[] = {
4798 4799 4800 4801 4802 4803 4804 4805 4806 4807
	{CCW_DEVICE_DEVTYPE(0x1731, 0x01, 0x1732, 0x01),
					.driver_info = QETH_CARD_TYPE_OSD},
	{CCW_DEVICE_DEVTYPE(0x1731, 0x05, 0x1732, 0x05),
					.driver_info = QETH_CARD_TYPE_IQD},
	{CCW_DEVICE_DEVTYPE(0x1731, 0x06, 0x1732, 0x06),
					.driver_info = QETH_CARD_TYPE_OSN},
	{CCW_DEVICE_DEVTYPE(0x1731, 0x02, 0x1732, 0x03),
					.driver_info = QETH_CARD_TYPE_OSM},
	{CCW_DEVICE_DEVTYPE(0x1731, 0x02, 0x1732, 0x02),
					.driver_info = QETH_CARD_TYPE_OSX},
F
Frank Blaschka 已提交
4808 4809 4810 4811 4812
	{},
};
MODULE_DEVICE_TABLE(ccw, qeth_ids);

static struct ccw_driver qeth_ccw_driver = {
4813
	.driver = {
S
Sebastian Ott 已提交
4814
		.owner = THIS_MODULE,
4815 4816
		.name = "qeth",
	},
F
Frank Blaschka 已提交
4817 4818 4819 4820 4821
	.ids = qeth_ids,
	.probe = ccwgroup_probe_ccwdev,
	.remove = ccwgroup_remove_ccwdev,
};

J
Julian Wiedmann 已提交
4822
int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok)
F
Frank Blaschka 已提交
4823
{
4824
	int retries = 3;
F
Frank Blaschka 已提交
4825 4826
	int rc;

4827
	QETH_CARD_TEXT(card, 2, "hrdsetup");
F
Frank Blaschka 已提交
4828
	atomic_set(&card->force_alloc_skb, 0);
4829 4830 4831
	rc = qeth_update_from_chp_desc(card);
	if (rc)
		return rc;
F
Frank Blaschka 已提交
4832
retry:
4833
	if (retries < 3)
4834 4835
		QETH_DBF_MESSAGE(2, "Retrying to do IDX activates on device %x.\n",
				 CARD_DEVID(card));
4836
	rc = qeth_qdio_clear_card(card, !IS_IQD(card));
4837 4838 4839
	ccw_device_set_offline(CARD_DDEV(card));
	ccw_device_set_offline(CARD_WDEV(card));
	ccw_device_set_offline(CARD_RDEV(card));
4840
	qdio_free(CARD_DDEV(card));
4841 4842 4843 4844 4845 4846 4847 4848 4849 4850
	rc = ccw_device_set_online(CARD_RDEV(card));
	if (rc)
		goto retriable;
	rc = ccw_device_set_online(CARD_WDEV(card));
	if (rc)
		goto retriable;
	rc = ccw_device_set_online(CARD_DDEV(card));
	if (rc)
		goto retriable;
retriable:
F
Frank Blaschka 已提交
4851
	if (rc == -ERESTARTSYS) {
4852
		QETH_CARD_TEXT(card, 2, "break1");
F
Frank Blaschka 已提交
4853 4854
		return rc;
	} else if (rc) {
4855
		QETH_CARD_TEXT_(card, 2, "1err%d", rc);
4856
		if (--retries < 0)
F
Frank Blaschka 已提交
4857 4858 4859 4860
			goto out;
		else
			goto retry;
	}
4861
	qeth_determine_capabilities(card);
F
Frank Blaschka 已提交
4862 4863
	qeth_init_tokens(card);
	qeth_init_func_level(card);
4864 4865 4866

	rc = qeth_idx_activate_read_channel(card);
	if (rc == -EINTR) {
4867
		QETH_CARD_TEXT(card, 2, "break2");
F
Frank Blaschka 已提交
4868 4869
		return rc;
	} else if (rc) {
4870
		QETH_CARD_TEXT_(card, 2, "3err%d", rc);
F
Frank Blaschka 已提交
4871 4872 4873 4874 4875
		if (--retries < 0)
			goto out;
		else
			goto retry;
	}
4876 4877 4878

	rc = qeth_idx_activate_write_channel(card);
	if (rc == -EINTR) {
4879
		QETH_CARD_TEXT(card, 2, "break3");
F
Frank Blaschka 已提交
4880 4881
		return rc;
	} else if (rc) {
4882
		QETH_CARD_TEXT_(card, 2, "4err%d", rc);
F
Frank Blaschka 已提交
4883 4884 4885 4886 4887
		if (--retries < 0)
			goto out;
		else
			goto retry;
	}
4888
	card->read_or_write_problem = 0;
F
Frank Blaschka 已提交
4889 4890
	rc = qeth_mpc_initialize(card);
	if (rc) {
4891
		QETH_CARD_TEXT_(card, 2, "5err%d", rc);
F
Frank Blaschka 已提交
4892 4893
		goto out;
	}
4894

4895 4896
	rc = qeth_send_startlan(card);
	if (rc) {
4897
		QETH_CARD_TEXT_(card, 2, "6err%d", rc);
4898 4899
		if (rc == -ENETDOWN) {
			dev_warn(&card->gdev->dev, "The LAN is offline\n");
J
Julian Wiedmann 已提交
4900
			*carrier_ok = false;
4901 4902 4903
		} else {
			goto out;
		}
4904
	} else {
J
Julian Wiedmann 已提交
4905 4906 4907
		*carrier_ok = true;
	}

4908
	card->options.ipa4.supported_funcs = 0;
4909
	card->options.ipa6.supported_funcs = 0;
4910
	card->options.adp.supported_funcs = 0;
4911
	card->options.sbp.supported_funcs = 0;
4912
	card->info.diagass_support = 0;
4913 4914 4915
	rc = qeth_query_ipassists(card, QETH_PROT_IPV4);
	if (rc == -ENOMEM)
		goto out;
4916 4917 4918 4919 4920
	if (qeth_is_supported(card, IPA_IPV6)) {
		rc = qeth_query_ipassists(card, QETH_PROT_IPV6);
		if (rc == -ENOMEM)
			goto out;
	}
4921 4922 4923
	if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) {
		rc = qeth_query_setadapterparms(card);
		if (rc < 0) {
4924
			QETH_CARD_TEXT_(card, 2, "7err%d", rc);
4925 4926 4927 4928 4929 4930
			goto out;
		}
	}
	if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) {
		rc = qeth_query_setdiagass(card);
		if (rc < 0) {
4931
			QETH_CARD_TEXT_(card, 2, "8err%d", rc);
4932 4933 4934
			goto out;
		}
	}
F
Frank Blaschka 已提交
4935 4936
	return 0;
out:
4937 4938
	dev_warn(&card->gdev->dev, "The qeth device driver failed to recover "
		"an error on the device\n");
4939 4940
	QETH_DBF_MESSAGE(2, "Initialization for device %x failed in hardsetup! rc=%d\n",
			 CARD_DEVID(card), rc);
F
Frank Blaschka 已提交
4941 4942 4943 4944
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_core_hardsetup_card);

4945 4946
static void qeth_create_skb_frag(struct qdio_buffer_element *element,
				 struct sk_buff *skb, int offset, int data_len)
F
Frank Blaschka 已提交
4947 4948
{
	struct page *page = virt_to_page(element->addr);
4949
	unsigned int next_frag;
4950

4951 4952 4953
	/* first fill the linear space */
	if (!skb->len) {
		unsigned int linear = min(data_len, skb_tailroom(skb));
4954

4955 4956 4957 4958 4959 4960
		skb_put_data(skb, element->addr + offset, linear);
		data_len -= linear;
		if (!data_len)
			return;
		offset += linear;
		/* fall through to add page frag for remaining data */
F
Frank Blaschka 已提交
4961
	}
4962

4963
	next_frag = skb_shinfo(skb)->nr_frags;
4964
	get_page(page);
4965
	skb_add_rx_frag(skb, next_frag, page, offset, data_len, data_len);
F
Frank Blaschka 已提交
4966 4967
}

4968 4969 4970 4971 4972
static inline int qeth_is_last_sbale(struct qdio_buffer_element *sbale)
{
	return (sbale->eflags & SBAL_EFLAGS_LAST_ENTRY);
}

F
Frank Blaschka 已提交
4973
struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
4974
		struct qeth_qdio_buffer *qethbuffer,
F
Frank Blaschka 已提交
4975 4976 4977 4978
		struct qdio_buffer_element **__element, int *__offset,
		struct qeth_hdr **hdr)
{
	struct qdio_buffer_element *element = *__element;
4979
	struct qdio_buffer *buffer = qethbuffer->buffer;
F
Frank Blaschka 已提交
4980
	int offset = *__offset;
4981
	struct sk_buff *skb;
4982
	int skb_len = 0;
F
Frank Blaschka 已提交
4983 4984 4985 4986 4987 4988
	void *data_ptr;
	int data_len;
	int headroom = 0;
	int use_rx_sg = 0;

	/* qeth_hdr must not cross element boundaries */
4989
	while (element->length < offset + sizeof(struct qeth_hdr)) {
F
Frank Blaschka 已提交
4990 4991 4992 4993 4994 4995 4996 4997
		if (qeth_is_last_sbale(element))
			return NULL;
		element++;
		offset = 0;
	}
	*hdr = element->addr + offset;

	offset += sizeof(struct qeth_hdr);
4998 4999 5000 5001 5002
	switch ((*hdr)->hdr.l2.id) {
	case QETH_HEADER_TYPE_LAYER2:
		skb_len = (*hdr)->hdr.l2.pkt_length;
		break;
	case QETH_HEADER_TYPE_LAYER3:
F
Frank Blaschka 已提交
5003
		skb_len = (*hdr)->hdr.l3.length;
5004
		headroom = ETH_HLEN;
5005 5006 5007 5008 5009 5010 5011
		break;
	case QETH_HEADER_TYPE_OSN:
		skb_len = (*hdr)->hdr.osn.pdu_length;
		headroom = sizeof(struct qeth_hdr);
		break;
	default:
		break;
F
Frank Blaschka 已提交
5012 5013 5014 5015 5016
	}

	if (!skb_len)
		return NULL;

5017
	if (((skb_len >= card->options.rx_sg_cb) &&
5018
	     !IS_OSN(card) &&
5019
	     (!atomic_read(&card->force_alloc_skb))) ||
5020
	    (card->options.cq == QETH_CQ_ENABLED))
F
Frank Blaschka 已提交
5021
		use_rx_sg = 1;
5022 5023 5024 5025 5026

	if (use_rx_sg && qethbuffer->rx_skb) {
		/* QETH_CQ_ENABLED only: */
		skb = qethbuffer->rx_skb;
		qethbuffer->rx_skb = NULL;
F
Frank Blaschka 已提交
5027
	} else {
5028 5029
		unsigned int linear = (use_rx_sg) ? QETH_RX_PULL_LEN : skb_len;

5030
		skb = napi_alloc_skb(&card->napi, linear + headroom);
F
Frank Blaschka 已提交
5031
	}
5032 5033 5034 5035
	if (!skb)
		goto no_mem;
	if (headroom)
		skb_reserve(skb, headroom);
F
Frank Blaschka 已提交
5036 5037 5038 5039 5040

	data_ptr = element->addr + offset;
	while (skb_len) {
		data_len = min(skb_len, (int)(element->length - offset));
		if (data_len) {
5041 5042 5043 5044
			if (use_rx_sg)
				qeth_create_skb_frag(element, skb, offset,
						     data_len);
			else
5045
				skb_put_data(skb, data_ptr, data_len);
F
Frank Blaschka 已提交
5046 5047 5048 5049
		}
		skb_len -= data_len;
		if (skb_len) {
			if (qeth_is_last_sbale(element)) {
C
Carsten Otte 已提交
5050
				QETH_CARD_TEXT(card, 4, "unexeob");
C
Carsten Otte 已提交
5051
				QETH_CARD_HEX(card, 2, buffer, sizeof(void *));
F
Frank Blaschka 已提交
5052
				dev_kfree_skb_any(skb);
5053
				QETH_CARD_STAT_INC(card, rx_errors);
F
Frank Blaschka 已提交
5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064
				return NULL;
			}
			element++;
			offset = 0;
			data_ptr = element->addr;
		} else {
			offset += data_len;
		}
	}
	*__element = element;
	*__offset = offset;
5065 5066 5067 5068
	if (use_rx_sg) {
		QETH_CARD_STAT_INC(card, rx_sg_skbs);
		QETH_CARD_STAT_ADD(card, rx_sg_frags,
				   skb_shinfo(skb)->nr_frags);
F
Frank Blaschka 已提交
5069 5070 5071 5072
	}
	return skb;
no_mem:
	if (net_ratelimit()) {
C
Carsten Otte 已提交
5073
		QETH_CARD_TEXT(card, 2, "noskbmem");
F
Frank Blaschka 已提交
5074
	}
5075
	QETH_CARD_STAT_INC(card, rx_dropped);
F
Frank Blaschka 已提交
5076 5077 5078 5079
	return NULL;
}
EXPORT_SYMBOL_GPL(qeth_core_get_next_skb);

5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115
int qeth_poll(struct napi_struct *napi, int budget)
{
	struct qeth_card *card = container_of(napi, struct qeth_card, napi);
	int work_done = 0;
	struct qeth_qdio_buffer *buffer;
	int done;
	int new_budget = budget;

	while (1) {
		if (!card->rx.b_count) {
			card->rx.qdio_err = 0;
			card->rx.b_count = qdio_get_next_buffers(
				card->data.ccwdev, 0, &card->rx.b_index,
				&card->rx.qdio_err);
			if (card->rx.b_count <= 0) {
				card->rx.b_count = 0;
				break;
			}
			card->rx.b_element =
				&card->qdio.in_q->bufs[card->rx.b_index]
				.buffer->element[0];
			card->rx.e_offset = 0;
		}

		while (card->rx.b_count) {
			buffer = &card->qdio.in_q->bufs[card->rx.b_index];
			if (!(card->rx.qdio_err &&
			    qeth_check_qdio_errors(card, buffer->buffer,
			    card->rx.qdio_err, "qinerr")))
				work_done +=
					card->discipline->process_rx_buffer(
						card, new_budget, &done);
			else
				done = 1;

			if (done) {
5116
				QETH_CARD_STAT_INC(card, rx_bufs);
5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139
				qeth_put_buffer_pool_entry(card,
					buffer->pool_entry);
				qeth_queue_input_buffer(card, card->rx.b_index);
				card->rx.b_count--;
				if (card->rx.b_count) {
					card->rx.b_index =
						(card->rx.b_index + 1) %
						QDIO_MAX_BUFFERS_PER_Q;
					card->rx.b_element =
						&card->qdio.in_q
						->bufs[card->rx.b_index]
						.buffer->element[0];
					card->rx.e_offset = 0;
				}
			}

			if (work_done >= budget)
				goto out;
			else
				new_budget = budget - work_done;
		}
	}

5140
	napi_complete_done(napi, work_done);
5141 5142 5143 5144 5145 5146 5147
	if (qdio_start_irq(card->data.ccwdev, 0))
		napi_schedule(&card->napi);
out:
	return work_done;
}
EXPORT_SYMBOL_GPL(qeth_poll);

5148 5149 5150 5151 5152 5153 5154
static int qeth_setassparms_inspect_rc(struct qeth_ipa_cmd *cmd)
{
	if (!cmd->hdr.return_code)
		cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code;
	return cmd->hdr.return_code;
}

5155 5156 5157 5158 5159 5160 5161 5162
static int qeth_setassparms_get_caps_cb(struct qeth_card *card,
					struct qeth_reply *reply,
					unsigned long data)
{
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
	struct qeth_ipa_caps *caps = reply->param;

	if (qeth_setassparms_inspect_rc(cmd))
5163
		return -EIO;
5164 5165 5166 5167 5168 5169

	caps->supported = cmd->data.setassparms.data.caps.supported;
	caps->enabled = cmd->data.setassparms.data.caps.enabled;
	return 0;
}

5170 5171
int qeth_setassparms_cb(struct qeth_card *card,
			struct qeth_reply *reply, unsigned long data)
5172
{
5173
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
5174 5175 5176

	QETH_CARD_TEXT(card, 4, "defadpcb");

5177 5178 5179 5180 5181 5182 5183 5184
	if (cmd->hdr.return_code)
		return -EIO;

	cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code;
	if (cmd->hdr.prot_version == QETH_PROT_IPV4)
		card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
	if (cmd->hdr.prot_version == QETH_PROT_IPV6)
		card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
5185 5186
	return 0;
}
5187
EXPORT_SYMBOL_GPL(qeth_setassparms_cb);
5188

5189 5190
struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card,
						 enum qeth_ipa_funcs ipa_func,
5191 5192
						 u16 cmd_code,
						 unsigned int data_length,
5193
						 enum qeth_prot_versions prot)
5194
{
5195 5196
	struct qeth_ipacmd_setassparms *setassparms;
	struct qeth_ipacmd_setassparms_hdr *hdr;
5197 5198 5199
	struct qeth_cmd_buffer *iob;

	QETH_CARD_TEXT(card, 4, "getasscm");
5200 5201 5202 5203 5204 5205
	iob = qeth_ipa_alloc_cmd(card, IPA_CMD_SETASSPARMS, prot,
				 data_length +
				 offsetof(struct qeth_ipacmd_setassparms,
					  data));
	if (!iob)
		return NULL;
5206

5207 5208
	setassparms = &__ipa_cmd(iob)->data.setassparms;
	setassparms->assist_no = ipa_func;
5209

5210 5211 5212
	hdr = &setassparms->hdr;
	hdr->length = sizeof(*hdr) + data_length;
	hdr->command_code = cmd_code;
5213 5214
	return iob;
}
5215
EXPORT_SYMBOL_GPL(qeth_get_setassparms_cmd);
5216

5217 5218
int qeth_send_simple_setassparms_prot(struct qeth_card *card,
				      enum qeth_ipa_funcs ipa_func,
5219
				      u16 cmd_code, u32 *data,
5220
				      enum qeth_prot_versions prot)
5221
{
5222
	unsigned int length = data ? SETASS_DATA_SIZEOF(flags_32bit) : 0;
5223 5224
	struct qeth_cmd_buffer *iob;

5225 5226
	QETH_CARD_TEXT_(card, 4, "simassp%i", prot);
	iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code, length, prot);
5227 5228
	if (!iob)
		return -ENOMEM;
5229

5230 5231
	if (data)
		__ipa_cmd(iob)->data.setassparms.data.flags_32bit = *data;
5232
	return qeth_send_ipa_cmd(card, iob, qeth_setassparms_cb, NULL);
5233
}
5234
EXPORT_SYMBOL_GPL(qeth_send_simple_setassparms_prot);
5235

F
Frank Blaschka 已提交
5236 5237
static void qeth_unregister_dbf_views(void)
{
5238 5239 5240 5241 5242
	int x;
	for (x = 0; x < QETH_DBF_INFOS; x++) {
		debug_unregister(qeth_dbf[x].id);
		qeth_dbf[x].id = NULL;
	}
F
Frank Blaschka 已提交
5243 5244
}

C
Carsten Otte 已提交
5245
void qeth_dbf_longtext(debug_info_t *id, int level, char *fmt, ...)
P
Peter Tiedemann 已提交
5246 5247
{
	char dbf_txt_buf[32];
5248
	va_list args;
P
Peter Tiedemann 已提交
5249

5250
	if (!debug_level_enabled(id, level))
P
Peter Tiedemann 已提交
5251
		return;
5252 5253 5254
	va_start(args, fmt);
	vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args);
	va_end(args);
C
Carsten Otte 已提交
5255
	debug_text_event(id, level, dbf_txt_buf);
P
Peter Tiedemann 已提交
5256 5257 5258
}
EXPORT_SYMBOL_GPL(qeth_dbf_longtext);

F
Frank Blaschka 已提交
5259 5260
static int qeth_register_dbf_views(void)
{
5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273
	int ret;
	int x;

	for (x = 0; x < QETH_DBF_INFOS; x++) {
		/* register the areas */
		qeth_dbf[x].id = debug_register(qeth_dbf[x].name,
						qeth_dbf[x].pages,
						qeth_dbf[x].areas,
						qeth_dbf[x].len);
		if (qeth_dbf[x].id == NULL) {
			qeth_unregister_dbf_views();
			return -ENOMEM;
		}
F
Frank Blaschka 已提交
5274

5275 5276 5277 5278 5279 5280
		/* register a view */
		ret = debug_register_view(qeth_dbf[x].id, qeth_dbf[x].view);
		if (ret) {
			qeth_unregister_dbf_views();
			return ret;
		}
F
Frank Blaschka 已提交
5281

5282 5283 5284
		/* set a passing level */
		debug_set_level(qeth_dbf[x].id, qeth_dbf[x].level);
	}
F
Frank Blaschka 已提交
5285 5286 5287 5288

	return 0;
}

5289 5290
static DEFINE_MUTEX(qeth_mod_mutex);	/* for synchronized module loading */

F
Frank Blaschka 已提交
5291 5292 5293
int qeth_core_load_discipline(struct qeth_card *card,
		enum qeth_discipline_id discipline)
{
5294
	mutex_lock(&qeth_mod_mutex);
F
Frank Blaschka 已提交
5295 5296
	switch (discipline) {
	case QETH_DISCIPLINE_LAYER3:
5297 5298
		card->discipline = try_then_request_module(
			symbol_get(qeth_l3_discipline), "qeth_l3");
F
Frank Blaschka 已提交
5299 5300
		break;
	case QETH_DISCIPLINE_LAYER2:
5301 5302
		card->discipline = try_then_request_module(
			symbol_get(qeth_l2_discipline), "qeth_l2");
F
Frank Blaschka 已提交
5303
		break;
5304 5305
	default:
		break;
F
Frank Blaschka 已提交
5306
	}
5307
	mutex_unlock(&qeth_mod_mutex);
5308

5309
	if (!card->discipline) {
5310 5311
		dev_err(&card->gdev->dev, "There is no kernel module to "
			"support discipline %d\n", discipline);
5312
		return -EINVAL;
F
Frank Blaschka 已提交
5313
	}
5314

5315
	card->options.layer = discipline;
5316
	return 0;
F
Frank Blaschka 已提交
5317 5318 5319 5320
}

void qeth_core_free_discipline(struct qeth_card *card)
{
5321
	if (IS_LAYER2(card))
5322
		symbol_put(qeth_l2_discipline);
F
Frank Blaschka 已提交
5323
	else
5324
		symbol_put(qeth_l3_discipline);
5325
	card->options.layer = QETH_DISCIPLINE_UNDETERMINED;
5326
	card->discipline = NULL;
F
Frank Blaschka 已提交
5327 5328
}

5329
const struct device_type qeth_generic_devtype = {
5330 5331 5332
	.name = "qeth_generic",
	.groups = qeth_generic_attr_groups,
};
5333 5334
EXPORT_SYMBOL_GPL(qeth_generic_devtype);

5335 5336 5337 5338 5339
static const struct device_type qeth_osn_devtype = {
	.name = "qeth_osn",
	.groups = qeth_osn_attr_groups,
};

5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407
#define DBF_NAME_LEN	20

struct qeth_dbf_entry {
	char dbf_name[DBF_NAME_LEN];
	debug_info_t *dbf_info;
	struct list_head dbf_list;
};

static LIST_HEAD(qeth_dbf_list);
static DEFINE_MUTEX(qeth_dbf_list_mutex);

static debug_info_t *qeth_get_dbf_entry(char *name)
{
	struct qeth_dbf_entry *entry;
	debug_info_t *rc = NULL;

	mutex_lock(&qeth_dbf_list_mutex);
	list_for_each_entry(entry, &qeth_dbf_list, dbf_list) {
		if (strcmp(entry->dbf_name, name) == 0) {
			rc = entry->dbf_info;
			break;
		}
	}
	mutex_unlock(&qeth_dbf_list_mutex);
	return rc;
}

static int qeth_add_dbf_entry(struct qeth_card *card, char *name)
{
	struct qeth_dbf_entry *new_entry;

	card->debug = debug_register(name, 2, 1, 8);
	if (!card->debug) {
		QETH_DBF_TEXT_(SETUP, 2, "%s", "qcdbf");
		goto err;
	}
	if (debug_register_view(card->debug, &debug_hex_ascii_view))
		goto err_dbg;
	new_entry = kzalloc(sizeof(struct qeth_dbf_entry), GFP_KERNEL);
	if (!new_entry)
		goto err_dbg;
	strncpy(new_entry->dbf_name, name, DBF_NAME_LEN);
	new_entry->dbf_info = card->debug;
	mutex_lock(&qeth_dbf_list_mutex);
	list_add(&new_entry->dbf_list, &qeth_dbf_list);
	mutex_unlock(&qeth_dbf_list_mutex);

	return 0;

err_dbg:
	debug_unregister(card->debug);
err:
	return -ENOMEM;
}

static void qeth_clear_dbf_list(void)
{
	struct qeth_dbf_entry *entry, *tmp;

	mutex_lock(&qeth_dbf_list_mutex);
	list_for_each_entry_safe(entry, tmp, &qeth_dbf_list, dbf_list) {
		list_del(&entry->dbf_list);
		debug_unregister(entry->dbf_info);
		kfree(entry);
	}
	mutex_unlock(&qeth_dbf_list_mutex);
}

5408 5409 5410 5411 5412 5413
static struct net_device *qeth_alloc_netdev(struct qeth_card *card)
{
	struct net_device *dev;

	switch (card->info.type) {
	case QETH_CARD_TYPE_IQD:
5414 5415
		dev = alloc_netdev_mqs(0, "hsi%d", NET_NAME_UNKNOWN,
				       ether_setup, QETH_MAX_QUEUES, 1);
5416
		break;
5417 5418 5419
	case QETH_CARD_TYPE_OSM:
		dev = alloc_etherdev(0);
		break;
5420 5421 5422 5423
	case QETH_CARD_TYPE_OSN:
		dev = alloc_netdev(0, "osn%d", NET_NAME_UNKNOWN, ether_setup);
		break;
	default:
5424
		dev = alloc_etherdev_mqs(0, QETH_MAX_QUEUES, 1);
5425 5426 5427 5428 5429 5430 5431
	}

	if (!dev)
		return NULL;

	dev->ml_priv = card;
	dev->watchdog_timeo = QETH_TX_TIMEOUT;
5432
	dev->min_mtu = IS_OSN(card) ? 64 : 576;
5433 5434 5435
	 /* initialized when device first goes online: */
	dev->max_mtu = 0;
	dev->mtu = 0;
5436 5437
	SET_NETDEV_DEV(dev, &card->gdev->dev);
	netif_carrier_off(dev);
5438

5439 5440 5441 5442
	if (IS_OSN(card)) {
		dev->ethtool_ops = &qeth_osn_ethtool_ops;
	} else {
		dev->ethtool_ops = &qeth_ethtool_ops;
5443 5444 5445
		dev->priv_flags &= ~IFF_TX_SKB_SHARING;
		dev->hw_features |= NETIF_F_SG;
		dev->vlan_features |= NETIF_F_SG;
5446
		if (IS_IQD(card)) {
5447
			dev->features |= NETIF_F_SG;
5448 5449 5450 5451 5452
			if (netif_set_real_num_tx_queues(dev,
							 QETH_IQD_MIN_TXQ)) {
				free_netdev(dev);
				return NULL;
			}
5453
		}
5454 5455
	}

5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469
	return dev;
}

struct net_device *qeth_clone_netdev(struct net_device *orig)
{
	struct net_device *clone = qeth_alloc_netdev(orig->ml_priv);

	if (!clone)
		return NULL;

	clone->dev_port = orig->dev_port;
	return clone;
}

F
Frank Blaschka 已提交
5470 5471 5472 5473 5474
static int qeth_core_probe_device(struct ccwgroup_device *gdev)
{
	struct qeth_card *card;
	struct device *dev;
	int rc;
5475
	enum qeth_discipline_id enforced_disc;
5476
	char dbf_name[DBF_NAME_LEN];
F
Frank Blaschka 已提交
5477

5478
	QETH_DBF_TEXT(SETUP, 2, "probedev");
F
Frank Blaschka 已提交
5479 5480 5481 5482 5483

	dev = &gdev->dev;
	if (!get_device(dev))
		return -ENODEV;

5484
	QETH_DBF_TEXT_(SETUP, 2, "%s", dev_name(&gdev->dev));
F
Frank Blaschka 已提交
5485

5486
	card = qeth_alloc_card(gdev);
F
Frank Blaschka 已提交
5487
	if (!card) {
5488
		QETH_DBF_TEXT_(SETUP, 2, "1err%d", -ENOMEM);
F
Frank Blaschka 已提交
5489 5490 5491
		rc = -ENOMEM;
		goto err_dev;
	}
5492 5493 5494

	snprintf(dbf_name, sizeof(dbf_name), "qeth_card_%s",
		dev_name(&gdev->dev));
5495
	card->debug = qeth_get_dbf_entry(dbf_name);
5496
	if (!card->debug) {
5497 5498 5499
		rc = qeth_add_dbf_entry(card, dbf_name);
		if (rc)
			goto err_card;
5500 5501
	}

5502
	qeth_setup_card(card);
5503
	card->dev = qeth_alloc_netdev(card);
5504 5505
	if (!card->dev) {
		rc = -ENOMEM;
5506
		goto err_card;
5507
	}
5508

5509 5510 5511 5512
	card->qdio.no_out_queues = card->dev->num_tx_queues;
	rc = qeth_update_from_chp_desc(card);
	if (rc)
		goto err_chp_desc;
5513
	qeth_determine_capabilities(card);
5514 5515
	qeth_set_blkt_defaults(card);

5516 5517 5518 5519 5520 5521 5522 5523
	enforced_disc = qeth_enforce_discipline(card);
	switch (enforced_disc) {
	case QETH_DISCIPLINE_UNDETERMINED:
		gdev->dev.type = &qeth_generic_devtype;
		break;
	default:
		card->info.layer_enforced = true;
		rc = qeth_core_load_discipline(card, enforced_disc);
5524
		if (rc)
5525
			goto err_load;
5526

5527 5528
		gdev->dev.type = IS_OSN(card) ? &qeth_osn_devtype :
						card->discipline->devtype;
5529
		rc = card->discipline->setup(card->gdev);
F
Frank Blaschka 已提交
5530
		if (rc)
5531
			goto err_disc;
5532
		break;
F
Frank Blaschka 已提交
5533 5534 5535 5536
	}

	return 0;

5537 5538
err_disc:
	qeth_core_free_discipline(card);
5539
err_load:
5540
err_chp_desc:
5541
	free_netdev(card->dev);
F
Frank Blaschka 已提交
5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552
err_card:
	qeth_core_free_card(card);
err_dev:
	put_device(dev);
	return rc;
}

static void qeth_core_remove_device(struct ccwgroup_device *gdev)
{
	struct qeth_card *card = dev_get_drvdata(&gdev->dev);

5553
	QETH_CARD_TEXT(card, 2, "removedv");
F
Frank Blaschka 已提交
5554

5555 5556
	if (card->discipline) {
		card->discipline->remove(gdev);
5557 5558 5559
		qeth_core_free_discipline(card);
	}

5560
	free_netdev(card->dev);
F
Frank Blaschka 已提交
5561 5562 5563 5564 5565 5566 5567 5568
	qeth_core_free_card(card);
	put_device(&gdev->dev);
}

static int qeth_core_set_online(struct ccwgroup_device *gdev)
{
	struct qeth_card *card = dev_get_drvdata(&gdev->dev);
	int rc = 0;
5569
	enum qeth_discipline_id def_discipline;
F
Frank Blaschka 已提交
5570

5571
	if (!card->discipline) {
5572 5573
		def_discipline = IS_IQD(card) ? QETH_DISCIPLINE_LAYER3 :
						QETH_DISCIPLINE_LAYER2;
F
Frank Blaschka 已提交
5574 5575 5576
		rc = qeth_core_load_discipline(card, def_discipline);
		if (rc)
			goto err;
5577
		rc = card->discipline->setup(card->gdev);
5578 5579
		if (rc) {
			qeth_core_free_discipline(card);
F
Frank Blaschka 已提交
5580
			goto err;
5581
		}
F
Frank Blaschka 已提交
5582
	}
5583
	rc = card->discipline->set_online(gdev);
F
Frank Blaschka 已提交
5584 5585 5586 5587 5588 5589 5590
err:
	return rc;
}

static int qeth_core_set_offline(struct ccwgroup_device *gdev)
{
	struct qeth_card *card = dev_get_drvdata(&gdev->dev);
5591
	return card->discipline->set_offline(gdev);
F
Frank Blaschka 已提交
5592 5593 5594 5595 5596
}

static void qeth_core_shutdown(struct ccwgroup_device *gdev)
{
	struct qeth_card *card = dev_get_drvdata(&gdev->dev);
5597 5598 5599 5600
	qeth_set_allowed_threads(card, 0, 1);
	if ((gdev->state == CCWGROUP_ONLINE) && card->info.hwtrap)
		qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
	qeth_qdio_clear_card(card, 0);
5601
	qeth_drain_output_queues(card);
5602
	qdio_free(CARD_DDEV(card));
F
Frank Blaschka 已提交
5603 5604
}

5605 5606 5607
static int qeth_core_freeze(struct ccwgroup_device *gdev)
{
	struct qeth_card *card = dev_get_drvdata(&gdev->dev);
5608 5609
	if (card->discipline && card->discipline->freeze)
		return card->discipline->freeze(gdev);
5610 5611 5612 5613 5614 5615
	return 0;
}

static int qeth_core_thaw(struct ccwgroup_device *gdev)
{
	struct qeth_card *card = dev_get_drvdata(&gdev->dev);
5616 5617
	if (card->discipline && card->discipline->thaw)
		return card->discipline->thaw(gdev);
5618 5619 5620 5621 5622 5623
	return 0;
}

static int qeth_core_restore(struct ccwgroup_device *gdev)
{
	struct qeth_card *card = dev_get_drvdata(&gdev->dev);
5624 5625
	if (card->discipline && card->discipline->restore)
		return card->discipline->restore(gdev);
5626 5627 5628
	return 0;
}

5629 5630
static ssize_t group_store(struct device_driver *ddrv, const char *buf,
			   size_t count)
F
Frank Blaschka 已提交
5631 5632 5633
{
	int err;

5634 5635
	err = ccwgroup_create_dev(qeth_core_root_dev, to_ccwgroupdrv(ddrv), 3,
				  buf);
5636 5637 5638

	return err ? err : count;
}
5639
static DRIVER_ATTR_WO(group);
F
Frank Blaschka 已提交
5640

5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652
static struct attribute *qeth_drv_attrs[] = {
	&driver_attr_group.attr,
	NULL,
};
static struct attribute_group qeth_drv_attr_group = {
	.attrs = qeth_drv_attrs,
};
static const struct attribute_group *qeth_drv_attr_groups[] = {
	&qeth_drv_attr_group,
	NULL,
};

5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671
static struct ccwgroup_driver qeth_core_ccwgroup_driver = {
	.driver = {
		.groups = qeth_drv_attr_groups,
		.owner = THIS_MODULE,
		.name = "qeth",
	},
	.ccw_driver = &qeth_ccw_driver,
	.setup = qeth_core_probe_device,
	.remove = qeth_core_remove_device,
	.set_online = qeth_core_set_online,
	.set_offline = qeth_core_set_offline,
	.shutdown = qeth_core_shutdown,
	.prepare = NULL,
	.complete = NULL,
	.freeze = qeth_core_freeze,
	.thaw = qeth_core_thaw,
	.restore = qeth_core_restore,
};

J
Julian Wiedmann 已提交
5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686
struct qeth_card *qeth_get_card_by_busid(char *bus_id)
{
	struct ccwgroup_device *gdev;
	struct qeth_card *card;

	gdev = get_ccwgroupdev_by_busid(&qeth_core_ccwgroup_driver, bus_id);
	if (!gdev)
		return NULL;

	card = dev_get_drvdata(&gdev->dev);
	put_device(&gdev->dev);
	return card;
}
EXPORT_SYMBOL_GPL(qeth_get_card_by_busid);

5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700
int qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
	struct qeth_card *card = dev->ml_priv;
	struct mii_ioctl_data *mii_data;
	int rc = 0;

	if (!card)
		return -ENODEV;

	switch (cmd) {
	case SIOC_QETH_ADP_SET_SNMP_CONTROL:
		rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data);
		break;
	case SIOC_QETH_GET_CARD_TYPE:
5701 5702
		if ((IS_OSD(card) || IS_OSM(card) || IS_OSX(card)) &&
		    !IS_VM_NIC(card))
5703
			return 1;
5704
		return 0;
5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731
	case SIOCGMIIPHY:
		mii_data = if_mii(rq);
		mii_data->phy_id = 0;
		break;
	case SIOCGMIIREG:
		mii_data = if_mii(rq);
		if (mii_data->phy_id != 0)
			rc = -EINVAL;
		else
			mii_data->val_out = qeth_mdio_read(dev,
				mii_data->phy_id, mii_data->reg_num);
		break;
	case SIOC_QETH_QUERY_OAT:
		rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data);
		break;
	default:
		if (card->discipline->do_ioctl)
			rc = card->discipline->do_ioctl(dev, rq, cmd);
		else
			rc = -EOPNOTSUPP;
	}
	if (rc)
		QETH_CARD_TEXT_(card, 2, "ioce%x", rc);
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_do_ioctl);

5732 5733
static int qeth_start_csum_cb(struct qeth_card *card, struct qeth_reply *reply,
			      unsigned long data)
5734 5735
{
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
5736
	u32 *features = reply->param;
5737

5738
	if (qeth_setassparms_inspect_rc(cmd))
5739
		return -EIO;
5740

5741
	*features = cmd->data.setassparms.data.flags_32bit;
5742 5743 5744
	return 0;
}

5745 5746
static int qeth_set_csum_off(struct qeth_card *card, enum qeth_ipa_funcs cstype,
			     enum qeth_prot_versions prot)
5747
{
5748 5749
	return qeth_send_simple_setassparms_prot(card, cstype, IPA_CMD_ASS_STOP,
						 NULL, prot);
5750 5751
}

5752 5753
static int qeth_set_csum_on(struct qeth_card *card, enum qeth_ipa_funcs cstype,
			    enum qeth_prot_versions prot)
5754
{
5755
	u32 required_features = QETH_IPA_CHECKSUM_UDP | QETH_IPA_CHECKSUM_TCP;
5756 5757 5758
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_caps caps;
	u32 features;
5759 5760
	int rc;

5761 5762 5763
	/* some L3 HW requires combined L3+L4 csum offload: */
	if (IS_LAYER3(card) && prot == QETH_PROT_IPV4 &&
	    cstype == IPA_OUTBOUND_CHECKSUM)
5764
		required_features |= QETH_IPA_CHECKSUM_IP_HDR;
5765

5766 5767 5768 5769 5770 5771 5772
	iob = qeth_get_setassparms_cmd(card, cstype, IPA_CMD_ASS_START, 0,
				       prot);
	if (!iob)
		return -ENOMEM;

	rc = qeth_send_ipa_cmd(card, iob, qeth_start_csum_cb, &features);
	if (rc)
5773
		return rc;
5774

5775 5776 5777 5778
	if ((required_features & features) != required_features) {
		qeth_set_csum_off(card, cstype, prot);
		return -EOPNOTSUPP;
	}
5779

5780 5781
	iob = qeth_get_setassparms_cmd(card, cstype, IPA_CMD_ASS_ENABLE,
				       SETASS_DATA_SIZEOF(flags_32bit),
5782
				       prot);
5783 5784 5785
	if (!iob) {
		qeth_set_csum_off(card, cstype, prot);
		return -ENOMEM;
5786
	}
5787 5788 5789 5790 5791

	if (features & QETH_IPA_CHECKSUM_LP2LP)
		required_features |= QETH_IPA_CHECKSUM_LP2LP;
	__ipa_cmd(iob)->data.setassparms.data.flags_32bit = required_features;
	rc = qeth_send_ipa_cmd(card, iob, qeth_setassparms_get_caps_cb, &caps);
5792
	if (rc) {
5793
		qeth_set_csum_off(card, cstype, prot);
5794 5795
		return rc;
	}
5796

5797 5798 5799 5800 5801 5802
	if (!qeth_ipa_caps_supported(&caps, required_features) ||
	    !qeth_ipa_caps_enabled(&caps, required_features)) {
		qeth_set_csum_off(card, cstype, prot);
		return -EOPNOTSUPP;
	}

5803 5804
	dev_info(&card->gdev->dev, "HW Checksumming (%sbound IPv%d) enabled\n",
		 cstype == IPA_INBOUND_CHECKSUM ? "in" : "out", prot);
5805 5806 5807 5808 5809
	if (!qeth_ipa_caps_enabled(&caps, QETH_IPA_CHECKSUM_LP2LP) &&
	    cstype == IPA_OUTBOUND_CHECKSUM)
		dev_warn(&card->gdev->dev,
			 "Hardware checksumming is performed only if %s and its peer use different OSA Express 3 ports\n",
			 QETH_CARD_IFNAME(card));
5810 5811 5812
	return 0;
}

5813 5814
static int qeth_set_ipa_csum(struct qeth_card *card, bool on, int cstype,
			     enum qeth_prot_versions prot)
5815
{
5816 5817
	return on ? qeth_set_csum_on(card, cstype, prot) :
		    qeth_set_csum_off(card, cstype, prot);
5818 5819
}

5820 5821 5822 5823 5824 5825 5826
static int qeth_start_tso_cb(struct qeth_card *card, struct qeth_reply *reply,
			     unsigned long data)
{
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
	struct qeth_tso_start_data *tso_data = reply->param;

	if (qeth_setassparms_inspect_rc(cmd))
5827
		return -EIO;
5828 5829 5830 5831 5832 5833

	tso_data->mss = cmd->data.setassparms.data.tso.mss;
	tso_data->supported = cmd->data.setassparms.data.tso.supported;
	return 0;
}

5834 5835
static int qeth_set_tso_off(struct qeth_card *card,
			    enum qeth_prot_versions prot)
5836
{
5837
	return qeth_send_simple_setassparms_prot(card, IPA_OUTBOUND_TSO,
5838
						 IPA_CMD_ASS_STOP, NULL, prot);
5839
}
5840

5841 5842 5843
static int qeth_set_tso_on(struct qeth_card *card,
			   enum qeth_prot_versions prot)
{
5844 5845 5846 5847 5848 5849 5850 5851 5852 5853
	struct qeth_tso_start_data tso_data;
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_caps caps;
	int rc;

	iob = qeth_get_setassparms_cmd(card, IPA_OUTBOUND_TSO,
				       IPA_CMD_ASS_START, 0, prot);
	if (!iob)
		return -ENOMEM;

5854
	rc = qeth_send_ipa_cmd(card, iob, qeth_start_tso_cb, &tso_data);
5855 5856 5857 5858 5859 5860 5861 5862 5863
	if (rc)
		return rc;

	if (!tso_data.mss || !(tso_data.supported & QETH_IPA_LARGE_SEND_TCP)) {
		qeth_set_tso_off(card, prot);
		return -EOPNOTSUPP;
	}

	iob = qeth_get_setassparms_cmd(card, IPA_OUTBOUND_TSO,
5864 5865
				       IPA_CMD_ASS_ENABLE,
				       SETASS_DATA_SIZEOF(caps), prot);
5866 5867 5868 5869 5870 5871
	if (!iob) {
		qeth_set_tso_off(card, prot);
		return -ENOMEM;
	}

	/* enable TSO capability */
5872 5873 5874
	__ipa_cmd(iob)->data.setassparms.data.caps.enabled =
		QETH_IPA_LARGE_SEND_TCP;
	rc = qeth_send_ipa_cmd(card, iob, qeth_setassparms_get_caps_cb, &caps);
5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888
	if (rc) {
		qeth_set_tso_off(card, prot);
		return rc;
	}

	if (!qeth_ipa_caps_supported(&caps, QETH_IPA_LARGE_SEND_TCP) ||
	    !qeth_ipa_caps_enabled(&caps, QETH_IPA_LARGE_SEND_TCP)) {
		qeth_set_tso_off(card, prot);
		return -EOPNOTSUPP;
	}

	dev_info(&card->gdev->dev, "TSOv%u enabled (MSS: %u)\n", prot,
		 tso_data.mss);
	return 0;
5889
}
5890

5891 5892 5893
static int qeth_set_ipa_tso(struct qeth_card *card, bool on,
			    enum qeth_prot_versions prot)
{
5894
	return on ? qeth_set_tso_on(card, prot) : qeth_set_tso_off(card, prot);
5895
}
5896

5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907
static int qeth_set_ipa_rx_csum(struct qeth_card *card, bool on)
{
	int rc_ipv4 = (on) ? -EOPNOTSUPP : 0;
	int rc_ipv6;

	if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
		rc_ipv4 = qeth_set_ipa_csum(card, on, IPA_INBOUND_CHECKSUM,
					    QETH_PROT_IPV4);
	if (!qeth_is_supported6(card, IPA_INBOUND_CHECKSUM_V6))
		/* no/one Offload Assist available, so the rc is trivial */
		return rc_ipv4;
5908

5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919
	rc_ipv6 = qeth_set_ipa_csum(card, on, IPA_INBOUND_CHECKSUM,
				    QETH_PROT_IPV6);

	if (on)
		/* enable: success if any Assist is active */
		return (rc_ipv6) ? rc_ipv4 : 0;

	/* disable: failure if any Assist is still active */
	return (rc_ipv6) ? rc_ipv6 : rc_ipv4;
}

5920
/**
5921 5922
 * qeth_enable_hw_features() - (Re-)Enable HW functions for device features
 * @dev:	a net_device
5923
 */
5924
void qeth_enable_hw_features(struct net_device *dev)
5925 5926
{
	struct qeth_card *card = dev->ml_priv;
5927
	netdev_features_t features;
5928

5929
	features = dev->features;
5930
	/* force-off any feature that might need an IPA sequence.
5931 5932
	 * netdev_update_features() will restart them.
	 */
5933 5934 5935 5936 5937 5938
	dev->features &= ~dev->hw_features;
	/* toggle VLAN filter, so that VIDs are re-programmed: */
	if (IS_LAYER2(card) && IS_VM_NIC(card)) {
		dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
		dev->wanted_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
	}
5939
	netdev_update_features(dev);
5940 5941 5942
	if (features != dev->features)
		dev_warn(&card->gdev->dev,
			 "Device recovery failed to restore all offload features\n");
5943
}
5944
EXPORT_SYMBOL_GPL(qeth_enable_hw_features);
5945

5946 5947 5948
int qeth_set_features(struct net_device *dev, netdev_features_t features)
{
	struct qeth_card *card = dev->ml_priv;
5949
	netdev_features_t changed = dev->features ^ features;
5950 5951
	int rc = 0;

5952 5953
	QETH_CARD_TEXT(card, 2, "setfeat");
	QETH_CARD_HEX(card, 2, &features, sizeof(features));
5954

5955
	if ((changed & NETIF_F_IP_CSUM)) {
5956 5957
		rc = qeth_set_ipa_csum(card, features & NETIF_F_IP_CSUM,
				       IPA_OUTBOUND_CHECKSUM, QETH_PROT_IPV4);
5958 5959 5960
		if (rc)
			changed ^= NETIF_F_IP_CSUM;
	}
5961 5962 5963 5964 5965 5966
	if (changed & NETIF_F_IPV6_CSUM) {
		rc = qeth_set_ipa_csum(card, features & NETIF_F_IPV6_CSUM,
				       IPA_OUTBOUND_CHECKSUM, QETH_PROT_IPV6);
		if (rc)
			changed ^= NETIF_F_IPV6_CSUM;
	}
5967 5968
	if (changed & NETIF_F_RXCSUM) {
		rc = qeth_set_ipa_rx_csum(card, features & NETIF_F_RXCSUM);
5969 5970 5971
		if (rc)
			changed ^= NETIF_F_RXCSUM;
	}
5972 5973 5974
	if (changed & NETIF_F_TSO) {
		rc = qeth_set_ipa_tso(card, features & NETIF_F_TSO,
				      QETH_PROT_IPV4);
5975 5976 5977
		if (rc)
			changed ^= NETIF_F_TSO;
	}
5978 5979 5980 5981 5982 5983
	if (changed & NETIF_F_TSO6) {
		rc = qeth_set_ipa_tso(card, features & NETIF_F_TSO6,
				      QETH_PROT_IPV6);
		if (rc)
			changed ^= NETIF_F_TSO6;
	}
5984 5985 5986 5987 5988 5989 5990

	/* everything changed successfully? */
	if ((dev->features ^ features) == changed)
		return 0;
	/* something went wrong. save changed features and return error */
	dev->features ^= changed;
	return -EIO;
5991 5992 5993 5994 5995 5996 5997 5998
}
EXPORT_SYMBOL_GPL(qeth_set_features);

netdev_features_t qeth_fix_features(struct net_device *dev,
				    netdev_features_t features)
{
	struct qeth_card *card = dev->ml_priv;

5999
	QETH_CARD_TEXT(card, 2, "fixfeat");
6000 6001
	if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
		features &= ~NETIF_F_IP_CSUM;
6002 6003
	if (!qeth_is_supported6(card, IPA_OUTBOUND_CHECKSUM_V6))
		features &= ~NETIF_F_IPV6_CSUM;
6004 6005
	if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM) &&
	    !qeth_is_supported6(card, IPA_INBOUND_CHECKSUM_V6))
6006
		features &= ~NETIF_F_RXCSUM;
6007
	if (!qeth_is_supported(card, IPA_OUTBOUND_TSO))
6008
		features &= ~NETIF_F_TSO;
6009 6010
	if (!qeth_is_supported6(card, IPA_OUTBOUND_TSO))
		features &= ~NETIF_F_TSO6;
6011

6012
	QETH_CARD_HEX(card, 2, &features, sizeof(features));
6013 6014 6015
	return features;
}
EXPORT_SYMBOL_GPL(qeth_fix_features);
6016

6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042
netdev_features_t qeth_features_check(struct sk_buff *skb,
				      struct net_device *dev,
				      netdev_features_t features)
{
	/* GSO segmentation builds skbs with
	 *	a (small) linear part for the headers, and
	 *	page frags for the data.
	 * Compared to a linear skb, the header-only part consumes an
	 * additional buffer element. This reduces buffer utilization, and
	 * hurts throughput. So compress small segments into one element.
	 */
	if (netif_needs_gso(skb, features)) {
		/* match skb_segment(): */
		unsigned int doffset = skb->data - skb_mac_header(skb);
		unsigned int hsize = skb_shinfo(skb)->gso_size;
		unsigned int hroom = skb_headroom(skb);

		/* linearize only if resulting skb allocations are order-0: */
		if (SKB_DATA_ALIGN(hroom + doffset + hsize) <= SKB_MAX_HEAD(0))
			features &= ~NETIF_F_SG;
	}

	return vlan_features_check(skb, features);
}
EXPORT_SYMBOL_GPL(qeth_features_check);

6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067
void qeth_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{
	struct qeth_card *card = dev->ml_priv;
	struct qeth_qdio_out_q *queue;
	unsigned int i;

	QETH_CARD_TEXT(card, 5, "getstat");

	stats->rx_packets = card->stats.rx_packets;
	stats->rx_bytes = card->stats.rx_bytes;
	stats->rx_errors = card->stats.rx_errors;
	stats->rx_dropped = card->stats.rx_dropped;
	stats->multicast = card->stats.rx_multicast;

	for (i = 0; i < card->qdio.no_out_queues; i++) {
		queue = card->qdio.out_qs[i];

		stats->tx_packets += queue->stats.tx_packets;
		stats->tx_bytes += queue->stats.tx_bytes;
		stats->tx_errors += queue->stats.tx_errors;
		stats->tx_dropped += queue->stats.tx_dropped;
	}
}
EXPORT_SYMBOL_GPL(qeth_get_stats64);

6068 6069 6070 6071 6072 6073 6074 6075 6076
u16 qeth_iqd_select_queue(struct net_device *dev, struct sk_buff *skb,
			  u8 cast_type, struct net_device *sb_dev)
{
	if (cast_type != RTN_UNICAST)
		return QETH_IQD_MCAST_TXQ;
	return QETH_IQD_MIN_UCAST_TXQ;
}
EXPORT_SYMBOL_GPL(qeth_iqd_select_queue);

6077
int qeth_open(struct net_device *dev)
6078 6079 6080 6081 6082 6083 6084 6085 6086
{
	struct qeth_card *card = dev->ml_priv;

	QETH_CARD_TEXT(card, 4, "qethopen");

	if (qdio_stop_irq(CARD_DDEV(card), 0) < 0)
		return -EIO;

	card->data.state = CH_STATE_UP;
6087
	netif_tx_start_all_queues(dev);
6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103

	napi_enable(&card->napi);
	local_bh_disable();
	napi_schedule(&card->napi);
	/* kick-start the NAPI softirq: */
	local_bh_enable();
	return 0;
}
EXPORT_SYMBOL_GPL(qeth_open);

int qeth_stop(struct net_device *dev)
{
	struct qeth_card *card = dev->ml_priv;

	QETH_CARD_TEXT(card, 4, "qethstop");
	netif_tx_disable(dev);
6104
	napi_disable(&card->napi);
6105 6106 6107 6108
	return 0;
}
EXPORT_SYMBOL_GPL(qeth_stop);

F
Frank Blaschka 已提交
6109 6110 6111 6112
static int __init qeth_core_init(void)
{
	int rc;

6113
	pr_info("loading core functions\n");
F
Frank Blaschka 已提交
6114 6115 6116

	rc = qeth_register_dbf_views();
	if (rc)
6117
		goto dbf_err;
M
Mark McLoughlin 已提交
6118
	qeth_core_root_dev = root_device_register("qeth");
6119
	rc = PTR_ERR_OR_ZERO(qeth_core_root_dev);
F
Frank Blaschka 已提交
6120 6121
	if (rc)
		goto register_err;
6122 6123 6124 6125
	qeth_core_header_cache =
		kmem_cache_create("qeth_hdr", QETH_HDR_CACHE_OBJ_SIZE,
				  roundup_pow_of_two(QETH_HDR_CACHE_OBJ_SIZE),
				  0, NULL);
6126 6127 6128 6129
	if (!qeth_core_header_cache) {
		rc = -ENOMEM;
		goto slab_err;
	}
6130 6131 6132 6133 6134 6135
	qeth_qdio_outbuf_cache = kmem_cache_create("qeth_buf",
			sizeof(struct qeth_qdio_out_buffer), 0, 0, NULL);
	if (!qeth_qdio_outbuf_cache) {
		rc = -ENOMEM;
		goto cqslab_err;
	}
6136 6137 6138 6139 6140 6141
	rc = ccw_driver_register(&qeth_ccw_driver);
	if (rc)
		goto ccw_err;
	rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver);
	if (rc)
		goto ccwgroup_err;
6142

6143
	return 0;
6144 6145 6146 6147 6148

ccwgroup_err:
	ccw_driver_unregister(&qeth_ccw_driver);
ccw_err:
	kmem_cache_destroy(qeth_qdio_outbuf_cache);
6149 6150
cqslab_err:
	kmem_cache_destroy(qeth_core_header_cache);
6151
slab_err:
M
Mark McLoughlin 已提交
6152
	root_device_unregister(qeth_core_root_dev);
F
Frank Blaschka 已提交
6153 6154
register_err:
	qeth_unregister_dbf_views();
6155
dbf_err:
6156
	pr_err("Initializing the qeth device driver failed\n");
F
Frank Blaschka 已提交
6157 6158 6159 6160 6161
	return rc;
}

static void __exit qeth_core_exit(void)
{
6162
	qeth_clear_dbf_list();
F
Frank Blaschka 已提交
6163 6164
	ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
	ccw_driver_unregister(&qeth_ccw_driver);
6165
	kmem_cache_destroy(qeth_qdio_outbuf_cache);
6166
	kmem_cache_destroy(qeth_core_header_cache);
6167
	root_device_unregister(qeth_core_root_dev);
F
Frank Blaschka 已提交
6168
	qeth_unregister_dbf_views();
6169
	pr_info("core functions removed\n");
F
Frank Blaschka 已提交
6170 6171 6172 6173 6174 6175 6176
}

module_init(qeth_core_init);
module_exit(qeth_core_exit);
MODULE_AUTHOR("Frank Blaschka <frank.blaschka@de.ibm.com>");
MODULE_DESCRIPTION("qeth core functions");
MODULE_LICENSE("GPL");