diff options
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 137 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe.h | 8 | ||||
-rw-r--r-- | include/scsi/libfcoe.h | 9 |
3 files changed, 102 insertions, 52 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 76e3d0b5bfa6..4bb42e19d537 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -282,7 +282,7 @@ static struct scsi_host_template fcoe_shost_template = { | |||
282 | static int fcoe_interface_setup(struct fcoe_interface *fcoe, | 282 | static int fcoe_interface_setup(struct fcoe_interface *fcoe, |
283 | struct net_device *netdev) | 283 | struct net_device *netdev) |
284 | { | 284 | { |
285 | struct fcoe_ctlr *fip = &fcoe->ctlr; | 285 | struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); |
286 | struct netdev_hw_addr *ha; | 286 | struct netdev_hw_addr *ha; |
287 | struct net_device *real_dev; | 287 | struct net_device *real_dev; |
288 | u8 flogi_maddr[ETH_ALEN]; | 288 | u8 flogi_maddr[ETH_ALEN]; |
@@ -366,7 +366,9 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe, | |||
366 | static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, | 366 | static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, |
367 | enum fip_state fip_mode) | 367 | enum fip_state fip_mode) |
368 | { | 368 | { |
369 | struct fcoe_ctlr *ctlr; | ||
369 | struct fcoe_interface *fcoe; | 370 | struct fcoe_interface *fcoe; |
371 | int size; | ||
370 | int err; | 372 | int err; |
371 | 373 | ||
372 | if (!try_module_get(THIS_MODULE)) { | 374 | if (!try_module_get(THIS_MODULE)) { |
@@ -376,7 +378,9 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, | |||
376 | goto out; | 378 | goto out; |
377 | } | 379 | } |
378 | 380 | ||
379 | fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL); | 381 | size = sizeof(struct fcoe_ctlr) + sizeof(struct fcoe_interface); |
382 | ctlr = kzalloc(size, GFP_KERNEL); | ||
383 | fcoe = fcoe_ctlr_priv(ctlr); | ||
380 | if (!fcoe) { | 384 | if (!fcoe) { |
381 | FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); | 385 | FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); |
382 | fcoe = ERR_PTR(-ENOMEM); | 386 | fcoe = ERR_PTR(-ENOMEM); |
@@ -388,15 +392,14 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, | |||
388 | /* | 392 | /* |
389 | * Initialize FIP. | 393 | * Initialize FIP. |
390 | */ | 394 | */ |
391 | fcoe_ctlr_init(&fcoe->ctlr, fip_mode); | 395 | fcoe_ctlr_init(ctlr, fip_mode); |
392 | fcoe->ctlr.send = fcoe_fip_send; | 396 | ctlr->send = fcoe_fip_send; |
393 | fcoe->ctlr.update_mac = fcoe_update_src_mac; | 397 | ctlr->update_mac = fcoe_update_src_mac; |
394 | fcoe->ctlr.get_src_addr = fcoe_get_src_mac; | 398 | ctlr->get_src_addr = fcoe_get_src_mac; |
395 | 399 | ||
396 | err = fcoe_interface_setup(fcoe, netdev); | 400 | err = fcoe_interface_setup(fcoe, netdev); |
397 | if (err) { | 401 | if (err) { |
398 | fcoe_ctlr_destroy(&fcoe->ctlr); | 402 | fcoe_ctlr_destroy(ctlr); |
399 | kfree(fcoe); | ||
400 | dev_put(netdev); | 403 | dev_put(netdev); |
401 | fcoe = ERR_PTR(err); | 404 | fcoe = ERR_PTR(err); |
402 | goto out_putmod; | 405 | goto out_putmod; |
@@ -419,7 +422,7 @@ out: | |||
419 | static void fcoe_interface_remove(struct fcoe_interface *fcoe) | 422 | static void fcoe_interface_remove(struct fcoe_interface *fcoe) |
420 | { | 423 | { |
421 | struct net_device *netdev = fcoe->netdev; | 424 | struct net_device *netdev = fcoe->netdev; |
422 | struct fcoe_ctlr *fip = &fcoe->ctlr; | 425 | struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); |
423 | u8 flogi_maddr[ETH_ALEN]; | 426 | u8 flogi_maddr[ETH_ALEN]; |
424 | const struct net_device_ops *ops; | 427 | const struct net_device_ops *ops; |
425 | 428 | ||
@@ -462,7 +465,7 @@ static void fcoe_interface_remove(struct fcoe_interface *fcoe) | |||
462 | static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) | 465 | static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) |
463 | { | 466 | { |
464 | struct net_device *netdev = fcoe->netdev; | 467 | struct net_device *netdev = fcoe->netdev; |
465 | struct fcoe_ctlr *fip = &fcoe->ctlr; | 468 | struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); |
466 | 469 | ||
467 | rtnl_lock(); | 470 | rtnl_lock(); |
468 | if (!fcoe->removed) | 471 | if (!fcoe->removed) |
@@ -472,8 +475,8 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) | |||
472 | /* Release the self-reference taken during fcoe_interface_create() */ | 475 | /* Release the self-reference taken during fcoe_interface_create() */ |
473 | /* tear-down the FCoE controller */ | 476 | /* tear-down the FCoE controller */ |
474 | fcoe_ctlr_destroy(fip); | 477 | fcoe_ctlr_destroy(fip); |
475 | scsi_host_put(fcoe->ctlr.lp->host); | 478 | scsi_host_put(fip->lp->host); |
476 | kfree(fcoe); | 479 | kfree(fip); |
477 | dev_put(netdev); | 480 | dev_put(netdev); |
478 | module_put(THIS_MODULE); | 481 | module_put(THIS_MODULE); |
479 | } | 482 | } |
@@ -493,9 +496,11 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *netdev, | |||
493 | struct net_device *orig_dev) | 496 | struct net_device *orig_dev) |
494 | { | 497 | { |
495 | struct fcoe_interface *fcoe; | 498 | struct fcoe_interface *fcoe; |
499 | struct fcoe_ctlr *ctlr; | ||
496 | 500 | ||
497 | fcoe = container_of(ptype, struct fcoe_interface, fip_packet_type); | 501 | fcoe = container_of(ptype, struct fcoe_interface, fip_packet_type); |
498 | fcoe_ctlr_recv(&fcoe->ctlr, skb); | 502 | ctlr = fcoe_to_ctlr(fcoe); |
503 | fcoe_ctlr_recv(ctlr, skb); | ||
499 | return 0; | 504 | return 0; |
500 | } | 505 | } |
501 | 506 | ||
@@ -645,11 +650,13 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev) | |||
645 | u32 mfs; | 650 | u32 mfs; |
646 | u64 wwnn, wwpn; | 651 | u64 wwnn, wwpn; |
647 | struct fcoe_interface *fcoe; | 652 | struct fcoe_interface *fcoe; |
653 | struct fcoe_ctlr *ctlr; | ||
648 | struct fcoe_port *port; | 654 | struct fcoe_port *port; |
649 | 655 | ||
650 | /* Setup lport private data to point to fcoe softc */ | 656 | /* Setup lport private data to point to fcoe softc */ |
651 | port = lport_priv(lport); | 657 | port = lport_priv(lport); |
652 | fcoe = port->priv; | 658 | fcoe = port->priv; |
659 | ctlr = fcoe_to_ctlr(fcoe); | ||
653 | 660 | ||
654 | /* | 661 | /* |
655 | * Determine max frame size based on underlying device and optional | 662 | * 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 | 683 | ||
677 | if (!lport->vport) { | 684 | if (!lport->vport) { |
678 | if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN)) | 685 | if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN)) |
679 | wwnn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 1, 0); | 686 | wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, 1, 0); |
680 | fc_set_wwnn(lport, wwnn); | 687 | fc_set_wwnn(lport, wwnn); |
681 | if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN)) | 688 | if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN)) |
682 | wwpn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, | 689 | wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, |
683 | 2, 0); | 690 | 2, 0); |
684 | fc_set_wwpn(lport, wwpn); | 691 | fc_set_wwpn(lport, wwpn); |
685 | } | 692 | } |
@@ -1056,6 +1063,7 @@ static int fcoe_ddp_done(struct fc_lport *lport, u16 xid) | |||
1056 | static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, | 1063 | static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, |
1057 | struct device *parent, int npiv) | 1064 | struct device *parent, int npiv) |
1058 | { | 1065 | { |
1066 | struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); | ||
1059 | struct net_device *netdev = fcoe->netdev; | 1067 | struct net_device *netdev = fcoe->netdev; |
1060 | struct fc_lport *lport, *n_port; | 1068 | struct fc_lport *lport, *n_port; |
1061 | struct fcoe_port *port; | 1069 | struct fcoe_port *port; |
@@ -1119,7 +1127,7 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, | |||
1119 | } | 1127 | } |
1120 | 1128 | ||
1121 | /* Initialize the library */ | 1129 | /* Initialize the library */ |
1122 | rc = fcoe_libfc_config(lport, &fcoe->ctlr, &fcoe_libfc_fcn_templ, 1); | 1130 | rc = fcoe_libfc_config(lport, ctlr, &fcoe_libfc_fcn_templ, 1); |
1123 | if (rc) { | 1131 | if (rc) { |
1124 | FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the " | 1132 | FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the " |
1125 | "interface\n"); | 1133 | "interface\n"); |
@@ -1386,6 +1394,7 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, | |||
1386 | { | 1394 | { |
1387 | struct fc_lport *lport; | 1395 | struct fc_lport *lport; |
1388 | struct fcoe_rcv_info *fr; | 1396 | struct fcoe_rcv_info *fr; |
1397 | struct fcoe_ctlr *ctlr; | ||
1389 | struct fcoe_interface *fcoe; | 1398 | struct fcoe_interface *fcoe; |
1390 | struct fc_frame_header *fh; | 1399 | struct fc_frame_header *fh; |
1391 | struct fcoe_percpu_s *fps; | 1400 | struct fcoe_percpu_s *fps; |
@@ -1393,7 +1402,8 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, | |||
1393 | unsigned int cpu; | 1402 | unsigned int cpu; |
1394 | 1403 | ||
1395 | fcoe = container_of(ptype, struct fcoe_interface, fcoe_packet_type); | 1404 | fcoe = container_of(ptype, struct fcoe_interface, fcoe_packet_type); |
1396 | lport = fcoe->ctlr.lp; | 1405 | ctlr = fcoe_to_ctlr(fcoe); |
1406 | lport = ctlr->lp; | ||
1397 | if (unlikely(!lport)) { | 1407 | if (unlikely(!lport)) { |
1398 | FCOE_NETDEV_DBG(netdev, "Cannot find hba structure"); | 1408 | FCOE_NETDEV_DBG(netdev, "Cannot find hba structure"); |
1399 | goto err2; | 1409 | goto err2; |
@@ -1409,8 +1419,8 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, | |||
1409 | 1419 | ||
1410 | eh = eth_hdr(skb); | 1420 | eh = eth_hdr(skb); |
1411 | 1421 | ||
1412 | if (is_fip_mode(&fcoe->ctlr) && | 1422 | if (is_fip_mode(ctlr) && |
1413 | compare_ether_addr(eh->h_source, fcoe->ctlr.dest_addr)) { | 1423 | compare_ether_addr(eh->h_source, ctlr->dest_addr)) { |
1414 | FCOE_NETDEV_DBG(netdev, "wrong source mac address:%pM\n", | 1424 | FCOE_NETDEV_DBG(netdev, "wrong source mac address:%pM\n", |
1415 | eh->h_source); | 1425 | eh->h_source); |
1416 | goto err; | 1426 | goto err; |
@@ -1544,6 +1554,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) | |||
1544 | unsigned int elen; /* eth header, may include vlan */ | 1554 | unsigned int elen; /* eth header, may include vlan */ |
1545 | struct fcoe_port *port = lport_priv(lport); | 1555 | struct fcoe_port *port = lport_priv(lport); |
1546 | struct fcoe_interface *fcoe = port->priv; | 1556 | struct fcoe_interface *fcoe = port->priv; |
1557 | struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); | ||
1547 | u8 sof, eof; | 1558 | u8 sof, eof; |
1548 | struct fcoe_hdr *hp; | 1559 | struct fcoe_hdr *hp; |
1549 | 1560 | ||
@@ -1559,7 +1570,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) | |||
1559 | } | 1570 | } |
1560 | 1571 | ||
1561 | if (unlikely(fh->fh_type == FC_TYPE_ELS) && | 1572 | if (unlikely(fh->fh_type == FC_TYPE_ELS) && |
1562 | fcoe_ctlr_els_send(&fcoe->ctlr, lport, skb)) | 1573 | fcoe_ctlr_els_send(ctlr, lport, skb)) |
1563 | return 0; | 1574 | return 0; |
1564 | 1575 | ||
1565 | sof = fr_sof(fp); | 1576 | sof = fr_sof(fp); |
@@ -1623,12 +1634,12 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) | |||
1623 | /* fill up mac and fcoe headers */ | 1634 | /* fill up mac and fcoe headers */ |
1624 | eh = eth_hdr(skb); | 1635 | eh = eth_hdr(skb); |
1625 | eh->h_proto = htons(ETH_P_FCOE); | 1636 | eh->h_proto = htons(ETH_P_FCOE); |
1626 | memcpy(eh->h_dest, fcoe->ctlr.dest_addr, ETH_ALEN); | 1637 | memcpy(eh->h_dest, ctlr->dest_addr, ETH_ALEN); |
1627 | if (fcoe->ctlr.map_dest) | 1638 | if (ctlr->map_dest) |
1628 | memcpy(eh->h_dest + 3, fh->fh_d_id, 3); | 1639 | memcpy(eh->h_dest + 3, fh->fh_d_id, 3); |
1629 | 1640 | ||
1630 | if (unlikely(fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN)) | 1641 | if (unlikely(ctlr->flogi_oxid != FC_XID_UNKNOWN)) |
1631 | memcpy(eh->h_source, fcoe->ctlr.ctl_src_addr, ETH_ALEN); | 1642 | memcpy(eh->h_source, ctlr->ctl_src_addr, ETH_ALEN); |
1632 | else | 1643 | else |
1633 | memcpy(eh->h_source, port->data_src_addr, ETH_ALEN); | 1644 | memcpy(eh->h_source, port->data_src_addr, ETH_ALEN); |
1634 | 1645 | ||
@@ -1677,6 +1688,7 @@ static void fcoe_percpu_flush_done(struct sk_buff *skb) | |||
1677 | static inline int fcoe_filter_frames(struct fc_lport *lport, | 1688 | static inline int fcoe_filter_frames(struct fc_lport *lport, |
1678 | struct fc_frame *fp) | 1689 | struct fc_frame *fp) |
1679 | { | 1690 | { |
1691 | struct fcoe_ctlr *ctlr; | ||
1680 | struct fcoe_interface *fcoe; | 1692 | struct fcoe_interface *fcoe; |
1681 | struct fc_frame_header *fh; | 1693 | struct fc_frame_header *fh; |
1682 | struct sk_buff *skb = (struct sk_buff *)fp; | 1694 | struct sk_buff *skb = (struct sk_buff *)fp; |
@@ -1698,7 +1710,8 @@ static inline int fcoe_filter_frames(struct fc_lport *lport, | |||
1698 | return 0; | 1710 | return 0; |
1699 | 1711 | ||
1700 | fcoe = ((struct fcoe_port *)lport_priv(lport))->priv; | 1712 | fcoe = ((struct fcoe_port *)lport_priv(lport))->priv; |
1701 | if (is_fip_mode(&fcoe->ctlr) && fc_frame_payload_op(fp) == ELS_LOGO && | 1713 | ctlr = fcoe_to_ctlr(fcoe); |
1714 | if (is_fip_mode(ctlr) && fc_frame_payload_op(fp) == ELS_LOGO && | ||
1702 | ntoh24(fh->fh_s_id) == FC_FID_FLOGI) { | 1715 | ntoh24(fh->fh_s_id) == FC_FID_FLOGI) { |
1703 | FCOE_DBG("fcoe: dropping FCoE lport LOGO in fip mode\n"); | 1716 | FCOE_DBG("fcoe: dropping FCoE lport LOGO in fip mode\n"); |
1704 | return -EINVAL; | 1717 | return -EINVAL; |
@@ -1877,6 +1890,7 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier, | |||
1877 | ulong event, void *ptr) | 1890 | ulong event, void *ptr) |
1878 | { | 1891 | { |
1879 | struct dcb_app_type *entry = ptr; | 1892 | struct dcb_app_type *entry = ptr; |
1893 | struct fcoe_ctlr *ctlr; | ||
1880 | struct fcoe_interface *fcoe; | 1894 | struct fcoe_interface *fcoe; |
1881 | struct net_device *netdev; | 1895 | struct net_device *netdev; |
1882 | struct fcoe_port *port; | 1896 | struct fcoe_port *port; |
@@ -1894,6 +1908,8 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier, | |||
1894 | if (!fcoe) | 1908 | if (!fcoe) |
1895 | return NOTIFY_OK; | 1909 | return NOTIFY_OK; |
1896 | 1910 | ||
1911 | ctlr = fcoe_to_ctlr(fcoe); | ||
1912 | |||
1897 | if (entry->dcbx & DCB_CAP_DCBX_VER_CEE) | 1913 | if (entry->dcbx & DCB_CAP_DCBX_VER_CEE) |
1898 | prio = ffs(entry->app.priority) - 1; | 1914 | prio = ffs(entry->app.priority) - 1; |
1899 | else | 1915 | else |
@@ -1904,10 +1920,10 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier, | |||
1904 | 1920 | ||
1905 | if (entry->app.protocol == ETH_P_FIP || | 1921 | if (entry->app.protocol == ETH_P_FIP || |
1906 | entry->app.protocol == ETH_P_FCOE) | 1922 | entry->app.protocol == ETH_P_FCOE) |
1907 | fcoe->ctlr.priority = prio; | 1923 | ctlr->priority = prio; |
1908 | 1924 | ||
1909 | if (entry->app.protocol == ETH_P_FCOE) { | 1925 | if (entry->app.protocol == ETH_P_FCOE) { |
1910 | port = lport_priv(fcoe->ctlr.lp); | 1926 | port = lport_priv(ctlr->lp); |
1911 | port->priority = prio; | 1927 | port->priority = prio; |
1912 | } | 1928 | } |
1913 | 1929 | ||
@@ -1929,6 +1945,7 @@ static int fcoe_device_notification(struct notifier_block *notifier, | |||
1929 | { | 1945 | { |
1930 | struct fc_lport *lport = NULL; | 1946 | struct fc_lport *lport = NULL; |
1931 | struct net_device *netdev = ptr; | 1947 | struct net_device *netdev = ptr; |
1948 | struct fcoe_ctlr *ctlr; | ||
1932 | struct fcoe_interface *fcoe; | 1949 | struct fcoe_interface *fcoe; |
1933 | struct fcoe_port *port; | 1950 | struct fcoe_port *port; |
1934 | struct fcoe_dev_stats *stats; | 1951 | struct fcoe_dev_stats *stats; |
@@ -1938,7 +1955,8 @@ static int fcoe_device_notification(struct notifier_block *notifier, | |||
1938 | 1955 | ||
1939 | list_for_each_entry(fcoe, &fcoe_hostlist, list) { | 1956 | list_for_each_entry(fcoe, &fcoe_hostlist, list) { |
1940 | if (fcoe->netdev == netdev) { | 1957 | if (fcoe->netdev == netdev) { |
1941 | lport = fcoe->ctlr.lp; | 1958 | ctlr = fcoe_to_ctlr(fcoe); |
1959 | lport = ctlr->lp; | ||
1942 | break; | 1960 | break; |
1943 | } | 1961 | } |
1944 | } | 1962 | } |
@@ -1967,7 +1985,7 @@ static int fcoe_device_notification(struct notifier_block *notifier, | |||
1967 | break; | 1985 | break; |
1968 | case NETDEV_UNREGISTER: | 1986 | case NETDEV_UNREGISTER: |
1969 | list_del(&fcoe->list); | 1987 | list_del(&fcoe->list); |
1970 | port = lport_priv(fcoe->ctlr.lp); | 1988 | port = lport_priv(ctlr->lp); |
1971 | queue_work(fcoe_wq, &port->destroy_work); | 1989 | queue_work(fcoe_wq, &port->destroy_work); |
1972 | goto out; | 1990 | goto out; |
1973 | break; | 1991 | break; |
@@ -1982,8 +2000,8 @@ static int fcoe_device_notification(struct notifier_block *notifier, | |||
1982 | fcoe_link_speed_update(lport); | 2000 | fcoe_link_speed_update(lport); |
1983 | 2001 | ||
1984 | if (link_possible && !fcoe_link_ok(lport)) | 2002 | if (link_possible && !fcoe_link_ok(lport)) |
1985 | fcoe_ctlr_link_up(&fcoe->ctlr); | 2003 | fcoe_ctlr_link_up(ctlr); |
1986 | else if (fcoe_ctlr_link_down(&fcoe->ctlr)) { | 2004 | else if (fcoe_ctlr_link_down(ctlr)) { |
1987 | stats = per_cpu_ptr(lport->dev_stats, get_cpu()); | 2005 | stats = per_cpu_ptr(lport->dev_stats, get_cpu()); |
1988 | stats->LinkFailureCount++; | 2006 | stats->LinkFailureCount++; |
1989 | put_cpu(); | 2007 | put_cpu(); |
@@ -2003,6 +2021,7 @@ out: | |||
2003 | */ | 2021 | */ |
2004 | static int fcoe_disable(struct net_device *netdev) | 2022 | static int fcoe_disable(struct net_device *netdev) |
2005 | { | 2023 | { |
2024 | struct fcoe_ctlr *ctlr; | ||
2006 | struct fcoe_interface *fcoe; | 2025 | struct fcoe_interface *fcoe; |
2007 | int rc = 0; | 2026 | int rc = 0; |
2008 | 2027 | ||
@@ -2013,8 +2032,9 @@ static int fcoe_disable(struct net_device *netdev) | |||
2013 | rtnl_unlock(); | 2032 | rtnl_unlock(); |
2014 | 2033 | ||
2015 | if (fcoe) { | 2034 | if (fcoe) { |
2016 | fcoe_ctlr_link_down(&fcoe->ctlr); | 2035 | ctlr = fcoe_to_ctlr(fcoe); |
2017 | fcoe_clean_pending_queue(fcoe->ctlr.lp); | 2036 | fcoe_ctlr_link_down(ctlr); |
2037 | fcoe_clean_pending_queue(ctlr->lp); | ||
2018 | } else | 2038 | } else |
2019 | rc = -ENODEV; | 2039 | rc = -ENODEV; |
2020 | 2040 | ||
@@ -2032,6 +2052,7 @@ static int fcoe_disable(struct net_device *netdev) | |||
2032 | */ | 2052 | */ |
2033 | static int fcoe_enable(struct net_device *netdev) | 2053 | static int fcoe_enable(struct net_device *netdev) |
2034 | { | 2054 | { |
2055 | struct fcoe_ctlr *ctlr; | ||
2035 | struct fcoe_interface *fcoe; | 2056 | struct fcoe_interface *fcoe; |
2036 | int rc = 0; | 2057 | int rc = 0; |
2037 | 2058 | ||
@@ -2040,11 +2061,17 @@ static int fcoe_enable(struct net_device *netdev) | |||
2040 | fcoe = fcoe_hostlist_lookup_port(netdev); | 2061 | fcoe = fcoe_hostlist_lookup_port(netdev); |
2041 | rtnl_unlock(); | 2062 | rtnl_unlock(); |
2042 | 2063 | ||
2043 | if (!fcoe) | 2064 | if (!fcoe) { |
2044 | rc = -ENODEV; | 2065 | rc = -ENODEV; |
2045 | else if (!fcoe_link_ok(fcoe->ctlr.lp)) | 2066 | goto out; |
2046 | fcoe_ctlr_link_up(&fcoe->ctlr); | 2067 | } |
2047 | 2068 | ||
2069 | ctlr = fcoe_to_ctlr(fcoe); | ||
2070 | |||
2071 | if (!fcoe_link_ok(ctlr->lp)) | ||
2072 | fcoe_ctlr_link_up(ctlr); | ||
2073 | |||
2074 | out: | ||
2048 | mutex_unlock(&fcoe_config_mutex); | 2075 | mutex_unlock(&fcoe_config_mutex); |
2049 | return rc; | 2076 | return rc; |
2050 | } | 2077 | } |
@@ -2059,6 +2086,7 @@ static int fcoe_enable(struct net_device *netdev) | |||
2059 | */ | 2086 | */ |
2060 | static int fcoe_destroy(struct net_device *netdev) | 2087 | static int fcoe_destroy(struct net_device *netdev) |
2061 | { | 2088 | { |
2089 | struct fcoe_ctlr *ctlr; | ||
2062 | struct fcoe_interface *fcoe; | 2090 | struct fcoe_interface *fcoe; |
2063 | struct fc_lport *lport; | 2091 | struct fc_lport *lport; |
2064 | struct fcoe_port *port; | 2092 | struct fcoe_port *port; |
@@ -2071,7 +2099,8 @@ static int fcoe_destroy(struct net_device *netdev) | |||
2071 | rc = -ENODEV; | 2099 | rc = -ENODEV; |
2072 | goto out_nodev; | 2100 | goto out_nodev; |
2073 | } | 2101 | } |
2074 | lport = fcoe->ctlr.lp; | 2102 | ctlr = fcoe_to_ctlr(fcoe); |
2103 | lport = ctlr->lp; | ||
2075 | port = lport_priv(lport); | 2104 | port = lport_priv(lport); |
2076 | list_del(&fcoe->list); | 2105 | list_del(&fcoe->list); |
2077 | queue_work(fcoe_wq, &port->destroy_work); | 2106 | queue_work(fcoe_wq, &port->destroy_work); |
@@ -2126,7 +2155,8 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe) | |||
2126 | int dcbx; | 2155 | int dcbx; |
2127 | u8 fup, up; | 2156 | u8 fup, up; |
2128 | struct net_device *netdev = fcoe->realdev; | 2157 | struct net_device *netdev = fcoe->realdev; |
2129 | struct fcoe_port *port = lport_priv(fcoe->ctlr.lp); | 2158 | struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); |
2159 | struct fcoe_port *port = lport_priv(ctlr->lp); | ||
2130 | struct dcb_app app = { | 2160 | struct dcb_app app = { |
2131 | .priority = 0, | 2161 | .priority = 0, |
2132 | .protocol = ETH_P_FCOE | 2162 | .protocol = ETH_P_FCOE |
@@ -2149,7 +2179,7 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe) | |||
2149 | } | 2179 | } |
2150 | 2180 | ||
2151 | port->priority = ffs(up) ? ffs(up) - 1 : 0; | 2181 | port->priority = ffs(up) ? ffs(up) - 1 : 0; |
2152 | fcoe->ctlr.priority = ffs(fup) ? ffs(fup) - 1 : port->priority; | 2182 | ctlr->priority = ffs(fup) ? ffs(fup) - 1 : port->priority; |
2153 | } | 2183 | } |
2154 | #endif | 2184 | #endif |
2155 | } | 2185 | } |
@@ -2166,6 +2196,7 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe) | |||
2166 | static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | 2196 | static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) |
2167 | { | 2197 | { |
2168 | int rc = 0; | 2198 | int rc = 0; |
2199 | struct fcoe_ctlr *ctlr; | ||
2169 | struct fcoe_interface *fcoe; | 2200 | struct fcoe_interface *fcoe; |
2170 | struct fc_lport *lport; | 2201 | struct fc_lport *lport; |
2171 | 2202 | ||
@@ -2184,6 +2215,8 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | |||
2184 | goto out_nodev; | 2215 | goto out_nodev; |
2185 | } | 2216 | } |
2186 | 2217 | ||
2218 | ctlr = fcoe_to_ctlr(fcoe); | ||
2219 | |||
2187 | lport = fcoe_if_create(fcoe, &netdev->dev, 0); | 2220 | lport = fcoe_if_create(fcoe, &netdev->dev, 0); |
2188 | if (IS_ERR(lport)) { | 2221 | if (IS_ERR(lport)) { |
2189 | printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", | 2222 | 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 | } | 2228 | } |
2196 | 2229 | ||
2197 | /* Make this the "master" N_Port */ | 2230 | /* Make this the "master" N_Port */ |
2198 | fcoe->ctlr.lp = lport; | 2231 | ctlr->lp = lport; |
2199 | 2232 | ||
2200 | /* setup DCB priority attributes. */ | 2233 | /* setup DCB priority attributes. */ |
2201 | fcoe_dcb_create(fcoe); | 2234 | fcoe_dcb_create(fcoe); |
@@ -2208,7 +2241,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | |||
2208 | fc_fabric_login(lport); | 2241 | fc_fabric_login(lport); |
2209 | if (!fcoe_link_ok(lport)) { | 2242 | if (!fcoe_link_ok(lport)) { |
2210 | rtnl_unlock(); | 2243 | rtnl_unlock(); |
2211 | fcoe_ctlr_link_up(&fcoe->ctlr); | 2244 | fcoe_ctlr_link_up(ctlr); |
2212 | mutex_unlock(&fcoe_config_mutex); | 2245 | mutex_unlock(&fcoe_config_mutex); |
2213 | return rc; | 2246 | return rc; |
2214 | } | 2247 | } |
@@ -2320,11 +2353,12 @@ static int fcoe_reset(struct Scsi_Host *shost) | |||
2320 | struct fc_lport *lport = shost_priv(shost); | 2353 | struct fc_lport *lport = shost_priv(shost); |
2321 | struct fcoe_port *port = lport_priv(lport); | 2354 | struct fcoe_port *port = lport_priv(lport); |
2322 | struct fcoe_interface *fcoe = port->priv; | 2355 | struct fcoe_interface *fcoe = port->priv; |
2356 | struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); | ||
2323 | 2357 | ||
2324 | fcoe_ctlr_link_down(&fcoe->ctlr); | 2358 | fcoe_ctlr_link_down(ctlr); |
2325 | fcoe_clean_pending_queue(fcoe->ctlr.lp); | 2359 | fcoe_clean_pending_queue(ctlr->lp); |
2326 | if (!fcoe_link_ok(fcoe->ctlr.lp)) | 2360 | if (!fcoe_link_ok(ctlr->lp)) |
2327 | fcoe_ctlr_link_up(&fcoe->ctlr); | 2361 | fcoe_ctlr_link_up(ctlr); |
2328 | return 0; | 2362 | return 0; |
2329 | } | 2363 | } |
2330 | 2364 | ||
@@ -2359,10 +2393,12 @@ fcoe_hostlist_lookup_port(const struct net_device *netdev) | |||
2359 | */ | 2393 | */ |
2360 | static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) | 2394 | static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) |
2361 | { | 2395 | { |
2396 | struct fcoe_ctlr *ctlr; | ||
2362 | struct fcoe_interface *fcoe; | 2397 | struct fcoe_interface *fcoe; |
2363 | 2398 | ||
2364 | fcoe = fcoe_hostlist_lookup_port(netdev); | 2399 | fcoe = fcoe_hostlist_lookup_port(netdev); |
2365 | return (fcoe) ? fcoe->ctlr.lp : NULL; | 2400 | ctlr = fcoe_to_ctlr(fcoe); |
2401 | return (fcoe) ? ctlr->lp : NULL; | ||
2366 | } | 2402 | } |
2367 | 2403 | ||
2368 | /** | 2404 | /** |
@@ -2466,6 +2502,7 @@ module_init(fcoe_init); | |||
2466 | static void __exit fcoe_exit(void) | 2502 | static void __exit fcoe_exit(void) |
2467 | { | 2503 | { |
2468 | struct fcoe_interface *fcoe, *tmp; | 2504 | struct fcoe_interface *fcoe, *tmp; |
2505 | struct fcoe_ctlr *ctlr; | ||
2469 | struct fcoe_port *port; | 2506 | struct fcoe_port *port; |
2470 | unsigned int cpu; | 2507 | unsigned int cpu; |
2471 | 2508 | ||
@@ -2477,7 +2514,8 @@ static void __exit fcoe_exit(void) | |||
2477 | rtnl_lock(); | 2514 | rtnl_lock(); |
2478 | list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) { | 2515 | list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) { |
2479 | list_del(&fcoe->list); | 2516 | list_del(&fcoe->list); |
2480 | port = lport_priv(fcoe->ctlr.lp); | 2517 | ctlr = fcoe_to_ctlr(fcoe); |
2518 | port = lport_priv(ctlr->lp); | ||
2481 | queue_work(fcoe_wq, &port->destroy_work); | 2519 | queue_work(fcoe_wq, &port->destroy_work); |
2482 | } | 2520 | } |
2483 | rtnl_unlock(); | 2521 | rtnl_unlock(); |
@@ -2573,7 +2611,7 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did, | |||
2573 | { | 2611 | { |
2574 | struct fcoe_port *port = lport_priv(lport); | 2612 | struct fcoe_port *port = lport_priv(lport); |
2575 | struct fcoe_interface *fcoe = port->priv; | 2613 | struct fcoe_interface *fcoe = port->priv; |
2576 | struct fcoe_ctlr *fip = &fcoe->ctlr; | 2614 | struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); |
2577 | struct fc_frame_header *fh = fc_frame_header_get(fp); | 2615 | struct fc_frame_header *fh = fc_frame_header_get(fp); |
2578 | 2616 | ||
2579 | switch (op) { | 2617 | switch (op) { |
@@ -2747,7 +2785,8 @@ static void fcoe_set_port_id(struct fc_lport *lport, | |||
2747 | { | 2785 | { |
2748 | struct fcoe_port *port = lport_priv(lport); | 2786 | struct fcoe_port *port = lport_priv(lport); |
2749 | struct fcoe_interface *fcoe = port->priv; | 2787 | struct fcoe_interface *fcoe = port->priv; |
2788 | struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); | ||
2750 | 2789 | ||
2751 | if (fp && fc_frame_payload_op(fp) == ELS_FLOGI) | 2790 | if (fp && fc_frame_payload_op(fp) == ELS_FLOGI) |
2752 | fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp); | 2791 | fcoe_ctlr_recv_flogi(ctlr, lport, fp); |
2753 | } | 2792 | } |
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h index 96ac938d39cc..a624add4f8ec 100644 --- a/drivers/scsi/fcoe/fcoe.h +++ b/drivers/scsi/fcoe/fcoe.h | |||
@@ -68,7 +68,6 @@ do { \ | |||
68 | * @netdev: The associated net device | 68 | * @netdev: The associated net device |
69 | * @fcoe_packet_type: FCoE packet type | 69 | * @fcoe_packet_type: FCoE packet type |
70 | * @fip_packet_type: FIP packet type | 70 | * @fip_packet_type: FIP packet type |
71 | * @ctlr: The FCoE controller (for FIP) | ||
72 | * @oem: The offload exchange manager for all local port | 71 | * @oem: The offload exchange manager for all local port |
73 | * instances associated with this port | 72 | * instances associated with this port |
74 | * @removed: Indicates fcoe interface removed from net device | 73 | * @removed: Indicates fcoe interface removed from net device |
@@ -80,12 +79,15 @@ struct fcoe_interface { | |||
80 | struct net_device *realdev; | 79 | struct net_device *realdev; |
81 | struct packet_type fcoe_packet_type; | 80 | struct packet_type fcoe_packet_type; |
82 | struct packet_type fip_packet_type; | 81 | struct packet_type fip_packet_type; |
83 | struct fcoe_ctlr ctlr; | ||
84 | struct fc_exch_mgr *oem; | 82 | struct fc_exch_mgr *oem; |
85 | u8 removed; | 83 | u8 removed; |
86 | }; | 84 | }; |
87 | 85 | ||
88 | #define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr) | 86 | #define fcoe_to_ctlr(x) \ |
87 | (struct fcoe_ctlr *)(((struct fcoe_ctlr *)(x)) - 1) | ||
88 | |||
89 | #define fcoe_from_ctlr(x) \ | ||
90 | ((struct fcoe_interface *)((x) + 1)) | ||
89 | 91 | ||
90 | /** | 92 | /** |
91 | * fcoe_netdev() - Return the net device associated with a local port | 93 | * fcoe_netdev() - Return the net device associated with a local port |
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index cfdb55f0937e..69eca4b7ce2b 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h | |||
@@ -159,6 +159,15 @@ struct fcoe_ctlr { | |||
159 | }; | 159 | }; |
160 | 160 | ||
161 | /** | 161 | /** |
162 | * fcoe_ctlr_priv() - Return the private data from a fcoe_ctlr | ||
163 | * @cltr: The fcoe_ctlr whose private data will be returned | ||
164 | */ | ||
165 | static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr) | ||
166 | { | ||
167 | return (void *)(ctlr + 1); | ||
168 | } | ||
169 | |||
170 | /** | ||
162 | * struct fcoe_fcf - Fibre-Channel Forwarder | 171 | * struct fcoe_fcf - Fibre-Channel Forwarder |
163 | * @list: list linkage | 172 | * @list: list linkage |
164 | * @time: system time (jiffies) when an advertisement was last received | 173 | * @time: system time (jiffies) when an advertisement was last received |