}
 
 static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb);
-static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new);
+static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr);
+static u8 *fcoe_get_src_mac(struct fc_lport *lport);
 static void fcoe_destroy_work(struct work_struct *work);
 
 /**
        fcoe_ctlr_init(&fcoe->ctlr);
        fcoe->ctlr.send = fcoe_fip_send;
        fcoe->ctlr.update_mac = fcoe_update_src_mac;
+       fcoe->ctlr.get_src_addr = fcoe_get_src_mac;
 
        fcoe_interface_setup(fcoe, netdev);
 
        /* Delete secondary MAC addresses */
        memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
        dev_unicast_delete(netdev, flogi_maddr);
-       if (!is_zero_ether_addr(fip->data_src_addr))
-               dev_unicast_delete(netdev, fip->data_src_addr);
        if (fip->spma)
                dev_unicast_delete(netdev, fip->ctl_src_addr);
        dev_mc_delete(netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
 
 /**
  * fcoe_update_src_mac() - Update Ethernet MAC filters.
- * @fip: FCoE controller.
- * @old: Unicast MAC address to delete if the MAC is non-zero.
- * @new: Unicast MAC address to add.
+ * @lport: libfc lport
+ * @addr: Unicast MAC address to add.
  *
  * Remove any previously-set unicast MAC filter.
  * Add secondary FCoE MAC address filter for our OUI.
  */
-static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new)
+static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr)
 {
-       struct fcoe_interface *fcoe;
+       struct fcoe_port *port = lport_priv(lport);
+       struct fcoe_interface *fcoe = port->fcoe;
 
-       fcoe = fcoe_from_ctlr(fip);
        rtnl_lock();
-       if (!is_zero_ether_addr(old))
-               dev_unicast_delete(fcoe->netdev, old);
-       dev_unicast_add(fcoe->netdev, new);
+       if (!is_zero_ether_addr(port->data_src_addr))
+               dev_unicast_delete(fcoe->netdev, port->data_src_addr);
+       if (!is_zero_ether_addr(addr))
+               dev_unicast_add(fcoe->netdev, addr);
+       memcpy(port->data_src_addr, addr, ETH_ALEN);
        rtnl_unlock();
 }
 
+/**
+ * fcoe_get_src_mac() - return the Ethernet source address for an lport
+ * @lport: libfc lport
+ */
+static u8 *fcoe_get_src_mac(struct fc_lport *lport)
+{
+       struct fcoe_port *port = lport_priv(lport);
+
+       return port->data_src_addr;
+}
+
 /**
  * fcoe_lport_config() - sets up the fc_lport
  * @lp: ptr to the fc_lport
        /* Free existing transmit skbs */
        fcoe_clean_pending_queue(lport);
 
+       rtnl_lock();
+       if (!is_zero_ether_addr(port->data_src_addr))
+               dev_unicast_delete(netdev, port->data_src_addr);
+       rtnl_unlock();
+
        /* receives may not be stopped until after this */
        fcoe_interface_put(fcoe);
 
        return 0;
 }
 
+static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport,
+               u32 did, struct fc_frame *fp, unsigned int op,
+               void (*resp)(struct fc_seq *, struct fc_frame *, void *),
+               void *arg, u32 timeout);
+
 static struct libfc_function_template fcoe_libfc_fcn_templ = {
        .frame_send = fcoe_xmit,
        .ddp_setup = fcoe_ddp_setup,
        .ddp_done = fcoe_ddp_done,
+       .elsct_send = fcoe_elsct_send,
 };
 
 /**
        }
 
        if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) &&
-           fcoe_ctlr_els_send(&fcoe->ctlr, skb))
+           fcoe_ctlr_els_send(&fcoe->ctlr, lp, skb))
                return 0;
 
        sof = fr_sof(fp);
        if (unlikely(fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN))
                memcpy(eh->h_source, fcoe->ctlr.ctl_src_addr, ETH_ALEN);
        else
-               memcpy(eh->h_source, fcoe->ctlr.data_src_addr, ETH_ALEN);
+               memcpy(eh->h_source, port->data_src_addr, ETH_ALEN);
 
        hp = (struct fcoe_hdr *)(eh + 1);
        memset(hp, 0, sizeof(*hp));
                        }
                        fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
                }
-               if (unlikely(port->fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN) &&
-                   fcoe_ctlr_recv_flogi(&port->fcoe->ctlr, fp, mac)) {
-                       fc_frame_free(fp);
-                       continue;
-               }
                fc_exch_recv(lp, fp);
        }
        return 0;
        fcoe_if_exit();
 }
 module_exit(fcoe_exit);
+
+/**
+ * fcoe_flogi_resp() - FCoE specific FLOGI and FDISC response handler
+ * @seq: active sequence in the FLOGI or FDISC exchange
+ * @fp: response frame, or error encoded in a pointer (timeout)
+ * @arg: pointer the the fcoe_ctlr structure
+ *
+ * This handles MAC address managment for FCoE, then passes control on to
+ * the libfc FLOGI response handler.
+ */
+static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
+{
+       struct fcoe_ctlr *fip = arg;
+       struct fc_exch *exch = fc_seq_exch(seq);
+       struct fc_lport *lport = exch->lp;
+       u8 *mac;
+
+       if (IS_ERR(fp))
+               goto done;
+
+       mac = fr_cb(fp)->granted_mac;
+       if (is_zero_ether_addr(mac)) {
+               /* pre-FIP */
+               mac = eth_hdr(&fp->skb)->h_source;
+               if (fcoe_ctlr_recv_flogi(fip, lport, fp, mac)) {
+                       fc_frame_free(fp);
+                       return;
+               }
+       } else {
+               /* FIP, libfcoe has already seen it */
+               fip->update_mac(lport, fr_cb(fp)->granted_mac);
+       }
+done:
+       fc_lport_flogi_resp(seq, fp, lport);
+}
+
+/**
+ * fcoe_logo_resp() - FCoE specific LOGO response handler
+ * @seq: active sequence in the LOGO exchange
+ * @fp: response frame, or error encoded in a pointer (timeout)
+ * @arg: pointer the the fcoe_ctlr structure
+ *
+ * This handles MAC address managment for FCoE, then passes control on to
+ * the libfc LOGO response handler.
+ */
+static void fcoe_logo_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
+{
+       struct fcoe_ctlr *fip = arg;
+       struct fc_exch *exch = fc_seq_exch(seq);
+       struct fc_lport *lport = exch->lp;
+       static u8 zero_mac[ETH_ALEN] = { 0 };
+
+       if (!IS_ERR(fp))
+               fip->update_mac(lport, zero_mac);
+       fc_lport_logo_resp(seq, fp, lport);
+}
+
+/**
+ * fcoe_elsct_send - FCoE specific ELS handler
+ *
+ * This does special case handling of FIP encapsualted ELS exchanges for FCoE,
+ * using FCoE specific response handlers and passing the FIP controller as
+ * the argument (the lport is still available from the exchange).
+ *
+ * Most of the work here is just handed off to the libfc routine.
+ */
+static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport,
+               u32 did, struct fc_frame *fp, unsigned int op,
+               void (*resp)(struct fc_seq *, struct fc_frame *, void *),
+               void *arg, u32 timeout)
+{
+       struct fcoe_port *port = lport_priv(lport);
+       struct fcoe_interface *fcoe = port->fcoe;
+       struct fcoe_ctlr *fip = &fcoe->ctlr;
+       struct fc_frame_header *fh = fc_frame_header_get(fp);
+
+       switch (op) {
+       case ELS_FLOGI:
+       case ELS_FDISC:
+               return fc_elsct_send(lport, did, fp, op, fcoe_flogi_resp,
+                                    fip, timeout);
+       case ELS_LOGO:
+               /* only hook onto fabric logouts, not port logouts */
+               if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI)
+                       break;
+               return fc_elsct_send(lport, did, fp, op, fcoe_logo_resp,
+                                    fip, timeout);
+       }
+       return fc_elsct_send(lport, did, fp, op, resp, arg, timeout);
+}
+
 
        u8      fcoe_pending_queue_active;
        struct timer_list timer;                /* queue timer */
        struct work_struct destroy_work;        /* to prevent rtnl deadlocks */
+       u8 data_src_addr[ETH_ALEN];
 };
 
 #define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr)
 
 /**
  * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF.
  * @fip:       FCoE controller.
+ * @lport:     libfc fc_lport to send from
  * @ports:     0 for controller keep-alive, 1 for port keep-alive.
  * @sa:                source MAC address.
  *
  * The source MAC is the assigned mapped source address.
  * The destination is the FCF's F-port.
  */
-static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa)
+static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip,
+                                     struct fc_lport *lport,
+                                     int ports, u8 *sa)
 {
        struct sk_buff *skb;
        struct fip_kal {
        kal->mac.fd_desc.fip_dtype = FIP_DT_MAC;
        kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW;
        memcpy(kal->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
-
        if (ports) {
                vn = (struct fip_vn_desc *)(kal + 1);
                vn->fd_desc.fip_dtype = FIP_DT_VN_ID;
                vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW;
-               memcpy(vn->fd_mac, fip->data_src_addr, ETH_ALEN);
+               memcpy(vn->fd_mac, fip->get_src_addr(lport), ETH_ALEN);
                hton24(vn->fd_fc_id, fc_host_port_id(lp->host));
                put_unaligned_be64(lp->wwpn, &vn->fd_wwpn);
        }
-
        skb_put(skb, len);
        skb->protocol = htons(ETH_P_FIP);
        skb_reset_mac_header(skb);
 /**
  * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it.
  * @fip:       FCoE controller.
+ * @lport:     libfc fc_lport to use for the source address
  * @dtype:     FIP descriptor type for the frame.
  * @skb:       FCoE ELS frame including FC header but no FCoE headers.
  *
  * Headroom includes the FIP encapsulation description, FIP header, and
  * Ethernet header.  The tailroom is for the FIP MAC descriptor.
  */
-static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
+static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport,
                            u8 dtype, struct sk_buff *skb)
 {
        struct fip_encaps_head {
        mac->fd_desc.fip_dtype = FIP_DT_MAC;
        mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
        if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC)
-               memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN);
+               memcpy(mac->fd_mac, fip->get_src_addr(lport), ETH_ALEN);
        else if (fip->spma)
                memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);
 
 /**
  * fcoe_ctlr_els_send() - Send an ELS frame encapsulated by FIP if appropriate.
  * @fip:       FCoE controller.
+ * @lport:     libfc fc_lport to send from
  * @skb:       FCoE ELS frame including FC header but no FCoE headers.
  *
  * Returns a non-zero error code if the frame should not be sent.
  * The caller must check that the length is a multiple of 4.
  * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
  */
-int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
+int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
+                      struct sk_buff *skb)
 {
        struct fc_frame_header *fh;
        u16 old_xid;
        u8 op;
+       u8 mac[ETH_ALEN];
 
        fh = (struct fc_frame_header *)skb->data;
        op = *(u8 *)(fh + 1);
                 * FLOGI.
                 */
                fip->flogi_oxid = FC_XID_UNKNOWN;
-               fc_fcoe_set_mac(fip->data_src_addr, fh->fh_s_id);
+               fc_fcoe_set_mac(mac, fh->fh_d_id);
+               fip->update_mac(lport, mac);
                return 0;
        default:
                if (fip->state != FIP_ST_ENABLED)
                        goto drop;
                return 0;
        }
-       if (fcoe_ctlr_encaps(fip, op, skb))
+       if (fcoe_ctlr_encaps(fip, lport, op, skb))
                goto drop;
        fip->send(fip, skb);
        return -EINPROGRESS;
 {
        struct fc_lport *lp = fip->lp;
        struct fip_header *fiph;
-       struct fc_frame *fp;
+       struct fc_frame *fp = (struct fc_frame *)skb;
        struct fc_frame_header *fh = NULL;
        struct fip_desc *desc;
        struct fip_encaps *els;
                                                "in FIP ELS\n");
                                goto drop;
                        }
+                       memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN);
                        break;
                case FIP_DT_FLOGI:
                case FIP_DT_FDISC:
                goto drop;
        els_op = *(u8 *)(fh + 1);
 
-       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)) {
+       if (els_dtype == FIP_DT_FLOGI && 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);
-               memcpy(fip->data_src_addr, granted_mac, ETH_ALEN);
-       }
 
        /*
         * Convert skb into an fc_frame containing only the ELS.
                        if (dlen < sizeof(*vp))
                                return;
                        if (compare_ether_addr(vp->fd_mac,
-                           fip->data_src_addr) == 0 &&
+                           fip->get_src_addr(lp)) == 0 &&
                            get_unaligned_be64(&vp->fd_wwpn) == lp->wwpn &&
                            ntoh24(vp->fd_fc_id) == fc_host_port_id(lp->host))
                                desc_mask &= ~BIT(FIP_DT_VN_ID);
        struct fcoe_fcf *sel;
        struct fcoe_fcf *fcf;
        unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
-       u8 send_ctlr_ka;
-       u8 send_port_ka;
 
        spin_lock_bh(&fip->lock);
        if (fip->state == FIP_ST_DISABLED) {
                schedule_work(&fip->link_work);
        }
 
-       send_ctlr_ka = 0;
-       send_port_ka = 0;
        if (sel) {
                if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
                        fip->ctlr_ka_time = jiffies + sel->fka_period;
-                       send_ctlr_ka = 1;
+                       fip->send_ctlr_ka = 1;
                }
                if (time_after(next_timer, fip->ctlr_ka_time))
                        next_timer = fip->ctlr_ka_time;
                if (time_after_eq(jiffies, fip->port_ka_time)) {
                        fip->port_ka_time += jiffies +
                                        msecs_to_jiffies(FIP_VN_KA_PERIOD);
-                       send_port_ka = 1;
+                       fip->send_port_ka = 1;
                }
                if (time_after(next_timer, fip->port_ka_time))
                        next_timer = fip->port_ka_time;
                                msecs_to_jiffies(FCOE_CTLR_START_DELAY);
                mod_timer(&fip->timer, next_timer);
        }
+       if (fip->send_ctlr_ka || fip->send_port_ka)
+               schedule_work(&fip->link_work);
        spin_unlock_bh(&fip->lock);
-
-       if (send_ctlr_ka)
-               fcoe_ctlr_send_keep_alive(fip, 0, fip->ctl_src_addr);
-       if (send_port_ka)
-               fcoe_ctlr_send_keep_alive(fip, 1, fip->data_src_addr);
 }
 
 /**
 static void fcoe_ctlr_link_work(struct work_struct *work)
 {
        struct fcoe_ctlr *fip;
+       struct fc_lport *vport;
+       u8 *mac;
        int link;
        int last_link;
 
                else
                        fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT);
        }
+
+       if (fip->send_ctlr_ka) {
+               fip->send_ctlr_ka = 0;
+               fcoe_ctlr_send_keep_alive(fip, NULL, 0, fip->ctl_src_addr);
+       }
+       if (fip->send_port_ka) {
+               fip->send_port_ka = 0;
+               mutex_lock(&fip->lp->lp_mutex);
+               mac = fip->get_src_addr(fip->lp);
+               fcoe_ctlr_send_keep_alive(fip, fip->lp, 1, mac);
+               list_for_each_entry(vport, &fip->lp->vports, list) {
+                       mac = fip->get_src_addr(vport);
+                       fcoe_ctlr_send_keep_alive(fip, vport, 1, mac);
+               }
+               mutex_unlock(&fip->lp->lp_mutex);
+       }
 }
 
 /**
 /**
  * fcoe_ctlr_recv_flogi() - snoop Pre-FIP receipt of FLOGI response or request.
  * @fip:       FCoE controller.
+ * @lport:     libfc fc_lport instance received on
  * @fp:                FC frame.
  * @sa:                Ethernet source MAC address from received FCoE frame.
  *
  *
  * Return non-zero if the frame should not be delivered to libfc.
  */
-int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa)
+int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport,
+                        struct fc_frame *fp, u8 *sa)
 {
        struct fc_frame_header *fh;
        u8 op;
                        fip->map_dest = 0;
                }
                fip->flogi_oxid = FC_XID_UNKNOWN;
-               memcpy(mac, fip->data_src_addr, ETH_ALEN);
-               fc_fcoe_set_mac(fip->data_src_addr, fh->fh_d_id);
+               fc_fcoe_set_mac(mac, fh->fh_d_id);
+               fip->update_mac(lport, mac);
                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) {
                /*
                 * Save source MAC for point-to-point responses.
        return 0;
 }
 EXPORT_SYMBOL_GPL(fcoe_libfc_config);
+
 
 /*
  * fc_elsct_send - sends ELS/CT frame
  */
-static struct fc_seq *fc_elsct_send(struct fc_lport *lport,
+struct fc_seq *fc_elsct_send(struct fc_lport *lport,
                                    u32 did,
                                    struct fc_frame *fp,
                                    unsigned int op,
 
        return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec);
 }
+EXPORT_SYMBOL(fc_elsct_send);
 
 int fc_elsct_init(struct fc_lport *lport)
 {
 
  * held, but it will lock, call an _enter_* function or fc_lport_error
  * and then unlock the lport.
  */
-static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
+void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
                               void *lp_arg)
 {
        struct fc_lport *lport = lp_arg;
 err:
        mutex_unlock(&lport->lp_mutex);
 }
+EXPORT_SYMBOL(fc_lport_logo_resp);
 
 /**
  * fc_rport_enter_logo() - Logout of the fabric
  * held, but it will lock, call an _enter_* function or fc_lport_error
  * and then unlock the lport.
  */
-static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
+void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
                                void *lp_arg)
 {
        struct fc_lport *lport = lp_arg;
 err:
        mutex_unlock(&lport->lp_mutex);
 }
+EXPORT_SYMBOL(fc_lport_flogi_resp);
 
 /**
  * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager
 
 #include <scsi/fc/fc_fcp.h>
 #include <scsi/fc/fc_encaps.h>
 
+#include <linux/if_ether.h>
+
 /*
  * The fc_frame interface is used to pass frame data between functions.
  * The frame includes the data buffer, length, and SOF / EOF delimiter types.
        enum fc_sof     fr_sof;         /* start of frame delimiter */
        enum fc_eof     fr_eof;         /* end of frame delimiter */
        u8              fr_flags;       /* flags - see below */
+       u8              granted_mac[ETH_ALEN]; /* FCoE MAC address */
 };
 
 
 
  * Initializes ELS/CT interface
  */
 int fc_elsct_init(struct fc_lport *lp);
+struct fc_seq *fc_elsct_send(struct fc_lport *lport,
+                                   u32 did,
+                                   struct fc_frame *fp,
+                                   unsigned int op,
+                                   void (*resp)(struct fc_seq *,
+                                                struct fc_frame *fp,
+                                                void *arg),
+                                   void *arg, u32 timer_msec);
+void fc_lport_flogi_resp(struct fc_seq *, struct fc_frame *, void *);
+void fc_lport_logo_resp(struct fc_seq *, struct fc_frame *, void *);
 
 
 /*
 
  * @last_link: last link state reported to libfc.
  * @map_dest:  use the FC_MAP mode for destination MAC addresses.
  * @spma:      supports SPMA server-provided MACs mode
+ * @send_ctlr_ka: need to send controller keep alive
+ * @send_port_ka: need to send port keep alives
  * @dest_addr: MAC address of the selected FC forwarder.
  * @ctl_src_addr: the native MAC address of our local port.
- * @data_src_addr: the assigned MAC address for the local port after FLOGI.
  * @send:      LLD-supplied function to handle sending of FIP Ethernet frames.
  * @update_mac: LLD-supplied function to handle changes to MAC addresses.
+ * @get_src_addr: LLD-supplied function to supply a source MAC address.
  * @lock:      lock protecting this structure.
  *
  * This structure is used by all FCoE drivers.  It contains information
        u8 last_link;
        u8 map_dest;
        u8 spma;
+       u8 send_ctlr_ka;
+       u8 send_port_ka;
        u8 dest_addr[ETH_ALEN];
        u8 ctl_src_addr[ETH_ALEN];
-       u8 data_src_addr[ETH_ALEN];
 
        void (*send)(struct fcoe_ctlr *, struct sk_buff *);
-       void (*update_mac)(struct fcoe_ctlr *, u8 *old, u8 *new);
+       void (*update_mac)(struct fc_lport *, u8 *addr);
+       u8 * (*get_src_addr)(struct fc_lport *);
        spinlock_t lock;
 };
 
 void fcoe_ctlr_destroy(struct fcoe_ctlr *);
 void fcoe_ctlr_link_up(struct fcoe_ctlr *);
 int fcoe_ctlr_link_down(struct fcoe_ctlr *);
-int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct sk_buff *);
+int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct fc_lport *, struct sk_buff *);
 void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *);
-int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_frame *fp, u8 *sa);
+int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *lport,
+                        struct fc_frame *fp, u8 *sa);
 
 /* libfcoe funcs */
 u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int);