fc_rport.c 61.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
/*
 * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Maintained at www.Open-FCoE.org
 */

/*
 * RPORT GENERAL INFO
 *
 * This file contains all processing regarding fc_rports. It contains the
 * rport state machine and does all rport interaction with the transport class.
 * There should be no other places in libfc that interact directly with the
 * transport class in regards to adding and deleting rports.
 *
 * fc_rport's represent N_Port's within the fabric.
 */

/*
 * RPORT LOCKING
 *
 * The rport should never hold the rport mutex and then attempt to acquire
 * either the lport or disc mutexes. The rport's mutex is considered lesser
 * than both the lport's mutex and the disc mutex. Refer to fc_lport.c for
37
 * more comments on the hierarchy.
38 39 40 41 42 43 44 45 46
 *
 * The locking strategy is similar to the lport's strategy. The lock protects
 * the rport's states and is held and released by the entry points to the rport
 * block. All _enter_* functions correspond to rport states and expect the rport
 * mutex to be locked before calling them. This means that rports only handle
 * one request or response at a time, since they're not critical for the I/O
 * path this potential over-use of the mutex is acceptable.
 */

47 48 49 50 51 52 53 54 55 56 57 58 59
/*
 * RPORT REFERENCE COUNTING
 *
 * A rport reference should be taken when:
 * - an rport is allocated
 * - a workqueue item is scheduled
 * - an ELS request is send
 * The reference should be dropped when:
 * - the workqueue function has finished
 * - the ELS response is handled
 * - an rport is removed
 */

60 61 62
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
63
#include <linux/slab.h>
64 65 66
#include <linux/rcupdate.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
67
#include <linux/export.h>
68 69 70 71 72
#include <asm/unaligned.h>

#include <scsi/libfc.h>
#include <scsi/fc_encode.h>

73 74
#include "fc_libfc.h"

75
static struct workqueue_struct *rport_event_queue;
76

77
static void fc_rport_enter_flogi(struct fc_rport_priv *);
78 79 80 81 82
static void fc_rport_enter_plogi(struct fc_rport_priv *);
static void fc_rport_enter_prli(struct fc_rport_priv *);
static void fc_rport_enter_rtv(struct fc_rport_priv *);
static void fc_rport_enter_ready(struct fc_rport_priv *);
static void fc_rport_enter_logo(struct fc_rport_priv *);
83
static void fc_rport_enter_adisc(struct fc_rport_priv *);
84

85 86 87 88
static void fc_rport_recv_plogi_req(struct fc_lport *, struct fc_frame *);
static void fc_rport_recv_prli_req(struct fc_rport_priv *, struct fc_frame *);
static void fc_rport_recv_prlo_req(struct fc_rport_priv *, struct fc_frame *);
static void fc_rport_recv_logo_req(struct fc_lport *, struct fc_frame *);
89
static void fc_rport_timeout(struct work_struct *);
90 91
static void fc_rport_error(struct fc_rport_priv *, int);
static void fc_rport_error_retry(struct fc_rport_priv *, int);
92 93 94 95
static void fc_rport_work(struct work_struct *);

static const char *fc_rport_state_names[] = {
	[RPORT_ST_INIT] = "Init",
96 97
	[RPORT_ST_FLOGI] = "FLOGI",
	[RPORT_ST_PLOGI_WAIT] = "PLOGI_WAIT",
98 99 100 101
	[RPORT_ST_PLOGI] = "PLOGI",
	[RPORT_ST_PRLI] = "PRLI",
	[RPORT_ST_RTV] = "RTV",
	[RPORT_ST_READY] = "Ready",
102
	[RPORT_ST_ADISC] = "ADISC",
103
	[RPORT_ST_DELETE] = "Delete",
104 105
};

106
/**
107 108 109
 * fc_rport_lookup() - Lookup a remote port by port_id
 * @lport:   The local port to lookup the remote port on
 * @port_id: The remote port ID to look up
110
 *
111 112
 * The reference count of the fc_rport_priv structure is
 * increased by one.
113
 */
114 115
struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport,
				      u32 port_id)
116
{
117
	struct fc_rport_priv *rdata = NULL, *tmp_rdata;
118

119 120 121 122 123 124 125 126 127
	rcu_read_lock();
	list_for_each_entry_rcu(tmp_rdata, &lport->disc.rports, peers)
		if (tmp_rdata->ids.port_id == port_id &&
		    kref_get_unless_zero(&tmp_rdata->kref)) {
			rdata = tmp_rdata;
			break;
		}
	rcu_read_unlock();
	return rdata;
128
}
129
EXPORT_SYMBOL(fc_rport_lookup);
130

131
/**
132
 * fc_rport_create() - Create a new remote port
133 134 135 136
 * @lport: The local port this remote port will be associated with
 * @ids:   The identifiers for the new remote port
 *
 * The remote port will start in the INIT state.
137
 *
138
 * Locking note:  must be called with the disc_mutex held.
139
 */
140
struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id)
141
{
142
	struct fc_rport_priv *rdata;
143

144
	rdata = fc_rport_lookup(lport, port_id);
145 146 147
	if (rdata)
		return rdata;

148
	rdata = kzalloc(sizeof(*rdata) + lport->rport_priv_size, GFP_KERNEL);
149
	if (!rdata)
150 151
		return NULL;

152 153 154 155 156
	rdata->ids.node_name = -1;
	rdata->ids.port_name = -1;
	rdata->ids.port_id = port_id;
	rdata->ids.roles = FC_RPORT_ROLE_UNKNOWN;

157
	kref_init(&rdata->kref);
158
	mutex_init(&rdata->rp_mutex);
159
	rdata->local_port = lport;
160 161 162
	rdata->rp_state = RPORT_ST_INIT;
	rdata->event = RPORT_EV_NONE;
	rdata->flags = FC_RP_FLAGS_REC_SUPPORTED;
163 164
	rdata->e_d_tov = lport->e_d_tov;
	rdata->r_a_tov = lport->r_a_tov;
165
	rdata->maxframe_size = FC_MIN_MAX_PAYLOAD;
166 167
	INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout);
	INIT_WORK(&rdata->event_work, fc_rport_work);
168 169
	if (port_id != FC_FID_DIR_SERV) {
		rdata->lld_event_callback = lport->tt.rport_event_callback;
170
		list_add_rcu(&rdata->peers, &lport->disc.rports);
171
	}
172
	return rdata;
173
}
174
EXPORT_SYMBOL(fc_rport_create);
175

176
/**
177 178
 * fc_rport_destroy() - Free a remote port after last reference is released
 * @kref: The remote port's kref
179
 */
180
void fc_rport_destroy(struct kref *kref)
181 182 183 184
{
	struct fc_rport_priv *rdata;

	rdata = container_of(kref, struct fc_rport_priv, kref);
185
	kfree_rcu(rdata, rcu);
186
}
187
EXPORT_SYMBOL(fc_rport_destroy);
188

189
/**
190 191
 * fc_rport_state() - Return a string identifying the remote port's state
 * @rdata: The remote port
192
 */
193
static const char *fc_rport_state(struct fc_rport_priv *rdata)
194 195 196 197 198 199 200 201 202 203
{
	const char *cp;

	cp = fc_rport_state_names[rdata->rp_state];
	if (!cp)
		cp = "Unknown";
	return cp;
}

/**
204 205 206
 * fc_set_rport_loss_tmo() - Set the remote port loss timeout
 * @rport:   The remote port that gets a new timeout value
 * @timeout: The new timeout value (in seconds)
207 208 209 210
 */
void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
{
	if (timeout)
211
		rport->dev_loss_tmo = timeout;
212
	else
213
		rport->dev_loss_tmo = 1;
214 215 216 217
}
EXPORT_SYMBOL(fc_set_rport_loss_tmo);

/**
218 219
 * fc_plogi_get_maxframe() - Get the maximum payload from the common service
 *			     parameters in a FLOGI frame
220
 * @flp:    The FLOGI or PLOGI payload
221 222
 * @maxval: The maximum frame size upper limit; this may be less than what
 *	    is in the service parameters
223
 */
224 225
static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp,
					  unsigned int maxval)
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
{
	unsigned int mfs;

	/*
	 * Get max payload from the common service parameters and the
	 * class 3 receive data field size.
	 */
	mfs = ntohs(flp->fl_csp.sp_bb_data) & FC_SP_BB_DATA_MASK;
	if (mfs >= FC_SP_MIN_MAX_PAYLOAD && mfs < maxval)
		maxval = mfs;
	mfs = ntohs(flp->fl_cssp[3 - 1].cp_rdfs);
	if (mfs >= FC_SP_MIN_MAX_PAYLOAD && mfs < maxval)
		maxval = mfs;
	return maxval;
}

/**
243 244 245
 * fc_rport_state_enter() - Change the state of a remote port
 * @rdata: The remote port whose state should change
 * @new:   The new state
246 247 248
 *
 * Locking Note: Called with the rport lock held
 */
249
static void fc_rport_state_enter(struct fc_rport_priv *rdata,
250 251 252 253 254 255 256
				 enum fc_rport_state new)
{
	if (rdata->rp_state != new)
		rdata->retries = 0;
	rdata->rp_state = new;
}

257 258 259
/**
 * fc_rport_work() - Handler for remote port events in the rport_event_queue
 * @work: Handle to the remote port being dequeued
260 261
 *
 * Reference counting: drops kref on return
262
 */
263 264
static void fc_rport_work(struct work_struct *work)
{
265
	u32 port_id;
266 267
	struct fc_rport_priv *rdata =
		container_of(work, struct fc_rport_priv, event_work);
268
	struct fc_rport_libfc_priv *rpriv;
269 270 271
	enum fc_rport_event event;
	struct fc_lport *lport = rdata->local_port;
	struct fc_rport_operations *rport_ops;
272
	struct fc_rport_identifiers ids;
273
	struct fc_rport *rport;
274 275
	struct fc4_prov *prov;
	u8 type;
276 277 278 279

	mutex_lock(&rdata->rp_mutex);
	event = rdata->event;
	rport_ops = rdata->ops;
280
	rport = rdata->rport;
281

282 283
	FC_RPORT_DBG(rdata, "work event %u\n", event);

284
	switch (event) {
285
	case RPORT_EV_READY:
286
		ids = rdata->ids;
287
		rdata->event = RPORT_EV_NONE;
288
		rdata->major_retries = 0;
289
		kref_get(&rdata->kref);
290 291
		mutex_unlock(&rdata->rp_mutex);

292 293
		if (!rport) {
			FC_RPORT_DBG(rdata, "No rport!\n");
294
			rport = fc_remote_port_add(lport->host, 0, &ids);
295
		}
296 297
		if (!rport) {
			FC_RPORT_DBG(rdata, "Failed to add the rport\n");
298
			fc_rport_logoff(rdata);
299
			kref_put(&rdata->kref, fc_rport_destroy);
300
			return;
301
		}
302 303 304 305 306 307 308
		mutex_lock(&rdata->rp_mutex);
		if (rdata->rport)
			FC_RPORT_DBG(rdata, "rport already allocated\n");
		rdata->rport = rport;
		rport->maxframe_size = rdata->maxframe_size;
		rport->supported_classes = rdata->supported_classes;

309 310 311 312 313 314
		rpriv = rport->dd_data;
		rpriv->local_port = lport;
		rpriv->rp_state = rdata->rp_state;
		rpriv->flags = rdata->flags;
		rpriv->e_d_tov = rdata->e_d_tov;
		rpriv->r_a_tov = rdata->r_a_tov;
315 316
		mutex_unlock(&rdata->rp_mutex);

317
		if (rport_ops && rport_ops->event_callback) {
318
			FC_RPORT_DBG(rdata, "callback ev %d\n", event);
319
			rport_ops->event_callback(lport, rdata, event);
320
		}
321 322 323 324
		if (rdata->lld_event_callback) {
			FC_RPORT_DBG(rdata, "lld callback ev %d\n", event);
			rdata->lld_event_callback(lport, rdata, event);
		}
325
		kref_put(&rdata->kref, fc_rport_destroy);
326 327 328 329 330
		break;

	case RPORT_EV_FAILED:
	case RPORT_EV_LOGO:
	case RPORT_EV_STOP:
331 332 333 334 335 336 337 338 339
		if (rdata->prli_count) {
			mutex_lock(&fc_prov_mutex);
			for (type = 1; type < FC_FC4_PROV_SIZE; type++) {
				prov = fc_passive_prov[type];
				if (prov && prov->prlo)
					prov->prlo(rdata);
			}
			mutex_unlock(&fc_prov_mutex);
		}
340
		port_id = rdata->ids.port_id;
341
		mutex_unlock(&rdata->rp_mutex);
342

343
		if (rport_ops && rport_ops->event_callback) {
344
			FC_RPORT_DBG(rdata, "callback ev %d\n", event);
345
			rport_ops->event_callback(lport, rdata, event);
346
		}
347 348 349 350
		if (rdata->lld_event_callback) {
			FC_RPORT_DBG(rdata, "lld callback ev %d\n", event);
			rdata->lld_event_callback(lport, rdata, event);
		}
351
		if (cancel_delayed_work_sync(&rdata->retry_work))
352
			kref_put(&rdata->kref, fc_rport_destroy);
353 354 355 356 357 358 359 360

		/*
		 * Reset any outstanding exchanges before freeing rport.
		 */
		lport->tt.exch_mgr_reset(lport, 0, port_id);
		lport->tt.exch_mgr_reset(lport, port_id, 0);

		if (rport) {
361 362
			rpriv = rport->dd_data;
			rpriv->rp_state = RPORT_ST_DELETE;
363 364 365
			mutex_lock(&rdata->rp_mutex);
			rdata->rport = NULL;
			mutex_unlock(&rdata->rp_mutex);
366
			fc_remote_port_delete(rport);
367
		}
368 369 370 371 372 373

		mutex_lock(&rdata->rp_mutex);
		if (rdata->rp_state == RPORT_ST_DELETE) {
			if (port_id == FC_FID_DIR_SERV) {
				rdata->event = RPORT_EV_NONE;
				mutex_unlock(&rdata->rp_mutex);
374
				kref_put(&rdata->kref, fc_rport_destroy);
375 376 377 378
			} else if ((rdata->flags & FC_RP_STARTED) &&
				   rdata->major_retries <
				   lport->max_rport_retry_count) {
				rdata->major_retries++;
379 380
				rdata->event = RPORT_EV_NONE;
				FC_RPORT_DBG(rdata, "work restart\n");
381
				fc_rport_enter_flogi(rdata);
382 383 384
				mutex_unlock(&rdata->rp_mutex);
			} else {
				FC_RPORT_DBG(rdata, "work delete\n");
385
				mutex_lock(&lport->disc.disc_mutex);
386
				list_del_rcu(&rdata->peers);
387
				mutex_unlock(&lport->disc.disc_mutex);
388
				mutex_unlock(&rdata->rp_mutex);
389
				kref_put(&rdata->kref, fc_rport_destroy);
390 391 392 393 394 395
			}
		} else {
			/*
			 * Re-open for events.  Reissue READY event if ready.
			 */
			rdata->event = RPORT_EV_NONE;
396 397
			if (rdata->rp_state == RPORT_ST_READY) {
				FC_RPORT_DBG(rdata, "work reopen\n");
398
				fc_rport_enter_ready(rdata);
399
			}
400
			mutex_unlock(&rdata->rp_mutex);
401
		}
402 403 404
		break;

	default:
405
		mutex_unlock(&rdata->rp_mutex);
406 407
		break;
	}
408
	kref_put(&rdata->kref, fc_rport_destroy);
409 410 411
}

/**
412
 * fc_rport_login() - Start the remote port login state machine
413
 * @rdata: The remote port to be logged in to
414
 *
415 416 417 418 419 420 421 422
 * Initiates the RP state machine. It is called from the LP module.
 * This function will issue the following commands to the N_Port
 * identified by the FC ID provided.
 *
 * - PLOGI
 * - PRLI
 * - RTV
 *
423 424 425
 * Locking Note: Called without the rport lock held. This
 * function will hold the rport lock, call an _enter_*
 * function and then unlock the rport.
426 427 428 429
 *
 * This indicates the intent to be logged into the remote port.
 * If it appears we are already logged in, ADISC is used to verify
 * the setup.
430
 */
431
int fc_rport_login(struct fc_rport_priv *rdata)
432 433 434
{
	mutex_lock(&rdata->rp_mutex);

435 436 437 438 439 440
	if (rdata->flags & FC_RP_STARTED) {
		FC_RPORT_DBG(rdata, "port already started\n");
		mutex_unlock(&rdata->rp_mutex);
		return 0;
	}

441
	rdata->flags |= FC_RP_STARTED;
442 443 444 445 446
	switch (rdata->rp_state) {
	case RPORT_ST_READY:
		FC_RPORT_DBG(rdata, "ADISC port\n");
		fc_rport_enter_adisc(rdata);
		break;
447 448 449
	case RPORT_ST_DELETE:
		FC_RPORT_DBG(rdata, "Restart deleted port\n");
		break;
450
	case RPORT_ST_INIT:
451
		FC_RPORT_DBG(rdata, "Login to port\n");
452
		fc_rport_enter_flogi(rdata);
453
		break;
454 455 456 457
	default:
		FC_RPORT_DBG(rdata, "Login in progress, state %s\n",
			     fc_rport_state(rdata));
		break;
458
	}
459 460 461 462
	mutex_unlock(&rdata->rp_mutex);

	return 0;
}
463
EXPORT_SYMBOL(fc_rport_login);
464

465
/**
466 467 468
 * fc_rport_enter_delete() - Schedule a remote port to be deleted
 * @rdata: The remote port to be deleted
 * @event: The event to report as the reason for deletion
469 470 471 472 473 474 475 476 477
 *
 * Locking Note: Called with the rport lock held.
 *
 * Allow state change into DELETE only once.
 *
 * Call queue_work only if there's no event already pending.
 * Set the new event so that the old pending event will not occur.
 * Since we have the mutex, even if fc_rport_work() is already started,
 * it'll see the new event.
478 479
 *
 * Reference counting: does not modify kref
480
 */
481
static void fc_rport_enter_delete(struct fc_rport_priv *rdata,
482 483 484 485 486
				  enum fc_rport_event event)
{
	if (rdata->rp_state == RPORT_ST_DELETE)
		return;

487
	FC_RPORT_DBG(rdata, "Delete port\n");
488

489
	fc_rport_state_enter(rdata, RPORT_ST_DELETE);
490

491 492 493
	kref_get(&rdata->kref);
	if (rdata->event == RPORT_EV_NONE &&
	    !queue_work(rport_event_queue, &rdata->event_work))
494
		kref_put(&rdata->kref, fc_rport_destroy);
495

496 497 498
	rdata->event = event;
}

499
/**
500 501
 * fc_rport_logoff() - Logoff and remove a remote port
 * @rdata: The remote port to be logged off of
502 503 504 505 506
 *
 * Locking Note: Called without the rport lock held. This
 * function will hold the rport lock, call an _enter_*
 * function and then unlock the rport.
 */
507
int fc_rport_logoff(struct fc_rport_priv *rdata)
508
{
509 510 511
	struct fc_lport *lport = rdata->local_port;
	u32 port_id = rdata->ids.port_id;

512 513
	mutex_lock(&rdata->rp_mutex);

514
	FC_RPORT_DBG(rdata, "Remove port\n");
515

516
	rdata->flags &= ~FC_RP_STARTED;
517
	if (rdata->rp_state == RPORT_ST_DELETE) {
518
		FC_RPORT_DBG(rdata, "Port in Delete state, not removing\n");
519 520
		goto out;
	}
521 522 523 524 525 526 527 528 529
	/*
	 * FC-LS states:
	 * To explicitly Logout, the initiating Nx_Port shall terminate
	 * other open Sequences that it initiated with the destination
	 * Nx_Port prior to performing Logout.
	 */
	lport->tt.exch_mgr_reset(lport, 0, port_id);
	lport->tt.exch_mgr_reset(lport, port_id, 0);

530
	fc_rport_enter_logo(rdata);
531 532

	/*
533
	 * Change the state to Delete so that we discard
534 535
	 * the response.
	 */
536
	fc_rport_enter_delete(rdata, RPORT_EV_STOP);
537
out:
538
	mutex_unlock(&rdata->rp_mutex);
539 540
	return 0;
}
541
EXPORT_SYMBOL(fc_rport_logoff);
542 543

/**
544 545
 * fc_rport_enter_ready() - Transition to the RPORT_ST_READY state
 * @rdata: The remote port that is ready
546 547 548
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this routine.
549 550
 *
 * Reference counting: schedules workqueue, does not modify kref
551
 */
552
static void fc_rport_enter_ready(struct fc_rport_priv *rdata)
553
{
554
	fc_rport_state_enter(rdata, RPORT_ST_READY);
555

556
	FC_RPORT_DBG(rdata, "Port is Ready\n");
557

558 559 560
	kref_get(&rdata->kref);
	if (rdata->event == RPORT_EV_NONE &&
	    !queue_work(rport_event_queue, &rdata->event_work))
561
		kref_put(&rdata->kref, fc_rport_destroy);
562

563
	rdata->event = RPORT_EV_READY;
564 565 566
}

/**
567 568
 * fc_rport_timeout() - Handler for the retry_work timer
 * @work: Handle to the remote port that has timed out
569 570 571 572
 *
 * Locking Note: Called without the rport lock held. This
 * function will hold the rport lock, call an _enter_*
 * function and then unlock the rport.
573 574
 *
 * Reference counting: Drops kref on return.
575 576 577
 */
static void fc_rport_timeout(struct work_struct *work)
{
578 579
	struct fc_rport_priv *rdata =
		container_of(work, struct fc_rport_priv, retry_work.work);
580 581

	mutex_lock(&rdata->rp_mutex);
582
	FC_RPORT_DBG(rdata, "Port timeout, state %s\n", fc_rport_state(rdata));
583 584

	switch (rdata->rp_state) {
585 586 587
	case RPORT_ST_FLOGI:
		fc_rport_enter_flogi(rdata);
		break;
588
	case RPORT_ST_PLOGI:
589
		fc_rport_enter_plogi(rdata);
590 591
		break;
	case RPORT_ST_PRLI:
592
		fc_rport_enter_prli(rdata);
593 594
		break;
	case RPORT_ST_RTV:
595
		fc_rport_enter_rtv(rdata);
596
		break;
597 598 599
	case RPORT_ST_ADISC:
		fc_rport_enter_adisc(rdata);
		break;
600
	case RPORT_ST_PLOGI_WAIT:
601 602
	case RPORT_ST_READY:
	case RPORT_ST_INIT:
603
	case RPORT_ST_DELETE:
604 605 606 607
		break;
	}

	mutex_unlock(&rdata->rp_mutex);
608
	kref_put(&rdata->kref, fc_rport_destroy);
609 610 611
}

/**
612
 * fc_rport_error() - Error handler, called once retries have been exhausted
613
 * @rdata: The remote port the error is happened on
614
 * @err:   The error code
615 616 617
 *
 * Locking Note: The rport lock is expected to be held before
 * calling this routine
618 619
 *
 * Reference counting: does not modify kref
620
 */
621
static void fc_rport_error(struct fc_rport_priv *rdata, int err)
622
{
623 624
	struct fc_lport *lport = rdata->local_port;

625 626
	FC_RPORT_DBG(rdata, "Error %d in state %s, retries %d\n",
		     -err, fc_rport_state(rdata), rdata->retries);
627

628
	switch (rdata->rp_state) {
629
	case RPORT_ST_FLOGI:
630
		rdata->flags &= ~FC_RP_STARTED;
631
		fc_rport_enter_delete(rdata, RPORT_EV_FAILED);
632
		break;
633 634 635 636 637 638 639
	case RPORT_ST_PLOGI:
		if (lport->point_to_multipoint) {
			rdata->flags &= ~FC_RP_STARTED;
			fc_rport_enter_delete(rdata, RPORT_EV_FAILED);
		} else
			fc_rport_enter_logo(rdata);
		break;
640
	case RPORT_ST_RTV:
641
		fc_rport_enter_ready(rdata);
642
		break;
643 644 645 646
	case RPORT_ST_PRLI:
	case RPORT_ST_ADISC:
		fc_rport_enter_logo(rdata);
		break;
647
	case RPORT_ST_PLOGI_WAIT:
648
	case RPORT_ST_DELETE:
649 650 651
	case RPORT_ST_READY:
	case RPORT_ST_INIT:
		break;
652 653 654
	}
}

655
/**
656 657
 * fc_rport_error_retry() - Handler for remote port state retries
 * @rdata: The remote port whose state is to be retried
658
 * @err:   The error code
659 660 661 662 663 664
 *
 * If the error was an exchange timeout retry immediately,
 * otherwise wait for E_D_TOV.
 *
 * Locking Note: The rport lock is expected to be held before
 * calling this routine
665 666
 *
 * Reference counting: increments kref when scheduling retry_work
667
 */
668
static void fc_rport_error_retry(struct fc_rport_priv *rdata, int err)
669
{
670
	unsigned long delay = msecs_to_jiffies(rdata->e_d_tov);
671 672

	/* make sure this isn't an FC_EX_CLOSED error, never retry those */
673
	if (err == -FC_EX_CLOSED)
674
		goto out;
675

676
	if (rdata->retries < rdata->local_port->max_rport_retry_count) {
677 678
		FC_RPORT_DBG(rdata, "Error %d in state %s, retrying\n",
			     err, fc_rport_state(rdata));
679 680
		rdata->retries++;
		/* no additional delay on exchange timeouts */
681
		if (err == -FC_EX_TIMEOUT)
682
			delay = 0;
683 684
		kref_get(&rdata->kref);
		if (!schedule_delayed_work(&rdata->retry_work, delay))
685
			kref_put(&rdata->kref, fc_rport_destroy);
686 687 688
		return;
	}

689
out:
690
	fc_rport_error(rdata, err);
691 692
}

693
/**
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
 * fc_rport_login_complete() - Handle parameters and completion of p-mp login.
 * @rdata:  The remote port which we logged into or which logged into us.
 * @fp:     The FLOGI or PLOGI request or response frame
 *
 * Returns non-zero error if a problem is detected with the frame.
 * Does not free the frame.
 *
 * This is only used in point-to-multipoint mode for FIP currently.
 */
static int fc_rport_login_complete(struct fc_rport_priv *rdata,
				   struct fc_frame *fp)
{
	struct fc_lport *lport = rdata->local_port;
	struct fc_els_flogi *flogi;
	unsigned int e_d_tov;
	u16 csp_flags;

	flogi = fc_frame_payload_get(fp, sizeof(*flogi));
	if (!flogi)
		return -EINVAL;

	csp_flags = ntohs(flogi->fl_csp.sp_features);

	if (fc_frame_payload_op(fp) == ELS_FLOGI) {
		if (csp_flags & FC_SP_FT_FPORT) {
			FC_RPORT_DBG(rdata, "Fabric bit set in FLOGI\n");
			return -EINVAL;
		}
	} else {

		/*
		 * E_D_TOV is not valid on an incoming FLOGI request.
		 */
		e_d_tov = ntohl(flogi->fl_csp.sp_e_d_tov);
		if (csp_flags & FC_SP_FT_EDTR)
			e_d_tov /= 1000000;
		if (e_d_tov > rdata->e_d_tov)
			rdata->e_d_tov = e_d_tov;
	}
	rdata->maxframe_size = fc_plogi_get_maxframe(flogi, lport->mfs);
	return 0;
}

/**
 * fc_rport_flogi_resp() - Handle response to FLOGI request for p-mp mode
 * @sp:	    The sequence that the FLOGI was on
 * @fp:	    The FLOGI response frame
 * @rp_arg: The remote port that received the FLOGI response
 */
743 744
static void fc_rport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
				void *rp_arg)
745 746 747 748 749
{
	struct fc_rport_priv *rdata = rp_arg;
	struct fc_lport *lport = rdata->local_port;
	struct fc_els_flogi *flogi;
	unsigned int r_a_tov;
750 751
	u8 opcode;
	int err = 0;
752

753 754
	FC_RPORT_DBG(rdata, "Received a FLOGI %s\n",
		     IS_ERR(fp) ? "error" : fc_els_resp_type(fp));
755 756

	if (fp == ERR_PTR(-FC_EX_CLOSED))
757
		goto put;
758 759 760 761 762 763 764 765 766 767 768 769

	mutex_lock(&rdata->rp_mutex);

	if (rdata->rp_state != RPORT_ST_FLOGI) {
		FC_RPORT_DBG(rdata, "Received a FLOGI response, but in state "
			     "%s\n", fc_rport_state(rdata));
		if (IS_ERR(fp))
			goto err;
		goto out;
	}

	if (IS_ERR(fp)) {
770
		fc_rport_error(rdata, PTR_ERR(fp));
771 772
		goto err;
	}
773 774 775
	opcode = fc_frame_payload_op(fp);
	if (opcode == ELS_LS_RJT) {
		struct fc_els_ls_rjt *rjt;
776

777 778 779 780 781 782 783 784
		rjt = fc_frame_payload_get(fp, sizeof(*rjt));
		FC_RPORT_DBG(rdata, "FLOGI ELS rejected, reason %x expl %x\n",
			     rjt->er_reason, rjt->er_explan);
		err = -FC_EX_ELS_RJT;
		goto bad;
	} else if (opcode != ELS_LS_ACC) {
		FC_RPORT_DBG(rdata, "FLOGI ELS invalid opcode %x\n", opcode);
		err = -FC_EX_ELS_RJT;
785
		goto bad;
786 787 788 789
	}
	if (fc_rport_login_complete(rdata, fp)) {
		FC_RPORT_DBG(rdata, "FLOGI failed, no login\n");
		err = -FC_EX_INV_LOGIN;
790
		goto bad;
791
	}
792 793

	flogi = fc_frame_payload_get(fp, sizeof(*flogi));
794
	if (!flogi) {
795
		err = -FC_EX_ALLOC_ERR;
796
		goto bad;
797
	}
798 799 800 801 802 803 804 805 806 807 808 809
	r_a_tov = ntohl(flogi->fl_csp.sp_r_a_tov);
	if (r_a_tov > rdata->r_a_tov)
		rdata->r_a_tov = r_a_tov;

	if (rdata->ids.port_name < lport->wwpn)
		fc_rport_enter_plogi(rdata);
	else
		fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);
out:
	fc_frame_free(fp);
err:
	mutex_unlock(&rdata->rp_mutex);
810
put:
811
	kref_put(&rdata->kref, fc_rport_destroy);
812 813
	return;
bad:
814 815
	FC_RPORT_DBG(rdata, "Bad FLOGI response\n");
	fc_rport_error_retry(rdata, err);
816 817 818 819 820 821 822 823 824
	goto out;
}

/**
 * fc_rport_enter_flogi() - Send a FLOGI request to the remote port for p-mp
 * @rdata: The remote port to send a FLOGI to
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this routine.
825 826
 *
 * Reference counting: increments kref when sending ELS
827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
 */
static void fc_rport_enter_flogi(struct fc_rport_priv *rdata)
{
	struct fc_lport *lport = rdata->local_port;
	struct fc_frame *fp;

	if (!lport->point_to_multipoint)
		return fc_rport_enter_plogi(rdata);

	FC_RPORT_DBG(rdata, "Entered FLOGI state from %s state\n",
		     fc_rport_state(rdata));

	fc_rport_state_enter(rdata, RPORT_ST_FLOGI);

	fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
	if (!fp)
843
		return fc_rport_error_retry(rdata, -FC_EX_ALLOC_ERR);
844

845
	kref_get(&rdata->kref);
846 847
	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_FLOGI,
				  fc_rport_flogi_resp, rdata,
848
				  2 * lport->r_a_tov)) {
849
		fc_rport_error_retry(rdata, -FC_EX_XMIT_ERR);
850
		kref_put(&rdata->kref, fc_rport_destroy);
851
	}
852 853 854 855 856 857
}

/**
 * fc_rport_recv_flogi_req() - Handle Fabric Login (FLOGI) request in p-mp mode
 * @lport: The local port that received the PLOGI request
 * @rx_fp: The PLOGI request frame
858 859
 *
 * Reference counting: drops kref on return
860 861
 */
static void fc_rport_recv_flogi_req(struct fc_lport *lport,
862
				    struct fc_frame *rx_fp)
863 864 865 866 867 868
{
	struct fc_disc *disc;
	struct fc_els_flogi *flp;
	struct fc_rport_priv *rdata;
	struct fc_frame *fp = rx_fp;
	struct fc_seq_els_data rjt_data;
869
	u32 sid;
870

871
	sid = fc_frame_sid(fp);
872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888

	FC_RPORT_ID_DBG(lport, sid, "Received FLOGI request\n");

	disc = &lport->disc;
	if (!lport->point_to_multipoint) {
		rjt_data.reason = ELS_RJT_UNSUP;
		rjt_data.explan = ELS_EXPL_NONE;
		goto reject;
	}

	flp = fc_frame_payload_get(fp, sizeof(*flp));
	if (!flp) {
		rjt_data.reason = ELS_RJT_LOGIC;
		rjt_data.explan = ELS_EXPL_INV_LEN;
		goto reject;
	}

889
	rdata = fc_rport_lookup(lport, sid);
890 891 892 893 894 895 896 897 898 899 900 901
	if (!rdata) {
		rjt_data.reason = ELS_RJT_FIP;
		rjt_data.explan = ELS_EXPL_NOT_NEIGHBOR;
		goto reject;
	}
	mutex_lock(&rdata->rp_mutex);

	FC_RPORT_DBG(rdata, "Received FLOGI in %s state\n",
		     fc_rport_state(rdata));

	switch (rdata->rp_state) {
	case RPORT_ST_INIT:
902 903 904 905 906 907 908 909 910 911 912 913
		/*
		 * If received the FLOGI request on RPORT which is INIT state
		 * (means not transition to FLOGI either fc_rport timeout
		 * function didn;t trigger or this end hasn;t received
		 * beacon yet from other end. In that case only, allow RPORT
		 * state machine to continue, otherwise fall through which
		 * causes the code to send reject response.
		 * NOTE; Not checking for FIP->state such as VNMP_UP or
		 * VNMP_CLAIM because if FIP state is not one of those,
		 * RPORT wouldn;t have created and 'rport_lookup' would have
		 * failed anyway in that case.
		 */
914
		break;
915 916 917 918
	case RPORT_ST_DELETE:
		mutex_unlock(&rdata->rp_mutex);
		rjt_data.reason = ELS_RJT_FIP;
		rjt_data.explan = ELS_EXPL_NOT_NEIGHBOR;
919
		goto reject_put;
920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935
	case RPORT_ST_FLOGI:
	case RPORT_ST_PLOGI_WAIT:
	case RPORT_ST_PLOGI:
		break;
	case RPORT_ST_PRLI:
	case RPORT_ST_RTV:
	case RPORT_ST_READY:
	case RPORT_ST_ADISC:
		/*
		 * Set the remote port to be deleted and to then restart.
		 * This queues work to be sure exchanges are reset.
		 */
		fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
		mutex_unlock(&rdata->rp_mutex);
		rjt_data.reason = ELS_RJT_BUSY;
		rjt_data.explan = ELS_EXPL_NONE;
936
		goto reject_put;
937 938 939 940 941
	}
	if (fc_rport_login_complete(rdata, fp)) {
		mutex_unlock(&rdata->rp_mutex);
		rjt_data.reason = ELS_RJT_LOGIC;
		rjt_data.explan = ELS_EXPL_NONE;
942
		goto reject_put;
943 944 945 946 947 948 949 950 951 952
	}

	fp = fc_frame_alloc(lport, sizeof(*flp));
	if (!fp)
		goto out;

	fc_flogi_fill(lport, fp);
	flp = fc_frame_payload_get(fp, sizeof(*flp));
	flp->fl_cmd = ELS_LS_ACC;

953 954
	fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
	lport->tt.frame_send(lport, fp);
955

956 957 958 959 960 961 962 963 964 965 966
	/*
	 * Do not proceed with the state machine if our
	 * FLOGI has crossed with an FLOGI from the
	 * remote port; wait for the FLOGI response instead.
	 */
	if (rdata->rp_state != RPORT_ST_FLOGI) {
		if (rdata->ids.port_name < lport->wwpn)
			fc_rport_enter_plogi(rdata);
		else
			fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);
	}
967 968
out:
	mutex_unlock(&rdata->rp_mutex);
969
	kref_put(&rdata->kref, fc_rport_destroy);
970
	fc_frame_free(rx_fp);
971 972
	return;

973
reject_put:
974
	kref_put(&rdata->kref, fc_rport_destroy);
975
reject:
976
	fc_seq_els_rsp_send(rx_fp, ELS_LS_RJT, &rjt_data);
977
	fc_frame_free(rx_fp);
978 979 980 981
}

/**
 * fc_rport_plogi_resp() - Handler for ELS PLOGI responses
982 983 984
 * @sp:	       The sequence the PLOGI is on
 * @fp:	       The PLOGI response frame
 * @rdata_arg: The remote port that sent the PLOGI response
985 986 987 988 989 990
 *
 * Locking Note: This function will be called without the rport lock
 * held, but it will lock, call an _enter_* function or fc_rport_error
 * and then unlock the rport.
 */
static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
991
				void *rdata_arg)
992
{
993
	struct fc_rport_priv *rdata = rdata_arg;
994
	struct fc_lport *lport = rdata->local_port;
995
	struct fc_els_flogi *plp = NULL;
996 997 998 999
	u16 csp_seq;
	u16 cssp_seq;
	u8 op;

1000
	FC_RPORT_DBG(rdata, "Received a PLOGI %s\n", fc_els_resp_type(fp));
1001

1002 1003 1004 1005 1006
	if (fp == ERR_PTR(-FC_EX_CLOSED))
		goto put;

	mutex_lock(&rdata->rp_mutex);

1007
	if (rdata->rp_state != RPORT_ST_PLOGI) {
1008 1009
		FC_RPORT_DBG(rdata, "Received a PLOGI response, but in state "
			     "%s\n", fc_rport_state(rdata));
1010 1011
		if (IS_ERR(fp))
			goto err;
1012 1013 1014
		goto out;
	}

1015
	if (IS_ERR(fp)) {
1016
		fc_rport_error_retry(rdata, PTR_ERR(fp));
1017 1018 1019
		goto err;
	}

1020 1021 1022
	op = fc_frame_payload_op(fp);
	if (op == ELS_LS_ACC &&
	    (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) {
1023 1024
		rdata->ids.port_name = get_unaligned_be64(&plp->fl_wwpn);
		rdata->ids.node_name = get_unaligned_be64(&plp->fl_wwnn);
1025

1026 1027 1028
		/* save plogi response sp_features for further reference */
		rdata->sp_features = ntohs(plp->fl_csp.sp_features);

1029 1030
		if (lport->point_to_multipoint)
			fc_rport_login_complete(rdata, fp);
1031 1032 1033 1034 1035
		csp_seq = ntohs(plp->fl_csp.sp_tot_seq);
		cssp_seq = ntohs(plp->fl_cssp[3 - 1].cp_con_seq);
		if (cssp_seq < csp_seq)
			csp_seq = cssp_seq;
		rdata->max_seq = csp_seq;
1036
		rdata->maxframe_size = fc_plogi_get_maxframe(plp, lport->mfs);
1037
		fc_rport_enter_prli(rdata);
1038 1039
	} else {
		struct fc_els_ls_rjt *rjt;
1040

1041 1042 1043 1044 1045
		rjt = fc_frame_payload_get(fp, sizeof(*rjt));
		FC_RPORT_DBG(rdata, "PLOGI ELS rejected, reason %x expl %x\n",
			     rjt->er_reason, rjt->er_explan);
		fc_rport_error_retry(rdata, -FC_EX_ELS_RJT);
	}
1046 1047 1048 1049
out:
	fc_frame_free(fp);
err:
	mutex_unlock(&rdata->rp_mutex);
1050
put:
1051
	kref_put(&rdata->kref, fc_rport_destroy);
1052 1053
}

1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067
static bool
fc_rport_compatible_roles(struct fc_lport *lport, struct fc_rport_priv *rdata)
{
	if (rdata->ids.roles == FC_PORT_ROLE_UNKNOWN)
		return true;
	if ((rdata->ids.roles & FC_PORT_ROLE_FCP_TARGET) &&
	    (lport->service_params & FCP_SPPF_INIT_FCN))
		return true;
	if ((rdata->ids.roles & FC_PORT_ROLE_FCP_INITIATOR) &&
	    (lport->service_params & FCP_SPPF_TARG_FCN))
		return true;
	return false;
}

1068
/**
1069 1070
 * fc_rport_enter_plogi() - Send Port Login (PLOGI) request
 * @rdata: The remote port to send a PLOGI to
1071 1072 1073
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this routine.
1074 1075
 *
 * Reference counting: increments kref when sending ELS
1076
 */
1077
static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)
1078 1079 1080 1081
{
	struct fc_lport *lport = rdata->local_port;
	struct fc_frame *fp;

1082 1083 1084 1085 1086 1087
	if (!fc_rport_compatible_roles(lport, rdata)) {
		FC_RPORT_DBG(rdata, "PLOGI suppressed for incompatible role\n");
		fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);
		return;
	}

1088 1089
	FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n",
		     fc_rport_state(rdata));
1090

1091
	fc_rport_state_enter(rdata, RPORT_ST_PLOGI);
1092

1093
	rdata->maxframe_size = FC_MIN_MAX_PAYLOAD;
1094 1095
	fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
	if (!fp) {
1096
		FC_RPORT_DBG(rdata, "%s frame alloc failed\n", __func__);
1097
		fc_rport_error_retry(rdata, -FC_EX_ALLOC_ERR);
1098 1099 1100 1101
		return;
	}
	rdata->e_d_tov = lport->e_d_tov;

1102
	kref_get(&rdata->kref);
1103
	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PLOGI,
1104
				  fc_rport_plogi_resp, rdata,
1105
				  2 * lport->r_a_tov)) {
1106
		fc_rport_error_retry(rdata, -FC_EX_XMIT_ERR);
1107
		kref_put(&rdata->kref, fc_rport_destroy);
1108
	}
1109 1110 1111
}

/**
1112
 * fc_rport_prli_resp() - Process Login (PRLI) response handler
1113 1114 1115
 * @sp:	       The sequence the PRLI response was on
 * @fp:	       The PRLI response frame
 * @rdata_arg: The remote port that sent the PRLI response
1116 1117 1118 1119 1120 1121
 *
 * Locking Note: This function will be called without the rport lock
 * held, but it will lock, call an _enter_* function or fc_rport_error
 * and then unlock the rport.
 */
static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
1122
			       void *rdata_arg)
1123
{
1124
	struct fc_rport_priv *rdata = rdata_arg;
1125 1126 1127 1128
	struct {
		struct fc_els_prli prli;
		struct fc_els_spp spp;
	} *pp;
1129
	struct fc_els_spp temp_spp;
1130
	struct fc_els_ls_rjt *rjt;
1131
	struct fc4_prov *prov;
1132 1133 1134
	u32 roles = FC_RPORT_ROLE_UNKNOWN;
	u32 fcp_parm = 0;
	u8 op;
1135
	enum fc_els_spp_resp resp_code;
1136

1137
	FC_RPORT_DBG(rdata, "Received a PRLI %s\n", fc_els_resp_type(fp));
1138

1139 1140 1141 1142 1143
	if (fp == ERR_PTR(-FC_EX_CLOSED))
		goto put;

	mutex_lock(&rdata->rp_mutex);

1144
	if (rdata->rp_state != RPORT_ST_PRLI) {
1145 1146
		FC_RPORT_DBG(rdata, "Received a PRLI response, but in state "
			     "%s\n", fc_rport_state(rdata));
1147 1148
		if (IS_ERR(fp))
			goto err;
1149 1150 1151
		goto out;
	}

1152
	if (IS_ERR(fp)) {
1153
		fc_rport_error_retry(rdata, PTR_ERR(fp));
1154 1155 1156
		goto err;
	}

1157 1158 1159
	/* reinitialize remote port roles */
	rdata->ids.roles = FC_RPORT_ROLE_UNKNOWN;

1160 1161 1162
	op = fc_frame_payload_op(fp);
	if (op == ELS_LS_ACC) {
		pp = fc_frame_payload_get(fp, sizeof(*pp));
1163 1164 1165 1166
		if (!pp)
			goto out;

		resp_code = (pp->spp.spp_flags & FC_SPP_RESP_MASK);
1167 1168
		FC_RPORT_DBG(rdata, "PRLI spp_flags = 0x%x spp_type 0x%x\n",
			     pp->spp.spp_flags, pp->spp.spp_type);
1169
		rdata->spp_type = pp->spp.spp_type;
1170 1171
		if (resp_code != FC_SPP_RESP_ACK) {
			if (resp_code == FC_SPP_RESP_CONF)
1172
				fc_rport_error(rdata, -FC_EX_SEQ_ERR);
1173
			else
1174
				fc_rport_error_retry(rdata, -FC_EX_SEQ_ERR);
1175
			goto out;
1176
		}
1177 1178 1179 1180 1181 1182
		if (pp->prli.prli_spp_len < sizeof(pp->spp))
			goto out;

		fcp_parm = ntohl(pp->spp.spp_params);
		if (fcp_parm & FCP_SPPF_RETRY)
			rdata->flags |= FC_RP_FLAGS_RETRY;
1183 1184
		if (fcp_parm & FCP_SPPF_CONF_COMPL)
			rdata->flags |= FC_RP_FLAGS_CONF_REQ;
1185

1186 1187 1188 1189
		/*
		 * Call prli provider if we should act as a target
		 */
		prov = fc_passive_prov[rdata->spp_type];
1190 1191 1192 1193 1194
		if (prov) {
			memset(&temp_spp, 0, sizeof(temp_spp));
			prov->prli(rdata, pp->prli.prli_spp_len,
				   &pp->spp, &temp_spp);
		}
1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205
		/*
		 * Check if the image pair could be established
		 */
		if (rdata->spp_type != FC_TYPE_FCP ||
		    resp_code != FC_SPP_RESP_ACK ||
		    !(pp->spp.spp_flags & FC_SPP_EST_IMG_PAIR)) {
			/*
			 * Nope; we can't use this port as a target.
			 */
			fcp_parm &= ~FCP_SPPF_TARG_FCN;
		}
1206
		rdata->supported_classes = FC_COS_CLASS3;
1207 1208 1209 1210 1211
		if (fcp_parm & FCP_SPPF_INIT_FCN)
			roles |= FC_RPORT_ROLE_FCP_INITIATOR;
		if (fcp_parm & FCP_SPPF_TARG_FCN)
			roles |= FC_RPORT_ROLE_FCP_TARGET;

1212
		rdata->ids.roles = roles;
1213
		fc_rport_enter_rtv(rdata);
1214 1215

	} else {
1216 1217 1218
		rjt = fc_frame_payload_get(fp, sizeof(*rjt));
		FC_RPORT_DBG(rdata, "PRLI ELS rejected, reason %x expl %x\n",
			     rjt->er_reason, rjt->er_explan);
1219
		fc_rport_error_retry(rdata, FC_EX_ELS_RJT);
1220 1221 1222 1223 1224 1225
	}

out:
	fc_frame_free(fp);
err:
	mutex_unlock(&rdata->rp_mutex);
1226
put:
1227
	kref_put(&rdata->kref, fc_rport_destroy);
1228 1229 1230
}

/**
1231 1232
 * fc_rport_enter_prli() - Send Process Login (PRLI) request
 * @rdata: The remote port to send the PRLI request to
1233 1234 1235
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this routine.
1236 1237
 *
 * Reference counting: increments kref when sending ELS
1238
 */
1239
static void fc_rport_enter_prli(struct fc_rport_priv *rdata)
1240 1241 1242 1243 1244 1245 1246
{
	struct fc_lport *lport = rdata->local_port;
	struct {
		struct fc_els_prli prli;
		struct fc_els_spp spp;
	} *pp;
	struct fc_frame *fp;
1247
	struct fc4_prov *prov;
1248

1249 1250 1251 1252 1253 1254 1255 1256 1257
	/*
	 * If the rport is one of the well known addresses
	 * we skip PRLI and RTV and go straight to READY.
	 */
	if (rdata->ids.port_id >= FC_FID_DOM_MGR) {
		fc_rport_enter_ready(rdata);
		return;
	}

1258 1259 1260 1261 1262 1263 1264 1265 1266
	/*
	 * And if the local port does not support the initiator function
	 * there's no need to send a PRLI, either.
	 */
	if (!(lport->service_params & FCP_SPPF_INIT_FCN)) {
		    fc_rport_enter_ready(rdata);
		    return;
	}

1267 1268
	FC_RPORT_DBG(rdata, "Port entered PRLI state from %s state\n",
		     fc_rport_state(rdata));
1269

1270
	fc_rport_state_enter(rdata, RPORT_ST_PRLI);
1271 1272 1273

	fp = fc_frame_alloc(lport, sizeof(*pp));
	if (!fp) {
1274
		fc_rport_error_retry(rdata, -FC_EX_ALLOC_ERR);
1275 1276 1277
		return;
	}

1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289
	fc_prli_fill(lport, fp);

	prov = fc_passive_prov[FC_TYPE_FCP];
	if (prov) {
		pp = fc_frame_payload_get(fp, sizeof(*pp));
		prov->prli(rdata, sizeof(pp->spp), NULL, &pp->spp);
	}

	fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rdata->ids.port_id,
		       fc_host_port_id(lport->host), FC_TYPE_ELS,
		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);

1290
	kref_get(&rdata->kref);
1291 1292
	if (!fc_exch_seq_send(lport, fp, fc_rport_prli_resp,
			      NULL, rdata, 2 * lport->r_a_tov)) {
1293
		fc_rport_error_retry(rdata, -FC_EX_XMIT_ERR);
1294
		kref_put(&rdata->kref, fc_rport_destroy);
1295
	}
1296 1297 1298
}

/**
1299
 * fc_rport_rtv_resp() - Handler for Request Timeout Value (RTV) responses
1300 1301 1302
 * @sp:	       The sequence the RTV was on
 * @fp:	       The RTV response frame
 * @rdata_arg: The remote port that sent the RTV response
1303 1304 1305 1306 1307 1308 1309 1310
 *
 * Many targets don't seem to support this.
 *
 * Locking Note: This function will be called without the rport lock
 * held, but it will lock, call an _enter_* function or fc_rport_error
 * and then unlock the rport.
 */
static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
1311
			      void *rdata_arg)
1312
{
1313
	struct fc_rport_priv *rdata = rdata_arg;
1314 1315
	u8 op;

1316
	FC_RPORT_DBG(rdata, "Received a RTV %s\n", fc_els_resp_type(fp));
1317

1318 1319 1320 1321 1322
	if (fp == ERR_PTR(-FC_EX_CLOSED))
		goto put;

	mutex_lock(&rdata->rp_mutex);

1323
	if (rdata->rp_state != RPORT_ST_RTV) {
1324 1325
		FC_RPORT_DBG(rdata, "Received a RTV response, but in state "
			     "%s\n", fc_rport_state(rdata));
1326 1327
		if (IS_ERR(fp))
			goto err;
1328 1329 1330
		goto out;
	}

1331
	if (IS_ERR(fp)) {
1332
		fc_rport_error(rdata, PTR_ERR(fp));
1333 1334 1335
		goto err;
	}

1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347
	op = fc_frame_payload_op(fp);
	if (op == ELS_LS_ACC) {
		struct fc_els_rtv_acc *rtv;
		u32 toq;
		u32 tov;

		rtv = fc_frame_payload_get(fp, sizeof(*rtv));
		if (rtv) {
			toq = ntohl(rtv->rtv_toq);
			tov = ntohl(rtv->rtv_r_a_tov);
			if (tov == 0)
				tov = 1;
1348 1349
			if (tov > rdata->r_a_tov)
				rdata->r_a_tov = tov;
1350 1351 1352 1353 1354
			tov = ntohl(rtv->rtv_e_d_tov);
			if (toq & FC_ELS_RTV_EDRES)
				tov /= 1000000;
			if (tov == 0)
				tov = 1;
1355 1356
			if (tov > rdata->e_d_tov)
				rdata->e_d_tov = tov;
1357 1358 1359
		}
	}

1360
	fc_rport_enter_ready(rdata);
1361 1362 1363 1364 1365

out:
	fc_frame_free(fp);
err:
	mutex_unlock(&rdata->rp_mutex);
1366
put:
1367
	kref_put(&rdata->kref, fc_rport_destroy);
1368 1369 1370
}

/**
1371 1372
 * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request
 * @rdata: The remote port to send the RTV request to
1373 1374 1375
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this routine.
1376 1377
 *
 * Reference counting: increments kref when sending ELS
1378
 */
1379
static void fc_rport_enter_rtv(struct fc_rport_priv *rdata)
1380 1381 1382 1383
{
	struct fc_frame *fp;
	struct fc_lport *lport = rdata->local_port;

1384 1385
	FC_RPORT_DBG(rdata, "Port entered RTV state from %s state\n",
		     fc_rport_state(rdata));
1386

1387
	fc_rport_state_enter(rdata, RPORT_ST_RTV);
1388 1389 1390

	fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv));
	if (!fp) {
1391
		fc_rport_error_retry(rdata, -FC_EX_ALLOC_ERR);
1392 1393 1394
		return;
	}

1395
	kref_get(&rdata->kref);
1396
	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_RTV,
1397
				  fc_rport_rtv_resp, rdata,
1398
				  2 * lport->r_a_tov)) {
1399
		fc_rport_error_retry(rdata, -FC_EX_XMIT_ERR);
1400
		kref_put(&rdata->kref, fc_rport_destroy);
1401
	}
1402 1403
}

1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424
/**
 * fc_rport_recv_rtv_req() - Handler for Read Timeout Value (RTV) requests
 * @rdata: The remote port that sent the RTV request
 * @in_fp: The RTV request frame
 *
 * Locking Note:  Called with the lport and rport locks held.
 */
static void fc_rport_recv_rtv_req(struct fc_rport_priv *rdata,
				  struct fc_frame *in_fp)
{
	struct fc_lport *lport = rdata->local_port;
	struct fc_frame *fp;
	struct fc_els_rtv_acc *rtv;
	struct fc_seq_els_data rjt_data;

	FC_RPORT_DBG(rdata, "Received RTV request\n");

	fp = fc_frame_alloc(lport, sizeof(*rtv));
	if (!fp) {
		rjt_data.reason = ELS_RJT_UNAB;
		rjt_data.reason = ELS_EXPL_INSUF_RES;
1425
		fc_seq_els_rsp_send(in_fp, ELS_LS_RJT, &rjt_data);
1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438
		goto drop;
	}
	rtv = fc_frame_payload_get(fp, sizeof(*rtv));
	rtv->rtv_cmd = ELS_LS_ACC;
	rtv->rtv_r_a_tov = htonl(lport->r_a_tov);
	rtv->rtv_e_d_tov = htonl(lport->e_d_tov);
	rtv->rtv_toq = 0;
	fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
	lport->tt.frame_send(lport, fp);
drop:
	fc_frame_free(in_fp);
}

1439 1440 1441 1442 1443 1444 1445
/**
 * fc_rport_logo_resp() - Handler for logout (LOGO) responses
 * @sp:	       The sequence the LOGO was on
 * @fp:	       The LOGO response frame
 * @lport_arg: The local port
 */
static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
1446
			       void *rdata_arg)
1447
{
1448 1449
	struct fc_rport_priv *rdata = rdata_arg;
	struct fc_lport *lport = rdata->local_port;
1450 1451 1452

	FC_RPORT_ID_DBG(lport, fc_seq_exch(sp)->did,
			"Received a LOGO %s\n", fc_els_resp_type(fp));
1453 1454
	if (!IS_ERR(fp))
		fc_frame_free(fp);
1455
	kref_put(&rdata->kref, fc_rport_destroy);
1456 1457
}

1458
/**
1459 1460
 * fc_rport_enter_logo() - Send a logout (LOGO) request
 * @rdata: The remote port to send the LOGO request to
1461 1462 1463
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this routine.
1464 1465
 *
 * Reference counting: increments kref when sending ELS
1466
 */
1467
static void fc_rport_enter_logo(struct fc_rport_priv *rdata)
1468 1469 1470 1471
{
	struct fc_lport *lport = rdata->local_port;
	struct fc_frame *fp;

1472
	FC_RPORT_DBG(rdata, "Port sending LOGO from %s state\n",
1473
		     fc_rport_state(rdata));
1474 1475

	fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo));
1476
	if (!fp)
1477
		return;
1478 1479 1480
	kref_get(&rdata->kref);
	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_LOGO,
				  fc_rport_logo_resp, rdata, 0))
1481
		kref_put(&rdata->kref, fc_rport_destroy);
1482 1483
}

1484
/**
1485 1486 1487 1488
 * fc_rport_els_adisc_resp() - Handler for Address Discovery (ADISC) responses
 * @sp:	       The sequence the ADISC response was on
 * @fp:	       The ADISC response frame
 * @rdata_arg: The remote port that sent the ADISC response
1489 1490 1491 1492 1493 1494
 *
 * Locking Note: This function will be called without the rport lock
 * held, but it will lock, call an _enter_* function or fc_rport_error
 * and then unlock the rport.
 */
static void fc_rport_adisc_resp(struct fc_seq *sp, struct fc_frame *fp,
1495
				void *rdata_arg)
1496 1497 1498 1499 1500 1501 1502
{
	struct fc_rport_priv *rdata = rdata_arg;
	struct fc_els_adisc *adisc;
	u8 op;

	FC_RPORT_DBG(rdata, "Received a ADISC response\n");

1503 1504 1505 1506 1507
	if (fp == ERR_PTR(-FC_EX_CLOSED))
		goto put;

	mutex_lock(&rdata->rp_mutex);

1508 1509 1510 1511 1512 1513 1514 1515 1516
	if (rdata->rp_state != RPORT_ST_ADISC) {
		FC_RPORT_DBG(rdata, "Received a ADISC resp but in state %s\n",
			     fc_rport_state(rdata));
		if (IS_ERR(fp))
			goto err;
		goto out;
	}

	if (IS_ERR(fp)) {
1517
		fc_rport_error(rdata, PTR_ERR(fp));
1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532
		goto err;
	}

	/*
	 * If address verification failed.  Consider us logged out of the rport.
	 * Since the rport is still in discovery, we want to be
	 * logged in, so go to PLOGI state.  Otherwise, go back to READY.
	 */
	op = fc_frame_payload_op(fp);
	adisc = fc_frame_payload_get(fp, sizeof(*adisc));
	if (op != ELS_LS_ACC || !adisc ||
	    ntoh24(adisc->adisc_port_id) != rdata->ids.port_id ||
	    get_unaligned_be64(&adisc->adisc_wwpn) != rdata->ids.port_name ||
	    get_unaligned_be64(&adisc->adisc_wwnn) != rdata->ids.node_name) {
		FC_RPORT_DBG(rdata, "ADISC error or mismatch\n");
1533
		fc_rport_enter_flogi(rdata);
1534 1535 1536 1537 1538 1539 1540 1541
	} else {
		FC_RPORT_DBG(rdata, "ADISC OK\n");
		fc_rport_enter_ready(rdata);
	}
out:
	fc_frame_free(fp);
err:
	mutex_unlock(&rdata->rp_mutex);
1542
put:
1543
	kref_put(&rdata->kref, fc_rport_destroy);
1544 1545 1546
}

/**
1547 1548
 * fc_rport_enter_adisc() - Send Address Discover (ADISC) request
 * @rdata: The remote port to send the ADISC request to
1549 1550 1551
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this routine.
1552 1553
 *
 * Reference counting: increments kref when sending ELS
1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566
 */
static void fc_rport_enter_adisc(struct fc_rport_priv *rdata)
{
	struct fc_lport *lport = rdata->local_port;
	struct fc_frame *fp;

	FC_RPORT_DBG(rdata, "sending ADISC from %s state\n",
		     fc_rport_state(rdata));

	fc_rport_state_enter(rdata, RPORT_ST_ADISC);

	fp = fc_frame_alloc(lport, sizeof(struct fc_els_adisc));
	if (!fp) {
1567
		fc_rport_error_retry(rdata, -FC_EX_ALLOC_ERR);
1568 1569
		return;
	}
1570
	kref_get(&rdata->kref);
1571
	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_ADISC,
1572
				  fc_rport_adisc_resp, rdata,
1573
				  2 * lport->r_a_tov)) {
1574
		fc_rport_error_retry(rdata, -FC_EX_XMIT_ERR);
1575
		kref_put(&rdata->kref, fc_rport_destroy);
1576
	}
1577 1578
}

1579
/**
1580 1581 1582
 * fc_rport_recv_adisc_req() - Handler for Address Discovery (ADISC) requests
 * @rdata: The remote port that sent the ADISC request
 * @in_fp: The ADISC request frame
1583 1584 1585 1586
 *
 * Locking Note:  Called with the lport and rport locks held.
 */
static void fc_rport_recv_adisc_req(struct fc_rport_priv *rdata,
1587
				    struct fc_frame *in_fp)
1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599
{
	struct fc_lport *lport = rdata->local_port;
	struct fc_frame *fp;
	struct fc_els_adisc *adisc;
	struct fc_seq_els_data rjt_data;

	FC_RPORT_DBG(rdata, "Received ADISC request\n");

	adisc = fc_frame_payload_get(in_fp, sizeof(*adisc));
	if (!adisc) {
		rjt_data.reason = ELS_RJT_PROT;
		rjt_data.explan = ELS_EXPL_INV_LEN;
1600
		fc_seq_els_rsp_send(in_fp, ELS_LS_RJT, &rjt_data);
1601 1602 1603 1604 1605 1606 1607 1608 1609
		goto drop;
	}

	fp = fc_frame_alloc(lport, sizeof(*adisc));
	if (!fp)
		goto drop;
	fc_adisc_fill(lport, fp);
	adisc = fc_frame_payload_get(fp, sizeof(*adisc));
	adisc->adisc_cmd = ELS_LS_ACC;
1610 1611
	fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
	lport->tt.frame_send(lport, fp);
1612 1613 1614 1615
drop:
	fc_frame_free(in_fp);
}

1616 1617 1618 1619 1620 1621 1622 1623 1624
/**
 * fc_rport_recv_rls_req() - Handle received Read Link Status request
 * @rdata: The remote port that sent the RLS request
 * @rx_fp: The PRLI request frame
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this function.
 */
static void fc_rport_recv_rls_req(struct fc_rport_priv *rdata,
1625
				  struct fc_frame *rx_fp)
1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670

{
	struct fc_lport *lport = rdata->local_port;
	struct fc_frame *fp;
	struct fc_els_rls *rls;
	struct fc_els_rls_resp *rsp;
	struct fc_els_lesb *lesb;
	struct fc_seq_els_data rjt_data;
	struct fc_host_statistics *hst;

	FC_RPORT_DBG(rdata, "Received RLS request while in state %s\n",
		     fc_rport_state(rdata));

	rls = fc_frame_payload_get(rx_fp, sizeof(*rls));
	if (!rls) {
		rjt_data.reason = ELS_RJT_PROT;
		rjt_data.explan = ELS_EXPL_INV_LEN;
		goto out_rjt;
	}

	fp = fc_frame_alloc(lport, sizeof(*rsp));
	if (!fp) {
		rjt_data.reason = ELS_RJT_UNAB;
		rjt_data.explan = ELS_EXPL_INSUF_RES;
		goto out_rjt;
	}

	rsp = fc_frame_payload_get(fp, sizeof(*rsp));
	memset(rsp, 0, sizeof(*rsp));
	rsp->rls_cmd = ELS_LS_ACC;
	lesb = &rsp->rls_lesb;
	if (lport->tt.get_lesb) {
		/* get LESB from LLD if it supports it */
		lport->tt.get_lesb(lport, lesb);
	} else {
		fc_get_host_stats(lport->host);
		hst = &lport->host_stats;
		lesb->lesb_link_fail = htonl(hst->link_failure_count);
		lesb->lesb_sync_loss = htonl(hst->loss_of_sync_count);
		lesb->lesb_sig_loss = htonl(hst->loss_of_signal_count);
		lesb->lesb_prim_err = htonl(hst->prim_seq_protocol_err_count);
		lesb->lesb_inv_word = htonl(hst->invalid_tx_word_count);
		lesb->lesb_inv_crc = htonl(hst->invalid_crc_count);
	}

1671 1672
	fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
	lport->tt.frame_send(lport, fp);
1673 1674 1675
	goto out;

out_rjt:
1676
	fc_seq_els_rsp_send(rx_fp, ELS_LS_RJT, &rjt_data);
1677 1678 1679 1680
out:
	fc_frame_free(rx_fp);
}

1681
/**
1682 1683 1684
 * fc_rport_recv_els_req() - Handler for validated ELS requests
 * @lport: The local port that received the ELS request
 * @fp:	   The ELS request frame
1685 1686 1687
 *
 * Handle incoming ELS requests that require port login.
 * The ELS opcode has already been validated by the caller.
1688
 *
1689
 * Locking Note: Called with the lport lock held.
1690 1691
 *
 * Reference counting: does not modify kref
1692
 */
1693
static void fc_rport_recv_els_req(struct fc_lport *lport, struct fc_frame *fp)
1694
{
1695
	struct fc_rport_priv *rdata;
1696 1697
	struct fc_seq_els_data els_data;

1698
	rdata = fc_rport_lookup(lport, fc_frame_sid(fp));
1699 1700 1701 1702
	if (!rdata) {
		FC_RPORT_ID_DBG(lport, fc_frame_sid(fp),
				"Received ELS 0x%02x from non-logged-in port\n",
				fc_frame_payload_op(fp));
1703
		goto reject;
1704
	}
1705

1706 1707
	mutex_lock(&rdata->rp_mutex);

1708 1709 1710 1711
	switch (rdata->rp_state) {
	case RPORT_ST_PRLI:
	case RPORT_ST_RTV:
	case RPORT_ST_READY:
1712
	case RPORT_ST_ADISC:
1713
		break;
1714 1715 1716 1717 1718 1719
	case RPORT_ST_PLOGI:
		if (fc_frame_payload_op(fp) == ELS_PRLI) {
			FC_RPORT_DBG(rdata, "Reject ELS PRLI "
				     "while in state %s\n",
				     fc_rport_state(rdata));
			mutex_unlock(&rdata->rp_mutex);
1720
			kref_put(&rdata->kref, fc_rport_destroy);
1721 1722
			goto busy;
		}
1723
	default:
1724 1725 1726
		FC_RPORT_DBG(rdata,
			     "Reject ELS 0x%02x while in state %s\n",
			     fc_frame_payload_op(fp), fc_rport_state(rdata));
1727
		mutex_unlock(&rdata->rp_mutex);
1728
		kref_put(&rdata->kref, fc_rport_destroy);
1729 1730 1731 1732
		goto reject;
	}

	switch (fc_frame_payload_op(fp)) {
1733
	case ELS_PRLI:
1734
		fc_rport_recv_prli_req(rdata, fp);
1735 1736
		break;
	case ELS_PRLO:
1737
		fc_rport_recv_prlo_req(rdata, fp);
1738
		break;
1739
	case ELS_ADISC:
1740
		fc_rport_recv_adisc_req(rdata, fp);
1741
		break;
1742
	case ELS_RRQ:
1743
		fc_seq_els_rsp_send(fp, ELS_RRQ, NULL);
1744
		fc_frame_free(fp);
1745 1746
		break;
	case ELS_REC:
1747
		fc_seq_els_rsp_send(fp, ELS_REC, NULL);
1748
		fc_frame_free(fp);
1749
		break;
1750
	case ELS_RLS:
1751
		fc_rport_recv_rls_req(rdata, fp);
1752
		break;
1753 1754 1755
	case ELS_RTV:
		fc_rport_recv_rtv_req(rdata, fp);
		break;
1756
	default:
1757
		fc_frame_free(fp);	/* can't happen */
1758
		break;
1759 1760 1761
	}

	mutex_unlock(&rdata->rp_mutex);
1762
	kref_put(&rdata->kref, fc_rport_destroy);
1763 1764 1765
	return;

reject:
1766 1767
	els_data.reason = ELS_RJT_UNAB;
	els_data.explan = ELS_EXPL_PLOGI_REQD;
1768
	fc_seq_els_rsp_send(fp, ELS_LS_RJT, &els_data);
1769
	fc_frame_free(fp);
1770 1771 1772 1773 1774
	return;

busy:
	els_data.reason = ELS_RJT_BUSY;
	els_data.explan = ELS_EXPL_NONE;
1775
	fc_seq_els_rsp_send(fp, ELS_LS_RJT, &els_data);
1776 1777
	fc_frame_free(fp);
	return;
1778 1779 1780
}

/**
1781 1782
 * fc_rport_recv_req() - Handler for requests
 * @lport: The local port that received the request
1783
 * @fp:	   The request frame
1784 1785
 *
 * Locking Note: Called with the lport lock held.
1786 1787
 *
 * Reference counting: does not modify kref
1788
 */
1789
void fc_rport_recv_req(struct fc_lport *lport, struct fc_frame *fp)
1790 1791 1792 1793
{
	struct fc_seq_els_data els_data;

	/*
1794
	 * Handle FLOGI, PLOGI and LOGO requests separately, since they
1795 1796 1797 1798 1799
	 * don't require prior login.
	 * Check for unsupported opcodes first and reject them.
	 * For some ops, it would be incorrect to reject with "PLOGI required".
	 */
	switch (fc_frame_payload_op(fp)) {
1800
	case ELS_FLOGI:
1801
		fc_rport_recv_flogi_req(lport, fp);
1802
		break;
1803
	case ELS_PLOGI:
1804
		fc_rport_recv_plogi_req(lport, fp);
1805 1806
		break;
	case ELS_LOGO:
1807
		fc_rport_recv_logo_req(lport, fp);
1808 1809 1810
		break;
	case ELS_PRLI:
	case ELS_PRLO:
1811
	case ELS_ADISC:
1812 1813
	case ELS_RRQ:
	case ELS_REC:
1814
	case ELS_RLS:
1815
	case ELS_RTV:
1816
		fc_rport_recv_els_req(lport, fp);
1817 1818 1819 1820
		break;
	default:
		els_data.reason = ELS_RJT_UNSUP;
		els_data.explan = ELS_EXPL_NONE;
1821
		fc_seq_els_rsp_send(fp, ELS_LS_RJT, &els_data);
1822
		fc_frame_free(fp);
1823 1824
		break;
	}
1825
}
1826
EXPORT_SYMBOL(fc_rport_recv_req);
1827 1828

/**
1829 1830 1831
 * fc_rport_recv_plogi_req() - Handler for Port Login (PLOGI) requests
 * @lport: The local port that received the PLOGI request
 * @rx_fp: The PLOGI request frame
1832
 *
1833
 * Locking Note: The rport lock is held before calling this function.
1834 1835
 *
 * Reference counting: increments kref on return
1836
 */
1837
static void fc_rport_recv_plogi_req(struct fc_lport *lport,
1838
				    struct fc_frame *rx_fp)
1839
{
1840 1841
	struct fc_disc *disc;
	struct fc_rport_priv *rdata;
1842 1843 1844
	struct fc_frame *fp = rx_fp;
	struct fc_els_flogi *pl;
	struct fc_seq_els_data rjt_data;
1845
	u32 sid;
1846

1847
	sid = fc_frame_sid(fp);
1848

1849
	FC_RPORT_ID_DBG(lport, sid, "Received PLOGI request\n");
1850 1851 1852

	pl = fc_frame_payload_get(fp, sizeof(*pl));
	if (!pl) {
1853 1854 1855 1856
		FC_RPORT_ID_DBG(lport, sid, "Received PLOGI too short\n");
		rjt_data.reason = ELS_RJT_PROT;
		rjt_data.explan = ELS_EXPL_INV_LEN;
		goto reject;
1857
	}
1858 1859 1860

	disc = &lport->disc;
	mutex_lock(&disc->disc_mutex);
1861
	rdata = fc_rport_create(lport, sid);
1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873
	if (!rdata) {
		mutex_unlock(&disc->disc_mutex);
		rjt_data.reason = ELS_RJT_UNAB;
		rjt_data.explan = ELS_EXPL_INSUF_RES;
		goto reject;
	}

	mutex_lock(&rdata->rp_mutex);
	mutex_unlock(&disc->disc_mutex);

	rdata->ids.port_name = get_unaligned_be64(&pl->fl_wwpn);
	rdata->ids.node_name = get_unaligned_be64(&pl->fl_wwnn);
1874 1875

	/*
1876
	 * If the rport was just created, possibly due to the incoming PLOGI,
1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887
	 * set the state appropriately and accept the PLOGI.
	 *
	 * If we had also sent a PLOGI, and if the received PLOGI is from a
	 * higher WWPN, we accept it, otherwise an LS_RJT is sent with reason
	 * "command already in progress".
	 *
	 * XXX TBD: If the session was ready before, the PLOGI should result in
	 * all outstanding exchanges being reset.
	 */
	switch (rdata->rp_state) {
	case RPORT_ST_INIT:
1888
		FC_RPORT_DBG(rdata, "Received PLOGI in INIT state\n");
1889
		break;
1890 1891 1892
	case RPORT_ST_PLOGI_WAIT:
		FC_RPORT_DBG(rdata, "Received PLOGI in PLOGI_WAIT state\n");
		break;
1893
	case RPORT_ST_PLOGI:
1894 1895 1896 1897 1898 1899 1900
		FC_RPORT_DBG(rdata, "Received PLOGI in PLOGI state\n");
		if (rdata->ids.port_name < lport->wwpn) {
			mutex_unlock(&rdata->rp_mutex);
			rjt_data.reason = ELS_RJT_INPROG;
			rjt_data.explan = ELS_EXPL_NONE;
			goto reject;
		}
1901 1902
		break;
	case RPORT_ST_PRLI:
1903
	case RPORT_ST_RTV:
1904
	case RPORT_ST_READY:
1905 1906 1907 1908
	case RPORT_ST_ADISC:
		FC_RPORT_DBG(rdata, "Received PLOGI in logged-in state %d "
			     "- ignored for now\n", rdata->rp_state);
		/* XXX TBD - should reset */
1909
		break;
1910
	case RPORT_ST_FLOGI:
1911
	case RPORT_ST_DELETE:
1912 1913 1914 1915 1916 1917
		FC_RPORT_DBG(rdata, "Received PLOGI in state %s - send busy\n",
			     fc_rport_state(rdata));
		mutex_unlock(&rdata->rp_mutex);
		rjt_data.reason = ELS_RJT_BUSY;
		rjt_data.explan = ELS_EXPL_NONE;
		goto reject;
1918
	}
1919 1920 1921 1922 1923 1924 1925
	if (!fc_rport_compatible_roles(lport, rdata)) {
		FC_RPORT_DBG(rdata, "Received PLOGI for incompatible role\n");
		mutex_unlock(&rdata->rp_mutex);
		rjt_data.reason = ELS_RJT_LOGIC;
		rjt_data.explan = ELS_EXPL_NONE;
		goto reject;
	}
1926

1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939
	/*
	 * Get session payload size from incoming PLOGI.
	 */
	rdata->maxframe_size = fc_plogi_get_maxframe(pl, lport->mfs);

	/*
	 * Send LS_ACC.	 If this fails, the originator should retry.
	 */
	fp = fc_frame_alloc(lport, sizeof(*pl));
	if (!fp)
		goto out;

	fc_plogi_fill(lport, fp, ELS_LS_ACC);
1940 1941
	fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
	lport->tt.frame_send(lport, fp);
1942 1943 1944
	fc_rport_enter_prli(rdata);
out:
	mutex_unlock(&rdata->rp_mutex);
1945
	fc_frame_free(rx_fp);
1946 1947 1948
	return;

reject:
1949
	fc_seq_els_rsp_send(fp, ELS_LS_RJT, &rjt_data);
1950
	fc_frame_free(fp);
1951 1952 1953
}

/**
1954 1955 1956
 * fc_rport_recv_prli_req() - Handler for process login (PRLI) requests
 * @rdata: The remote port that sent the PRLI request
 * @rx_fp: The PRLI request frame
1957
 *
1958
 * Locking Note: The rport lock is expected to be held before calling
1959 1960
 * this function.
 */
1961
static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
1962
				   struct fc_frame *rx_fp)
1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975
{
	struct fc_lport *lport = rdata->local_port;
	struct fc_frame *fp;
	struct {
		struct fc_els_prli prli;
		struct fc_els_spp spp;
	} *pp;
	struct fc_els_spp *rspp;	/* request service param page */
	struct fc_els_spp *spp;	/* response spp */
	unsigned int len;
	unsigned int plen;
	enum fc_els_spp_resp resp;
	struct fc_seq_els_data rjt_data;
1976
	struct fc4_prov *prov;
1977

1978 1979
	FC_RPORT_DBG(rdata, "Received PRLI request while in state %s\n",
		     fc_rport_state(rdata));
1980

1981
	len = fr_len(rx_fp) - sizeof(struct fc_frame_header);
1982
	pp = fc_frame_payload_get(rx_fp, sizeof(*pp));
1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000
	if (!pp)
		goto reject_len;
	plen = ntohs(pp->prli.prli_len);
	if ((plen % 4) != 0 || plen > len || plen < 16)
		goto reject_len;
	if (plen < len)
		len = plen;
	plen = pp->prli.prli_spp_len;
	if ((plen % 4) != 0 || plen < sizeof(*spp) ||
	    plen > len || len < sizeof(*pp) || plen < 12)
		goto reject_len;
	rspp = &pp->spp;

	fp = fc_frame_alloc(lport, len);
	if (!fp) {
		rjt_data.reason = ELS_RJT_UNAB;
		rjt_data.explan = ELS_EXPL_INSUF_RES;
		goto reject;
2001
	}
2002 2003 2004 2005 2006 2007 2008
	pp = fc_frame_payload_get(fp, len);
	WARN_ON(!pp);
	memset(pp, 0, len);
	pp->prli.prli_cmd = ELS_LS_ACC;
	pp->prli.prli_spp_len = plen;
	pp->prli.prli_len = htons(len);
	len -= sizeof(struct fc_els_prli);
2009

2010 2011 2012 2013 2014 2015
	/*
	 * Go through all the service parameter pages and build
	 * response.  If plen indicates longer SPP than standard,
	 * use that.  The entire response has been pre-cleared above.
	 */
	spp = &pp->spp;
2016
	mutex_lock(&fc_prov_mutex);
2017
	while (len >= plen) {
2018
		rdata->spp_type = rspp->spp_type;
2019 2020
		spp->spp_type = rspp->spp_type;
		spp->spp_type_ext = rspp->spp_type_ext;
2021 2022 2023
		resp = 0;

		if (rspp->spp_type < FC_FC4_PROV_SIZE) {
2024 2025
			enum fc_els_spp_resp active = 0, passive = 0;

2026 2027
			prov = fc_active_prov[rspp->spp_type];
			if (prov)
2028
				active = prov->prli(rdata, plen, rspp, spp);
2029
			prov = fc_passive_prov[rspp->spp_type];
2030
			if (prov)
2031
				passive = prov->prli(rdata, plen, rspp, spp);
2032 2033 2034 2035 2036 2037 2038
			if (!active || passive == FC_SPP_RESP_ACK)
				resp = passive;
			else
				resp = active;
			FC_RPORT_DBG(rdata, "PRLI rspp type %x "
				     "active %x passive %x\n",
				     rspp->spp_type, active, passive);
2039 2040 2041 2042 2043 2044
		}
		if (!resp) {
			if (spp->spp_flags & FC_SPP_EST_IMG_PAIR)
				resp |= FC_SPP_RESP_CONF;
			else
				resp |= FC_SPP_RESP_INVL;
2045
		}
2046 2047 2048 2049 2050
		spp->spp_flags |= resp;
		len -= plen;
		rspp = (struct fc_els_spp *)((char *)rspp + plen);
		spp = (struct fc_els_spp *)((char *)spp + plen);
	}
2051
	mutex_unlock(&fc_prov_mutex);
2052 2053 2054 2055

	/*
	 * Send LS_ACC.	 If this fails, the originator should retry.
	 */
2056 2057
	fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
	lport->tt.frame_send(lport, fp);
2058 2059 2060 2061 2062 2063 2064

	goto drop;

reject_len:
	rjt_data.reason = ELS_RJT_PROT;
	rjt_data.explan = ELS_EXPL_INV_LEN;
reject:
2065
	fc_seq_els_rsp_send(rx_fp, ELS_LS_RJT, &rjt_data);
2066
drop:
2067 2068 2069 2070
	fc_frame_free(rx_fp);
}

/**
2071 2072
 * fc_rport_recv_prlo_req() - Handler for process logout (PRLO) requests
 * @rdata: The remote port that sent the PRLO request
2073
 * @rx_fp: The PRLO request frame
2074
 *
2075
 * Locking Note: The rport lock is expected to be held before calling
2076 2077
 * this function.
 */
2078
static void fc_rport_recv_prlo_req(struct fc_rport_priv *rdata,
2079
				   struct fc_frame *rx_fp)
2080 2081
{
	struct fc_lport *lport = rdata->local_port;
2082 2083 2084 2085 2086 2087 2088 2089 2090
	struct fc_frame *fp;
	struct {
		struct fc_els_prlo prlo;
		struct fc_els_spp spp;
	} *pp;
	struct fc_els_spp *rspp;	/* request service param page */
	struct fc_els_spp *spp;		/* response spp */
	unsigned int len;
	unsigned int plen;
2091 2092
	struct fc_seq_els_data rjt_data;

2093 2094
	FC_RPORT_DBG(rdata, "Received PRLO request while in state %s\n",
		     fc_rport_state(rdata));
2095

2096
	len = fr_len(rx_fp) - sizeof(struct fc_frame_header);
2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125
	pp = fc_frame_payload_get(rx_fp, sizeof(*pp));
	if (!pp)
		goto reject_len;
	plen = ntohs(pp->prlo.prlo_len);
	if (plen != 20)
		goto reject_len;
	if (plen < len)
		len = plen;

	rspp = &pp->spp;

	fp = fc_frame_alloc(lport, len);
	if (!fp) {
		rjt_data.reason = ELS_RJT_UNAB;
		rjt_data.explan = ELS_EXPL_INSUF_RES;
		goto reject;
	}

	pp = fc_frame_payload_get(fp, len);
	WARN_ON(!pp);
	memset(pp, 0, len);
	pp->prlo.prlo_cmd = ELS_LS_ACC;
	pp->prlo.prlo_obs = 0x10;
	pp->prlo.prlo_len = htons(len);
	spp = &pp->spp;
	spp->spp_type = rspp->spp_type;
	spp->spp_type_ext = rspp->spp_type_ext;
	spp->spp_flags = FC_SPP_RESP_ACK;

2126
	fc_rport_enter_prli(rdata);
2127

2128 2129
	fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
	lport->tt.frame_send(lport, fp);
2130 2131 2132 2133 2134 2135
	goto drop;

reject_len:
	rjt_data.reason = ELS_RJT_PROT;
	rjt_data.explan = ELS_EXPL_INV_LEN;
reject:
2136
	fc_seq_els_rsp_send(rx_fp, ELS_LS_RJT, &rjt_data);
2137 2138
drop:
	fc_frame_free(rx_fp);
2139 2140 2141
}

/**
2142 2143 2144
 * fc_rport_recv_logo_req() - Handler for logout (LOGO) requests
 * @lport: The local port that received the LOGO request
 * @fp:	   The LOGO request frame
2145
 *
2146
 * Locking Note: The rport lock is expected to be held before calling
2147
 * this function.
2148 2149
 *
 * Reference counting: drops kref on return
2150
 */
2151
static void fc_rport_recv_logo_req(struct fc_lport *lport, struct fc_frame *fp)
2152
{
2153 2154
	struct fc_rport_priv *rdata;
	u32 sid;
2155

2156
	fc_seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
2157

2158
	sid = fc_frame_sid(fp);
2159

2160
	rdata = fc_rport_lookup(lport, sid);
2161 2162 2163 2164
	if (rdata) {
		mutex_lock(&rdata->rp_mutex);
		FC_RPORT_DBG(rdata, "Received LOGO request while in state %s\n",
			     fc_rport_state(rdata));
2165

2166
		fc_rport_enter_delete(rdata, RPORT_EV_STOP);
2167
		mutex_unlock(&rdata->rp_mutex);
2168
		kref_put(&rdata->kref, fc_rport_destroy);
2169 2170 2171
	} else
		FC_RPORT_ID_DBG(lport, sid,
				"Received LOGO from non-logged-in port\n");
2172 2173 2174
	fc_frame_free(fp);
}

2175 2176 2177
/**
 * fc_rport_flush_queue() - Flush the rport_event_queue
 */
2178
void fc_rport_flush_queue(void)
2179 2180 2181
{
	flush_workqueue(rport_event_queue);
}
2182
EXPORT_SYMBOL(fc_rport_flush_queue);
2183

2184 2185 2186 2187
/**
 * fc_rport_init() - Initialize the remote port layer for a local port
 * @lport: The local port to initialize the remote port layer for
 */
2188 2189 2190 2191 2192 2193
int fc_rport_init(struct fc_lport *lport)
{
	return 0;
}
EXPORT_SYMBOL(fc_rport_init);

2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220
/**
 * fc_rport_fcp_prli() - Handle incoming PRLI for the FCP initiator.
 * @rdata: remote port private
 * @spp_len: service parameter page length
 * @rspp: received service parameter page
 * @spp: response service parameter page
 *
 * Returns the value for the response code to be placed in spp_flags;
 * Returns 0 if not an initiator.
 */
static int fc_rport_fcp_prli(struct fc_rport_priv *rdata, u32 spp_len,
			     const struct fc_els_spp *rspp,
			     struct fc_els_spp *spp)
{
	struct fc_lport *lport = rdata->local_port;
	u32 fcp_parm;

	fcp_parm = ntohl(rspp->spp_params);
	rdata->ids.roles = FC_RPORT_ROLE_UNKNOWN;
	if (fcp_parm & FCP_SPPF_INIT_FCN)
		rdata->ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
	if (fcp_parm & FCP_SPPF_TARG_FCN)
		rdata->ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
	if (fcp_parm & FCP_SPPF_RETRY)
		rdata->flags |= FC_RP_FLAGS_RETRY;
	rdata->supported_classes = FC_COS_CLASS3;

2221
	if (!(lport->service_params & FCP_SPPF_INIT_FCN))
2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266
		return 0;

	spp->spp_flags |= rspp->spp_flags & FC_SPP_EST_IMG_PAIR;

	/*
	 * OR in our service parameters with other providers (target), if any.
	 */
	fcp_parm = ntohl(spp->spp_params);
	spp->spp_params = htonl(fcp_parm | lport->service_params);
	return FC_SPP_RESP_ACK;
}

/*
 * FC-4 provider ops for FCP initiator.
 */
struct fc4_prov fc_rport_fcp_init = {
	.prli = fc_rport_fcp_prli,
};

/**
 * fc_rport_t0_prli() - Handle incoming PRLI parameters for type 0
 * @rdata: remote port private
 * @spp_len: service parameter page length
 * @rspp: received service parameter page
 * @spp: response service parameter page
 */
static int fc_rport_t0_prli(struct fc_rport_priv *rdata, u32 spp_len,
			    const struct fc_els_spp *rspp,
			    struct fc_els_spp *spp)
{
	if (rspp->spp_flags & FC_SPP_EST_IMG_PAIR)
		return FC_SPP_RESP_INVL;
	return FC_SPP_RESP_ACK;
}

/*
 * FC-4 provider ops for type 0 service parameters.
 *
 * This handles the special case of type 0 which is always successful
 * but doesn't do anything otherwise.
 */
struct fc4_prov fc_rport_t0_prov = {
	.prli = fc_rport_t0_prli,
};

2267 2268 2269
/**
 * fc_setup_rport() - Initialize the rport_event_queue
 */
2270
int fc_setup_rport(void)
2271 2272 2273 2274 2275 2276 2277
{
	rport_event_queue = create_singlethread_workqueue("fc_rport_eq");
	if (!rport_event_queue)
		return -ENOMEM;
	return 0;
}

2278 2279 2280
/**
 * fc_destroy_rport() - Destroy the rport_event_queue
 */
2281
void fc_destroy_rport(void)
2282 2283 2284 2285
{
	destroy_workqueue(rport_event_queue);
}

2286 2287 2288 2289
/**
 * fc_rport_terminate_io() - Stop all outstanding I/O on a remote port
 * @rport: The remote port whose I/O should be terminated
 */
2290 2291
void fc_rport_terminate_io(struct fc_rport *rport)
{
2292 2293
	struct fc_rport_libfc_priv *rpriv = rport->dd_data;
	struct fc_lport *lport = rpriv->local_port;
2294

2295 2296
	lport->tt.exch_mgr_reset(lport, 0, rport->port_id);
	lport->tt.exch_mgr_reset(lport, rport->port_id, 0);
2297 2298
}
EXPORT_SYMBOL(fc_rport_terminate_io);