cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fc_lport.c (59320B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright(c) 2007 Intel Corporation. All rights reserved.
      4 *
      5 * Maintained at www.Open-FCoE.org
      6 */
      7
      8/*
      9 * PORT LOCKING NOTES
     10 *
     11 * These comments only apply to the 'port code' which consists of the lport,
     12 * disc and rport blocks.
     13 *
     14 * MOTIVATION
     15 *
     16 * The lport, disc and rport blocks all have mutexes that are used to protect
     17 * those objects. The main motivation for these locks is to prevent from
     18 * having an lport reset just before we send a frame. In that scenario the
     19 * lport's FID would get set to zero and then we'd send a frame with an
     20 * invalid SID. We also need to ensure that states don't change unexpectedly
     21 * while processing another state.
     22 *
     23 * HIERARCHY
     24 *
     25 * The following hierarchy defines the locking rules. A greater lock
     26 * may be held before acquiring a lesser lock, but a lesser lock should never
     27 * be held while attempting to acquire a greater lock. Here is the hierarchy-
     28 *
     29 * lport > disc, lport > rport, disc > rport
     30 *
     31 * CALLBACKS
     32 *
     33 * The callbacks cause complications with this scheme. There is a callback
     34 * from the rport (to either lport or disc) and a callback from disc
     35 * (to the lport).
     36 *
     37 * As rports exit the rport state machine a callback is made to the owner of
     38 * the rport to notify success or failure. Since the callback is likely to
     39 * cause the lport or disc to grab its lock we cannot hold the rport lock
     40 * while making the callback. To ensure that the rport is not free'd while
     41 * processing the callback the rport callbacks are serialized through a
     42 * single-threaded workqueue. An rport would never be free'd while in a
     43 * callback handler because no other rport work in this queue can be executed
     44 * at the same time.
     45 *
     46 * When discovery succeeds or fails a callback is made to the lport as
     47 * notification. Currently, successful discovery causes the lport to take no
     48 * action. A failure will cause the lport to reset. There is likely a circular
     49 * locking problem with this implementation.
     50 */
     51
     52/*
     53 * LPORT LOCKING
     54 *
     55 * The critical sections protected by the lport's mutex are quite broad and
     56 * may be improved upon in the future. The lport code and its locking doesn't
     57 * influence the I/O path, so excessive locking doesn't penalize I/O
     58 * performance.
     59 *
     60 * The strategy is to lock whenever processing a request or response. Note
     61 * that every _enter_* function corresponds to a state change. They generally
     62 * change the lports state and then send a request out on the wire. We lock
     63 * before calling any of these functions to protect that state change. This
     64 * means that the entry points into the lport block manage the locks while
     65 * the state machine can transition between states (i.e. _enter_* functions)
     66 * while always staying protected.
     67 *
     68 * When handling responses we also hold the lport mutex broadly. When the
     69 * lport receives the response frame it locks the mutex and then calls the
     70 * appropriate handler for the particuar response. Generally a response will
     71 * trigger a state change and so the lock must already be held.
     72 *
     73 * Retries also have to consider the locking. The retries occur from a work
     74 * context and the work function will lock the lport and then retry the state
     75 * (i.e. _enter_* function).
     76 */
     77
     78#include <linux/timer.h>
     79#include <linux/delay.h>
     80#include <linux/module.h>
     81#include <linux/slab.h>
     82#include <asm/unaligned.h>
     83
     84#include <scsi/fc/fc_gs.h>
     85
     86#include <scsi/libfc.h>
     87#include <linux/scatterlist.h>
     88
     89#include "fc_encode.h"
     90#include "fc_libfc.h"
     91
     92/* Fabric IDs to use for point-to-point mode, chosen on whims. */
     93#define FC_LOCAL_PTP_FID_LO   0x010101
     94#define FC_LOCAL_PTP_FID_HI   0x010102
     95
     96#define	DNS_DELAY		3 /* Discovery delay after RSCN (in seconds)*/
     97#define	MAX_CT_PAYLOAD		2048
     98#define	DISCOVERED_PORTS	4
     99#define	NUMBER_OF_PORTS		1
    100
    101static void fc_lport_error(struct fc_lport *, struct fc_frame *);
    102
    103static void fc_lport_enter_reset(struct fc_lport *);
    104static void fc_lport_enter_flogi(struct fc_lport *);
    105static void fc_lport_enter_dns(struct fc_lport *);
    106static void fc_lport_enter_ns(struct fc_lport *, enum fc_lport_state);
    107static void fc_lport_enter_scr(struct fc_lport *);
    108static void fc_lport_enter_ready(struct fc_lport *);
    109static void fc_lport_enter_logo(struct fc_lport *);
    110static void fc_lport_enter_fdmi(struct fc_lport *lport);
    111static void fc_lport_enter_ms(struct fc_lport *, enum fc_lport_state);
    112
    113static const char *fc_lport_state_names[] = {
    114	[LPORT_ST_DISABLED] = "disabled",
    115	[LPORT_ST_FLOGI] =    "FLOGI",
    116	[LPORT_ST_DNS] =      "dNS",
    117	[LPORT_ST_RNN_ID] =   "RNN_ID",
    118	[LPORT_ST_RSNN_NN] =  "RSNN_NN",
    119	[LPORT_ST_RSPN_ID] =  "RSPN_ID",
    120	[LPORT_ST_RFT_ID] =   "RFT_ID",
    121	[LPORT_ST_RFF_ID] =   "RFF_ID",
    122	[LPORT_ST_FDMI] =     "FDMI",
    123	[LPORT_ST_RHBA] =     "RHBA",
    124	[LPORT_ST_RPA] =      "RPA",
    125	[LPORT_ST_DHBA] =     "DHBA",
    126	[LPORT_ST_DPRT] =     "DPRT",
    127	[LPORT_ST_SCR] =      "SCR",
    128	[LPORT_ST_READY] =    "Ready",
    129	[LPORT_ST_LOGO] =     "LOGO",
    130	[LPORT_ST_RESET] =    "reset",
    131};
    132
    133/**
    134 * struct fc_bsg_info - FC Passthrough managemet structure
    135 * @job:      The passthrough job
    136 * @lport:    The local port to pass through a command
    137 * @rsp_code: The expected response code
    138 * @sg:	      job->reply_payload.sg_list
    139 * @nents:    job->reply_payload.sg_cnt
    140 * @offset:   The offset into the response data
    141 */
    142struct fc_bsg_info {
    143	struct bsg_job *job;
    144	struct fc_lport *lport;
    145	u16 rsp_code;
    146	struct scatterlist *sg;
    147	u32 nents;
    148	size_t offset;
    149};
    150
    151/**
    152 * fc_frame_drop() - Dummy frame handler
    153 * @lport: The local port the frame was received on
    154 * @fp:	   The received frame
    155 */
    156static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp)
    157{
    158	fc_frame_free(fp);
    159	return 0;
    160}
    161
    162/**
    163 * fc_lport_rport_callback() - Event handler for rport events
    164 * @lport: The lport which is receiving the event
    165 * @rdata: private remote port data
    166 * @event: The event that occurred
    167 *
    168 * Locking Note: The rport lock should not be held when calling
    169 *		 this function.
    170 */
    171static void fc_lport_rport_callback(struct fc_lport *lport,
    172				    struct fc_rport_priv *rdata,
    173				    enum fc_rport_event event)
    174{
    175	FC_LPORT_DBG(lport, "Received a %d event for port (%6.6x)\n", event,
    176		     rdata->ids.port_id);
    177
    178	mutex_lock(&lport->lp_mutex);
    179	switch (event) {
    180	case RPORT_EV_READY:
    181		if (lport->state == LPORT_ST_DNS) {
    182			lport->dns_rdata = rdata;
    183			fc_lport_enter_ns(lport, LPORT_ST_RNN_ID);
    184		} else if (lport->state == LPORT_ST_FDMI) {
    185			lport->ms_rdata = rdata;
    186			fc_lport_enter_ms(lport, LPORT_ST_DHBA);
    187		} else {
    188			FC_LPORT_DBG(lport, "Received an READY event "
    189				     "on port (%6.6x) for the directory "
    190				     "server, but the lport is not "
    191				     "in the DNS or FDMI state, it's in the "
    192				     "%d state", rdata->ids.port_id,
    193				     lport->state);
    194			fc_rport_logoff(rdata);
    195		}
    196		break;
    197	case RPORT_EV_LOGO:
    198	case RPORT_EV_FAILED:
    199	case RPORT_EV_STOP:
    200		if (rdata->ids.port_id == FC_FID_DIR_SERV)
    201			lport->dns_rdata = NULL;
    202		else if (rdata->ids.port_id == FC_FID_MGMT_SERV)
    203			lport->ms_rdata = NULL;
    204		break;
    205	case RPORT_EV_NONE:
    206		break;
    207	}
    208	mutex_unlock(&lport->lp_mutex);
    209}
    210
    211/**
    212 * fc_lport_state() - Return a string which represents the lport's state
    213 * @lport: The lport whose state is to converted to a string
    214 */
    215static const char *fc_lport_state(struct fc_lport *lport)
    216{
    217	const char *cp;
    218
    219	cp = fc_lport_state_names[lport->state];
    220	if (!cp)
    221		cp = "unknown";
    222	return cp;
    223}
    224
    225/**
    226 * fc_lport_ptp_setup() - Create an rport for point-to-point mode
    227 * @lport:	 The lport to attach the ptp rport to
    228 * @remote_fid:	 The FID of the ptp rport
    229 * @remote_wwpn: The WWPN of the ptp rport
    230 * @remote_wwnn: The WWNN of the ptp rport
    231 */
    232static void fc_lport_ptp_setup(struct fc_lport *lport,
    233			       u32 remote_fid, u64 remote_wwpn,
    234			       u64 remote_wwnn)
    235{
    236	lockdep_assert_held(&lport->lp_mutex);
    237
    238	if (lport->ptp_rdata) {
    239		fc_rport_logoff(lport->ptp_rdata);
    240		kref_put(&lport->ptp_rdata->kref, fc_rport_destroy);
    241	}
    242	mutex_lock(&lport->disc.disc_mutex);
    243	lport->ptp_rdata = fc_rport_create(lport, remote_fid);
    244	kref_get(&lport->ptp_rdata->kref);
    245	lport->ptp_rdata->ids.port_name = remote_wwpn;
    246	lport->ptp_rdata->ids.node_name = remote_wwnn;
    247	mutex_unlock(&lport->disc.disc_mutex);
    248
    249	fc_rport_login(lport->ptp_rdata);
    250
    251	fc_lport_enter_ready(lport);
    252}
    253
    254/**
    255 * fc_get_host_port_state() - Return the port state of the given Scsi_Host
    256 * @shost:  The SCSI host whose port state is to be determined
    257 */
    258void fc_get_host_port_state(struct Scsi_Host *shost)
    259{
    260	struct fc_lport *lport = shost_priv(shost);
    261
    262	mutex_lock(&lport->lp_mutex);
    263	if (!lport->link_up)
    264		fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
    265	else
    266		switch (lport->state) {
    267		case LPORT_ST_READY:
    268			fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
    269			break;
    270		default:
    271			fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
    272		}
    273	mutex_unlock(&lport->lp_mutex);
    274}
    275EXPORT_SYMBOL(fc_get_host_port_state);
    276
    277/**
    278 * fc_get_host_speed() - Return the speed of the given Scsi_Host
    279 * @shost: The SCSI host whose port speed is to be determined
    280 */
    281void fc_get_host_speed(struct Scsi_Host *shost)
    282{
    283	struct fc_lport *lport = shost_priv(shost);
    284
    285	fc_host_speed(shost) = lport->link_speed;
    286}
    287EXPORT_SYMBOL(fc_get_host_speed);
    288
    289/**
    290 * fc_get_host_stats() - Return the Scsi_Host's statistics
    291 * @shost: The SCSI host whose statistics are to be returned
    292 */
    293struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
    294{
    295	struct fc_host_statistics *fc_stats;
    296	struct fc_lport *lport = shost_priv(shost);
    297	unsigned int cpu;
    298	u64 fcp_in_bytes = 0;
    299	u64 fcp_out_bytes = 0;
    300
    301	fc_stats = &lport->host_stats;
    302	memset(fc_stats, 0, sizeof(struct fc_host_statistics));
    303
    304	fc_stats->seconds_since_last_reset = (jiffies - lport->boot_time) / HZ;
    305
    306	for_each_possible_cpu(cpu) {
    307		struct fc_stats *stats;
    308
    309		stats = per_cpu_ptr(lport->stats, cpu);
    310
    311		fc_stats->tx_frames += READ_ONCE(stats->TxFrames);
    312		fc_stats->tx_words += READ_ONCE(stats->TxWords);
    313		fc_stats->rx_frames += READ_ONCE(stats->RxFrames);
    314		fc_stats->rx_words += READ_ONCE(stats->RxWords);
    315		fc_stats->error_frames += READ_ONCE(stats->ErrorFrames);
    316		fc_stats->invalid_crc_count += READ_ONCE(stats->InvalidCRCCount);
    317		fc_stats->fcp_input_requests += READ_ONCE(stats->InputRequests);
    318		fc_stats->fcp_output_requests += READ_ONCE(stats->OutputRequests);
    319		fc_stats->fcp_control_requests += READ_ONCE(stats->ControlRequests);
    320		fcp_in_bytes += READ_ONCE(stats->InputBytes);
    321		fcp_out_bytes += READ_ONCE(stats->OutputBytes);
    322		fc_stats->fcp_packet_alloc_failures += READ_ONCE(stats->FcpPktAllocFails);
    323		fc_stats->fcp_packet_aborts += READ_ONCE(stats->FcpPktAborts);
    324		fc_stats->fcp_frame_alloc_failures += READ_ONCE(stats->FcpFrameAllocFails);
    325		fc_stats->link_failure_count += READ_ONCE(stats->LinkFailureCount);
    326	}
    327	fc_stats->fcp_input_megabytes = div_u64(fcp_in_bytes, 1000000);
    328	fc_stats->fcp_output_megabytes = div_u64(fcp_out_bytes, 1000000);
    329	fc_stats->lip_count = -1;
    330	fc_stats->nos_count = -1;
    331	fc_stats->loss_of_sync_count = -1;
    332	fc_stats->loss_of_signal_count = -1;
    333	fc_stats->prim_seq_protocol_err_count = -1;
    334	fc_stats->dumped_frames = -1;
    335
    336	/* update exches stats */
    337	fc_exch_update_stats(lport);
    338
    339	return fc_stats;
    340}
    341EXPORT_SYMBOL(fc_get_host_stats);
    342
    343/**
    344 * fc_lport_flogi_fill() - Fill in FLOGI command for request
    345 * @lport: The local port the FLOGI is for
    346 * @flogi: The FLOGI command
    347 * @op:	   The opcode
    348 */
    349static void fc_lport_flogi_fill(struct fc_lport *lport,
    350				struct fc_els_flogi *flogi,
    351				unsigned int op)
    352{
    353	struct fc_els_csp *sp;
    354	struct fc_els_cssp *cp;
    355
    356	memset(flogi, 0, sizeof(*flogi));
    357	flogi->fl_cmd = (u8) op;
    358	put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn);
    359	put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn);
    360	sp = &flogi->fl_csp;
    361	sp->sp_hi_ver = 0x20;
    362	sp->sp_lo_ver = 0x20;
    363	sp->sp_bb_cred = htons(10);	/* this gets set by gateway */
    364	sp->sp_bb_data = htons((u16) lport->mfs);
    365	cp = &flogi->fl_cssp[3 - 1];	/* class 3 parameters */
    366	cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
    367	if (op != ELS_FLOGI) {
    368		sp->sp_features = htons(FC_SP_FT_CIRO);
    369		sp->sp_tot_seq = htons(255);	/* seq. we accept */
    370		sp->sp_rel_off = htons(0x1f);
    371		sp->sp_e_d_tov = htonl(lport->e_d_tov);
    372
    373		cp->cp_rdfs = htons((u16) lport->mfs);
    374		cp->cp_con_seq = htons(255);
    375		cp->cp_open_seq = 1;
    376	}
    377}
    378
    379/**
    380 * fc_lport_add_fc4_type() - Add a supported FC-4 type to a local port
    381 * @lport: The local port to add a new FC-4 type to
    382 * @type:  The new FC-4 type
    383 */
    384static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
    385{
    386	__be32 *mp;
    387
    388	mp = &lport->fcts.ff_type_map[type / FC_NS_BPW];
    389	*mp = htonl(ntohl(*mp) | 1UL << (type % FC_NS_BPW));
    390}
    391
    392/**
    393 * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report.
    394 * @lport: Fibre Channel local port receiving the RLIR
    395 * @fp:	   The RLIR request frame
    396 */
    397static void fc_lport_recv_rlir_req(struct fc_lport *lport, struct fc_frame *fp)
    398{
    399	lockdep_assert_held(&lport->lp_mutex);
    400
    401	FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n",
    402		     fc_lport_state(lport));
    403
    404	fc_seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
    405	fc_frame_free(fp);
    406}
    407
    408/**
    409 * fc_lport_recv_echo_req() - Handle received ECHO request
    410 * @lport: The local port receiving the ECHO
    411 * @in_fp: ECHO request frame
    412 */
    413static void fc_lport_recv_echo_req(struct fc_lport *lport,
    414				   struct fc_frame *in_fp)
    415{
    416	struct fc_frame *fp;
    417	unsigned int len;
    418	void *pp;
    419	void *dp;
    420
    421	lockdep_assert_held(&lport->lp_mutex);
    422
    423	FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n",
    424		     fc_lport_state(lport));
    425
    426	len = fr_len(in_fp) - sizeof(struct fc_frame_header);
    427	pp = fc_frame_payload_get(in_fp, len);
    428
    429	if (len < sizeof(__be32))
    430		len = sizeof(__be32);
    431
    432	fp = fc_frame_alloc(lport, len);
    433	if (fp) {
    434		dp = fc_frame_payload_get(fp, len);
    435		memcpy(dp, pp, len);
    436		*((__be32 *)dp) = htonl(ELS_LS_ACC << 24);
    437		fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
    438		lport->tt.frame_send(lport, fp);
    439	}
    440	fc_frame_free(in_fp);
    441}
    442
    443/**
    444 * fc_lport_recv_rnid_req() - Handle received Request Node ID data request
    445 * @lport: The local port receiving the RNID
    446 * @in_fp: The RNID request frame
    447 */
    448static void fc_lport_recv_rnid_req(struct fc_lport *lport,
    449				   struct fc_frame *in_fp)
    450{
    451	struct fc_frame *fp;
    452	struct fc_els_rnid *req;
    453	struct {
    454		struct fc_els_rnid_resp rnid;
    455		struct fc_els_rnid_cid cid;
    456		struct fc_els_rnid_gen gen;
    457	} *rp;
    458	struct fc_seq_els_data rjt_data;
    459	u8 fmt;
    460	size_t len;
    461
    462	lockdep_assert_held(&lport->lp_mutex);
    463
    464	FC_LPORT_DBG(lport, "Received RNID request while in state %s\n",
    465		     fc_lport_state(lport));
    466
    467	req = fc_frame_payload_get(in_fp, sizeof(*req));
    468	if (!req) {
    469		rjt_data.reason = ELS_RJT_LOGIC;
    470		rjt_data.explan = ELS_EXPL_NONE;
    471		fc_seq_els_rsp_send(in_fp, ELS_LS_RJT, &rjt_data);
    472	} else {
    473		fmt = req->rnid_fmt;
    474		len = sizeof(*rp);
    475		if (fmt != ELS_RNIDF_GEN ||
    476		    ntohl(lport->rnid_gen.rnid_atype) == 0) {
    477			fmt = ELS_RNIDF_NONE;	/* nothing to provide */
    478			len -= sizeof(rp->gen);
    479		}
    480		fp = fc_frame_alloc(lport, len);
    481		if (fp) {
    482			rp = fc_frame_payload_get(fp, len);
    483			memset(rp, 0, len);
    484			rp->rnid.rnid_cmd = ELS_LS_ACC;
    485			rp->rnid.rnid_fmt = fmt;
    486			rp->rnid.rnid_cid_len = sizeof(rp->cid);
    487			rp->cid.rnid_wwpn = htonll(lport->wwpn);
    488			rp->cid.rnid_wwnn = htonll(lport->wwnn);
    489			if (fmt == ELS_RNIDF_GEN) {
    490				rp->rnid.rnid_sid_len = sizeof(rp->gen);
    491				memcpy(&rp->gen, &lport->rnid_gen,
    492				       sizeof(rp->gen));
    493			}
    494			fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
    495			lport->tt.frame_send(lport, fp);
    496		}
    497	}
    498	fc_frame_free(in_fp);
    499}
    500
    501/**
    502 * fc_lport_recv_logo_req() - Handle received fabric LOGO request
    503 * @lport: The local port receiving the LOGO
    504 * @fp:	   The LOGO request frame
    505 */
    506static void fc_lport_recv_logo_req(struct fc_lport *lport, struct fc_frame *fp)
    507{
    508	lockdep_assert_held(&lport->lp_mutex);
    509
    510	fc_seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
    511	fc_lport_enter_reset(lport);
    512	fc_frame_free(fp);
    513}
    514
    515/**
    516 * fc_fabric_login() - Start the lport state machine
    517 * @lport: The local port that should log into the fabric
    518 *
    519 * Locking Note: This function should not be called
    520 *		 with the lport lock held.
    521 */
    522int fc_fabric_login(struct fc_lport *lport)
    523{
    524	int rc = -1;
    525
    526	mutex_lock(&lport->lp_mutex);
    527	if (lport->state == LPORT_ST_DISABLED ||
    528	    lport->state == LPORT_ST_LOGO) {
    529		fc_lport_state_enter(lport, LPORT_ST_RESET);
    530		fc_lport_enter_reset(lport);
    531		rc = 0;
    532	}
    533	mutex_unlock(&lport->lp_mutex);
    534
    535	return rc;
    536}
    537EXPORT_SYMBOL(fc_fabric_login);
    538
    539/**
    540 * __fc_linkup() - Handler for transport linkup events
    541 * @lport: The lport whose link is up
    542 */
    543void __fc_linkup(struct fc_lport *lport)
    544{
    545	lockdep_assert_held(&lport->lp_mutex);
    546
    547	if (!lport->link_up) {
    548		lport->link_up = 1;
    549
    550		if (lport->state == LPORT_ST_RESET)
    551			fc_lport_enter_flogi(lport);
    552	}
    553}
    554
    555/**
    556 * fc_linkup() - Handler for transport linkup events
    557 * @lport: The local port whose link is up
    558 */
    559void fc_linkup(struct fc_lport *lport)
    560{
    561	printk(KERN_INFO "host%d: libfc: Link up on port (%6.6x)\n",
    562	       lport->host->host_no, lport->port_id);
    563
    564	mutex_lock(&lport->lp_mutex);
    565	__fc_linkup(lport);
    566	mutex_unlock(&lport->lp_mutex);
    567}
    568EXPORT_SYMBOL(fc_linkup);
    569
    570/**
    571 * __fc_linkdown() - Handler for transport linkdown events
    572 * @lport: The lport whose link is down
    573 */
    574void __fc_linkdown(struct fc_lport *lport)
    575{
    576	lockdep_assert_held(&lport->lp_mutex);
    577
    578	if (lport->link_up) {
    579		lport->link_up = 0;
    580		fc_lport_enter_reset(lport);
    581		lport->tt.fcp_cleanup(lport);
    582	}
    583}
    584
    585/**
    586 * fc_linkdown() - Handler for transport linkdown events
    587 * @lport: The local port whose link is down
    588 */
    589void fc_linkdown(struct fc_lport *lport)
    590{
    591	printk(KERN_INFO "host%d: libfc: Link down on port (%6.6x)\n",
    592	       lport->host->host_no, lport->port_id);
    593
    594	mutex_lock(&lport->lp_mutex);
    595	__fc_linkdown(lport);
    596	mutex_unlock(&lport->lp_mutex);
    597}
    598EXPORT_SYMBOL(fc_linkdown);
    599
    600/**
    601 * fc_fabric_logoff() - Logout of the fabric
    602 * @lport: The local port to logoff the fabric
    603 *
    604 * Return value:
    605 *	0 for success, -1 for failure
    606 */
    607int fc_fabric_logoff(struct fc_lport *lport)
    608{
    609	lport->tt.disc_stop_final(lport);
    610	mutex_lock(&lport->lp_mutex);
    611	if (lport->dns_rdata)
    612		fc_rport_logoff(lport->dns_rdata);
    613	mutex_unlock(&lport->lp_mutex);
    614	fc_rport_flush_queue();
    615	mutex_lock(&lport->lp_mutex);
    616	fc_lport_enter_logo(lport);
    617	mutex_unlock(&lport->lp_mutex);
    618	cancel_delayed_work_sync(&lport->retry_work);
    619	return 0;
    620}
    621EXPORT_SYMBOL(fc_fabric_logoff);
    622
    623/**
    624 * fc_lport_destroy() - Unregister a fc_lport
    625 * @lport: The local port to unregister
    626 *
    627 * Note:
    628 * exit routine for fc_lport instance
    629 * clean-up all the allocated memory
    630 * and free up other system resources.
    631 *
    632 */
    633int fc_lport_destroy(struct fc_lport *lport)
    634{
    635	mutex_lock(&lport->lp_mutex);
    636	lport->state = LPORT_ST_DISABLED;
    637	lport->link_up = 0;
    638	lport->tt.frame_send = fc_frame_drop;
    639	mutex_unlock(&lport->lp_mutex);
    640
    641	lport->tt.fcp_abort_io(lport);
    642	lport->tt.disc_stop_final(lport);
    643	lport->tt.exch_mgr_reset(lport, 0, 0);
    644	cancel_delayed_work_sync(&lport->retry_work);
    645	fc_fc4_del_lport(lport);
    646	return 0;
    647}
    648EXPORT_SYMBOL(fc_lport_destroy);
    649
    650/**
    651 * fc_set_mfs() - Set the maximum frame size for a local port
    652 * @lport: The local port to set the MFS for
    653 * @mfs:   The new MFS
    654 */
    655int fc_set_mfs(struct fc_lport *lport, u32 mfs)
    656{
    657	unsigned int old_mfs;
    658	int rc = -EINVAL;
    659
    660	mutex_lock(&lport->lp_mutex);
    661
    662	old_mfs = lport->mfs;
    663
    664	if (mfs >= FC_MIN_MAX_FRAME) {
    665		mfs &= ~3;
    666		if (mfs > FC_MAX_FRAME)
    667			mfs = FC_MAX_FRAME;
    668		mfs -= sizeof(struct fc_frame_header);
    669		lport->mfs = mfs;
    670		rc = 0;
    671	}
    672
    673	if (!rc && mfs < old_mfs)
    674		fc_lport_enter_reset(lport);
    675
    676	mutex_unlock(&lport->lp_mutex);
    677
    678	return rc;
    679}
    680EXPORT_SYMBOL(fc_set_mfs);
    681
    682/**
    683 * fc_lport_disc_callback() - Callback for discovery events
    684 * @lport: The local port receiving the event
    685 * @event: The discovery event
    686 */
    687static void fc_lport_disc_callback(struct fc_lport *lport,
    688				   enum fc_disc_event event)
    689{
    690	switch (event) {
    691	case DISC_EV_SUCCESS:
    692		FC_LPORT_DBG(lport, "Discovery succeeded\n");
    693		break;
    694	case DISC_EV_FAILED:
    695		printk(KERN_ERR "host%d: libfc: "
    696		       "Discovery failed for port (%6.6x)\n",
    697		       lport->host->host_no, lport->port_id);
    698		mutex_lock(&lport->lp_mutex);
    699		fc_lport_enter_reset(lport);
    700		mutex_unlock(&lport->lp_mutex);
    701		break;
    702	case DISC_EV_NONE:
    703		WARN_ON(1);
    704		break;
    705	}
    706}
    707
    708/**
    709 * fc_lport_enter_ready() - Enter the ready state and start discovery
    710 * @lport: The local port that is ready
    711 */
    712static void fc_lport_enter_ready(struct fc_lport *lport)
    713{
    714	lockdep_assert_held(&lport->lp_mutex);
    715
    716	FC_LPORT_DBG(lport, "Entered READY from state %s\n",
    717		     fc_lport_state(lport));
    718
    719	fc_lport_state_enter(lport, LPORT_ST_READY);
    720	if (lport->vport)
    721		fc_vport_set_state(lport->vport, FC_VPORT_ACTIVE);
    722	fc_vports_linkchange(lport);
    723
    724	if (!lport->ptp_rdata)
    725		lport->tt.disc_start(fc_lport_disc_callback, lport);
    726}
    727
    728/**
    729 * fc_lport_set_port_id() - set the local port Port ID
    730 * @lport: The local port which will have its Port ID set.
    731 * @port_id: The new port ID.
    732 * @fp: The frame containing the incoming request, or NULL.
    733 */
    734static void fc_lport_set_port_id(struct fc_lport *lport, u32 port_id,
    735				 struct fc_frame *fp)
    736{
    737	lockdep_assert_held(&lport->lp_mutex);
    738
    739	if (port_id)
    740		printk(KERN_INFO "host%d: Assigned Port ID %6.6x\n",
    741		       lport->host->host_no, port_id);
    742
    743	lport->port_id = port_id;
    744
    745	/* Update the fc_host */
    746	fc_host_port_id(lport->host) = port_id;
    747
    748	if (lport->tt.lport_set_port_id)
    749		lport->tt.lport_set_port_id(lport, port_id, fp);
    750}
    751
    752/**
    753 * fc_lport_set_local_id() - set the local port Port ID for point-to-multipoint
    754 * @lport: The local port which will have its Port ID set.
    755 * @port_id: The new port ID.
    756 *
    757 * Called by the lower-level driver when transport sets the local port_id.
    758 * This is used in VN_port to VN_port mode for FCoE, and causes FLOGI and
    759 * discovery to be skipped.
    760 */
    761void fc_lport_set_local_id(struct fc_lport *lport, u32 port_id)
    762{
    763	mutex_lock(&lport->lp_mutex);
    764
    765	fc_lport_set_port_id(lport, port_id, NULL);
    766
    767	switch (lport->state) {
    768	case LPORT_ST_RESET:
    769	case LPORT_ST_FLOGI:
    770		if (port_id)
    771			fc_lport_enter_ready(lport);
    772		break;
    773	default:
    774		break;
    775	}
    776	mutex_unlock(&lport->lp_mutex);
    777}
    778EXPORT_SYMBOL(fc_lport_set_local_id);
    779
    780/**
    781 * fc_lport_recv_flogi_req() - Receive a FLOGI request
    782 * @lport: The local port that received the request
    783 * @rx_fp: The FLOGI frame
    784 *
    785 * A received FLOGI request indicates a point-to-point connection.
    786 * Accept it with the common service parameters indicating our N port.
    787 * Set up to do a PLOGI if we have the higher-number WWPN.
    788 */
    789static void fc_lport_recv_flogi_req(struct fc_lport *lport,
    790				    struct fc_frame *rx_fp)
    791{
    792	struct fc_frame *fp;
    793	struct fc_frame_header *fh;
    794	struct fc_els_flogi *flp;
    795	struct fc_els_flogi *new_flp;
    796	u64 remote_wwpn;
    797	u32 remote_fid;
    798	u32 local_fid;
    799
    800	lockdep_assert_held(&lport->lp_mutex);
    801
    802	FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n",
    803		     fc_lport_state(lport));
    804
    805	remote_fid = fc_frame_sid(rx_fp);
    806	flp = fc_frame_payload_get(rx_fp, sizeof(*flp));
    807	if (!flp)
    808		goto out;
    809	remote_wwpn = get_unaligned_be64(&flp->fl_wwpn);
    810	if (remote_wwpn == lport->wwpn) {
    811		printk(KERN_WARNING "host%d: libfc: Received FLOGI from port "
    812		       "with same WWPN %16.16llx\n",
    813		       lport->host->host_no, remote_wwpn);
    814		goto out;
    815	}
    816	FC_LPORT_DBG(lport, "FLOGI from port WWPN %16.16llx\n", remote_wwpn);
    817
    818	/*
    819	 * XXX what is the right thing to do for FIDs?
    820	 * The originator might expect our S_ID to be 0xfffffe.
    821	 * But if so, both of us could end up with the same FID.
    822	 */
    823	local_fid = FC_LOCAL_PTP_FID_LO;
    824	if (remote_wwpn < lport->wwpn) {
    825		local_fid = FC_LOCAL_PTP_FID_HI;
    826		if (!remote_fid || remote_fid == local_fid)
    827			remote_fid = FC_LOCAL_PTP_FID_LO;
    828	} else if (!remote_fid) {
    829		remote_fid = FC_LOCAL_PTP_FID_HI;
    830	}
    831
    832	fc_lport_set_port_id(lport, local_fid, rx_fp);
    833
    834	fp = fc_frame_alloc(lport, sizeof(*flp));
    835	if (fp) {
    836		new_flp = fc_frame_payload_get(fp, sizeof(*flp));
    837		fc_lport_flogi_fill(lport, new_flp, ELS_FLOGI);
    838		new_flp->fl_cmd = (u8) ELS_LS_ACC;
    839
    840		/*
    841		 * Send the response.  If this fails, the originator should
    842		 * repeat the sequence.
    843		 */
    844		fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
    845		fh = fc_frame_header_get(fp);
    846		hton24(fh->fh_s_id, local_fid);
    847		hton24(fh->fh_d_id, remote_fid);
    848		lport->tt.frame_send(lport, fp);
    849
    850	} else {
    851		fc_lport_error(lport, fp);
    852	}
    853	fc_lport_ptp_setup(lport, remote_fid, remote_wwpn,
    854			   get_unaligned_be64(&flp->fl_wwnn));
    855out:
    856	fc_frame_free(rx_fp);
    857}
    858
    859/**
    860 * fc_lport_recv_els_req() - The generic lport ELS request handler
    861 * @lport: The local port that received the request
    862 * @fp:	   The request frame
    863 *
    864 * This function will see if the lport handles the request or
    865 * if an rport should handle the request.
    866 *
    867 * Locking Note: This function should not be called with the lport
    868 *		 lock held because it will grab the lock.
    869 */
    870static void fc_lport_recv_els_req(struct fc_lport *lport,
    871				  struct fc_frame *fp)
    872{
    873	mutex_lock(&lport->lp_mutex);
    874
    875	/*
    876	 * Handle special ELS cases like FLOGI, LOGO, and
    877	 * RSCN here.  These don't require a session.
    878	 * Even if we had a session, it might not be ready.
    879	 */
    880	if (!lport->link_up)
    881		fc_frame_free(fp);
    882	else {
    883		/*
    884		 * Check opcode.
    885		 */
    886		switch (fc_frame_payload_op(fp)) {
    887		case ELS_FLOGI:
    888			if (!lport->point_to_multipoint)
    889				fc_lport_recv_flogi_req(lport, fp);
    890			else
    891				fc_rport_recv_req(lport, fp);
    892			break;
    893		case ELS_LOGO:
    894			if (fc_frame_sid(fp) == FC_FID_FLOGI)
    895				fc_lport_recv_logo_req(lport, fp);
    896			else
    897				fc_rport_recv_req(lport, fp);
    898			break;
    899		case ELS_RSCN:
    900			lport->tt.disc_recv_req(lport, fp);
    901			break;
    902		case ELS_ECHO:
    903			fc_lport_recv_echo_req(lport, fp);
    904			break;
    905		case ELS_RLIR:
    906			fc_lport_recv_rlir_req(lport, fp);
    907			break;
    908		case ELS_RNID:
    909			fc_lport_recv_rnid_req(lport, fp);
    910			break;
    911		default:
    912			fc_rport_recv_req(lport, fp);
    913			break;
    914		}
    915	}
    916	mutex_unlock(&lport->lp_mutex);
    917}
    918
    919static int fc_lport_els_prli(struct fc_rport_priv *rdata, u32 spp_len,
    920			     const struct fc_els_spp *spp_in,
    921			     struct fc_els_spp *spp_out)
    922{
    923	return FC_SPP_RESP_INVL;
    924}
    925
    926struct fc4_prov fc_lport_els_prov = {
    927	.prli = fc_lport_els_prli,
    928	.recv = fc_lport_recv_els_req,
    929};
    930
    931/**
    932 * fc_lport_recv() - The generic lport request handler
    933 * @lport: The lport that received the request
    934 * @fp: The frame the request is in
    935 *
    936 * Locking Note: This function should not be called with the lport
    937 *		 lock held because it may grab the lock.
    938 */
    939void fc_lport_recv(struct fc_lport *lport, struct fc_frame *fp)
    940{
    941	struct fc_frame_header *fh = fc_frame_header_get(fp);
    942	struct fc_seq *sp = fr_seq(fp);
    943	struct fc4_prov *prov;
    944
    945	/*
    946	 * Use RCU read lock and module_lock to be sure module doesn't
    947	 * deregister and get unloaded while we're calling it.
    948	 * try_module_get() is inlined and accepts a NULL parameter.
    949	 * Only ELSes and FCP target ops should come through here.
    950	 * The locking is unfortunate, and a better scheme is being sought.
    951	 */
    952
    953	rcu_read_lock();
    954	if (fh->fh_type >= FC_FC4_PROV_SIZE)
    955		goto drop;
    956	prov = rcu_dereference(fc_passive_prov[fh->fh_type]);
    957	if (!prov || !try_module_get(prov->module))
    958		goto drop;
    959	rcu_read_unlock();
    960	prov->recv(lport, fp);
    961	module_put(prov->module);
    962	return;
    963drop:
    964	rcu_read_unlock();
    965	FC_LPORT_DBG(lport, "dropping unexpected frame type %x\n", fh->fh_type);
    966	fc_frame_free(fp);
    967	if (sp)
    968		fc_exch_done(sp);
    969}
    970EXPORT_SYMBOL(fc_lport_recv);
    971
    972/**
    973 * fc_lport_reset() - Reset a local port
    974 * @lport: The local port which should be reset
    975 *
    976 * Locking Note: This functions should not be called with the
    977 *		 lport lock held.
    978 */
    979int fc_lport_reset(struct fc_lport *lport)
    980{
    981	cancel_delayed_work_sync(&lport->retry_work);
    982	mutex_lock(&lport->lp_mutex);
    983	fc_lport_enter_reset(lport);
    984	mutex_unlock(&lport->lp_mutex);
    985	return 0;
    986}
    987EXPORT_SYMBOL(fc_lport_reset);
    988
    989/**
    990 * fc_lport_reset_locked() - Reset the local port w/ the lport lock held
    991 * @lport: The local port to be reset
    992 */
    993static void fc_lport_reset_locked(struct fc_lport *lport)
    994{
    995	lockdep_assert_held(&lport->lp_mutex);
    996
    997	if (lport->dns_rdata) {
    998		fc_rport_logoff(lport->dns_rdata);
    999		lport->dns_rdata = NULL;
   1000	}
   1001
   1002	if (lport->ptp_rdata) {
   1003		fc_rport_logoff(lport->ptp_rdata);
   1004		kref_put(&lport->ptp_rdata->kref, fc_rport_destroy);
   1005		lport->ptp_rdata = NULL;
   1006	}
   1007
   1008	lport->tt.disc_stop(lport);
   1009
   1010	lport->tt.exch_mgr_reset(lport, 0, 0);
   1011	fc_host_fabric_name(lport->host) = 0;
   1012
   1013	if (lport->port_id && (!lport->point_to_multipoint || !lport->link_up))
   1014		fc_lport_set_port_id(lport, 0, NULL);
   1015}
   1016
   1017/**
   1018 * fc_lport_enter_reset() - Reset the local port
   1019 * @lport: The local port to be reset
   1020 */
   1021static void fc_lport_enter_reset(struct fc_lport *lport)
   1022{
   1023	lockdep_assert_held(&lport->lp_mutex);
   1024
   1025	FC_LPORT_DBG(lport, "Entered RESET state from %s state\n",
   1026		     fc_lport_state(lport));
   1027
   1028	if (lport->state == LPORT_ST_DISABLED || lport->state == LPORT_ST_LOGO)
   1029		return;
   1030
   1031	if (lport->vport) {
   1032		if (lport->link_up)
   1033			fc_vport_set_state(lport->vport, FC_VPORT_INITIALIZING);
   1034		else
   1035			fc_vport_set_state(lport->vport, FC_VPORT_LINKDOWN);
   1036	}
   1037	fc_lport_state_enter(lport, LPORT_ST_RESET);
   1038	fc_host_post_event(lport->host, fc_get_event_number(),
   1039			   FCH_EVT_LIPRESET, 0);
   1040	fc_vports_linkchange(lport);
   1041	fc_lport_reset_locked(lport);
   1042	if (lport->link_up)
   1043		fc_lport_enter_flogi(lport);
   1044}
   1045
   1046/**
   1047 * fc_lport_enter_disabled() - Disable the local port
   1048 * @lport: The local port to be reset
   1049 */
   1050static void fc_lport_enter_disabled(struct fc_lport *lport)
   1051{
   1052	lockdep_assert_held(&lport->lp_mutex);
   1053
   1054	FC_LPORT_DBG(lport, "Entered disabled state from %s state\n",
   1055		     fc_lport_state(lport));
   1056
   1057	fc_lport_state_enter(lport, LPORT_ST_DISABLED);
   1058	fc_vports_linkchange(lport);
   1059	fc_lport_reset_locked(lport);
   1060}
   1061
   1062/**
   1063 * fc_lport_error() - Handler for any errors
   1064 * @lport: The local port that the error was on
   1065 * @fp:	   The error code encoded in a frame pointer
   1066 *
   1067 * If the error was caused by a resource allocation failure
   1068 * then wait for half a second and retry, otherwise retry
   1069 * after the e_d_tov time.
   1070 */
   1071static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
   1072{
   1073	unsigned long delay = 0;
   1074	FC_LPORT_DBG(lport, "Error %ld in state %s, retries %d\n",
   1075		     IS_ERR(fp) ? -PTR_ERR(fp) : 0, fc_lport_state(lport),
   1076		     lport->retry_count);
   1077
   1078	if (PTR_ERR(fp) == -FC_EX_CLOSED)
   1079		return;
   1080
   1081	/*
   1082	 * Memory allocation failure, or the exchange timed out
   1083	 * or we received LS_RJT.
   1084	 * Retry after delay
   1085	 */
   1086	if (lport->retry_count < lport->max_retry_count) {
   1087		lport->retry_count++;
   1088		if (!fp)
   1089			delay = msecs_to_jiffies(500);
   1090		else
   1091			delay =	msecs_to_jiffies(lport->e_d_tov);
   1092
   1093		schedule_delayed_work(&lport->retry_work, delay);
   1094	} else
   1095		fc_lport_enter_reset(lport);
   1096}
   1097
   1098/**
   1099 * fc_lport_ns_resp() - Handle response to a name server
   1100 *			registration exchange
   1101 * @sp:	    current sequence in exchange
   1102 * @fp:	    response frame
   1103 * @lp_arg: Fibre Channel host port instance
   1104 *
   1105 * Locking Note: This function will be called without the lport lock
   1106 * held, but it will lock, call an _enter_* function or fc_lport_error()
   1107 * and then unlock the lport.
   1108 */
   1109static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp,
   1110			     void *lp_arg)
   1111{
   1112	struct fc_lport *lport = lp_arg;
   1113	struct fc_frame_header *fh;
   1114	struct fc_ct_hdr *ct;
   1115
   1116	FC_LPORT_DBG(lport, "Received a ns %s\n", fc_els_resp_type(fp));
   1117
   1118	if (fp == ERR_PTR(-FC_EX_CLOSED))
   1119		return;
   1120
   1121	mutex_lock(&lport->lp_mutex);
   1122
   1123	if (lport->state < LPORT_ST_RNN_ID || lport->state > LPORT_ST_RFF_ID) {
   1124		FC_LPORT_DBG(lport, "Received a name server response, "
   1125			     "but in state %s\n", fc_lport_state(lport));
   1126		if (IS_ERR(fp))
   1127			goto err;
   1128		goto out;
   1129	}
   1130
   1131	if (IS_ERR(fp)) {
   1132		fc_lport_error(lport, fp);
   1133		goto err;
   1134	}
   1135
   1136	fh = fc_frame_header_get(fp);
   1137	ct = fc_frame_payload_get(fp, sizeof(*ct));
   1138
   1139	if (fh && ct && fh->fh_type == FC_TYPE_CT &&
   1140	    ct->ct_fs_type == FC_FST_DIR &&
   1141	    ct->ct_fs_subtype == FC_NS_SUBTYPE &&
   1142	    ntohs(ct->ct_cmd) == FC_FS_ACC)
   1143		switch (lport->state) {
   1144		case LPORT_ST_RNN_ID:
   1145			fc_lport_enter_ns(lport, LPORT_ST_RSNN_NN);
   1146			break;
   1147		case LPORT_ST_RSNN_NN:
   1148			fc_lport_enter_ns(lport, LPORT_ST_RSPN_ID);
   1149			break;
   1150		case LPORT_ST_RSPN_ID:
   1151			fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
   1152			break;
   1153		case LPORT_ST_RFT_ID:
   1154			fc_lport_enter_ns(lport, LPORT_ST_RFF_ID);
   1155			break;
   1156		case LPORT_ST_RFF_ID:
   1157			if (lport->fdmi_enabled)
   1158				fc_lport_enter_fdmi(lport);
   1159			else
   1160				fc_lport_enter_scr(lport);
   1161			break;
   1162		default:
   1163			/* should have already been caught by state checks */
   1164			break;
   1165		}
   1166	else
   1167		fc_lport_error(lport, fp);
   1168out:
   1169	fc_frame_free(fp);
   1170err:
   1171	mutex_unlock(&lport->lp_mutex);
   1172}
   1173
   1174/**
   1175 * fc_lport_ms_resp() - Handle response to a management server
   1176 *			exchange
   1177 * @sp:	    current sequence in exchange
   1178 * @fp:	    response frame
   1179 * @lp_arg: Fibre Channel host port instance
   1180 *
   1181 * Locking Note: This function will be called without the lport lock
   1182 * held, but it will lock, call an _enter_* function or fc_lport_error()
   1183 * and then unlock the lport.
   1184 */
   1185static void fc_lport_ms_resp(struct fc_seq *sp, struct fc_frame *fp,
   1186			     void *lp_arg)
   1187{
   1188	struct fc_lport *lport = lp_arg;
   1189	struct fc_frame_header *fh;
   1190	struct fc_ct_hdr *ct;
   1191	struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host);
   1192	FC_LPORT_DBG(lport, "Received a ms %s\n", fc_els_resp_type(fp));
   1193
   1194	if (fp == ERR_PTR(-FC_EX_CLOSED))
   1195		return;
   1196
   1197	mutex_lock(&lport->lp_mutex);
   1198
   1199	if (lport->state < LPORT_ST_RHBA || lport->state > LPORT_ST_DPRT) {
   1200		FC_LPORT_DBG(lport, "Received a management server response, "
   1201			     "but in state %s\n", fc_lport_state(lport));
   1202		if (IS_ERR(fp))
   1203			goto err;
   1204		goto out;
   1205	}
   1206
   1207	if (IS_ERR(fp)) {
   1208		fc_lport_error(lport, fp);
   1209		goto err;
   1210	}
   1211
   1212	fh = fc_frame_header_get(fp);
   1213	ct = fc_frame_payload_get(fp, sizeof(*ct));
   1214
   1215	if (fh && ct && fh->fh_type == FC_TYPE_CT &&
   1216	    ct->ct_fs_type == FC_FST_MGMT &&
   1217	    ct->ct_fs_subtype == FC_FDMI_SUBTYPE) {
   1218		FC_LPORT_DBG(lport, "Received a management server response, "
   1219				    "reason=%d explain=%d\n",
   1220				    ct->ct_reason,
   1221				    ct->ct_explan);
   1222
   1223		switch (lport->state) {
   1224		case LPORT_ST_RHBA:
   1225			if ((ntohs(ct->ct_cmd) == FC_FS_RJT) && fc_host->fdmi_version == FDMI_V2) {
   1226				FC_LPORT_DBG(lport, "Error for FDMI-V2, fall back to FDMI-V1\n");
   1227				fc_host->fdmi_version = FDMI_V1;
   1228
   1229				fc_lport_enter_ms(lport, LPORT_ST_RHBA);
   1230
   1231			} else if (ntohs(ct->ct_cmd) == FC_FS_ACC)
   1232				fc_lport_enter_ms(lport, LPORT_ST_RPA);
   1233			else /* Error Skip RPA */
   1234				fc_lport_enter_scr(lport);
   1235			break;
   1236		case LPORT_ST_RPA:
   1237			fc_lport_enter_scr(lport);
   1238			break;
   1239		case LPORT_ST_DPRT:
   1240			fc_lport_enter_ms(lport, LPORT_ST_RHBA);
   1241			break;
   1242		case LPORT_ST_DHBA:
   1243			fc_lport_enter_ms(lport, LPORT_ST_DPRT);
   1244			break;
   1245		default:
   1246			/* should have already been caught by state checks */
   1247			break;
   1248		}
   1249	} else {
   1250		/* Invalid Frame? */
   1251		fc_lport_error(lport, fp);
   1252	}
   1253out:
   1254	fc_frame_free(fp);
   1255err:
   1256	mutex_unlock(&lport->lp_mutex);
   1257}
   1258
   1259/**
   1260 * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request
   1261 * @sp:	    current sequence in SCR exchange
   1262 * @fp:	    response frame
   1263 * @lp_arg: Fibre Channel lport port instance that sent the registration request
   1264 *
   1265 * Locking Note: This function will be called without the lport lock
   1266 * held, but it will lock, call an _enter_* function or fc_lport_error
   1267 * and then unlock the lport.
   1268 */
   1269static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
   1270			      void *lp_arg)
   1271{
   1272	struct fc_lport *lport = lp_arg;
   1273	u8 op;
   1274
   1275	FC_LPORT_DBG(lport, "Received a SCR %s\n", fc_els_resp_type(fp));
   1276
   1277	if (fp == ERR_PTR(-FC_EX_CLOSED))
   1278		return;
   1279
   1280	mutex_lock(&lport->lp_mutex);
   1281
   1282	if (lport->state != LPORT_ST_SCR) {
   1283		FC_LPORT_DBG(lport, "Received a SCR response, but in state "
   1284			     "%s\n", fc_lport_state(lport));
   1285		if (IS_ERR(fp))
   1286			goto err;
   1287		goto out;
   1288	}
   1289
   1290	if (IS_ERR(fp)) {
   1291		fc_lport_error(lport, fp);
   1292		goto err;
   1293	}
   1294
   1295	op = fc_frame_payload_op(fp);
   1296	if (op == ELS_LS_ACC)
   1297		fc_lport_enter_ready(lport);
   1298	else
   1299		fc_lport_error(lport, fp);
   1300
   1301out:
   1302	fc_frame_free(fp);
   1303err:
   1304	mutex_unlock(&lport->lp_mutex);
   1305}
   1306
   1307/**
   1308 * fc_lport_enter_scr() - Send a SCR (State Change Register) request
   1309 * @lport: The local port to register for state changes
   1310 */
   1311static void fc_lport_enter_scr(struct fc_lport *lport)
   1312{
   1313	struct fc_frame *fp;
   1314
   1315	lockdep_assert_held(&lport->lp_mutex);
   1316
   1317	FC_LPORT_DBG(lport, "Entered SCR state from %s state\n",
   1318		     fc_lport_state(lport));
   1319
   1320	fc_lport_state_enter(lport, LPORT_ST_SCR);
   1321
   1322	fp = fc_frame_alloc(lport, sizeof(struct fc_els_scr));
   1323	if (!fp) {
   1324		fc_lport_error(lport, fp);
   1325		return;
   1326	}
   1327
   1328	if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR,
   1329				  fc_lport_scr_resp, lport,
   1330				  2 * lport->r_a_tov))
   1331		fc_lport_error(lport, NULL);
   1332}
   1333
   1334/**
   1335 * fc_lport_enter_ns() - register some object with the name server
   1336 * @lport: Fibre Channel local port to register
   1337 * @state: Local port state
   1338 */
   1339static void fc_lport_enter_ns(struct fc_lport *lport, enum fc_lport_state state)
   1340{
   1341	struct fc_frame *fp;
   1342	enum fc_ns_req cmd;
   1343	int size = sizeof(struct fc_ct_hdr);
   1344	size_t len;
   1345
   1346	lockdep_assert_held(&lport->lp_mutex);
   1347
   1348	FC_LPORT_DBG(lport, "Entered %s state from %s state\n",
   1349		     fc_lport_state_names[state],
   1350		     fc_lport_state(lport));
   1351
   1352	fc_lport_state_enter(lport, state);
   1353
   1354	switch (state) {
   1355	case LPORT_ST_RNN_ID:
   1356		cmd = FC_NS_RNN_ID;
   1357		size += sizeof(struct fc_ns_rn_id);
   1358		break;
   1359	case LPORT_ST_RSNN_NN:
   1360		len = strnlen(fc_host_symbolic_name(lport->host), 255);
   1361		/* if there is no symbolic name, skip to RFT_ID */
   1362		if (!len)
   1363			return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
   1364		cmd = FC_NS_RSNN_NN;
   1365		size += sizeof(struct fc_ns_rsnn) + len;
   1366		break;
   1367	case LPORT_ST_RSPN_ID:
   1368		len = strnlen(fc_host_symbolic_name(lport->host), 255);
   1369		/* if there is no symbolic name, skip to RFT_ID */
   1370		if (!len)
   1371			return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
   1372		cmd = FC_NS_RSPN_ID;
   1373		size += sizeof(struct fc_ns_rspn) + len;
   1374		break;
   1375	case LPORT_ST_RFT_ID:
   1376		cmd = FC_NS_RFT_ID;
   1377		size += sizeof(struct fc_ns_rft);
   1378		break;
   1379	case LPORT_ST_RFF_ID:
   1380		cmd = FC_NS_RFF_ID;
   1381		size += sizeof(struct fc_ns_rff_id);
   1382		break;
   1383	default:
   1384		fc_lport_error(lport, NULL);
   1385		return;
   1386	}
   1387
   1388	fp = fc_frame_alloc(lport, size);
   1389	if (!fp) {
   1390		fc_lport_error(lport, fp);
   1391		return;
   1392	}
   1393
   1394	if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, cmd,
   1395				  fc_lport_ns_resp,
   1396				  lport, 3 * lport->r_a_tov))
   1397		fc_lport_error(lport, fp);
   1398}
   1399
   1400static struct fc_rport_operations fc_lport_rport_ops = {
   1401	.event_callback = fc_lport_rport_callback,
   1402};
   1403
   1404/**
   1405 * fc_lport_enter_dns() - Create a fc_rport for the name server
   1406 * @lport: The local port requesting a remote port for the name server
   1407 */
   1408static void fc_lport_enter_dns(struct fc_lport *lport)
   1409{
   1410	struct fc_rport_priv *rdata;
   1411
   1412	lockdep_assert_held(&lport->lp_mutex);
   1413
   1414	FC_LPORT_DBG(lport, "Entered DNS state from %s state\n",
   1415		     fc_lport_state(lport));
   1416
   1417	fc_lport_state_enter(lport, LPORT_ST_DNS);
   1418
   1419	mutex_lock(&lport->disc.disc_mutex);
   1420	rdata = fc_rport_create(lport, FC_FID_DIR_SERV);
   1421	mutex_unlock(&lport->disc.disc_mutex);
   1422	if (!rdata)
   1423		goto err;
   1424
   1425	rdata->ops = &fc_lport_rport_ops;
   1426	fc_rport_login(rdata);
   1427	return;
   1428
   1429err:
   1430	fc_lport_error(lport, NULL);
   1431}
   1432
   1433/**
   1434 * fc_lport_enter_ms() - management server commands
   1435 * @lport: Fibre Channel local port to register
   1436 * @state: Local port state
   1437 */
   1438static void fc_lport_enter_ms(struct fc_lport *lport, enum fc_lport_state state)
   1439{
   1440	struct fc_frame *fp;
   1441	enum fc_fdmi_req cmd;
   1442	int size = sizeof(struct fc_ct_hdr);
   1443	size_t len;
   1444	int numattrs;
   1445	struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host);
   1446	lockdep_assert_held(&lport->lp_mutex);
   1447
   1448	FC_LPORT_DBG(lport, "Entered %s state from %s state\n",
   1449		     fc_lport_state_names[state],
   1450		     fc_lport_state(lport));
   1451
   1452	fc_lport_state_enter(lport, state);
   1453
   1454	switch (state) {
   1455	case LPORT_ST_RHBA:
   1456		cmd = FC_FDMI_RHBA;
   1457		/* Number of HBA Attributes */
   1458		numattrs = 11;
   1459		len = sizeof(struct fc_fdmi_rhba);
   1460		len -= sizeof(struct fc_fdmi_attr_entry);
   1461
   1462		len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
   1463		len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
   1464		len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
   1465		len += FC_FDMI_HBA_ATTR_MODEL_LEN;
   1466		len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
   1467		len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
   1468		len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
   1469		len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
   1470		len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
   1471		len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
   1472		len += FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN;
   1473
   1474
   1475		if (fc_host->fdmi_version == FDMI_V2) {
   1476			numattrs += 7;
   1477			len += FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN;
   1478			len += FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN;
   1479			len += FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN;
   1480			len += FC_FDMI_HBA_ATTR_FABRICNAME_LEN;
   1481			len += FC_FDMI_HBA_ATTR_BIOSVERSION_LEN;
   1482			len += FC_FDMI_HBA_ATTR_BIOSSTATE_LEN;
   1483			len += FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN;
   1484		}
   1485
   1486		len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
   1487
   1488		size += len;
   1489		break;
   1490	case LPORT_ST_RPA:
   1491		cmd = FC_FDMI_RPA;
   1492		/* Number of Port Attributes */
   1493		numattrs = 6;
   1494		len = sizeof(struct fc_fdmi_rpa);
   1495		len -= sizeof(struct fc_fdmi_attr_entry);
   1496		len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
   1497		len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
   1498		len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
   1499		len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
   1500		len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
   1501		len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
   1502
   1503		if (fc_host->fdmi_version == FDMI_V2) {
   1504			numattrs += 10;
   1505			len += FC_FDMI_PORT_ATTR_NODENAME_LEN;
   1506			len += FC_FDMI_PORT_ATTR_PORTNAME_LEN;
   1507			len += FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN;
   1508			len += FC_FDMI_PORT_ATTR_PORTTYPE_LEN;
   1509			len += FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN;
   1510			len += FC_FDMI_PORT_ATTR_FABRICNAME_LEN;
   1511			len += FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN;
   1512			len += FC_FDMI_PORT_ATTR_PORTSTATE_LEN;
   1513			len += FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN;
   1514			len += FC_FDMI_PORT_ATTR_PORTID_LEN;
   1515		}
   1516
   1517		len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
   1518
   1519		size += len;
   1520		break;
   1521	case LPORT_ST_DPRT:
   1522		cmd = FC_FDMI_DPRT;
   1523		len = sizeof(struct fc_fdmi_dprt);
   1524		size += len;
   1525		break;
   1526	case LPORT_ST_DHBA:
   1527		cmd = FC_FDMI_DHBA;
   1528		len = sizeof(struct fc_fdmi_dhba);
   1529		size += len;
   1530		break;
   1531	default:
   1532		fc_lport_error(lport, NULL);
   1533		return;
   1534	}
   1535
   1536	FC_LPORT_DBG(lport, "Cmd=0x%x Len %d size %d\n",
   1537			     cmd, (int)len, size);
   1538	fp = fc_frame_alloc(lport, size);
   1539	if (!fp) {
   1540		fc_lport_error(lport, fp);
   1541		return;
   1542	}
   1543
   1544	if (!lport->tt.elsct_send(lport, FC_FID_MGMT_SERV, fp, cmd,
   1545				  fc_lport_ms_resp,
   1546				  lport, 3 * lport->r_a_tov))
   1547		fc_lport_error(lport, fp);
   1548}
   1549
   1550/**
   1551 * fc_lport_enter_fdmi() - Create a fc_rport for the management server
   1552 * @lport: The local port requesting a remote port for the management server
   1553 */
   1554static void fc_lport_enter_fdmi(struct fc_lport *lport)
   1555{
   1556	struct fc_rport_priv *rdata;
   1557
   1558	lockdep_assert_held(&lport->lp_mutex);
   1559
   1560	FC_LPORT_DBG(lport, "Entered FDMI state from %s state\n",
   1561		     fc_lport_state(lport));
   1562
   1563	fc_lport_state_enter(lport, LPORT_ST_FDMI);
   1564
   1565	mutex_lock(&lport->disc.disc_mutex);
   1566	rdata = fc_rport_create(lport, FC_FID_MGMT_SERV);
   1567	mutex_unlock(&lport->disc.disc_mutex);
   1568	if (!rdata)
   1569		goto err;
   1570
   1571	rdata->ops = &fc_lport_rport_ops;
   1572	fc_rport_login(rdata);
   1573	return;
   1574
   1575err:
   1576	fc_lport_error(lport, NULL);
   1577}
   1578
   1579/**
   1580 * fc_lport_timeout() - Handler for the retry_work timer
   1581 * @work: The work struct of the local port
   1582 */
   1583static void fc_lport_timeout(struct work_struct *work)
   1584{
   1585	struct fc_lport *lport =
   1586		container_of(work, struct fc_lport,
   1587			     retry_work.work);
   1588	struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host);
   1589
   1590	mutex_lock(&lport->lp_mutex);
   1591
   1592	switch (lport->state) {
   1593	case LPORT_ST_DISABLED:
   1594		break;
   1595	case LPORT_ST_READY:
   1596		break;
   1597	case LPORT_ST_RESET:
   1598		break;
   1599	case LPORT_ST_FLOGI:
   1600		fc_lport_enter_flogi(lport);
   1601		break;
   1602	case LPORT_ST_DNS:
   1603		fc_lport_enter_dns(lport);
   1604		break;
   1605	case LPORT_ST_RNN_ID:
   1606	case LPORT_ST_RSNN_NN:
   1607	case LPORT_ST_RSPN_ID:
   1608	case LPORT_ST_RFT_ID:
   1609	case LPORT_ST_RFF_ID:
   1610		fc_lport_enter_ns(lport, lport->state);
   1611		break;
   1612	case LPORT_ST_FDMI:
   1613		fc_lport_enter_fdmi(lport);
   1614		break;
   1615	case LPORT_ST_RHBA:
   1616		if (fc_host->fdmi_version == FDMI_V2) {
   1617			FC_LPORT_DBG(lport, "timeout for FDMI-V2 RHBA,fall back to FDMI-V1\n");
   1618			fc_host->fdmi_version = FDMI_V1;
   1619			fc_lport_enter_ms(lport, LPORT_ST_RHBA);
   1620			break;
   1621		}
   1622		fallthrough;
   1623	case LPORT_ST_RPA:
   1624	case LPORT_ST_DHBA:
   1625	case LPORT_ST_DPRT:
   1626		FC_LPORT_DBG(lport, "Skipping lport state %s to SCR\n",
   1627			     fc_lport_state(lport));
   1628		fallthrough;
   1629	case LPORT_ST_SCR:
   1630		fc_lport_enter_scr(lport);
   1631		break;
   1632	case LPORT_ST_LOGO:
   1633		fc_lport_enter_logo(lport);
   1634		break;
   1635	}
   1636
   1637	mutex_unlock(&lport->lp_mutex);
   1638}
   1639
   1640/**
   1641 * fc_lport_logo_resp() - Handle response to LOGO request
   1642 * @sp:	    The sequence that the LOGO was on
   1643 * @fp:	    The LOGO frame
   1644 * @lp_arg: The lport port that received the LOGO request
   1645 *
   1646 * Locking Note: This function will be called without the lport lock
   1647 * held, but it will lock, call an _enter_* function or fc_lport_error()
   1648 * and then unlock the lport.
   1649 */
   1650void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
   1651			void *lp_arg)
   1652{
   1653	struct fc_lport *lport = lp_arg;
   1654	u8 op;
   1655
   1656	FC_LPORT_DBG(lport, "Received a LOGO %s\n", fc_els_resp_type(fp));
   1657
   1658	if (fp == ERR_PTR(-FC_EX_CLOSED))
   1659		return;
   1660
   1661	mutex_lock(&lport->lp_mutex);
   1662
   1663	if (lport->state != LPORT_ST_LOGO) {
   1664		FC_LPORT_DBG(lport, "Received a LOGO response, but in state "
   1665			     "%s\n", fc_lport_state(lport));
   1666		if (IS_ERR(fp))
   1667			goto err;
   1668		goto out;
   1669	}
   1670
   1671	if (IS_ERR(fp)) {
   1672		fc_lport_error(lport, fp);
   1673		goto err;
   1674	}
   1675
   1676	op = fc_frame_payload_op(fp);
   1677	if (op == ELS_LS_ACC)
   1678		fc_lport_enter_disabled(lport);
   1679	else
   1680		fc_lport_error(lport, fp);
   1681
   1682out:
   1683	fc_frame_free(fp);
   1684err:
   1685	mutex_unlock(&lport->lp_mutex);
   1686}
   1687EXPORT_SYMBOL(fc_lport_logo_resp);
   1688
   1689/**
   1690 * fc_lport_enter_logo() - Logout of the fabric
   1691 * @lport: The local port to be logged out
   1692 */
   1693static void fc_lport_enter_logo(struct fc_lport *lport)
   1694{
   1695	struct fc_frame *fp;
   1696	struct fc_els_logo *logo;
   1697
   1698	lockdep_assert_held(&lport->lp_mutex);
   1699
   1700	FC_LPORT_DBG(lport, "Entered LOGO state from %s state\n",
   1701		     fc_lport_state(lport));
   1702
   1703	fc_lport_state_enter(lport, LPORT_ST_LOGO);
   1704	fc_vports_linkchange(lport);
   1705
   1706	fp = fc_frame_alloc(lport, sizeof(*logo));
   1707	if (!fp) {
   1708		fc_lport_error(lport, fp);
   1709		return;
   1710	}
   1711
   1712	if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO,
   1713				  fc_lport_logo_resp, lport,
   1714				  2 * lport->r_a_tov))
   1715		fc_lport_error(lport, NULL);
   1716}
   1717
   1718/**
   1719 * fc_lport_flogi_resp() - Handle response to FLOGI request
   1720 * @sp:	    The sequence that the FLOGI was on
   1721 * @fp:	    The FLOGI response frame
   1722 * @lp_arg: The lport port that received the FLOGI response
   1723 *
   1724 * Locking Note: This function will be called without the lport lock
   1725 * held, but it will lock, call an _enter_* function or fc_lport_error()
   1726 * and then unlock the lport.
   1727 */
   1728void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
   1729			 void *lp_arg)
   1730{
   1731	struct fc_lport *lport = lp_arg;
   1732	struct fc_frame_header *fh;
   1733	struct fc_els_flogi *flp;
   1734	u32 did;
   1735	u16 csp_flags;
   1736	unsigned int r_a_tov;
   1737	unsigned int e_d_tov;
   1738	u16 mfs;
   1739
   1740	FC_LPORT_DBG(lport, "Received a FLOGI %s\n", fc_els_resp_type(fp));
   1741
   1742	if (fp == ERR_PTR(-FC_EX_CLOSED))
   1743		return;
   1744
   1745	mutex_lock(&lport->lp_mutex);
   1746
   1747	if (lport->state != LPORT_ST_FLOGI) {
   1748		FC_LPORT_DBG(lport, "Received a FLOGI response, but in state "
   1749			     "%s\n", fc_lport_state(lport));
   1750		if (IS_ERR(fp))
   1751			goto err;
   1752		goto out;
   1753	}
   1754
   1755	if (IS_ERR(fp)) {
   1756		fc_lport_error(lport, fp);
   1757		goto err;
   1758	}
   1759
   1760	fh = fc_frame_header_get(fp);
   1761	did = fc_frame_did(fp);
   1762	if (fh->fh_r_ctl != FC_RCTL_ELS_REP || did == 0 ||
   1763	    fc_frame_payload_op(fp) != ELS_LS_ACC) {
   1764		FC_LPORT_DBG(lport, "FLOGI not accepted or bad response\n");
   1765		fc_lport_error(lport, fp);
   1766		goto out;
   1767	}
   1768
   1769	flp = fc_frame_payload_get(fp, sizeof(*flp));
   1770	if (!flp) {
   1771		FC_LPORT_DBG(lport, "FLOGI bad response\n");
   1772		fc_lport_error(lport, fp);
   1773		goto out;
   1774	}
   1775
   1776	mfs = ntohs(flp->fl_csp.sp_bb_data) &
   1777		FC_SP_BB_DATA_MASK;
   1778
   1779	if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) {
   1780		FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, "
   1781			     "lport->mfs:%u\n", mfs, lport->mfs);
   1782		fc_lport_error(lport, fp);
   1783		goto out;
   1784	}
   1785
   1786	if (mfs <= lport->mfs) {
   1787		lport->mfs = mfs;
   1788		fc_host_maxframe_size(lport->host) = mfs;
   1789	}
   1790
   1791	csp_flags = ntohs(flp->fl_csp.sp_features);
   1792	r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov);
   1793	e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
   1794	if (csp_flags & FC_SP_FT_EDTR)
   1795		e_d_tov /= 1000000;
   1796
   1797	lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
   1798
   1799	if ((csp_flags & FC_SP_FT_FPORT) == 0) {
   1800		if (e_d_tov > lport->e_d_tov)
   1801			lport->e_d_tov = e_d_tov;
   1802		lport->r_a_tov = 2 * lport->e_d_tov;
   1803		fc_lport_set_port_id(lport, did, fp);
   1804		printk(KERN_INFO "host%d: libfc: "
   1805		       "Port (%6.6x) entered "
   1806		       "point-to-point mode\n",
   1807		       lport->host->host_no, did);
   1808		fc_lport_ptp_setup(lport, fc_frame_sid(fp),
   1809				   get_unaligned_be64(
   1810					   &flp->fl_wwpn),
   1811				   get_unaligned_be64(
   1812					   &flp->fl_wwnn));
   1813	} else {
   1814		if (e_d_tov > lport->e_d_tov)
   1815			lport->e_d_tov = e_d_tov;
   1816		if (r_a_tov > lport->r_a_tov)
   1817			lport->r_a_tov = r_a_tov;
   1818		fc_host_fabric_name(lport->host) =
   1819			get_unaligned_be64(&flp->fl_wwnn);
   1820		fc_lport_set_port_id(lport, did, fp);
   1821		fc_lport_enter_dns(lport);
   1822	}
   1823
   1824out:
   1825	fc_frame_free(fp);
   1826err:
   1827	mutex_unlock(&lport->lp_mutex);
   1828}
   1829EXPORT_SYMBOL(fc_lport_flogi_resp);
   1830
   1831/**
   1832 * fc_lport_enter_flogi() - Send a FLOGI request to the fabric manager
   1833 * @lport: Fibre Channel local port to be logged in to the fabric
   1834 */
   1835static void fc_lport_enter_flogi(struct fc_lport *lport)
   1836{
   1837	struct fc_frame *fp;
   1838
   1839	lockdep_assert_held(&lport->lp_mutex);
   1840
   1841	FC_LPORT_DBG(lport, "Entered FLOGI state from %s state\n",
   1842		     fc_lport_state(lport));
   1843
   1844	fc_lport_state_enter(lport, LPORT_ST_FLOGI);
   1845
   1846	if (lport->point_to_multipoint) {
   1847		if (lport->port_id)
   1848			fc_lport_enter_ready(lport);
   1849		return;
   1850	}
   1851
   1852	fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
   1853	if (!fp)
   1854		return fc_lport_error(lport, fp);
   1855
   1856	if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp,
   1857				  lport->vport ? ELS_FDISC : ELS_FLOGI,
   1858				  fc_lport_flogi_resp, lport,
   1859				  lport->vport ? 2 * lport->r_a_tov :
   1860				  lport->e_d_tov))
   1861		fc_lport_error(lport, NULL);
   1862}
   1863
   1864/**
   1865 * fc_lport_config() - Configure a fc_lport
   1866 * @lport: The local port to be configured
   1867 */
   1868int fc_lport_config(struct fc_lport *lport)
   1869{
   1870	INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout);
   1871	mutex_init(&lport->lp_mutex);
   1872
   1873	fc_lport_state_enter(lport, LPORT_ST_DISABLED);
   1874
   1875	fc_lport_add_fc4_type(lport, FC_TYPE_FCP);
   1876	fc_lport_add_fc4_type(lport, FC_TYPE_CT);
   1877	fc_fc4_conf_lport_params(lport, FC_TYPE_FCP);
   1878
   1879	return 0;
   1880}
   1881EXPORT_SYMBOL(fc_lport_config);
   1882
   1883/**
   1884 * fc_lport_init() - Initialize the lport layer for a local port
   1885 * @lport: The local port to initialize the exchange layer for
   1886 */
   1887int fc_lport_init(struct fc_lport *lport)
   1888{
   1889	struct fc_host_attrs *fc_host;
   1890
   1891	fc_host = shost_to_fc_host(lport->host);
   1892
   1893	/* Set FDMI version to FDMI-2 specification*/
   1894	fc_host->fdmi_version = FDMI_V2;
   1895
   1896	fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
   1897	fc_host_node_name(lport->host) = lport->wwnn;
   1898	fc_host_port_name(lport->host) = lport->wwpn;
   1899	fc_host_supported_classes(lport->host) = FC_COS_CLASS3;
   1900	memset(fc_host_supported_fc4s(lport->host), 0,
   1901	       sizeof(fc_host_supported_fc4s(lport->host)));
   1902	fc_host_supported_fc4s(lport->host)[2] = 1;
   1903	fc_host_supported_fc4s(lport->host)[7] = 1;
   1904	fc_host_num_discovered_ports(lport->host) = 4;
   1905
   1906	/* This value is also unchanging */
   1907	memset(fc_host_active_fc4s(lport->host), 0,
   1908	       sizeof(fc_host_active_fc4s(lport->host)));
   1909	fc_host_active_fc4s(lport->host)[2] = 1;
   1910	fc_host_active_fc4s(lport->host)[7] = 1;
   1911	fc_host_maxframe_size(lport->host) = lport->mfs;
   1912	fc_host_supported_speeds(lport->host) = 0;
   1913	if (lport->link_supported_speeds & FC_PORTSPEED_1GBIT)
   1914		fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_1GBIT;
   1915	if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT)
   1916		fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT;
   1917	if (lport->link_supported_speeds & FC_PORTSPEED_40GBIT)
   1918		fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_40GBIT;
   1919	if (lport->link_supported_speeds & FC_PORTSPEED_100GBIT)
   1920		fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_100GBIT;
   1921	if (lport->link_supported_speeds & FC_PORTSPEED_25GBIT)
   1922		fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_25GBIT;
   1923	if (lport->link_supported_speeds & FC_PORTSPEED_50GBIT)
   1924		fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_50GBIT;
   1925	if (lport->link_supported_speeds & FC_PORTSPEED_100GBIT)
   1926		fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_100GBIT;
   1927
   1928	fc_fc4_add_lport(lport);
   1929
   1930	fc_host_num_discovered_ports(lport->host) = DISCOVERED_PORTS;
   1931	fc_host_port_state(lport->host) = FC_PORTSTATE_ONLINE;
   1932	fc_host_max_ct_payload(lport->host) = MAX_CT_PAYLOAD;
   1933	fc_host_num_ports(lport->host) = NUMBER_OF_PORTS;
   1934	fc_host_bootbios_state(lport->host) = 0X00000000;
   1935	snprintf(fc_host_bootbios_version(lport->host),
   1936		FC_SYMBOLIC_NAME_SIZE, "%s", "Unknown");
   1937
   1938	return 0;
   1939}
   1940EXPORT_SYMBOL(fc_lport_init);
   1941
   1942/**
   1943 * fc_lport_bsg_resp() - The common response handler for FC Passthrough requests
   1944 * @sp:	      The sequence for the FC Passthrough response
   1945 * @fp:	      The response frame
   1946 * @info_arg: The BSG info that the response is for
   1947 */
   1948static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
   1949			      void *info_arg)
   1950{
   1951	struct fc_bsg_info *info = info_arg;
   1952	struct bsg_job *job = info->job;
   1953	struct fc_bsg_reply *bsg_reply = job->reply;
   1954	struct fc_lport *lport = info->lport;
   1955	struct fc_frame_header *fh;
   1956	size_t len;
   1957	void *buf;
   1958
   1959	if (IS_ERR(fp)) {
   1960		bsg_reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
   1961			-ECONNABORTED : -ETIMEDOUT;
   1962		job->reply_len = sizeof(uint32_t);
   1963		bsg_job_done(job, bsg_reply->result,
   1964			       bsg_reply->reply_payload_rcv_len);
   1965		kfree(info);
   1966		return;
   1967	}
   1968
   1969	mutex_lock(&lport->lp_mutex);
   1970	fh = fc_frame_header_get(fp);
   1971	len = fr_len(fp) - sizeof(*fh);
   1972	buf = fc_frame_payload_get(fp, 0);
   1973
   1974	if (fr_sof(fp) == FC_SOF_I3 && !ntohs(fh->fh_seq_cnt)) {
   1975		/* Get the response code from the first frame payload */
   1976		unsigned short cmd = (info->rsp_code == FC_FS_ACC) ?
   1977			ntohs(((struct fc_ct_hdr *)buf)->ct_cmd) :
   1978			(unsigned short)fc_frame_payload_op(fp);
   1979
   1980		/* Save the reply status of the job */
   1981		bsg_reply->reply_data.ctels_reply.status =
   1982			(cmd == info->rsp_code) ?
   1983			FC_CTELS_STATUS_OK : FC_CTELS_STATUS_REJECT;
   1984	}
   1985
   1986	bsg_reply->reply_payload_rcv_len +=
   1987		fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents,
   1988					 &info->offset, NULL);
   1989
   1990	if (fr_eof(fp) == FC_EOF_T &&
   1991	    (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
   1992	    (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
   1993		if (bsg_reply->reply_payload_rcv_len >
   1994		    job->reply_payload.payload_len)
   1995			bsg_reply->reply_payload_rcv_len =
   1996				job->reply_payload.payload_len;
   1997		bsg_reply->result = 0;
   1998		bsg_job_done(job, bsg_reply->result,
   1999			       bsg_reply->reply_payload_rcv_len);
   2000		kfree(info);
   2001	}
   2002	fc_frame_free(fp);
   2003	mutex_unlock(&lport->lp_mutex);
   2004}
   2005
   2006/**
   2007 * fc_lport_els_request() - Send ELS passthrough request
   2008 * @job:   The BSG Passthrough job
   2009 * @lport: The local port sending the request
   2010 * @did:   The destination port id
   2011 * @tov:   The timeout period (in ms)
   2012 */
   2013static int fc_lport_els_request(struct bsg_job *job,
   2014				struct fc_lport *lport,
   2015				u32 did, u32 tov)
   2016{
   2017	struct fc_bsg_info *info;
   2018	struct fc_frame *fp;
   2019	struct fc_frame_header *fh;
   2020	char *pp;
   2021	int len;
   2022
   2023	lockdep_assert_held(&lport->lp_mutex);
   2024
   2025	fp = fc_frame_alloc(lport, job->request_payload.payload_len);
   2026	if (!fp)
   2027		return -ENOMEM;
   2028
   2029	len = job->request_payload.payload_len;
   2030	pp = fc_frame_payload_get(fp, len);
   2031
   2032	sg_copy_to_buffer(job->request_payload.sg_list,
   2033			  job->request_payload.sg_cnt,
   2034			  pp, len);
   2035
   2036	fh = fc_frame_header_get(fp);
   2037	fh->fh_r_ctl = FC_RCTL_ELS_REQ;
   2038	hton24(fh->fh_d_id, did);
   2039	hton24(fh->fh_s_id, lport->port_id);
   2040	fh->fh_type = FC_TYPE_ELS;
   2041	hton24(fh->fh_f_ctl, FC_FCTL_REQ);
   2042	fh->fh_cs_ctl = 0;
   2043	fh->fh_df_ctl = 0;
   2044	fh->fh_parm_offset = 0;
   2045
   2046	info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
   2047	if (!info) {
   2048		fc_frame_free(fp);
   2049		return -ENOMEM;
   2050	}
   2051
   2052	info->job = job;
   2053	info->lport = lport;
   2054	info->rsp_code = ELS_LS_ACC;
   2055	info->nents = job->reply_payload.sg_cnt;
   2056	info->sg = job->reply_payload.sg_list;
   2057
   2058	if (!fc_exch_seq_send(lport, fp, fc_lport_bsg_resp,
   2059			      NULL, info, tov)) {
   2060		kfree(info);
   2061		return -ECOMM;
   2062	}
   2063	return 0;
   2064}
   2065
   2066/**
   2067 * fc_lport_ct_request() - Send CT Passthrough request
   2068 * @job:   The BSG Passthrough job
   2069 * @lport: The local port sending the request
   2070 * @did:   The destination FC-ID
   2071 * @tov:   The timeout period to wait for the response
   2072 */
   2073static int fc_lport_ct_request(struct bsg_job *job,
   2074			       struct fc_lport *lport, u32 did, u32 tov)
   2075{
   2076	struct fc_bsg_info *info;
   2077	struct fc_frame *fp;
   2078	struct fc_frame_header *fh;
   2079	struct fc_ct_req *ct;
   2080	size_t len;
   2081
   2082	lockdep_assert_held(&lport->lp_mutex);
   2083
   2084	fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
   2085			    job->request_payload.payload_len);
   2086	if (!fp)
   2087		return -ENOMEM;
   2088
   2089	len = job->request_payload.payload_len;
   2090	ct = fc_frame_payload_get(fp, len);
   2091
   2092	sg_copy_to_buffer(job->request_payload.sg_list,
   2093			  job->request_payload.sg_cnt,
   2094			  ct, len);
   2095
   2096	fh = fc_frame_header_get(fp);
   2097	fh->fh_r_ctl = FC_RCTL_DD_UNSOL_CTL;
   2098	hton24(fh->fh_d_id, did);
   2099	hton24(fh->fh_s_id, lport->port_id);
   2100	fh->fh_type = FC_TYPE_CT;
   2101	hton24(fh->fh_f_ctl, FC_FCTL_REQ);
   2102	fh->fh_cs_ctl = 0;
   2103	fh->fh_df_ctl = 0;
   2104	fh->fh_parm_offset = 0;
   2105
   2106	info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
   2107	if (!info) {
   2108		fc_frame_free(fp);
   2109		return -ENOMEM;
   2110	}
   2111
   2112	info->job = job;
   2113	info->lport = lport;
   2114	info->rsp_code = FC_FS_ACC;
   2115	info->nents = job->reply_payload.sg_cnt;
   2116	info->sg = job->reply_payload.sg_list;
   2117
   2118	if (!fc_exch_seq_send(lport, fp, fc_lport_bsg_resp,
   2119			      NULL, info, tov)) {
   2120		kfree(info);
   2121		return -ECOMM;
   2122	}
   2123	return 0;
   2124}
   2125
   2126/**
   2127 * fc_lport_bsg_request() - The common entry point for sending
   2128 *			    FC Passthrough requests
   2129 * @job: The BSG passthrough job
   2130 */
   2131int fc_lport_bsg_request(struct bsg_job *job)
   2132{
   2133	struct fc_bsg_request *bsg_request = job->request;
   2134	struct fc_bsg_reply *bsg_reply = job->reply;
   2135	struct Scsi_Host *shost = fc_bsg_to_shost(job);
   2136	struct fc_lport *lport = shost_priv(shost);
   2137	struct fc_rport *rport;
   2138	struct fc_rport_priv *rdata;
   2139	int rc = -EINVAL;
   2140	u32 did, tov;
   2141
   2142	bsg_reply->reply_payload_rcv_len = 0;
   2143
   2144	mutex_lock(&lport->lp_mutex);
   2145
   2146	switch (bsg_request->msgcode) {
   2147	case FC_BSG_RPT_ELS:
   2148		rport = fc_bsg_to_rport(job);
   2149		if (!rport)
   2150			break;
   2151
   2152		rdata = rport->dd_data;
   2153		rc = fc_lport_els_request(job, lport, rport->port_id,
   2154					  rdata->e_d_tov);
   2155		break;
   2156
   2157	case FC_BSG_RPT_CT:
   2158		rport = fc_bsg_to_rport(job);
   2159		if (!rport)
   2160			break;
   2161
   2162		rdata = rport->dd_data;
   2163		rc = fc_lport_ct_request(job, lport, rport->port_id,
   2164					 rdata->e_d_tov);
   2165		break;
   2166
   2167	case FC_BSG_HST_CT:
   2168		did = ntoh24(bsg_request->rqst_data.h_ct.port_id);
   2169		if (did == FC_FID_DIR_SERV) {
   2170			rdata = lport->dns_rdata;
   2171			if (!rdata)
   2172				break;
   2173			tov = rdata->e_d_tov;
   2174		} else {
   2175			rdata = fc_rport_lookup(lport, did);
   2176			if (!rdata)
   2177				break;
   2178			tov = rdata->e_d_tov;
   2179			kref_put(&rdata->kref, fc_rport_destroy);
   2180		}
   2181
   2182		rc = fc_lport_ct_request(job, lport, did, tov);
   2183		break;
   2184
   2185	case FC_BSG_HST_ELS_NOLOGIN:
   2186		did = ntoh24(bsg_request->rqst_data.h_els.port_id);
   2187		rc = fc_lport_els_request(job, lport, did, lport->e_d_tov);
   2188		break;
   2189	}
   2190
   2191	mutex_unlock(&lport->lp_mutex);
   2192	return rc;
   2193}
   2194EXPORT_SYMBOL(fc_lport_bsg_request);