Commit 619fe4be authored by Robert Love's avatar Robert Love Committed by James Bottomley

[SCSI] fcoe: Allocate fcoe_ctlr with fcoe_interface, not as a member

Currently the fcoe_ctlr associated with an interface is allocated
as a member of struct fcoe_interface. This causes problems when
attempting to use the new fcoe_sysfs APIs which allow us to allocate
the fcoe_interface as private data to the fcoe_ctlr_device instance.
The problem is that libfcoe wants to be able use pointer math to find a
fcoe_ctlr's fcoe_ctlr_device as well as finding a fcoe_ctlr_device's
assocated fcoe_ctlr. To do this we need to allocate the
fcoe_ctlr_device, with private data for the LLD. The private data
contains the fcoe_ctlr and its private data is the fcoe_interface.
This patch only allocates the fcoe_interface with the fcoe_ctlr, the
fcoe_ctlr_device will be added in a later patch, which will complete
the below diagram-

+------------------+
| fcoe_ctlr_device |
+------------------+
| fcoe_ctlr        |
+------------------+
| fcoe_interface   |
+------------------+

This prep work will allow us to go from a fcoe_ctlr_device instance
to its fcoe_ctlr as well as from a fcoe_ctlr to its fcoe_ctlr_device
once the fcoe_sysfs API is in use (later patches in this series).
Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
Tested-by: default avatarRoss Brattain <ross.b.brattain@intel.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent b7e94a16
...@@ -282,7 +282,7 @@ static struct scsi_host_template fcoe_shost_template = { ...@@ -282,7 +282,7 @@ static struct scsi_host_template fcoe_shost_template = {
static int fcoe_interface_setup(struct fcoe_interface *fcoe, static int fcoe_interface_setup(struct fcoe_interface *fcoe,
struct net_device *netdev) struct net_device *netdev)
{ {
struct fcoe_ctlr *fip = &fcoe->ctlr; struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe);
struct netdev_hw_addr *ha; struct netdev_hw_addr *ha;
struct net_device *real_dev; struct net_device *real_dev;
u8 flogi_maddr[ETH_ALEN]; u8 flogi_maddr[ETH_ALEN];
...@@ -366,7 +366,9 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe, ...@@ -366,7 +366,9 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe,
static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
enum fip_state fip_mode) enum fip_state fip_mode)
{ {
struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
int size;
int err; int err;
if (!try_module_get(THIS_MODULE)) { if (!try_module_get(THIS_MODULE)) {
...@@ -376,7 +378,9 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, ...@@ -376,7 +378,9 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
goto out; goto out;
} }
fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL); size = sizeof(struct fcoe_ctlr) + sizeof(struct fcoe_interface);
ctlr = kzalloc(size, GFP_KERNEL);
fcoe = fcoe_ctlr_priv(ctlr);
if (!fcoe) { if (!fcoe) {
FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n");
fcoe = ERR_PTR(-ENOMEM); fcoe = ERR_PTR(-ENOMEM);
...@@ -388,15 +392,14 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, ...@@ -388,15 +392,14 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
/* /*
* Initialize FIP. * Initialize FIP.
*/ */
fcoe_ctlr_init(&fcoe->ctlr, fip_mode); fcoe_ctlr_init(ctlr, fip_mode);
fcoe->ctlr.send = fcoe_fip_send; ctlr->send = fcoe_fip_send;
fcoe->ctlr.update_mac = fcoe_update_src_mac; ctlr->update_mac = fcoe_update_src_mac;
fcoe->ctlr.get_src_addr = fcoe_get_src_mac; ctlr->get_src_addr = fcoe_get_src_mac;
err = fcoe_interface_setup(fcoe, netdev); err = fcoe_interface_setup(fcoe, netdev);
if (err) { if (err) {
fcoe_ctlr_destroy(&fcoe->ctlr); fcoe_ctlr_destroy(ctlr);
kfree(fcoe);
dev_put(netdev); dev_put(netdev);
fcoe = ERR_PTR(err); fcoe = ERR_PTR(err);
goto out_putmod; goto out_putmod;
...@@ -419,7 +422,7 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, ...@@ -419,7 +422,7 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
static void fcoe_interface_remove(struct fcoe_interface *fcoe) static void fcoe_interface_remove(struct fcoe_interface *fcoe)
{ {
struct net_device *netdev = fcoe->netdev; struct net_device *netdev = fcoe->netdev;
struct fcoe_ctlr *fip = &fcoe->ctlr; struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe);
u8 flogi_maddr[ETH_ALEN]; u8 flogi_maddr[ETH_ALEN];
const struct net_device_ops *ops; const struct net_device_ops *ops;
...@@ -462,7 +465,7 @@ static void fcoe_interface_remove(struct fcoe_interface *fcoe) ...@@ -462,7 +465,7 @@ static void fcoe_interface_remove(struct fcoe_interface *fcoe)
static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
{ {
struct net_device *netdev = fcoe->netdev; struct net_device *netdev = fcoe->netdev;
struct fcoe_ctlr *fip = &fcoe->ctlr; struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe);
rtnl_lock(); rtnl_lock();
if (!fcoe->removed) if (!fcoe->removed)
...@@ -472,8 +475,8 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) ...@@ -472,8 +475,8 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
/* Release the self-reference taken during fcoe_interface_create() */ /* Release the self-reference taken during fcoe_interface_create() */
/* tear-down the FCoE controller */ /* tear-down the FCoE controller */
fcoe_ctlr_destroy(fip); fcoe_ctlr_destroy(fip);
scsi_host_put(fcoe->ctlr.lp->host); scsi_host_put(fip->lp->host);
kfree(fcoe); kfree(fip);
dev_put(netdev); dev_put(netdev);
module_put(THIS_MODULE); module_put(THIS_MODULE);
} }
...@@ -493,9 +496,11 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *netdev, ...@@ -493,9 +496,11 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *netdev,
struct net_device *orig_dev) struct net_device *orig_dev)
{ {
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
struct fcoe_ctlr *ctlr;
fcoe = container_of(ptype, struct fcoe_interface, fip_packet_type); fcoe = container_of(ptype, struct fcoe_interface, fip_packet_type);
fcoe_ctlr_recv(&fcoe->ctlr, skb); ctlr = fcoe_to_ctlr(fcoe);
fcoe_ctlr_recv(ctlr, skb);
return 0; return 0;
} }
...@@ -645,11 +650,13 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev) ...@@ -645,11 +650,13 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev)
u32 mfs; u32 mfs;
u64 wwnn, wwpn; u64 wwnn, wwpn;
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
struct fcoe_ctlr *ctlr;
struct fcoe_port *port; struct fcoe_port *port;
/* Setup lport private data to point to fcoe softc */ /* Setup lport private data to point to fcoe softc */
port = lport_priv(lport); port = lport_priv(lport);
fcoe = port->priv; fcoe = port->priv;
ctlr = fcoe_to_ctlr(fcoe);
/* /*
* Determine max frame size based on underlying device and optional * Determine max frame size based on underlying device and optional
...@@ -676,10 +683,10 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev) ...@@ -676,10 +683,10 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev)
if (!lport->vport) { if (!lport->vport) {
if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN)) if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN))
wwnn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 1, 0); wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, 1, 0);
fc_set_wwnn(lport, wwnn); fc_set_wwnn(lport, wwnn);
if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN)) if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN))
wwpn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr,
2, 0); 2, 0);
fc_set_wwpn(lport, wwpn); fc_set_wwpn(lport, wwpn);
} }
...@@ -1056,6 +1063,7 @@ static int fcoe_ddp_done(struct fc_lport *lport, u16 xid) ...@@ -1056,6 +1063,7 @@ static int fcoe_ddp_done(struct fc_lport *lport, u16 xid)
static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
struct device *parent, int npiv) struct device *parent, int npiv)
{ {
struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
struct net_device *netdev = fcoe->netdev; struct net_device *netdev = fcoe->netdev;
struct fc_lport *lport, *n_port; struct fc_lport *lport, *n_port;
struct fcoe_port *port; struct fcoe_port *port;
...@@ -1119,7 +1127,7 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, ...@@ -1119,7 +1127,7 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
} }
/* Initialize the library */ /* Initialize the library */
rc = fcoe_libfc_config(lport, &fcoe->ctlr, &fcoe_libfc_fcn_templ, 1); rc = fcoe_libfc_config(lport, ctlr, &fcoe_libfc_fcn_templ, 1);
if (rc) { if (rc) {
FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the " FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the "
"interface\n"); "interface\n");
...@@ -1386,6 +1394,7 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, ...@@ -1386,6 +1394,7 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
{ {
struct fc_lport *lport; struct fc_lport *lport;
struct fcoe_rcv_info *fr; struct fcoe_rcv_info *fr;
struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
struct fc_frame_header *fh; struct fc_frame_header *fh;
struct fcoe_percpu_s *fps; struct fcoe_percpu_s *fps;
...@@ -1393,7 +1402,8 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, ...@@ -1393,7 +1402,8 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
unsigned int cpu; unsigned int cpu;
fcoe = container_of(ptype, struct fcoe_interface, fcoe_packet_type); fcoe = container_of(ptype, struct fcoe_interface, fcoe_packet_type);
lport = fcoe->ctlr.lp; ctlr = fcoe_to_ctlr(fcoe);
lport = ctlr->lp;
if (unlikely(!lport)) { if (unlikely(!lport)) {
FCOE_NETDEV_DBG(netdev, "Cannot find hba structure"); FCOE_NETDEV_DBG(netdev, "Cannot find hba structure");
goto err2; goto err2;
...@@ -1409,8 +1419,8 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, ...@@ -1409,8 +1419,8 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
eh = eth_hdr(skb); eh = eth_hdr(skb);
if (is_fip_mode(&fcoe->ctlr) && if (is_fip_mode(ctlr) &&
compare_ether_addr(eh->h_source, fcoe->ctlr.dest_addr)) { compare_ether_addr(eh->h_source, ctlr->dest_addr)) {
FCOE_NETDEV_DBG(netdev, "wrong source mac address:%pM\n", FCOE_NETDEV_DBG(netdev, "wrong source mac address:%pM\n",
eh->h_source); eh->h_source);
goto err; goto err;
...@@ -1544,6 +1554,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) ...@@ -1544,6 +1554,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
unsigned int elen; /* eth header, may include vlan */ unsigned int elen; /* eth header, may include vlan */
struct fcoe_port *port = lport_priv(lport); struct fcoe_port *port = lport_priv(lport);
struct fcoe_interface *fcoe = port->priv; struct fcoe_interface *fcoe = port->priv;
struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
u8 sof, eof; u8 sof, eof;
struct fcoe_hdr *hp; struct fcoe_hdr *hp;
...@@ -1559,7 +1570,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) ...@@ -1559,7 +1570,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
} }
if (unlikely(fh->fh_type == FC_TYPE_ELS) && if (unlikely(fh->fh_type == FC_TYPE_ELS) &&
fcoe_ctlr_els_send(&fcoe->ctlr, lport, skb)) fcoe_ctlr_els_send(ctlr, lport, skb))
return 0; return 0;
sof = fr_sof(fp); sof = fr_sof(fp);
...@@ -1623,12 +1634,12 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) ...@@ -1623,12 +1634,12 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
/* fill up mac and fcoe headers */ /* fill up mac and fcoe headers */
eh = eth_hdr(skb); eh = eth_hdr(skb);
eh->h_proto = htons(ETH_P_FCOE); eh->h_proto = htons(ETH_P_FCOE);
memcpy(eh->h_dest, fcoe->ctlr.dest_addr, ETH_ALEN); memcpy(eh->h_dest, ctlr->dest_addr, ETH_ALEN);
if (fcoe->ctlr.map_dest) if (ctlr->map_dest)
memcpy(eh->h_dest + 3, fh->fh_d_id, 3); memcpy(eh->h_dest + 3, fh->fh_d_id, 3);
if (unlikely(fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN)) if (unlikely(ctlr->flogi_oxid != FC_XID_UNKNOWN))
memcpy(eh->h_source, fcoe->ctlr.ctl_src_addr, ETH_ALEN); memcpy(eh->h_source, ctlr->ctl_src_addr, ETH_ALEN);
else else
memcpy(eh->h_source, port->data_src_addr, ETH_ALEN); memcpy(eh->h_source, port->data_src_addr, ETH_ALEN);
...@@ -1677,6 +1688,7 @@ static void fcoe_percpu_flush_done(struct sk_buff *skb) ...@@ -1677,6 +1688,7 @@ static void fcoe_percpu_flush_done(struct sk_buff *skb)
static inline int fcoe_filter_frames(struct fc_lport *lport, static inline int fcoe_filter_frames(struct fc_lport *lport,
struct fc_frame *fp) struct fc_frame *fp)
{ {
struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
struct fc_frame_header *fh; struct fc_frame_header *fh;
struct sk_buff *skb = (struct sk_buff *)fp; struct sk_buff *skb = (struct sk_buff *)fp;
...@@ -1698,7 +1710,8 @@ static inline int fcoe_filter_frames(struct fc_lport *lport, ...@@ -1698,7 +1710,8 @@ static inline int fcoe_filter_frames(struct fc_lport *lport,
return 0; return 0;
fcoe = ((struct fcoe_port *)lport_priv(lport))->priv; fcoe = ((struct fcoe_port *)lport_priv(lport))->priv;
if (is_fip_mode(&fcoe->ctlr) && fc_frame_payload_op(fp) == ELS_LOGO && ctlr = fcoe_to_ctlr(fcoe);
if (is_fip_mode(ctlr) && fc_frame_payload_op(fp) == ELS_LOGO &&
ntoh24(fh->fh_s_id) == FC_FID_FLOGI) { ntoh24(fh->fh_s_id) == FC_FID_FLOGI) {
FCOE_DBG("fcoe: dropping FCoE lport LOGO in fip mode\n"); FCOE_DBG("fcoe: dropping FCoE lport LOGO in fip mode\n");
return -EINVAL; return -EINVAL;
...@@ -1877,6 +1890,7 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier, ...@@ -1877,6 +1890,7 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier,
ulong event, void *ptr) ulong event, void *ptr)
{ {
struct dcb_app_type *entry = ptr; struct dcb_app_type *entry = ptr;
struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
struct net_device *netdev; struct net_device *netdev;
struct fcoe_port *port; struct fcoe_port *port;
...@@ -1894,6 +1908,8 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier, ...@@ -1894,6 +1908,8 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier,
if (!fcoe) if (!fcoe)
return NOTIFY_OK; return NOTIFY_OK;
ctlr = fcoe_to_ctlr(fcoe);
if (entry->dcbx & DCB_CAP_DCBX_VER_CEE) if (entry->dcbx & DCB_CAP_DCBX_VER_CEE)
prio = ffs(entry->app.priority) - 1; prio = ffs(entry->app.priority) - 1;
else else
...@@ -1904,10 +1920,10 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier, ...@@ -1904,10 +1920,10 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier,
if (entry->app.protocol == ETH_P_FIP || if (entry->app.protocol == ETH_P_FIP ||
entry->app.protocol == ETH_P_FCOE) entry->app.protocol == ETH_P_FCOE)
fcoe->ctlr.priority = prio; ctlr->priority = prio;
if (entry->app.protocol == ETH_P_FCOE) { if (entry->app.protocol == ETH_P_FCOE) {
port = lport_priv(fcoe->ctlr.lp); port = lport_priv(ctlr->lp);
port->priority = prio; port->priority = prio;
} }
...@@ -1929,6 +1945,7 @@ static int fcoe_device_notification(struct notifier_block *notifier, ...@@ -1929,6 +1945,7 @@ static int fcoe_device_notification(struct notifier_block *notifier,
{ {
struct fc_lport *lport = NULL; struct fc_lport *lport = NULL;
struct net_device *netdev = ptr; struct net_device *netdev = ptr;
struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
struct fcoe_port *port; struct fcoe_port *port;
struct fcoe_dev_stats *stats; struct fcoe_dev_stats *stats;
...@@ -1938,7 +1955,8 @@ static int fcoe_device_notification(struct notifier_block *notifier, ...@@ -1938,7 +1955,8 @@ static int fcoe_device_notification(struct notifier_block *notifier,
list_for_each_entry(fcoe, &fcoe_hostlist, list) { list_for_each_entry(fcoe, &fcoe_hostlist, list) {
if (fcoe->netdev == netdev) { if (fcoe->netdev == netdev) {
lport = fcoe->ctlr.lp; ctlr = fcoe_to_ctlr(fcoe);
lport = ctlr->lp;
break; break;
} }
} }
...@@ -1967,7 +1985,7 @@ static int fcoe_device_notification(struct notifier_block *notifier, ...@@ -1967,7 +1985,7 @@ static int fcoe_device_notification(struct notifier_block *notifier,
break; break;
case NETDEV_UNREGISTER: case NETDEV_UNREGISTER:
list_del(&fcoe->list); list_del(&fcoe->list);
port = lport_priv(fcoe->ctlr.lp); port = lport_priv(ctlr->lp);
queue_work(fcoe_wq, &port->destroy_work); queue_work(fcoe_wq, &port->destroy_work);
goto out; goto out;
break; break;
...@@ -1982,8 +2000,8 @@ static int fcoe_device_notification(struct notifier_block *notifier, ...@@ -1982,8 +2000,8 @@ static int fcoe_device_notification(struct notifier_block *notifier,
fcoe_link_speed_update(lport); fcoe_link_speed_update(lport);
if (link_possible && !fcoe_link_ok(lport)) if (link_possible && !fcoe_link_ok(lport))
fcoe_ctlr_link_up(&fcoe->ctlr); fcoe_ctlr_link_up(ctlr);
else if (fcoe_ctlr_link_down(&fcoe->ctlr)) { else if (fcoe_ctlr_link_down(ctlr)) {
stats = per_cpu_ptr(lport->dev_stats, get_cpu()); stats = per_cpu_ptr(lport->dev_stats, get_cpu());
stats->LinkFailureCount++; stats->LinkFailureCount++;
put_cpu(); put_cpu();
...@@ -2003,6 +2021,7 @@ static int fcoe_device_notification(struct notifier_block *notifier, ...@@ -2003,6 +2021,7 @@ static int fcoe_device_notification(struct notifier_block *notifier,
*/ */
static int fcoe_disable(struct net_device *netdev) static int fcoe_disable(struct net_device *netdev)
{ {
struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
int rc = 0; int rc = 0;
...@@ -2013,8 +2032,9 @@ static int fcoe_disable(struct net_device *netdev) ...@@ -2013,8 +2032,9 @@ static int fcoe_disable(struct net_device *netdev)
rtnl_unlock(); rtnl_unlock();
if (fcoe) { if (fcoe) {
fcoe_ctlr_link_down(&fcoe->ctlr); ctlr = fcoe_to_ctlr(fcoe);
fcoe_clean_pending_queue(fcoe->ctlr.lp); fcoe_ctlr_link_down(ctlr);
fcoe_clean_pending_queue(ctlr->lp);
} else } else
rc = -ENODEV; rc = -ENODEV;
...@@ -2032,6 +2052,7 @@ static int fcoe_disable(struct net_device *netdev) ...@@ -2032,6 +2052,7 @@ static int fcoe_disable(struct net_device *netdev)
*/ */
static int fcoe_enable(struct net_device *netdev) static int fcoe_enable(struct net_device *netdev)
{ {
struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
int rc = 0; int rc = 0;
...@@ -2040,11 +2061,17 @@ static int fcoe_enable(struct net_device *netdev) ...@@ -2040,11 +2061,17 @@ static int fcoe_enable(struct net_device *netdev)
fcoe = fcoe_hostlist_lookup_port(netdev); fcoe = fcoe_hostlist_lookup_port(netdev);
rtnl_unlock(); rtnl_unlock();
if (!fcoe) if (!fcoe) {
rc = -ENODEV; rc = -ENODEV;
else if (!fcoe_link_ok(fcoe->ctlr.lp)) goto out;
fcoe_ctlr_link_up(&fcoe->ctlr); }
ctlr = fcoe_to_ctlr(fcoe);
if (!fcoe_link_ok(ctlr->lp))
fcoe_ctlr_link_up(ctlr);
out:
mutex_unlock(&fcoe_config_mutex); mutex_unlock(&fcoe_config_mutex);
return rc; return rc;
} }
...@@ -2059,6 +2086,7 @@ static int fcoe_enable(struct net_device *netdev) ...@@ -2059,6 +2086,7 @@ static int fcoe_enable(struct net_device *netdev)
*/ */
static int fcoe_destroy(struct net_device *netdev) static int fcoe_destroy(struct net_device *netdev)
{ {
struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
struct fc_lport *lport; struct fc_lport *lport;
struct fcoe_port *port; struct fcoe_port *port;
...@@ -2071,7 +2099,8 @@ static int fcoe_destroy(struct net_device *netdev) ...@@ -2071,7 +2099,8 @@ static int fcoe_destroy(struct net_device *netdev)
rc = -ENODEV; rc = -ENODEV;
goto out_nodev; goto out_nodev;
} }
lport = fcoe->ctlr.lp; ctlr = fcoe_to_ctlr(fcoe);
lport = ctlr->lp;
port = lport_priv(lport); port = lport_priv(lport);
list_del(&fcoe->list); list_del(&fcoe->list);
queue_work(fcoe_wq, &port->destroy_work); queue_work(fcoe_wq, &port->destroy_work);
...@@ -2126,7 +2155,8 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe) ...@@ -2126,7 +2155,8 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
int dcbx; int dcbx;
u8 fup, up; u8 fup, up;
struct net_device *netdev = fcoe->realdev; struct net_device *netdev = fcoe->realdev;
struct fcoe_port *port = lport_priv(fcoe->ctlr.lp); struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
struct fcoe_port *port = lport_priv(ctlr->lp);
struct dcb_app app = { struct dcb_app app = {
.priority = 0, .priority = 0,
.protocol = ETH_P_FCOE .protocol = ETH_P_FCOE
...@@ -2149,7 +2179,7 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe) ...@@ -2149,7 +2179,7 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
} }
port->priority = ffs(up) ? ffs(up) - 1 : 0; port->priority = ffs(up) ? ffs(up) - 1 : 0;
fcoe->ctlr.priority = ffs(fup) ? ffs(fup) - 1 : port->priority; ctlr->priority = ffs(fup) ? ffs(fup) - 1 : port->priority;
} }
#endif #endif
} }
...@@ -2166,6 +2196,7 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe) ...@@ -2166,6 +2196,7 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
{ {
int rc = 0; int rc = 0;
struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
struct fc_lport *lport; struct fc_lport *lport;
...@@ -2184,6 +2215,8 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) ...@@ -2184,6 +2215,8 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
goto out_nodev; goto out_nodev;
} }
ctlr = fcoe_to_ctlr(fcoe);
lport = fcoe_if_create(fcoe, &netdev->dev, 0); lport = fcoe_if_create(fcoe, &netdev->dev, 0);
if (IS_ERR(lport)) { if (IS_ERR(lport)) {
printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
...@@ -2195,7 +2228,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) ...@@ -2195,7 +2228,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
} }
/* Make this the "master" N_Port */ /* Make this the "master" N_Port */
fcoe->ctlr.lp = lport; ctlr->lp = lport;
/* setup DCB priority attributes. */ /* setup DCB priority attributes. */
fcoe_dcb_create(fcoe); fcoe_dcb_create(fcoe);
...@@ -2208,7 +2241,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) ...@@ -2208,7 +2241,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
fc_fabric_login(lport); fc_fabric_login(lport);
if (!fcoe_link_ok(lport)) { if (!fcoe_link_ok(lport)) {
rtnl_unlock(); rtnl_unlock();
fcoe_ctlr_link_up(&fcoe->ctlr); fcoe_ctlr_link_up(ctlr);
mutex_unlock(&fcoe_config_mutex); mutex_unlock(&fcoe_config_mutex);
return rc; return rc;
} }
...@@ -2320,11 +2353,12 @@ static int fcoe_reset(struct Scsi_Host *shost) ...@@ -2320,11 +2353,12 @@ static int fcoe_reset(struct Scsi_Host *shost)
struct fc_lport *lport = shost_priv(shost); struct fc_lport *lport = shost_priv(shost);
struct fcoe_port *port = lport_priv(lport); struct fcoe_port *port = lport_priv(lport);
struct fcoe_interface *fcoe = port->priv; struct fcoe_interface *fcoe = port->priv;
struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
fcoe_ctlr_link_down(&fcoe->ctlr); fcoe_ctlr_link_down(ctlr);
fcoe_clean_pending_queue(fcoe->ctlr.lp); fcoe_clean_pending_queue(ctlr->lp);
if (!fcoe_link_ok(fcoe->ctlr.lp)) if (!fcoe_link_ok(ctlr->lp))
fcoe_ctlr_link_up(&fcoe->ctlr); fcoe_ctlr_link_up(ctlr);
return 0; return 0;
} }
...@@ -2359,10 +2393,12 @@ fcoe_hostlist_lookup_port(const struct net_device *netdev) ...@@ -2359,10 +2393,12 @@ fcoe_hostlist_lookup_port(const struct net_device *netdev)
*/ */
static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
{ {
struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
fcoe = fcoe_hostlist_lookup_port(netdev); fcoe = fcoe_hostlist_lookup_port(netdev);
return (fcoe) ? fcoe->ctlr.lp : NULL; ctlr = fcoe_to_ctlr(fcoe);
return (fcoe) ? ctlr->lp : NULL;
} }
/** /**
...@@ -2466,6 +2502,7 @@ module_init(fcoe_init); ...@@ -2466,6 +2502,7 @@ module_init(fcoe_init);
static void __exit fcoe_exit(void) static void __exit fcoe_exit(void)
{ {
struct fcoe_interface *fcoe, *tmp; struct fcoe_interface *fcoe, *tmp;
struct fcoe_ctlr *ctlr;
struct fcoe_port *port; struct fcoe_port *port;
unsigned int cpu; unsigned int cpu;
...@@ -2477,7 +2514,8 @@ static void __exit fcoe_exit(void) ...@@ -2477,7 +2514,8 @@ static void __exit fcoe_exit(void)
rtnl_lock(); rtnl_lock();
list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) { list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) {
list_del(&fcoe->list); list_del(&fcoe->list);
port = lport_priv(fcoe->ctlr.lp); ctlr = fcoe_to_ctlr(fcoe);
port = lport_priv(ctlr->lp);
queue_work(fcoe_wq, &port->destroy_work); queue_work(fcoe_wq, &port->destroy_work);
} }
rtnl_unlock(); rtnl_unlock();
...@@ -2573,7 +2611,7 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did, ...@@ -2573,7 +2611,7 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did,
{ {
struct fcoe_port *port = lport_priv(lport); struct fcoe_port *port = lport_priv(lport);
struct fcoe_interface *fcoe = port->priv; struct fcoe_interface *fcoe = port->priv;
struct fcoe_ctlr *fip = &fcoe->ctlr; struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe);
struct fc_frame_header *fh = fc_frame_header_get(fp); struct fc_frame_header *fh = fc_frame_header_get(fp);
switch (op) { switch (op) {
...@@ -2747,7 +2785,8 @@ static void fcoe_set_port_id(struct fc_lport *lport, ...@@ -2747,7 +2785,8 @@ static void fcoe_set_port_id(struct fc_lport *lport,
{ {
struct fcoe_port *port = lport_priv(lport); struct fcoe_port *port = lport_priv(lport);
struct fcoe_interface *fcoe = port->priv; struct fcoe_interface *fcoe = port->priv;
struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
if (fp && fc_frame_payload_op(fp) == ELS_FLOGI) if (fp && fc_frame_payload_op(fp) == ELS_FLOGI)
fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp); fcoe_ctlr_recv_flogi(ctlr, lport, fp);
} }
...@@ -68,7 +68,6 @@ do { \ ...@@ -68,7 +68,6 @@ do { \
* @netdev: The associated net device * @netdev: The associated net device
* @fcoe_packet_type: FCoE packet type * @fcoe_packet_type: FCoE packet type
* @fip_packet_type: FIP packet type * @fip_packet_type: FIP packet type
* @ctlr: The FCoE controller (for FIP)
* @oem: The offload exchange manager for all local port * @oem: The offload exchange manager for all local port
* instances associated with this port * instances associated with this port
* @removed: Indicates fcoe interface removed from net device * @removed: Indicates fcoe interface removed from net device
...@@ -80,12 +79,15 @@ struct fcoe_interface { ...@@ -80,12 +79,15 @@ struct fcoe_interface {
struct net_device *realdev; struct net_device *realdev;
struct packet_type fcoe_packet_type; struct packet_type fcoe_packet_type;
struct packet_type fip_packet_type; struct packet_type fip_packet_type;
struct fcoe_ctlr ctlr;
struct fc_exch_mgr *oem; struct fc_exch_mgr *oem;
u8 removed; u8 removed;
}; };
#define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr) #define fcoe_to_ctlr(x) \
(struct fcoe_ctlr *)(((struct fcoe_ctlr *)(x)) - 1)
#define fcoe_from_ctlr(x) \
((struct fcoe_interface *)((x) + 1))
/** /**
* fcoe_netdev() - Return the net device associated with a local port * fcoe_netdev() - Return the net device associated with a local port
......
...@@ -158,6 +158,15 @@ struct fcoe_ctlr { ...@@ -158,6 +158,15 @@ struct fcoe_ctlr {
spinlock_t ctlr_lock; spinlock_t ctlr_lock;
}; };
/**
* fcoe_ctlr_priv() - Return the private data from a fcoe_ctlr
* @cltr: The fcoe_ctlr whose private data will be returned
*/
static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr)
{
return (void *)(ctlr + 1);
}
/** /**
* struct fcoe_fcf - Fibre-Channel Forwarder * struct fcoe_fcf - Fibre-Channel Forwarder
* @list: list linkage * @list: list linkage
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment