Skip to content

Commit

Permalink
[SCSI] libfc, libfcoe: FDISC ELS for NPIV
Browse files Browse the repository at this point in the history
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: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
Chris Leech authored and James Bottomley committed Dec 4, 2009
1 parent 8faecdd commit db36c06
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 5 deletions.
6 changes: 3 additions & 3 deletions drivers/scsi/fcoe/libfcoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 5 additions & 1 deletion drivers/scsi/libfc/fc_lport.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down
4 changes: 3 additions & 1 deletion include/scsi/fc/fc_els.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
29 changes: 29 additions & 0 deletions include/scsi/fc_encode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit db36c06

Please sign in to comment.