diff options
-rw-r--r-- | drivers/scsi/fcoe/libfcoe.c | 6 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 6 | ||||
-rw-r--r-- | include/scsi/fc/fc_els.h | 4 | ||||
-rw-r--r-- | include/scsi/fc_encode.h | 29 |
4 files changed, 40 insertions, 5 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c index 11ae5c94608b..d8ea04a29199 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c | |||
@@ -449,7 +449,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, | |||
449 | memset(mac, 0, sizeof(mac)); | 449 | memset(mac, 0, sizeof(mac)); |
450 | mac->fd_desc.fip_dtype = FIP_DT_MAC; | 450 | mac->fd_desc.fip_dtype = FIP_DT_MAC; |
451 | mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW; | 451 | mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW; |
452 | if (dtype != FIP_DT_FLOGI) | 452 | if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC) |
453 | memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN); | 453 | memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN); |
454 | else if (fip->spma) | 454 | else if (fip->spma) |
455 | memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN); | 455 | 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) | |||
865 | goto drop; | 865 | goto drop; |
866 | els_op = *(u8 *)(fh + 1); | 866 | els_op = *(u8 *)(fh + 1); |
867 | 867 | ||
868 | if (els_dtype == FIP_DT_FLOGI && sub == FIP_SC_REP && | 868 | if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) && |
869 | fip->flogi_oxid == ntohs(fh->fh_ox_id) && | 869 | sub == FIP_SC_REP && fip->flogi_oxid == ntohs(fh->fh_ox_id) && |
870 | els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) { | 870 | els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) { |
871 | fip->flogi_oxid = FC_XID_UNKNOWN; | 871 | fip->flogi_oxid = FC_XID_UNKNOWN; |
872 | fip->update_mac(fip, fip->data_src_addr, granted_mac); | 872 | 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 46897cf23ea6..ccba67ca68a1 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c | |||
@@ -1449,6 +1449,9 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
1449 | e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); | 1449 | e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); |
1450 | if (csp_flags & FC_SP_FT_EDTR) | 1450 | if (csp_flags & FC_SP_FT_EDTR) |
1451 | e_d_tov /= 1000000; | 1451 | e_d_tov /= 1000000; |
1452 | |||
1453 | lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC); | ||
1454 | |||
1452 | if ((csp_flags & FC_SP_FT_FPORT) == 0) { | 1455 | if ((csp_flags & FC_SP_FT_FPORT) == 0) { |
1453 | if (e_d_tov > lport->e_d_tov) | 1456 | if (e_d_tov > lport->e_d_tov) |
1454 | lport->e_d_tov = e_d_tov; | 1457 | lport->e_d_tov = e_d_tov; |
@@ -1498,7 +1501,8 @@ void fc_lport_enter_flogi(struct fc_lport *lport) | |||
1498 | if (!fp) | 1501 | if (!fp) |
1499 | return fc_lport_error(lport, fp); | 1502 | return fc_lport_error(lport, fp); |
1500 | 1503 | ||
1501 | if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_FLOGI, | 1504 | if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, |
1505 | lport->vport ? ELS_FDISC : ELS_FLOGI, | ||
1502 | fc_lport_flogi_resp, lport, lport->e_d_tov)) | 1506 | fc_lport_flogi_resp, lport, lport->e_d_tov)) |
1503 | fc_lport_error(lport, NULL); | 1507 | fc_lport_error(lport, NULL); |
1504 | } | 1508 | } |
diff --git a/include/scsi/fc/fc_els.h b/include/scsi/fc/fc_els.h index 195ca014d3ce..b0872afe2d30 100644 --- a/include/scsi/fc/fc_els.h +++ b/include/scsi/fc/fc_els.h | |||
@@ -248,10 +248,12 @@ struct fc_els_csp { | |||
248 | /* | 248 | /* |
249 | * sp_features | 249 | * sp_features |
250 | */ | 250 | */ |
251 | #define FC_SP_FT_CIRO 0x8000 /* continuously increasing rel. off. */ | 251 | #define FC_SP_FT_NPIV 0x8000 /* multiple N_Port_ID support (FLOGI) */ |
252 | #define FC_SP_FT_CIRO 0x8000 /* continuously increasing rel off (PLOGI) */ | ||
252 | #define FC_SP_FT_CLAD 0x8000 /* clean address (in FLOGI LS_ACC) */ | 253 | #define FC_SP_FT_CLAD 0x8000 /* clean address (in FLOGI LS_ACC) */ |
253 | #define FC_SP_FT_RAND 0x4000 /* random relative offset */ | 254 | #define FC_SP_FT_RAND 0x4000 /* random relative offset */ |
254 | #define FC_SP_FT_VAL 0x2000 /* valid vendor version level */ | 255 | #define FC_SP_FT_VAL 0x2000 /* valid vendor version level */ |
256 | #define FC_SP_FT_NPIV_ACC 0x2000 /* NPIV assignment (FLOGI LS_ACC) */ | ||
255 | #define FC_SP_FT_FPORT 0x1000 /* F port (1) vs. N port (0) */ | 257 | #define FC_SP_FT_FPORT 0x1000 /* F port (1) vs. N port (0) */ |
256 | #define FC_SP_FT_ABB 0x0800 /* alternate BB_credit management */ | 258 | #define FC_SP_FT_ABB 0x0800 /* alternate BB_credit management */ |
257 | #define FC_SP_FT_EDTR 0x0400 /* E_D_TOV Resolution is nanoseconds */ | 259 | #define FC_SP_FT_EDTR 0x0400 /* E_D_TOV Resolution is nanoseconds */ |
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h index 27dad703824f..c93ca3ece1a0 100644 --- a/include/scsi/fc_encode.h +++ b/include/scsi/fc_encode.h | |||
@@ -198,6 +198,31 @@ static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp) | |||
198 | sp->sp_bb_data = htons((u16) lport->mfs); | 198 | sp->sp_bb_data = htons((u16) lport->mfs); |
199 | cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ | 199 | cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ |
200 | cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); | 200 | cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); |
201 | if (lport->does_npiv) | ||
202 | sp->sp_features = htons(FC_SP_FT_NPIV); | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * fc_fdisc_fill - Fill in a fdisc request frame. | ||
207 | */ | ||
208 | static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp) | ||
209 | { | ||
210 | struct fc_els_csp *sp; | ||
211 | struct fc_els_cssp *cp; | ||
212 | struct fc_els_flogi *fdisc; | ||
213 | |||
214 | fdisc = fc_frame_payload_get(fp, sizeof(*fdisc)); | ||
215 | memset(fdisc, 0, sizeof(*fdisc)); | ||
216 | fdisc->fl_cmd = (u8) ELS_FDISC; | ||
217 | put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn); | ||
218 | put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn); | ||
219 | sp = &fdisc->fl_csp; | ||
220 | sp->sp_hi_ver = 0x20; | ||
221 | sp->sp_lo_ver = 0x20; | ||
222 | sp->sp_bb_cred = htons(10); /* this gets set by gateway */ | ||
223 | sp->sp_bb_data = htons((u16) lport->mfs); | ||
224 | cp = &fdisc->fl_cssp[3 - 1]; /* class 3 parameters */ | ||
225 | cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); | ||
201 | } | 226 | } |
202 | 227 | ||
203 | /** | 228 | /** |
@@ -296,6 +321,10 @@ static inline int fc_els_fill(struct fc_lport *lport, | |||
296 | fc_flogi_fill(lport, fp); | 321 | fc_flogi_fill(lport, fp); |
297 | break; | 322 | break; |
298 | 323 | ||
324 | case ELS_FDISC: | ||
325 | fc_fdisc_fill(lport, fp); | ||
326 | break; | ||
327 | |||
299 | case ELS_LOGO: | 328 | case ELS_LOGO: |
300 | fc_logo_fill(lport, fp); | 329 | fc_logo_fill(lport, fp); |
301 | break; | 330 | break; |