[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>
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 11ae5c9..d8ea04a 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -449,7 +449,7 @@
 	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 @@
 		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);
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 46897cf..ccba67c 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1449,6 +1449,9 @@
 			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 @@
 	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);
 }