[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: 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>
This commit is contained in:
parent
8faecddb21
commit
db36c06cc6
4 changed files with 40 additions and 5 deletions
|
@ -449,7 +449,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
|
||||||
memset(mac, 0, sizeof(mac));
|
memset(mac, 0, sizeof(mac));
|
||||||
mac->fd_desc.fip_dtype = FIP_DT_MAC;
|
mac->fd_desc.fip_dtype = FIP_DT_MAC;
|
||||||
mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
|
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);
|
memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN);
|
||||||
else if (fip->spma)
|
else if (fip->spma)
|
||||||
memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);
|
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;
|
goto drop;
|
||||||
els_op = *(u8 *)(fh + 1);
|
els_op = *(u8 *)(fh + 1);
|
||||||
|
|
||||||
if (els_dtype == FIP_DT_FLOGI && sub == FIP_SC_REP &&
|
if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) &&
|
||||||
fip->flogi_oxid == ntohs(fh->fh_ox_id) &&
|
sub == FIP_SC_REP && fip->flogi_oxid == ntohs(fh->fh_ox_id) &&
|
||||||
els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) {
|
els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) {
|
||||||
fip->flogi_oxid = FC_XID_UNKNOWN;
|
fip->flogi_oxid = FC_XID_UNKNOWN;
|
||||||
fip->update_mac(fip, fip->data_src_addr, granted_mac);
|
fip->update_mac(fip, fip->data_src_addr, granted_mac);
|
||||||
|
|
|
@ -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);
|
e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
|
||||||
if (csp_flags & FC_SP_FT_EDTR)
|
if (csp_flags & FC_SP_FT_EDTR)
|
||||||
e_d_tov /= 1000000;
|
e_d_tov /= 1000000;
|
||||||
|
|
||||||
|
lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
|
||||||
|
|
||||||
if ((csp_flags & FC_SP_FT_FPORT) == 0) {
|
if ((csp_flags & FC_SP_FT_FPORT) == 0) {
|
||||||
if (e_d_tov > lport->e_d_tov)
|
if (e_d_tov > lport->e_d_tov)
|
||||||
lport->e_d_tov = 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)
|
if (!fp)
|
||||||
return fc_lport_error(lport, 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_flogi_resp, lport, lport->e_d_tov))
|
||||||
fc_lport_error(lport, NULL);
|
fc_lport_error(lport, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,10 +248,12 @@ struct fc_els_csp {
|
||||||
/*
|
/*
|
||||||
* sp_features
|
* 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_CLAD 0x8000 /* clean address (in FLOGI LS_ACC) */
|
||||||
#define FC_SP_FT_RAND 0x4000 /* random relative offset */
|
#define FC_SP_FT_RAND 0x4000 /* random relative offset */
|
||||||
#define FC_SP_FT_VAL 0x2000 /* valid vendor version level */
|
#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_FPORT 0x1000 /* F port (1) vs. N port (0) */
|
||||||
#define FC_SP_FT_ABB 0x0800 /* alternate BB_credit management */
|
#define FC_SP_FT_ABB 0x0800 /* alternate BB_credit management */
|
||||||
#define FC_SP_FT_EDTR 0x0400 /* E_D_TOV Resolution is nanoseconds */
|
#define FC_SP_FT_EDTR 0x0400 /* E_D_TOV Resolution is nanoseconds */
|
||||||
|
|
|
@ -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);
|
sp->sp_bb_data = htons((u16) lport->mfs);
|
||||||
cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */
|
cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */
|
||||||
cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
|
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);
|
fc_flogi_fill(lport, fp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ELS_FDISC:
|
||||||
|
fc_fdisc_fill(lport, fp);
|
||||||
|
break;
|
||||||
|
|
||||||
case ELS_LOGO:
|
case ELS_LOGO:
|
||||||
fc_logo_fill(lport, fp);
|
fc_logo_fill(lport, fp);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Reference in a new issue