/*
 * 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
 * more comments on the heirarchy.
 *
 * 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.
 */

#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/rcupdate.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <asm/unaligned.h>

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

static int fc_rport_debug;

#define FC_DEBUG_RPORT(fmt...)			\
	do {					\
		if (fc_rport_debug)		\
			FC_DBG(fmt);		\
	} while (0)

struct workqueue_struct *rport_event_queue;

static void fc_rport_enter_plogi(struct fc_rport *);
static void fc_rport_enter_prli(struct fc_rport *);
static void fc_rport_enter_rtv(struct fc_rport *);
static void fc_rport_enter_ready(struct fc_rport *);
static void fc_rport_enter_logo(struct fc_rport *);

static void fc_rport_recv_plogi_req(struct fc_rport *,
				    struct fc_seq *, struct fc_frame *);
static void fc_rport_recv_prli_req(struct fc_rport *,
				   struct fc_seq *, struct fc_frame *);
static void fc_rport_recv_prlo_req(struct fc_rport *,
				   struct fc_seq *, struct fc_frame *);
static void fc_rport_recv_logo_req(struct fc_rport *,
				   struct fc_seq *, struct fc_frame *);
static void fc_rport_timeout(struct work_struct *);
static void fc_rport_error(struct fc_rport *, struct fc_frame *);
static void fc_rport_error_retry(struct fc_rport *, struct fc_frame *);
static void fc_rport_work(struct work_struct *);

static const char *fc_rport_state_names[] = {
	[RPORT_ST_NONE] = "None",
	[RPORT_ST_INIT] = "Init",
	[RPORT_ST_PLOGI] = "PLOGI",
	[RPORT_ST_PRLI] = "PRLI",
	[RPORT_ST_RTV] = "RTV",
	[RPORT_ST_READY] = "Ready",
	[RPORT_ST_LOGO] = "LOGO",
};

static void fc_rport_rogue_destroy(struct device *dev)
{
	struct fc_rport *rport = dev_to_rport(dev);
	FC_DEBUG_RPORT("Destroying rogue rport (%6x)\n", rport->port_id);
	kfree(rport);
}

struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *dp)
{
	struct fc_rport *rport;
	struct fc_rport_libfc_priv *rdata;
	rport = kzalloc(sizeof(*rport) + sizeof(*rdata), GFP_KERNEL);

	if (!rport)
		return NULL;

	rdata = RPORT_TO_PRIV(rport);

	rport->dd_data = rdata;
	rport->port_id = dp->ids.port_id;
	rport->port_name = dp->ids.port_name;
	rport->node_name = dp->ids.node_name;
	rport->roles = dp->ids.roles;
	rport->maxframe_size = FC_MIN_MAX_PAYLOAD;
	/*
	 * Note: all this libfc rogue rport code will be removed for
	 * upstream so it fine that this is really ugly and hacky right now.
	 */
	device_initialize(&rport->dev);
	rport->dev.release = fc_rport_rogue_destroy;

	mutex_init(&rdata->rp_mutex);
	rdata->local_port = dp->lp;
	rdata->trans_state = FC_PORTSTATE_ROGUE;
	rdata->rp_state = RPORT_ST_INIT;
	rdata->event = RPORT_EV_NONE;
	rdata->flags = FC_RP_FLAGS_REC_SUPPORTED;
	rdata->ops = NULL;
	rdata->e_d_tov = dp->lp->e_d_tov;
	rdata->r_a_tov = dp->lp->r_a_tov;
	INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout);
	INIT_WORK(&rdata->event_work, fc_rport_work);
	/*
	 * For good measure, but not necessary as we should only
	 * add REAL rport to the lport list.
	 */
	INIT_LIST_HEAD(&rdata->peers);

	return rport;
}

/**
 * fc_rport_state() - return a string for the state the rport is in
 * @rport: The rport whose state we want to get a string for
 */
static const char *fc_rport_state(struct fc_rport *rport)
{
	const char *cp;
	struct fc_rport_libfc_priv *rdata = rport->dd_data;

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

/**
 * fc_set_rport_loss_tmo() - Set the remote port loss timeout in seconds.
 * @rport: Pointer to Fibre Channel remote port structure
 * @timeout: timeout in seconds
 */
void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
{
	if (timeout)
		rport->dev_loss_tmo = timeout + 5;
	else
		rport->dev_loss_tmo = 30;
}
EXPORT_SYMBOL(fc_set_rport_loss_tmo);

/**
 * fc_plogi_get_maxframe() - Get max payload from the common service parameters
 * @flp: FLOGI payload structure
 * @maxval: upper limit, may be less than what is in the service parameters
 */
static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp,
					  unsigned int maxval)
{
	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;
}

/**
 * fc_rport_state_enter() - Change the rport's state
 * @rport: The rport whose state should change
 * @new: The new state of the rport
 *
 * Locking Note: Called with the rport lock held
 */
static void fc_rport_state_enter(struct fc_rport *rport,
				 enum fc_rport_state new)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	if (rdata->rp_state != new)
		rdata->retries = 0;
	rdata->rp_state = new;
}

static void fc_rport_work(struct work_struct *work)
{
	u32 port_id;
	struct fc_rport_libfc_priv *rdata =
		container_of(work, struct fc_rport_libfc_priv, event_work);
	enum fc_rport_event event;
	enum fc_rport_trans_state trans_state;
	struct fc_lport *lport = rdata->local_port;
	struct fc_rport_operations *rport_ops;
	struct fc_rport *rport = PRIV_TO_RPORT(rdata);

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

	if (event == RPORT_EV_CREATED) {
		struct fc_rport *new_rport;
		struct fc_rport_libfc_priv *new_rdata;
		struct fc_rport_identifiers ids;

		ids.port_id = rport->port_id;
		ids.roles = rport->roles;
		ids.port_name = rport->port_name;
		ids.node_name = rport->node_name;

		mutex_unlock(&rdata->rp_mutex);

		new_rport = fc_remote_port_add(lport->host, 0, &ids);
		if (new_rport) {
			/*
			 * Switch from the rogue rport to the rport
			 * returned by the FC class.
			 */
			new_rport->maxframe_size = rport->maxframe_size;

			new_rdata = new_rport->dd_data;
			new_rdata->e_d_tov = rdata->e_d_tov;
			new_rdata->r_a_tov = rdata->r_a_tov;
			new_rdata->ops = rdata->ops;
			new_rdata->local_port = rdata->local_port;
			new_rdata->flags = FC_RP_FLAGS_REC_SUPPORTED;
			new_rdata->trans_state = FC_PORTSTATE_REAL;
			mutex_init(&new_rdata->rp_mutex);
			INIT_DELAYED_WORK(&new_rdata->retry_work,
					  fc_rport_timeout);
			INIT_LIST_HEAD(&new_rdata->peers);
			INIT_WORK(&new_rdata->event_work, fc_rport_work);

			fc_rport_state_enter(new_rport, RPORT_ST_READY);
		} else {
			FC_DBG("Failed to create the rport for port "
			       "(%6x).\n", ids.port_id);
			event = RPORT_EV_FAILED;
		}
		put_device(&rport->dev);
		rport = new_rport;
		rdata = new_rport->dd_data;
		if (rport_ops->event_callback)
			rport_ops->event_callback(lport, rport, event);
	} else if ((event == RPORT_EV_FAILED) ||
		   (event == RPORT_EV_LOGO) ||
		   (event == RPORT_EV_STOP)) {
		trans_state = rdata->trans_state;
		mutex_unlock(&rdata->rp_mutex);
		if (rport_ops->event_callback)
			rport_ops->event_callback(lport, rport, event);
		if (trans_state == FC_PORTSTATE_ROGUE)
			put_device(&rport->dev);
		else {
			port_id = rport->port_id;
			fc_remote_port_delete(rport);
			lport->tt.exch_mgr_reset(lport, 0, port_id);
			lport->tt.exch_mgr_reset(lport, port_id, 0);
		}
	} else
		mutex_unlock(&rdata->rp_mutex);
}

/**
 * fc_rport_login() - Start the remote port login state machine
 * @rport: Fibre Channel remote port
 *
 * Locking Note: Called without the rport lock held. This
 * function will hold the rport lock, call an _enter_*
 * function and then unlock the rport.
 */
int fc_rport_login(struct fc_rport *rport)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;

	mutex_lock(&rdata->rp_mutex);

	FC_DEBUG_RPORT("Login to port (%6x)\n", rport->port_id);

	fc_rport_enter_plogi(rport);

	mutex_unlock(&rdata->rp_mutex);

	return 0;
}

/**
 * fc_rport_logoff() - Logoff and remove an rport
 * @rport: Fibre Channel remote port to be removed
 *
 * Locking Note: Called without the rport lock held. This
 * function will hold the rport lock, call an _enter_*
 * function and then unlock the rport.
 */
int fc_rport_logoff(struct fc_rport *rport)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;

	mutex_lock(&rdata->rp_mutex);

	FC_DEBUG_RPORT("Remove port (%6x)\n", rport->port_id);

	fc_rport_enter_logo(rport);

	/*
	 * Change the state to NONE so that we discard
	 * the response.
	 */
	fc_rport_state_enter(rport, RPORT_ST_NONE);

	mutex_unlock(&rdata->rp_mutex);

	cancel_delayed_work_sync(&rdata->retry_work);

	mutex_lock(&rdata->rp_mutex);

	rdata->event = RPORT_EV_STOP;
	queue_work(rport_event_queue, &rdata->event_work);

	mutex_unlock(&rdata->rp_mutex);

	return 0;
}

/**
 * fc_rport_enter_ready() - The rport is ready
 * @rport: Fibre Channel remote port that is ready
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this routine.
 */
static void fc_rport_enter_ready(struct fc_rport *rport)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;

	fc_rport_state_enter(rport, RPORT_ST_READY);

	FC_DEBUG_RPORT("Port (%6x) is Ready\n", rport->port_id);

	rdata->event = RPORT_EV_CREATED;
	queue_work(rport_event_queue, &rdata->event_work);
}

/**
 * fc_rport_timeout() - Handler for the retry_work timer.
 * @work: The work struct of the fc_rport_libfc_priv
 *
 * Locking Note: Called without the rport lock held. This
 * function will hold the rport lock, call an _enter_*
 * function and then unlock the rport.
 */
static void fc_rport_timeout(struct work_struct *work)
{
	struct fc_rport_libfc_priv *rdata =
		container_of(work, struct fc_rport_libfc_priv, retry_work.work);
	struct fc_rport *rport = PRIV_TO_RPORT(rdata);

	mutex_lock(&rdata->rp_mutex);

	switch (rdata->rp_state) {
	case RPORT_ST_PLOGI:
		fc_rport_enter_plogi(rport);
		break;
	case RPORT_ST_PRLI:
		fc_rport_enter_prli(rport);
		break;
	case RPORT_ST_RTV:
		fc_rport_enter_rtv(rport);
		break;
	case RPORT_ST_LOGO:
		fc_rport_enter_logo(rport);
		break;
	case RPORT_ST_READY:
	case RPORT_ST_INIT:
	case RPORT_ST_NONE:
		break;
	}

	mutex_unlock(&rdata->rp_mutex);
	put_device(&rport->dev);
}

/**
 * fc_rport_error() - Error handler, called once retries have been exhausted
 * @rport: The fc_rport object
 * @fp: The frame pointer
 *
 * Locking Note: The rport lock is expected to be held before
 * calling this routine
 */
static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;

	FC_DEBUG_RPORT("Error %ld in state %s, retries %d\n",
		       PTR_ERR(fp), fc_rport_state(rport), rdata->retries);

	switch (rdata->rp_state) {
	case RPORT_ST_PLOGI:
	case RPORT_ST_PRLI:
	case RPORT_ST_LOGO:
		rdata->event = RPORT_EV_FAILED;
		queue_work(rport_event_queue,
			   &rdata->event_work);
		break;
	case RPORT_ST_RTV:
		fc_rport_enter_ready(rport);
		break;
	case RPORT_ST_NONE:
	case RPORT_ST_READY:
	case RPORT_ST_INIT:
		break;
	}
}

/**
 * fc_rport_error_retry() - Error handler when retries are desired
 * @rport: The fc_rport object
 * @fp: The frame pointer
 *
 * 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
 */
static void fc_rport_error_retry(struct fc_rport *rport, struct fc_frame *fp)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	unsigned long delay = FC_DEF_E_D_TOV;

	/* make sure this isn't an FC_EX_CLOSED error, never retry those */
	if (PTR_ERR(fp) == -FC_EX_CLOSED)
		return fc_rport_error(rport, fp);

	if (rdata->retries < rdata->local_port->max_retry_count) {
		FC_DEBUG_RPORT("Error %ld in state %s, retrying\n",
			       PTR_ERR(fp), fc_rport_state(rport));
		rdata->retries++;
		/* no additional delay on exchange timeouts */
		if (PTR_ERR(fp) == -FC_EX_TIMEOUT)
			delay = 0;
		get_device(&rport->dev);
		schedule_delayed_work(&rdata->retry_work, delay);
		return;
	}

	return fc_rport_error(rport, fp);
}

/**
 * fc_rport_plogi_recv_resp() - Handle incoming ELS PLOGI response
 * @sp: current sequence in the PLOGI exchange
 * @fp: response frame
 * @rp_arg: Fibre Channel remote port
 *
 * 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,
				void *rp_arg)
{
	struct fc_rport *rport = rp_arg;
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct fc_lport *lport = rdata->local_port;
	struct fc_els_flogi *plp;
	unsigned int tov;
	u16 csp_seq;
	u16 cssp_seq;
	u8 op;

	mutex_lock(&rdata->rp_mutex);

	FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n",
		       rport->port_id);

	if (IS_ERR(fp)) {
		fc_rport_error_retry(rport, fp);
		goto err;
	}

	if (rdata->rp_state != RPORT_ST_PLOGI) {
		FC_DBG("Received a PLOGI response, but in state %s\n",
		       fc_rport_state(rport));
		goto out;
	}

	op = fc_frame_payload_op(fp);
	if (op == ELS_LS_ACC &&
	    (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) {
		rport->port_name = get_unaligned_be64(&plp->fl_wwpn);
		rport->node_name = get_unaligned_be64(&plp->fl_wwnn);

		tov = ntohl(plp->fl_csp.sp_e_d_tov);
		if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR)
			tov /= 1000;
		if (tov > rdata->e_d_tov)
			rdata->e_d_tov = tov;
		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;
		rport->maxframe_size =
			fc_plogi_get_maxframe(plp, lport->mfs);

		/*
		 * If the rport is one of the well known addresses
		 * we skip PRLI and RTV and go straight to READY.
		 */
		if (rport->port_id >= FC_FID_DOM_MGR)
			fc_rport_enter_ready(rport);
		else
			fc_rport_enter_prli(rport);
	} else
		fc_rport_error_retry(rport, fp);

out:
	fc_frame_free(fp);
err:
	mutex_unlock(&rdata->rp_mutex);
	put_device(&rport->dev);
}

/**
 * fc_rport_enter_plogi() - Send Port Login (PLOGI) request to peer
 * @rport: Fibre Channel remote port to send PLOGI to
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this routine.
 */
static void fc_rport_enter_plogi(struct fc_rport *rport)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct fc_lport *lport = rdata->local_port;
	struct fc_frame *fp;

	FC_DEBUG_RPORT("Port (%6x) entered PLOGI state from %s state\n",
		       rport->port_id, fc_rport_state(rport));

	fc_rport_state_enter(rport, RPORT_ST_PLOGI);

	rport->maxframe_size = FC_MIN_MAX_PAYLOAD;
	fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
	if (!fp) {
		fc_rport_error_retry(rport, fp);
		return;
	}
	rdata->e_d_tov = lport->e_d_tov;

	if (!lport->tt.elsct_send(lport, rport, fp, ELS_PLOGI,
				  fc_rport_plogi_resp, rport, lport->e_d_tov))
		fc_rport_error_retry(rport, fp);
	else
		get_device(&rport->dev);
}

/**
 * fc_rport_prli_resp() - Process Login (PRLI) response handler
 * @sp: current sequence in the PRLI exchange
 * @fp: response frame
 * @rp_arg: Fibre Channel remote port
 *
 * 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,
			       void *rp_arg)
{
	struct fc_rport *rport = rp_arg;
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct {
		struct fc_els_prli prli;
		struct fc_els_spp spp;
	} *pp;
	u32 roles = FC_RPORT_ROLE_UNKNOWN;
	u32 fcp_parm = 0;
	u8 op;

	mutex_lock(&rdata->rp_mutex);

	FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n",
		       rport->port_id);

	if (IS_ERR(fp)) {
		fc_rport_error_retry(rport, fp);
		goto err;
	}

	if (rdata->rp_state != RPORT_ST_PRLI) {
		FC_DBG("Received a PRLI response, but in state %s\n",
		       fc_rport_state(rport));
		goto out;
	}

	op = fc_frame_payload_op(fp);
	if (op == ELS_LS_ACC) {
		pp = fc_frame_payload_get(fp, sizeof(*pp));
		if (pp && pp->prli.prli_spp_len >= sizeof(pp->spp)) {
			fcp_parm = ntohl(pp->spp.spp_params);
			if (fcp_parm & FCP_SPPF_RETRY)
				rdata->flags |= FC_RP_FLAGS_RETRY;
		}

		rport->supported_classes = FC_COS_CLASS3;
		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;

		rport->roles = roles;
		fc_rport_enter_rtv(rport);

	} else {
		FC_DBG("Bad ELS response\n");
		rdata->event = RPORT_EV_FAILED;
		queue_work(rport_event_queue, &rdata->event_work);
	}

out:
	fc_frame_free(fp);
err:
	mutex_unlock(&rdata->rp_mutex);
	put_device(&rport->dev);
}

/**
 * fc_rport_logo_resp() - Logout (LOGO) response handler
 * @sp: current sequence in the LOGO exchange
 * @fp: response frame
 * @rp_arg: Fibre Channel remote port
 *
 * 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_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
			       void *rp_arg)
{
	struct fc_rport *rport = rp_arg;
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	u8 op;

	mutex_lock(&rdata->rp_mutex);

	FC_DEBUG_RPORT("Received a LOGO response from port (%6x)\n",
		       rport->port_id);

	if (IS_ERR(fp)) {
		fc_rport_error_retry(rport, fp);
		goto err;
	}

	if (rdata->rp_state != RPORT_ST_LOGO) {
		FC_DEBUG_RPORT("Received a LOGO response, but in state %s\n",
			       fc_rport_state(rport));
		goto out;
	}

	op = fc_frame_payload_op(fp);
	if (op == ELS_LS_ACC) {
		fc_rport_enter_rtv(rport);
	} else {
		FC_DBG("Bad ELS response\n");
		rdata->event = RPORT_EV_LOGO;
		queue_work(rport_event_queue, &rdata->event_work);
	}

out:
	fc_frame_free(fp);
err:
	mutex_unlock(&rdata->rp_mutex);
	put_device(&rport->dev);
}

/**
 * fc_rport_enter_prli() - Send Process Login (PRLI) request to peer
 * @rport: Fibre Channel remote port to send PRLI to
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this routine.
 */
static void fc_rport_enter_prli(struct fc_rport *rport)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct fc_lport *lport = rdata->local_port;
	struct {
		struct fc_els_prli prli;
		struct fc_els_spp spp;
	} *pp;
	struct fc_frame *fp;

	FC_DEBUG_RPORT("Port (%6x) entered PRLI state from %s state\n",
		       rport->port_id, fc_rport_state(rport));

	fc_rport_state_enter(rport, RPORT_ST_PRLI);

	fp = fc_frame_alloc(lport, sizeof(*pp));
	if (!fp) {
		fc_rport_error_retry(rport, fp);
		return;
	}

	if (!lport->tt.elsct_send(lport, rport, fp, ELS_PRLI,
				  fc_rport_prli_resp, rport, lport->e_d_tov))
		fc_rport_error_retry(rport, fp);
	else
		get_device(&rport->dev);
}

/**
 * fc_rport_els_rtv_resp() - Request Timeout Value response handler
 * @sp: current sequence in the RTV exchange
 * @fp: response frame
 * @rp_arg: Fibre Channel remote port
 *
 * 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,
			      void *rp_arg)
{
	struct fc_rport *rport = rp_arg;
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	u8 op;

	mutex_lock(&rdata->rp_mutex);

	FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n",
		       rport->port_id);

	if (IS_ERR(fp)) {
		fc_rport_error(rport, fp);
		goto err;
	}

	if (rdata->rp_state != RPORT_ST_RTV) {
		FC_DBG("Received a RTV response, but in state %s\n",
		       fc_rport_state(rport));
		goto out;
	}

	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;
			rdata->r_a_tov = tov;
			tov = ntohl(rtv->rtv_e_d_tov);
			if (toq & FC_ELS_RTV_EDRES)
				tov /= 1000000;
			if (tov == 0)
				tov = 1;
			rdata->e_d_tov = tov;
		}
	}

	fc_rport_enter_ready(rport);

out:
	fc_frame_free(fp);
err:
	mutex_unlock(&rdata->rp_mutex);
	put_device(&rport->dev);
}

/**
 * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request to peer
 * @rport: Fibre Channel remote port to send RTV to
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this routine.
 */
static void fc_rport_enter_rtv(struct fc_rport *rport)
{
	struct fc_frame *fp;
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct fc_lport *lport = rdata->local_port;

	FC_DEBUG_RPORT("Port (%6x) entered RTV state from %s state\n",
		       rport->port_id, fc_rport_state(rport));

	fc_rport_state_enter(rport, RPORT_ST_RTV);

	fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv));
	if (!fp) {
		fc_rport_error_retry(rport, fp);
		return;
	}

	if (!lport->tt.elsct_send(lport, rport, fp, ELS_RTV,
				     fc_rport_rtv_resp, rport, lport->e_d_tov))
		fc_rport_error_retry(rport, fp);
	else
		get_device(&rport->dev);
}

/**
 * fc_rport_enter_logo() - Send Logout (LOGO) request to peer
 * @rport: Fibre Channel remote port to send LOGO to
 *
 * Locking Note: The rport lock is expected to be held before calling
 * this routine.
 */
static void fc_rport_enter_logo(struct fc_rport *rport)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct fc_lport *lport = rdata->local_port;
	struct fc_frame *fp;

	FC_DEBUG_RPORT("Port (%6x) entered LOGO state from %s state\n",
		       rport->port_id, fc_rport_state(rport));

	fc_rport_state_enter(rport, RPORT_ST_LOGO);

	fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo));
	if (!fp) {
		fc_rport_error_retry(rport, fp);
		return;
	}

	if (!lport->tt.elsct_send(lport, rport, fp, ELS_LOGO,
				  fc_rport_logo_resp, rport, lport->e_d_tov))
		fc_rport_error_retry(rport, fp);
	else
		get_device(&rport->dev);
}


/**
 * fc_rport_recv_req() - Receive a request from a rport
 * @sp: current sequence in the PLOGI exchange
 * @fp: response frame
 * @rp_arg: Fibre Channel remote port
 *
 * Locking Note: Called without the rport lock held. This
 * function will hold the rport lock, call an _enter_*
 * function and then unlock the rport.
 */
void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp,
		       struct fc_rport *rport)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct fc_lport *lport = rdata->local_port;

	struct fc_frame_header *fh;
	struct fc_seq_els_data els_data;
	u8 op;

	mutex_lock(&rdata->rp_mutex);

	els_data.fp = NULL;
	els_data.explan = ELS_EXPL_NONE;
	els_data.reason = ELS_RJT_NONE;

	fh = fc_frame_header_get(fp);

	if (fh->fh_r_ctl == FC_RCTL_ELS_REQ && fh->fh_type == FC_TYPE_ELS) {
		op = fc_frame_payload_op(fp);
		switch (op) {
		case ELS_PLOGI:
			fc_rport_recv_plogi_req(rport, sp, fp);
			break;
		case ELS_PRLI:
			fc_rport_recv_prli_req(rport, sp, fp);
			break;
		case ELS_PRLO:
			fc_rport_recv_prlo_req(rport, sp, fp);
			break;
		case ELS_LOGO:
			fc_rport_recv_logo_req(rport, sp, fp);
			break;
		case ELS_RRQ:
			els_data.fp = fp;
			lport->tt.seq_els_rsp_send(sp, ELS_RRQ, &els_data);
			break;
		case ELS_REC:
			els_data.fp = fp;
			lport->tt.seq_els_rsp_send(sp, ELS_REC, &els_data);
			break;
		default:
			els_data.reason = ELS_RJT_UNSUP;
			lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &els_data);
			break;
		}
	}

	mutex_unlock(&rdata->rp_mutex);
}

/**
 * fc_rport_recv_plogi_req() - Handle incoming Port Login (PLOGI) request
 * @rport: Fibre Channel remote port that initiated PLOGI
 * @sp: current sequence in the PLOGI exchange
 * @fp: PLOGI request frame
 *
 * Locking Note: The rport lock is exected to be held before calling
 * this function.
 */
static void fc_rport_recv_plogi_req(struct fc_rport *rport,
				    struct fc_seq *sp, struct fc_frame *rx_fp)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct fc_lport *lport = rdata->local_port;
	struct fc_frame *fp = rx_fp;
	struct fc_exch *ep;
	struct fc_frame_header *fh;
	struct fc_els_flogi *pl;
	struct fc_seq_els_data rjt_data;
	u32 sid;
	u64 wwpn;
	u64 wwnn;
	enum fc_els_rjt_reason reject = 0;
	u32 f_ctl;
	rjt_data.fp = NULL;

	fh = fc_frame_header_get(fp);

	FC_DEBUG_RPORT("Received PLOGI request from port (%6x) "
		       "while in state %s\n", ntoh24(fh->fh_s_id),
		       fc_rport_state(rport));

	sid = ntoh24(fh->fh_s_id);
	pl = fc_frame_payload_get(fp, sizeof(*pl));
	if (!pl) {
		FC_DBG("incoming PLOGI from %x too short\n", sid);
		WARN_ON(1);
		/* XXX TBD: send reject? */
		fc_frame_free(fp);
		return;
	}
	wwpn = get_unaligned_be64(&pl->fl_wwpn);
	wwnn = get_unaligned_be64(&pl->fl_wwnn);

	/*
	 * If the session was just created, possibly due to the incoming PLOGI,
	 * 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:
		FC_DEBUG_RPORT("incoming PLOGI from %6x wwpn %llx state INIT "
			       "- reject\n", sid, wwpn);
		reject = ELS_RJT_UNSUP;
		break;
	case RPORT_ST_PLOGI:
		FC_DEBUG_RPORT("incoming PLOGI from %x in PLOGI state %d\n",
			       sid, rdata->rp_state);
		if (wwpn < lport->wwpn)
			reject = ELS_RJT_INPROG;
		break;
	case RPORT_ST_PRLI:
	case RPORT_ST_READY:
		FC_DEBUG_RPORT("incoming PLOGI from %x in logged-in state %d "
			       "- ignored for now\n", sid, rdata->rp_state);
		/* XXX TBD - should reset */
		break;
	case RPORT_ST_NONE:
	default:
		FC_DEBUG_RPORT("incoming PLOGI from %x in unexpected "
			       "state %d\n", sid, rdata->rp_state);
		break;
	}

	if (reject) {
		rjt_data.reason = reject;
		rjt_data.explan = ELS_EXPL_NONE;
		lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
		fc_frame_free(fp);
	} else {
		fp = fc_frame_alloc(lport, sizeof(*pl));
		if (fp == NULL) {
			fp = rx_fp;
			rjt_data.reason = ELS_RJT_UNAB;
			rjt_data.explan = ELS_EXPL_NONE;
			lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
			fc_frame_free(fp);
		} else {
			sp = lport->tt.seq_start_next(sp);
			WARN_ON(!sp);
			fc_rport_set_name(rport, wwpn, wwnn);

			/*
			 * Get session payload size from incoming PLOGI.
			 */
			rport->maxframe_size =
				fc_plogi_get_maxframe(pl, lport->mfs);
			fc_frame_free(rx_fp);
			fc_plogi_fill(lport, fp, ELS_LS_ACC);

			/*
			 * Send LS_ACC.	 If this fails,
			 * the originator should retry.
			 */
			f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
			f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
			ep = fc_seq_exch(sp);
			fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
				       FC_TYPE_ELS, f_ctl, 0);
			lport->tt.seq_send(lport, sp, fp);
			if (rdata->rp_state == RPORT_ST_PLOGI)
				fc_rport_enter_prli(rport);
		}
	}
}

/**
 * fc_rport_recv_prli_req() - Handle incoming Process Login (PRLI) request
 * @rport: Fibre Channel remote port that initiated PRLI
 * @sp: current sequence in the PRLI exchange
 * @fp: PRLI request frame
 *
 * Locking Note: The rport lock is exected to be held before calling
 * this function.
 */
static void fc_rport_recv_prli_req(struct fc_rport *rport,
				   struct fc_seq *sp, struct fc_frame *rx_fp)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct fc_lport *lport = rdata->local_port;
	struct fc_exch *ep;
	struct fc_frame *fp;
	struct fc_frame_header *fh;
	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_rjt_reason reason = ELS_RJT_UNAB;
	enum fc_els_rjt_explan explan = ELS_EXPL_NONE;
	enum fc_els_spp_resp resp;
	struct fc_seq_els_data rjt_data;
	u32 f_ctl;
	u32 fcp_parm;
	u32 roles = FC_RPORT_ROLE_UNKNOWN;
	rjt_data.fp = NULL;

	fh = fc_frame_header_get(rx_fp);

	FC_DEBUG_RPORT("Received PRLI request from port (%6x) "
		       "while in state %s\n", ntoh24(fh->fh_s_id),
		       fc_rport_state(rport));

	switch (rdata->rp_state) {
	case RPORT_ST_PRLI:
	case RPORT_ST_READY:
		reason = ELS_RJT_NONE;
		break;
	default:
		break;
	}
	len = fr_len(rx_fp) - sizeof(*fh);
	pp = fc_frame_payload_get(rx_fp, sizeof(*pp));
	if (pp == NULL) {
		reason = ELS_RJT_PROT;
		explan = ELS_EXPL_INV_LEN;
	} else {
		plen = ntohs(pp->prli.prli_len);
		if ((plen % 4) != 0 || plen > len) {
			reason = ELS_RJT_PROT;
			explan = ELS_EXPL_INV_LEN;
		} else if (plen < len) {
			len = plen;
		}
		plen = pp->prli.prli_spp_len;
		if ((plen % 4) != 0 || plen < sizeof(*spp) ||
		    plen > len || len < sizeof(*pp)) {
			reason = ELS_RJT_PROT;
			explan = ELS_EXPL_INV_LEN;
		}
		rspp = &pp->spp;
	}
	if (reason != ELS_RJT_NONE ||
	    (fp = fc_frame_alloc(lport, len)) == NULL) {
		rjt_data.reason = reason;
		rjt_data.explan = explan;
		lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
	} else {
		sp = lport->tt.seq_start_next(sp);
		WARN_ON(!sp);
		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);

		/*
		 * 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;
		while (len >= plen) {
			spp->spp_type = rspp->spp_type;
			spp->spp_type_ext = rspp->spp_type_ext;
			spp->spp_flags = rspp->spp_flags & FC_SPP_EST_IMG_PAIR;
			resp = FC_SPP_RESP_ACK;
			if (rspp->spp_flags & FC_SPP_RPA_VAL)
				resp = FC_SPP_RESP_NO_PA;
			switch (rspp->spp_type) {
			case 0:	/* common to all FC-4 types */
				break;
			case FC_TYPE_FCP:
				fcp_parm = ntohl(rspp->spp_params);
				if (fcp_parm * FCP_SPPF_RETRY)
					rdata->flags |= FC_RP_FLAGS_RETRY;
				rport->supported_classes = FC_COS_CLASS3;
				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;
				rport->roles = roles;

				spp->spp_params =
					htonl(lport->service_params);
				break;
			default:
				resp = FC_SPP_RESP_INVL;
				break;
			}
			spp->spp_flags |= resp;
			len -= plen;
			rspp = (struct fc_els_spp *)((char *)rspp + plen);
			spp = (struct fc_els_spp *)((char *)spp + plen);
		}

		/*
		 * Send LS_ACC.	 If this fails, the originator should retry.
		 */
		f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
		f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
		ep = fc_seq_exch(sp);
		fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
			       FC_TYPE_ELS, f_ctl, 0);
		lport->tt.seq_send(lport, sp, fp);

		/*
		 * Get lock and re-check state.
		 */
		switch (rdata->rp_state) {
		case RPORT_ST_PRLI:
			fc_rport_enter_ready(rport);
			break;
		case RPORT_ST_READY:
			break;
		default:
			break;
		}
	}
	fc_frame_free(rx_fp);
}

/**
 * fc_rport_recv_prlo_req() - Handle incoming Process Logout (PRLO) request
 * @rport: Fibre Channel remote port that initiated PRLO
 * @sp: current sequence in the PRLO exchange
 * @fp: PRLO request frame
 *
 * Locking Note: The rport lock is exected to be held before calling
 * this function.
 */
static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp,
				   struct fc_frame *fp)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct fc_lport *lport = rdata->local_port;

	struct fc_frame_header *fh;
	struct fc_seq_els_data rjt_data;

	fh = fc_frame_header_get(fp);

	FC_DEBUG_RPORT("Received PRLO request from port (%6x) "
		       "while in state %s\n", ntoh24(fh->fh_s_id),
		       fc_rport_state(rport));

	rjt_data.fp = NULL;
	rjt_data.reason = ELS_RJT_UNAB;
	rjt_data.explan = ELS_EXPL_NONE;
	lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
	fc_frame_free(fp);
}

/**
 * fc_rport_recv_logo_req() - Handle incoming Logout (LOGO) request
 * @rport: Fibre Channel remote port that initiated LOGO
 * @sp: current sequence in the LOGO exchange
 * @fp: LOGO request frame
 *
 * Locking Note: The rport lock is exected to be held before calling
 * this function.
 */
static void fc_rport_recv_logo_req(struct fc_rport *rport, struct fc_seq *sp,
				   struct fc_frame *fp)
{
	struct fc_frame_header *fh;
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct fc_lport *lport = rdata->local_port;

	fh = fc_frame_header_get(fp);

	FC_DEBUG_RPORT("Received LOGO request from port (%6x) "
		       "while in state %s\n", ntoh24(fh->fh_s_id),
		       fc_rport_state(rport));

	rdata->event = RPORT_EV_LOGO;
	queue_work(rport_event_queue, &rdata->event_work);

	lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
	fc_frame_free(fp);
}

static void fc_rport_flush_queue(void)
{
	flush_workqueue(rport_event_queue);
}


int fc_rport_init(struct fc_lport *lport)
{
	if (!lport->tt.rport_create)
		lport->tt.rport_create = fc_rport_rogue_create;

	if (!lport->tt.rport_login)
		lport->tt.rport_login = fc_rport_login;

	if (!lport->tt.rport_logoff)
		lport->tt.rport_logoff = fc_rport_logoff;

	if (!lport->tt.rport_recv_req)
		lport->tt.rport_recv_req = fc_rport_recv_req;

	if (!lport->tt.rport_flush_queue)
		lport->tt.rport_flush_queue = fc_rport_flush_queue;

	return 0;
}
EXPORT_SYMBOL(fc_rport_init);

int fc_setup_rport()
{
	rport_event_queue = create_singlethread_workqueue("fc_rport_eq");
	if (!rport_event_queue)
		return -ENOMEM;
	return 0;
}
EXPORT_SYMBOL(fc_setup_rport);

void fc_destroy_rport()
{
	destroy_workqueue(rport_event_queue);
}
EXPORT_SYMBOL(fc_destroy_rport);

void fc_rport_terminate_io(struct fc_rport *rport)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct fc_lport *lport = rdata->local_port;

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