Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db36c06c authored by Chris Leech's avatar Chris Leech Committed by James Bottomley
Browse files

[SCSI] libfc, libfcoe: FDISC ELS for NPIV



Add FDISC ELS handling to libfc and libfcoe, treat it the same as FLOGI where
appropriate.

Add checking for NPIV support in the FLOGI LS_ACC service parameters.

Signed-off-by: default avatarChris Leech <christopher.leech@intel.com>
Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 8faecddb
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -449,7 +449,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
	memset(mac, 0, sizeof(mac));
	mac->fd_desc.fip_dtype = FIP_DT_MAC;
	mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
	if (dtype != FIP_DT_FLOGI)
	if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC)
		memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN);
	else if (fip->spma)
		memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);
@@ -865,8 +865,8 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
		goto drop;
	els_op = *(u8 *)(fh + 1);

	if (els_dtype == FIP_DT_FLOGI && sub == FIP_SC_REP &&
	    fip->flogi_oxid == ntohs(fh->fh_ox_id) &&
	if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) &&
	    sub == FIP_SC_REP && fip->flogi_oxid == ntohs(fh->fh_ox_id) &&
	    els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) {
		fip->flogi_oxid = FC_XID_UNKNOWN;
		fip->update_mac(fip, fip->data_src_addr, granted_mac);
+5 −1
Original line number Diff line number Diff line
@@ -1449,6 +1449,9 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
			e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
			if (csp_flags & FC_SP_FT_EDTR)
				e_d_tov /= 1000000;

			lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);

			if ((csp_flags & FC_SP_FT_FPORT) == 0) {
				if (e_d_tov > lport->e_d_tov)
					lport->e_d_tov = e_d_tov;
@@ -1498,7 +1501,8 @@ void fc_lport_enter_flogi(struct fc_lport *lport)
	if (!fp)
		return fc_lport_error(lport, fp);

	if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_FLOGI,
	if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp,
				  lport->vport ? ELS_FDISC : ELS_FLOGI,
				  fc_lport_flogi_resp, lport, lport->e_d_tov))
		fc_lport_error(lport, NULL);
}
+3 −1
Original line number Diff line number Diff line
@@ -248,10 +248,12 @@ struct fc_els_csp {
/*
 * sp_features
 */
#define	FC_SP_FT_CIRO	0x8000	/* continuously increasing rel. off. */
#define	FC_SP_FT_NPIV	0x8000	/* multiple N_Port_ID support (FLOGI) */
#define	FC_SP_FT_CIRO	0x8000	/* continuously increasing rel off (PLOGI) */
#define	FC_SP_FT_CLAD	0x8000	/* clean address (in FLOGI LS_ACC) */
#define	FC_SP_FT_RAND	0x4000	/* random relative offset */
#define	FC_SP_FT_VAL	0x2000	/* valid vendor version level */
#define	FC_SP_FT_NPIV_ACC	0x2000	/* NPIV assignment (FLOGI LS_ACC) */
#define	FC_SP_FT_FPORT	0x1000	/* F port (1) vs. N port (0) */
#define	FC_SP_FT_ABB	0x0800	/* alternate BB_credit management */
#define	FC_SP_FT_EDTR	0x0400	/* E_D_TOV Resolution is nanoseconds */
+29 −0
Original line number Diff line number Diff line
@@ -198,6 +198,31 @@ static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp)
	sp->sp_bb_data = htons((u16) lport->mfs);
	cp = &flogi->fl_cssp[3 - 1];	/* class 3 parameters */
	cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
	if (lport->does_npiv)
		sp->sp_features = htons(FC_SP_FT_NPIV);
}

/**
 * fc_fdisc_fill - Fill in a fdisc request frame.
 */
static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp)
{
	struct fc_els_csp *sp;
	struct fc_els_cssp *cp;
	struct fc_els_flogi *fdisc;

	fdisc = fc_frame_payload_get(fp, sizeof(*fdisc));
	memset(fdisc, 0, sizeof(*fdisc));
	fdisc->fl_cmd = (u8) ELS_FDISC;
	put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn);
	put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn);
	sp = &fdisc->fl_csp;
	sp->sp_hi_ver = 0x20;
	sp->sp_lo_ver = 0x20;
	sp->sp_bb_cred = htons(10);	/* this gets set by gateway */
	sp->sp_bb_data = htons((u16) lport->mfs);
	cp = &fdisc->fl_cssp[3 - 1];	/* class 3 parameters */
	cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
}

/**
@@ -296,6 +321,10 @@ static inline int fc_els_fill(struct fc_lport *lport,
		fc_flogi_fill(lport, fp);
		break;

	case ELS_FDISC:
		fc_fdisc_fill(lport, fp);
		break;

	case ELS_LOGO:
		fc_logo_fill(lport, fp);
		break;