}
 }
 
-void qedf_update_src_mac(struct fc_lport *lport, u8 *addr)
-{
-       struct qedf_ctx *qedf = lport_priv(lport);
-
-       QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC,
-           "Setting data_src_addr=%pM.\n", addr);
-       ether_addr_copy(qedf->data_src_addr, addr);
-}
-
 u8 *qedf_get_src_mac(struct fc_lport *lport)
 {
-       u8 mac[ETH_ALEN];
-       u8 port_id[3];
        struct qedf_ctx *qedf = lport_priv(lport);
 
-       /* We need to use the lport port_id to create the data_src_addr */
-       if (is_zero_ether_addr(qedf->data_src_addr)) {
-               hton24(port_id, lport->port_id);
-               fc_fcoe_set_mac(mac, port_id);
-               qedf->ctlr.update_mac(lport, mac);
-       }
        return qedf->data_src_addr;
 }
 
 #include <linux/kthread.h>
 #include <scsi/libfc.h>
 #include <scsi/scsi_host.h>
+#include <scsi/fc_frame.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/cpu.h>
        }
 }
 
+#define        QEDF_FCOE_MAC_METHOD_GRANGED_MAC                1
+#define QEDF_FCOE_MAC_METHOD_FCF_MAP                   2
+#define QEDF_FCOE_MAC_METHOD_FCOE_SET_MAC              3
+static void qedf_set_data_src_addr(struct qedf_ctx *qedf, struct fc_frame *fp)
+{
+       u8 *granted_mac;
+       struct fc_frame_header *fh = fc_frame_header_get(fp);
+       u8 fc_map[3];
+       int method = 0;
+
+       /* Get granted MAC address from FIP FLOGI payload */
+       granted_mac = fr_cb(fp)->granted_mac;
+
+       /*
+        * We set the source MAC for FCoE traffic based on the Granted MAC
+        * address from the switch.
+        *
+        * If granted_mac is non-zero, we used that.
+        * If the granted_mac is zeroed out, created the FCoE MAC based on
+        * the sel_fcf->fc_map and the d_id fo the FLOGI frame.
+        * If sel_fcf->fc_map is 0 then we use the default FCF-MAC plus the
+        * d_id of the FLOGI frame.
+        */
+       if (!is_zero_ether_addr(granted_mac)) {
+               ether_addr_copy(qedf->data_src_addr, granted_mac);
+               method = QEDF_FCOE_MAC_METHOD_GRANGED_MAC;
+       } else if (qedf->ctlr.sel_fcf->fc_map != 0) {
+               hton24(fc_map, qedf->ctlr.sel_fcf->fc_map);
+               qedf->data_src_addr[0] = fc_map[0];
+               qedf->data_src_addr[1] = fc_map[1];
+               qedf->data_src_addr[2] = fc_map[2];
+               qedf->data_src_addr[3] = fh->fh_d_id[0];
+               qedf->data_src_addr[4] = fh->fh_d_id[1];
+               qedf->data_src_addr[5] = fh->fh_d_id[2];
+               method = QEDF_FCOE_MAC_METHOD_FCF_MAP;
+       } else {
+               fc_fcoe_set_mac(qedf->data_src_addr, fh->fh_d_id);
+               method = QEDF_FCOE_MAC_METHOD_FCOE_SET_MAC;
+       }
+
+       QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC,
+           "QEDF data_src_mac=%pM method=%d.\n", qedf->data_src_addr, method);
+}
+
 static void qedf_flogi_resp(struct fc_seq *seq, struct fc_frame *fp,
        void *arg)
 {
        /* Log stats for FLOGI reject */
        if (fc_frame_payload_op(fp) == ELS_LS_RJT)
                qedf->flogi_failed++;
+       else if (fc_frame_payload_op(fp) == ELS_LS_ACC) {
+               /* Set the source MAC we will use for FCoE traffic */
+               qedf_set_data_src_addr(qedf, fp);
+       }
 
        /* Complete flogi_compl so we can proceed to sending ADISCs */
        complete(&qedf->flogi_compl);
                ether_addr_copy(eh->h_dest, qedf->ctlr.dest_addr);
 
        /* Set the source MAC address */
-       fc_fcoe_set_mac(eh->h_source, fh->fh_s_id);
+       ether_addr_copy(eh->h_source, qedf->data_src_addr);
 
        hp = (struct fcoe_hdr *)(eh + 1);
        memset(hp, 0, sizeof(*hp));
 {
        struct qed_fcoe_params_offload conn_info;
        u32 port_id;
-       u8 lport_src_id[3];
        int rval;
        uint16_t total_sqe = (fcport->sq_mem_size / sizeof(struct fcoe_wqe));
 
            (dma_addr_t)(*(u64 *)(fcport->sq_pbl + 8));
 
        /* Need to use our FCoE MAC for the offload session */
-       port_id = fc_host_port_id(qedf->lport->host);
-       lport_src_id[2] = (port_id & 0x000000FF);
-       lport_src_id[1] = (port_id & 0x0000FF00) >> 8;
-       lport_src_id[0] = (port_id & 0x00FF0000) >> 16;
-       fc_fcoe_set_mac(conn_info.src_mac, lport_src_id);
+       ether_addr_copy(conn_info.src_mac, qedf->data_src_addr);
 
        ether_addr_copy(conn_info.dst_mac, qedf->ctlr.dest_addr);
 
        fcoe_ctlr_init(&qedf->ctlr, FIP_ST_AUTO);
 
        qedf->ctlr.send = qedf_fip_send;
-       qedf->ctlr.update_mac = qedf_update_src_mac;
        qedf->ctlr.get_src_addr = qedf_get_src_mac;
        ether_addr_copy(qedf->ctlr.ctl_src_addr, qedf->mac);
 }