struct sk_buff          *skb;
        struct fc_frame_header  *fh;
        struct bnx2fc_interface *interface;
+       struct fcoe_ctlr        *ctlr;
        struct bnx2fc_hba *hba;
        struct fcoe_port        *port;
        struct fcoe_hdr         *hp;
 
        port = (struct fcoe_port *)lport_priv(lport);
        interface = port->priv;
+       ctlr = bnx2fc_to_ctlr(interface);
        hba = interface->hba;
 
        fh = fc_frame_header_get(fp);
        }
 
        if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ)) {
-               if (!interface->ctlr.sel_fcf) {
+               if (!ctlr->sel_fcf) {
                        BNX2FC_HBA_DBG(lport, "FCF not selected yet!\n");
                        kfree_skb(skb);
                        return -EINVAL;
                }
-               if (fcoe_ctlr_els_send(&interface->ctlr, lport, skb))
+               if (fcoe_ctlr_els_send(ctlr, lport, skb))
                        return 0;
        }
 
        /* fill up mac and fcoe headers */
        eh = eth_hdr(skb);
        eh->h_proto = htons(ETH_P_FCOE);
-       if (interface->ctlr.map_dest)
+       if (ctlr->map_dest)
                fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id);
        else
                /* insert GW address */
-               memcpy(eh->h_dest, interface->ctlr.dest_addr, ETH_ALEN);
+               memcpy(eh->h_dest, ctlr->dest_addr, ETH_ALEN);
 
-       if (unlikely(interface->ctlr.flogi_oxid != FC_XID_UNKNOWN))
-               memcpy(eh->h_source, interface->ctlr.ctl_src_addr, ETH_ALEN);
+       if (unlikely(ctlr->flogi_oxid != FC_XID_UNKNOWN))
+               memcpy(eh->h_source, ctlr->ctl_src_addr, ETH_ALEN);
        else
                memcpy(eh->h_source, port->data_src_addr, ETH_ALEN);
 
 {
        struct fc_lport *lport;
        struct bnx2fc_interface *interface;
+       struct fcoe_ctlr *ctlr;
        struct fc_frame_header *fh;
        struct fcoe_rcv_info *fr;
        struct fcoe_percpu_s *bg;
 
        interface = container_of(ptype, struct bnx2fc_interface,
                                 fcoe_packet_type);
-       lport = interface->ctlr.lp;
+       ctlr = bnx2fc_to_ctlr(interface);
+       lport = ctlr->lp;
 
        if (unlikely(lport == NULL)) {
                printk(KERN_ERR PFX "bnx2fc_rcv: lport is NULL\n");
 {
        struct bnx2fc_hba *hba;
        struct bnx2fc_interface *interface;
+       struct fcoe_ctlr *ctlr;
        struct fcoe_port *port;
        u64 wwnn, wwpn;
 
        port = lport_priv(lport);
        interface = port->priv;
+       ctlr = bnx2fc_to_ctlr(interface);
        hba = interface->hba;
 
        /* require support for get_pauseparam ethtool op. */
 
        if (!lport->vport) {
                if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN))
-                       wwnn = fcoe_wwn_from_mac(interface->ctlr.ctl_src_addr,
+                       wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr,
                                                 1, 0);
                BNX2FC_HBA_DBG(lport, "WWNN = 0x%llx\n", wwnn);
                fc_set_wwnn(lport, wwnn);
 
                if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN))
-                       wwpn = fcoe_wwn_from_mac(interface->ctlr.ctl_src_addr,
+                       wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr,
                                                 2, 0);
 
                BNX2FC_HBA_DBG(lport, "WWPN = 0x%llx\n", wwpn);
        struct fc_lport *lport;
        struct fc_lport *vport;
        struct bnx2fc_interface *interface, *tmp;
+       struct fcoe_ctlr *ctlr;
        int wait_for_upload = 0;
        u32 link_possible = 1;
 
                if (interface->hba != hba)
                        continue;
 
-               lport = interface->ctlr.lp;
+               ctlr = bnx2fc_to_ctlr(interface);
+               lport = ctlr->lp;
                BNX2FC_HBA_DBG(lport, "netevent handler - event=%s %ld\n",
                                interface->netdev->name, event);
 
                         * on a stale vlan
                         */
                        if (interface->enabled)
-                               fcoe_ctlr_link_up(&interface->ctlr);
-               } else if (fcoe_ctlr_link_down(&interface->ctlr)) {
+                               fcoe_ctlr_link_up(ctlr);
+               } else if (fcoe_ctlr_link_down(ctlr)) {
                        mutex_lock(&lport->lp_mutex);
                        list_for_each_entry(vport, &lport->vports, list)
                                fc_host_port_type(vport->host) =
                           struct net_device *orig_dev)
 {
        struct bnx2fc_interface *interface;
+       struct fcoe_ctlr *ctlr;
        interface = container_of(ptype, struct bnx2fc_interface,
                                 fip_packet_type);
-       fcoe_ctlr_recv(&interface->ctlr, skb);
+       ctlr = bnx2fc_to_ctlr(interface);
+       fcoe_ctlr_recv(ctlr, skb);
        return 0;
 }
 
 {
        struct net_device *netdev = interface->netdev;
        struct net_device *physdev = interface->hba->phys_dev;
+       struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
        struct netdev_hw_addr *ha;
        int sel_san_mac = 0;
 
 
                if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
                    (is_valid_ether_addr(ha->addr))) {
-                       memcpy(interface->ctlr.ctl_src_addr, ha->addr,
+                       memcpy(ctlr->ctl_src_addr, ha->addr,
                               ETH_ALEN);
                        sel_san_mac = 1;
                        BNX2FC_MISC_DBG("Found SAN MAC\n");
 static void bnx2fc_interface_release(struct kref *kref)
 {
        struct bnx2fc_interface *interface;
+       struct fcoe_ctlr *ctlr;
        struct net_device *netdev;
 
        interface = container_of(kref, struct bnx2fc_interface, kref);
        BNX2FC_MISC_DBG("Interface is being released\n");
 
+       ctlr = bnx2fc_to_ctlr(interface);
        netdev = interface->netdev;
 
        /* tear-down FIP controller */
        if (test_and_clear_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags))
-               fcoe_ctlr_destroy(&interface->ctlr);
+               fcoe_ctlr_destroy(ctlr);
 
-       kfree(interface);
+       kfree(ctlr);
 
        dev_put(netdev);
        module_put(THIS_MODULE);
                                      enum fip_state fip_mode)
 {
        struct bnx2fc_interface *interface;
+       struct fcoe_ctlr *ctlr;
+       int size;
        int rc = 0;
 
-       interface = kzalloc(sizeof(*interface), GFP_KERNEL);
-       if (!interface) {
+       size = (sizeof(*interface) + sizeof(struct fcoe_ctlr));
+       ctlr = kzalloc(size, GFP_KERNEL);
+       if (!ctlr) {
                printk(KERN_ERR PFX "Unable to allocate interface structure\n");
                return NULL;
        }
+       interface = fcoe_ctlr_priv(ctlr);
        dev_hold(netdev);
        kref_init(&interface->kref);
        interface->hba = hba;
        interface->netdev = netdev;
 
        /* Initialize FIP */
-       fcoe_ctlr_init(&interface->ctlr, fip_mode);
-       interface->ctlr.send = bnx2fc_fip_send;
-       interface->ctlr.update_mac = bnx2fc_update_src_mac;
-       interface->ctlr.get_src_addr = bnx2fc_get_src_mac;
+       fcoe_ctlr_init(ctlr, fip_mode);
+       ctlr->send = bnx2fc_fip_send;
+       ctlr->update_mac = bnx2fc_update_src_mac;
+       ctlr->get_src_addr = bnx2fc_get_src_mac;
        set_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags);
 
        rc = bnx2fc_interface_setup(interface);
        if (!rc)
                return interface;
 
-       fcoe_ctlr_destroy(&interface->ctlr);
+       fcoe_ctlr_destroy(ctlr);
        dev_put(netdev);
-       kfree(interface);
+       kfree(ctlr);
        return NULL;
 }
 
 static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface,
                                  struct device *parent, int npiv)
 {
+       struct fcoe_ctlr        *ctlr = bnx2fc_to_ctlr(interface);
        struct fc_lport         *lport, *n_port;
        struct fcoe_port        *port;
        struct Scsi_Host        *shost;
 
        blport = kzalloc(sizeof(struct bnx2fc_lport), GFP_KERNEL);
        if (!blport) {
-               BNX2FC_HBA_DBG(interface->ctlr.lp, "Unable to alloc blport\n");
+               BNX2FC_HBA_DBG(ctlr->lp, "Unable to alloc blport\n");
                return NULL;
        }
 
 
 static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface)
 {
-       struct fc_lport *lport = interface->ctlr.lp;
+       struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
+       struct fc_lport *lport = ctlr->lp;
        struct fcoe_port *port = lport_priv(lport);
        struct bnx2fc_hba *hba = interface->hba;
 
 
 static void __bnx2fc_destroy(struct bnx2fc_interface *interface)
 {
-       struct fc_lport *lport = interface->ctlr.lp;
+       struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
+       struct fc_lport *lport = ctlr->lp;
        struct fcoe_port *port = lport_priv(lport);
 
        bnx2fc_interface_cleanup(interface);
 {
        struct bnx2fc_interface *interface = NULL;
        struct workqueue_struct *timer_work_queue;
+       struct fcoe_ctlr *ctlr;
        int rc = 0;
 
        rtnl_lock();
        mutex_lock(&bnx2fc_dev_lock);
 
        interface = bnx2fc_interface_lookup(netdev);
-       if (!interface || !interface->ctlr.lp) {
+       ctlr = bnx2fc_to_ctlr(interface);
+       if (!interface || !ctlr->lp) {
                rc = -ENODEV;
                printk(KERN_ERR PFX "bnx2fc_destroy: interface or lport not found\n");
                goto netdev_err;
 {
        struct bnx2fc_hba *hba = handle;
        struct bnx2fc_interface *interface;
+       struct fcoe_ctlr *ctlr;
        struct fc_lport *lport;
 
        mutex_lock(&bnx2fc_dev_lock);
 
        list_for_each_entry(interface, &if_list, list) {
                if (interface->hba == hba) {
-                       lport = interface->ctlr.lp;
+                       ctlr = bnx2fc_to_ctlr(interface);
+                       lport = ctlr->lp;
                        /* Kick off Fabric discovery*/
                        printk(KERN_ERR PFX "ulp_init: start discovery\n");
                        lport->tt.frame_send = bnx2fc_xmit;
 
 static void bnx2fc_stop(struct bnx2fc_interface *interface)
 {
+       struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
        struct fc_lport *lport;
        struct fc_lport *vport;
 
        if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags))
                return;
 
-       lport = interface->ctlr.lp;
+       lport = ctlr->lp;
        bnx2fc_port_shutdown(lport);
 
        mutex_lock(&lport->lp_mutex);
                                        FC_PORTTYPE_UNKNOWN;
        mutex_unlock(&lport->lp_mutex);
        fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN;
-       fcoe_ctlr_link_down(&interface->ctlr);
+       fcoe_ctlr_link_down(ctlr);
        fcoe_clean_pending_queue(lport);
 }
 
 
 static void bnx2fc_start_disc(struct bnx2fc_interface *interface)
 {
+       struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
        struct fc_lport *lport;
        int wait_cnt = 0;
 
                return;
        }
 
-       lport = interface->ctlr.lp;
+       lport = ctlr->lp;
        BNX2FC_HBA_DBG(lport, "calling fc_fabric_login\n");
 
        if (!bnx2fc_link_ok(lport) && interface->enabled) {
                BNX2FC_HBA_DBG(lport, "ctlr_link_up\n");
-               fcoe_ctlr_link_up(&interface->ctlr);
+               fcoe_ctlr_link_up(ctlr);
                fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
                set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state);
        }
 
        /* wait for the FCF to be selected before issuing FLOGI */
-       while (!interface->ctlr.sel_fcf) {
+       while (!ctlr->sel_fcf) {
                msleep(250);
                /* give up after 3 secs */
                if (++wait_cnt > 12)
 static int bnx2fc_disable(struct net_device *netdev)
 {
        struct bnx2fc_interface *interface;
+       struct fcoe_ctlr *ctlr;
        int rc = 0;
 
        rtnl_lock();
        mutex_lock(&bnx2fc_dev_lock);
 
        interface = bnx2fc_interface_lookup(netdev);
-       if (!interface || !interface->ctlr.lp) {
+       ctlr = bnx2fc_to_ctlr(interface);
+       if (!interface || !ctlr->lp) {
                rc = -ENODEV;
                printk(KERN_ERR PFX "bnx2fc_disable: interface or lport not found\n");
        } else {
                interface->enabled = false;
-               fcoe_ctlr_link_down(&interface->ctlr);
-               fcoe_clean_pending_queue(interface->ctlr.lp);
+               fcoe_ctlr_link_down(ctlr);
+               fcoe_clean_pending_queue(ctlr->lp);
        }
 
        mutex_unlock(&bnx2fc_dev_lock);
 static int bnx2fc_enable(struct net_device *netdev)
 {
        struct bnx2fc_interface *interface;
+       struct fcoe_ctlr *ctlr;
        int rc = 0;
 
        rtnl_lock();
        mutex_lock(&bnx2fc_dev_lock);
 
        interface = bnx2fc_interface_lookup(netdev);
-       if (!interface || !interface->ctlr.lp) {
+       ctlr = bnx2fc_to_ctlr(interface);
+       if (!interface || !ctlr->lp) {
                rc = -ENODEV;
                printk(KERN_ERR PFX "bnx2fc_enable: interface or lport not found\n");
-       } else if (!bnx2fc_link_ok(interface->ctlr.lp)) {
-               fcoe_ctlr_link_up(&interface->ctlr);
+       } else if (!bnx2fc_link_ok(ctlr->lp)) {
+               fcoe_ctlr_link_up(ctlr);
                interface->enabled = true;
        }
 
  */
 static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
 {
+       struct fcoe_ctlr *ctlr;
        struct bnx2fc_interface *interface;
        struct bnx2fc_hba *hba;
        struct net_device *phys_dev;
                goto ifput_err;
        }
 
+       ctlr = bnx2fc_to_ctlr(interface);
        interface->vlan_id = vlan_id;
        interface->vlan_enabled = 1;
 
        lport->boot_time = jiffies;
 
        /* Make this master N_port */
-       interface->ctlr.lp = lport;
+       ctlr->lp = lport;
 
        if (!bnx2fc_link_ok(lport)) {
-               fcoe_ctlr_link_up(&interface->ctlr);
+               fcoe_ctlr_link_up(ctlr);
                fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
                set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state);
        }
 
 {
        struct fc_lport *lport = port->lport;
        struct bnx2fc_interface *interface = port->priv;
+       struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
        struct bnx2fc_hba *hba = interface->hba;
        struct kwqe *kwqe_arr[4];
        struct fcoe_kwqe_conn_offload1 ofld_req1;
        ofld_req4.src_mac_addr_mid[1] =  port->data_src_addr[2];
        ofld_req4.src_mac_addr_hi[0] =  port->data_src_addr[1];
        ofld_req4.src_mac_addr_hi[1] =  port->data_src_addr[0];
-       ofld_req4.dst_mac_addr_lo[0] =  interface->ctlr.dest_addr[5];
+       ofld_req4.dst_mac_addr_lo[0] =  ctlr->dest_addr[5];
                                                        /* fcf mac */
-       ofld_req4.dst_mac_addr_lo[1] =  interface->ctlr.dest_addr[4];
-       ofld_req4.dst_mac_addr_mid[0] =  interface->ctlr.dest_addr[3];
-       ofld_req4.dst_mac_addr_mid[1] =  interface->ctlr.dest_addr[2];
-       ofld_req4.dst_mac_addr_hi[0] =  interface->ctlr.dest_addr[1];
-       ofld_req4.dst_mac_addr_hi[1] =  interface->ctlr.dest_addr[0];
+       ofld_req4.dst_mac_addr_lo[1] = ctlr->dest_addr[4];
+       ofld_req4.dst_mac_addr_mid[0] = ctlr->dest_addr[3];
+       ofld_req4.dst_mac_addr_mid[1] = ctlr->dest_addr[2];
+       ofld_req4.dst_mac_addr_hi[0] = ctlr->dest_addr[1];
+       ofld_req4.dst_mac_addr_hi[1] = ctlr->dest_addr[0];
 
        ofld_req4.lcq_addr_lo = (u32) tgt->lcq_dma;
        ofld_req4.lcq_addr_hi = (u32)((u64) tgt->lcq_dma >> 32);
 {
        struct kwqe *kwqe_arr[2];
        struct bnx2fc_interface *interface = port->priv;
+       struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
        struct bnx2fc_hba *hba = interface->hba;
        struct fcoe_kwqe_conn_enable_disable enbl_req;
        struct fc_lport *lport = port->lport;
        enbl_req.src_mac_addr_hi[1] =  port->data_src_addr[0];
        memcpy(tgt->src_addr, port->data_src_addr, ETH_ALEN);
 
-       enbl_req.dst_mac_addr_lo[0] =  interface->ctlr.dest_addr[5];
-       enbl_req.dst_mac_addr_lo[1] =  interface->ctlr.dest_addr[4];
-       enbl_req.dst_mac_addr_mid[0] =  interface->ctlr.dest_addr[3];
-       enbl_req.dst_mac_addr_mid[1] =  interface->ctlr.dest_addr[2];
-       enbl_req.dst_mac_addr_hi[0] =  interface->ctlr.dest_addr[1];
-       enbl_req.dst_mac_addr_hi[1] =  interface->ctlr.dest_addr[0];
+       enbl_req.dst_mac_addr_lo[0] =  ctlr->dest_addr[5];
+       enbl_req.dst_mac_addr_lo[1] =  ctlr->dest_addr[4];
+       enbl_req.dst_mac_addr_mid[0] = ctlr->dest_addr[3];
+       enbl_req.dst_mac_addr_mid[1] = ctlr->dest_addr[2];
+       enbl_req.dst_mac_addr_hi[0] = ctlr->dest_addr[1];
+       enbl_req.dst_mac_addr_hi[1] = ctlr->dest_addr[0];
 
        port_id = fc_host_port_id(lport->host);
        if (port_id != tgt->sid) {
                                    struct bnx2fc_rport *tgt)
 {
        struct bnx2fc_interface *interface = port->priv;
+       struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
        struct bnx2fc_hba *hba = interface->hba;
        struct fcoe_kwqe_conn_enable_disable disable_req;
        struct kwqe *kwqe_arr[2];
        disable_req.src_mac_addr_hi[0] =  tgt->src_addr[1];
        disable_req.src_mac_addr_hi[1] =  tgt->src_addr[0];
 
-       disable_req.dst_mac_addr_lo[0] =  interface->ctlr.dest_addr[5];
-       disable_req.dst_mac_addr_lo[1] =  interface->ctlr.dest_addr[4];
-       disable_req.dst_mac_addr_mid[0] =  interface->ctlr.dest_addr[3];
-       disable_req.dst_mac_addr_mid[1] =  interface->ctlr.dest_addr[2];
-       disable_req.dst_mac_addr_hi[0] =  interface->ctlr.dest_addr[1];
-       disable_req.dst_mac_addr_hi[1] =  interface->ctlr.dest_addr[0];
+       disable_req.dst_mac_addr_lo[0] =  ctlr->dest_addr[5];
+       disable_req.dst_mac_addr_lo[1] =  ctlr->dest_addr[4];
+       disable_req.dst_mac_addr_mid[0] = ctlr->dest_addr[3];
+       disable_req.dst_mac_addr_mid[1] = ctlr->dest_addr[2];
+       disable_req.dst_mac_addr_hi[0] = ctlr->dest_addr[1];
+       disable_req.dst_mac_addr_hi[1] = ctlr->dest_addr[0];
 
        port_id = tgt->sid;
        disable_req.s_id[0] = (port_id & 0x000000FF);