add FDISC ELS handling to libfc and libfcoe

Signed-off-by: Chris Leech <[email protected]>
---

 drivers/scsi/fcoe/libfcoe.c   |    7 ++++---
 drivers/scsi/libfc/fc_lport.c |    8 ++++++--
 include/scsi/fc_encode.h      |   28 ++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index f544340..afe5cf5 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -440,7 +440,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);
@@ -471,7 +471,7 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct 
sk_buff *skb)
        fh = (struct fc_frame_header *)skb->data;
        op = *(u8 *)(fh + 1);
 
-       if (op == ELS_FLOGI) {
+       if (op == ELS_FLOGI || op == ELS_FDISC) {
                old_xid = fip->flogi_oxid;
                fip->flogi_oxid = ntohs(fh->fh_ox_id);
                if (fip->state == FIP_ST_AUTO) {
@@ -1281,7 +1281,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct 
fc_frame *fp, u8 *sa)
                spin_unlock_bh(&fip->lock);
 
                fip->update_mac(fip, mac, fip->data_src_addr);
-       } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
+       } else if ((op == ELS_FLOGI || op == ELS_FDISC) &&
+                  fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
                /*
                 * Save source MAC for point-to-point responses.
                 */
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 745fa55..ce86120 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1529,6 +1529,7 @@ err:
 void fc_lport_enter_flogi(struct fc_lport *lport)
 {
        struct fc_frame *fp;
+       enum fc_els_cmd cmd;
 
        FC_LPORT_DBG(lport, "Entered FLOGI state from %s state\n",
                     fc_lport_state(lport));
@@ -1539,9 +1540,12 @@ void fc_lport_enter_flogi(struct fc_lport *lport)
        if (!fp)
                return fc_lport_error(lport, fp);
 
-       if (!lport->tt.elsct_send(lport, NULL, fp, ELS_FLOGI,
-                                 fc_lport_flogi_resp, lport, lport->e_d_tov))
+       cmd = lport->vn_port ? ELS_FDISC : ELS_FLOGI;
+       if (!lport->tt.elsct_send(lport, NULL, fp, cmd,
+                                 fc_lport_flogi_resp, lport, lport->e_d_tov)) {
                fc_lport_error(lport, fp);
+       }
+
 }
 
 /* Configure a fc_lport */
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h
index a0ff61c..24daabc 100644
--- a/include/scsi/fc_encode.h
+++ b/include/scsi/fc_encode.h
@@ -172,6 +172,29 @@ static inline void fc_flogi_fill(struct fc_lport *lport, 
struct fc_frame *fp)
 }
 
 /**
+ * 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);
+}
+
+/**
  * fc_logo_fill - Fill in a logo request frame.
  */
 static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp)
@@ -264,6 +287,11 @@ static inline int fc_els_fill(struct fc_lport *lport, 
struct fc_rport *rport,
                *did = FC_FID_FLOGI;
                break;
 
+       case ELS_FDISC:
+               fc_fdisc_fill(lport, fp);
+               *did = FC_FID_FLOGI;
+               break;
+
        case ELS_LOGO:
                fc_logo_fill(lport, fp);
                *did = FC_FID_FLOGI;

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to