/*
 * 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_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)
{
	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
			fc_remote_port_delete(rport);
	} 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 - Handler for any errors
 * @rport: The fc_rport object
 * @fp: The frame pointer
 *
 * If the error was caused by a resource allocation failure
 * then wait for half a second and retry, otherwise retry
 * immediately.
 *
 * 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;
	unsigned long delay = 0;

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

	if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) {
		/*
		 * Memory allocation failure, or the exchange timed out.
		 *  Retry after delay
		 */
		if (rdata->retries < rdata->local_port->max_retry_count) {
			rdata->retries++;
			if (!fp)
				delay = msecs_to_jiffies(500);
			get_device(&rport->dev);
			schedule_delayed_work(&rdata->retry_work, delay);
		} else {
			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_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 (rdata->rp_state != RPORT_ST_PLOGI) {
		FC_DBG("Received a PLOGI response, but in state %s\n",
		       fc_rport_state(rport));
		goto out;
	}

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

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

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

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

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

	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(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(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(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(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_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->emp, 0, rport->port_id);
	lport->tt.exch_mgr_reset(lport->emp, rport->port_id, 0);
}
EXPORT_SYMBOL(fc_rport_terminate_io);
