aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe/fcoe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r--drivers/scsi/fcoe/fcoe.c194
1 files changed, 128 insertions, 66 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index f01b9b44e8aa..ba75a98c960c 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -74,6 +74,7 @@ static int fcoe_rcv(struct sk_buff *, struct net_device *,
74static int fcoe_percpu_receive_thread(void *); 74static int fcoe_percpu_receive_thread(void *);
75static void fcoe_clean_pending_queue(struct fc_lport *); 75static void fcoe_clean_pending_queue(struct fc_lport *);
76static void fcoe_percpu_clean(struct fc_lport *); 76static void fcoe_percpu_clean(struct fc_lport *);
77static int fcoe_link_speed_update(struct fc_lport *);
77static int fcoe_link_ok(struct fc_lport *); 78static int fcoe_link_ok(struct fc_lport *);
78 79
79static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); 80static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
@@ -146,6 +147,7 @@ static int fcoe_vport_destroy(struct fc_vport *);
146static int fcoe_vport_create(struct fc_vport *, bool disabled); 147static int fcoe_vport_create(struct fc_vport *, bool disabled);
147static int fcoe_vport_disable(struct fc_vport *, bool disable); 148static int fcoe_vport_disable(struct fc_vport *, bool disable);
148static void fcoe_set_vport_symbolic_name(struct fc_vport *); 149static void fcoe_set_vport_symbolic_name(struct fc_vport *);
150static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *);
149 151
150static struct libfc_function_template fcoe_libfc_fcn_templ = { 152static struct libfc_function_template fcoe_libfc_fcn_templ = {
151 .frame_send = fcoe_xmit, 153 .frame_send = fcoe_xmit,
@@ -153,6 +155,7 @@ static struct libfc_function_template fcoe_libfc_fcn_templ = {
153 .ddp_done = fcoe_ddp_done, 155 .ddp_done = fcoe_ddp_done,
154 .elsct_send = fcoe_elsct_send, 156 .elsct_send = fcoe_elsct_send,
155 .get_lesb = fcoe_get_lesb, 157 .get_lesb = fcoe_get_lesb,
158 .lport_set_port_id = fcoe_set_port_id,
156}; 159};
157 160
158struct fc_function_template fcoe_transport_function = { 161struct fc_function_template fcoe_transport_function = {
@@ -629,6 +632,8 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev)
629 port->fcoe_pending_queue_active = 0; 632 port->fcoe_pending_queue_active = 0;
630 setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lport); 633 setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lport);
631 634
635 fcoe_link_speed_update(lport);
636
632 if (!lport->vport) { 637 if (!lport->vport) {
633 /* 638 /*
634 * Use NAA 1&2 (FC-FS Rev. 2.0, Sec. 15) to generate WWNN/WWPN: 639 * Use NAA 1&2 (FC-FS Rev. 2.0, Sec. 15) to generate WWNN/WWPN:
@@ -653,15 +658,13 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev)
653/** 658/**
654 * fcoe_shost_config() - Set up the SCSI host associated with a local port 659 * fcoe_shost_config() - Set up the SCSI host associated with a local port
655 * @lport: The local port 660 * @lport: The local port
656 * @shost: The SCSI host to associate with the local port
657 * @dev: The device associated with the SCSI host 661 * @dev: The device associated with the SCSI host
658 * 662 *
659 * Must be called after fcoe_lport_config() and fcoe_netdev_config() 663 * Must be called after fcoe_lport_config() and fcoe_netdev_config()
660 * 664 *
661 * Returns: 0 for success 665 * Returns: 0 for success
662 */ 666 */
663static int fcoe_shost_config(struct fc_lport *lport, struct Scsi_Host *shost, 667static int fcoe_shost_config(struct fc_lport *lport, struct device *dev)
664 struct device *dev)
665{ 668{
666 int rc = 0; 669 int rc = 0;
667 670
@@ -669,6 +672,8 @@ static int fcoe_shost_config(struct fc_lport *lport, struct Scsi_Host *shost,
669 lport->host->max_lun = FCOE_MAX_LUN; 672 lport->host->max_lun = FCOE_MAX_LUN;
670 lport->host->max_id = FCOE_MAX_FCP_TARGET; 673 lport->host->max_id = FCOE_MAX_FCP_TARGET;
671 lport->host->max_channel = 0; 674 lport->host->max_channel = 0;
675 lport->host->max_cmd_len = FCOE_MAX_CMD_LEN;
676
672 if (lport->vport) 677 if (lport->vport)
673 lport->host->transportt = fcoe_vport_transport_template; 678 lport->host->transportt = fcoe_vport_transport_template;
674 else 679 else
@@ -796,6 +801,12 @@ skip_oem:
796/** 801/**
797 * fcoe_if_destroy() - Tear down a SW FCoE instance 802 * fcoe_if_destroy() - Tear down a SW FCoE instance
798 * @lport: The local port to be destroyed 803 * @lport: The local port to be destroyed
804 *
805 * Locking: must be called with the RTNL mutex held and RTNL mutex
806 * needed to be dropped by this function since not dropping RTNL
807 * would cause circular locking warning on synchronous fip worker
808 * cancelling thru fcoe_interface_put invoked by this function.
809 *
799 */ 810 */
800static void fcoe_if_destroy(struct fc_lport *lport) 811static void fcoe_if_destroy(struct fc_lport *lport)
801{ 812{
@@ -818,7 +829,6 @@ static void fcoe_if_destroy(struct fc_lport *lport)
818 /* Free existing transmit skbs */ 829 /* Free existing transmit skbs */
819 fcoe_clean_pending_queue(lport); 830 fcoe_clean_pending_queue(lport);
820 831
821 rtnl_lock();
822 if (!is_zero_ether_addr(port->data_src_addr)) 832 if (!is_zero_ether_addr(port->data_src_addr))
823 dev_unicast_delete(netdev, port->data_src_addr); 833 dev_unicast_delete(netdev, port->data_src_addr);
824 rtnl_unlock(); 834 rtnl_unlock();
@@ -841,6 +851,7 @@ static void fcoe_if_destroy(struct fc_lport *lport)
841 851
842 /* Release the Scsi_Host */ 852 /* Release the Scsi_Host */
843 scsi_host_put(lport->host); 853 scsi_host_put(lport->host);
854 module_put(THIS_MODULE);
844} 855}
845 856
846/** 857/**
@@ -897,7 +908,6 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
897 struct net_device *netdev = fcoe->netdev; 908 struct net_device *netdev = fcoe->netdev;
898 struct fc_lport *lport = NULL; 909 struct fc_lport *lport = NULL;
899 struct fcoe_port *port; 910 struct fcoe_port *port;
900 struct Scsi_Host *shost;
901 int rc; 911 int rc;
902 /* 912 /*
903 * parent is only a vport if npiv is 1, 913 * parent is only a vport if npiv is 1,
@@ -919,7 +929,6 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
919 rc = -ENOMEM; 929 rc = -ENOMEM;
920 goto out; 930 goto out;
921 } 931 }
922 shost = lport->host;
923 port = lport_priv(lport); 932 port = lport_priv(lport);
924 port->lport = lport; 933 port->lport = lport;
925 port->fcoe = fcoe; 934 port->fcoe = fcoe;
@@ -934,7 +943,8 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
934 } 943 }
935 944
936 if (npiv) { 945 if (npiv) {
937 FCOE_NETDEV_DBG(netdev, "Setting vport names, 0x%llX 0x%llX\n", 946 FCOE_NETDEV_DBG(netdev, "Setting vport names, "
947 "%16.16llx %16.16llx\n",
938 vport->node_name, vport->port_name); 948 vport->node_name, vport->port_name);
939 fc_set_wwnn(lport, vport->node_name); 949 fc_set_wwnn(lport, vport->node_name);
940 fc_set_wwpn(lport, vport->port_name); 950 fc_set_wwpn(lport, vport->port_name);
@@ -949,7 +959,7 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
949 } 959 }
950 960
951 /* configure lport scsi host properties */ 961 /* configure lport scsi host properties */
952 rc = fcoe_shost_config(lport, shost, parent); 962 rc = fcoe_shost_config(lport, parent);
953 if (rc) { 963 if (rc) {
954 FCOE_NETDEV_DBG(netdev, "Could not configure shost for the " 964 FCOE_NETDEV_DBG(netdev, "Could not configure shost for the "
955 "interface\n"); 965 "interface\n");
@@ -1073,7 +1083,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu)
1073 struct sk_buff *skb; 1083 struct sk_buff *skb;
1074#ifdef CONFIG_SMP 1084#ifdef CONFIG_SMP
1075 struct fcoe_percpu_s *p0; 1085 struct fcoe_percpu_s *p0;
1076 unsigned targ_cpu = smp_processor_id(); 1086 unsigned targ_cpu = get_cpu();
1077#endif /* CONFIG_SMP */ 1087#endif /* CONFIG_SMP */
1078 1088
1079 FCOE_DBG("Destroying receive thread for CPU %d\n", cpu); 1089 FCOE_DBG("Destroying receive thread for CPU %d\n", cpu);
@@ -1129,6 +1139,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu)
1129 kfree_skb(skb); 1139 kfree_skb(skb);
1130 spin_unlock_bh(&p->fcoe_rx_list.lock); 1140 spin_unlock_bh(&p->fcoe_rx_list.lock);
1131 } 1141 }
1142 put_cpu();
1132#else 1143#else
1133 /* 1144 /*
1134 * This a non-SMP scenario where the singular Rx thread is 1145 * This a non-SMP scenario where the singular Rx thread is
@@ -1297,8 +1308,8 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
1297 1308
1298 return 0; 1309 return 0;
1299err: 1310err:
1300 fc_lport_get_stats(lport)->ErrorFrames++; 1311 per_cpu_ptr(lport->dev_stats, get_cpu())->ErrorFrames++;
1301 1312 put_cpu();
1302err2: 1313err2:
1303 kfree_skb(skb); 1314 kfree_skb(skb);
1304 return -1; 1315 return -1;
@@ -1444,7 +1455,7 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
1444 return 0; 1455 return 0;
1445 } 1456 }
1446 1457
1447 if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) && 1458 if (unlikely(fh->fh_type == FC_TYPE_ELS) &&
1448 fcoe_ctlr_els_send(&fcoe->ctlr, lport, skb)) 1459 fcoe_ctlr_els_send(&fcoe->ctlr, lport, skb))
1449 return 0; 1460 return 0;
1450 1461
@@ -1527,9 +1538,10 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
1527 skb_shinfo(skb)->gso_size = 0; 1538 skb_shinfo(skb)->gso_size = 0;
1528 } 1539 }
1529 /* update tx stats: regardless if LLD fails */ 1540 /* update tx stats: regardless if LLD fails */
1530 stats = fc_lport_get_stats(lport); 1541 stats = per_cpu_ptr(lport->dev_stats, get_cpu());
1531 stats->TxFrames++; 1542 stats->TxFrames++;
1532 stats->TxWords += wlen; 1543 stats->TxWords += wlen;
1544 put_cpu();
1533 1545
1534 /* send down to lld */ 1546 /* send down to lld */
1535 fr_dev(fp) = lport; 1547 fr_dev(fp) = lport;
@@ -1563,7 +1575,6 @@ static void fcoe_recv_frame(struct sk_buff *skb)
1563 struct fc_frame_header *fh; 1575 struct fc_frame_header *fh;
1564 struct fcoe_crc_eof crc_eof; 1576 struct fcoe_crc_eof crc_eof;
1565 struct fc_frame *fp; 1577 struct fc_frame *fp;
1566 u8 *mac = NULL;
1567 struct fcoe_port *port; 1578 struct fcoe_port *port;
1568 struct fcoe_hdr *hp; 1579 struct fcoe_hdr *hp;
1569 1580
@@ -1583,13 +1594,9 @@ static void fcoe_recv_frame(struct sk_buff *skb)
1583 skb_end_pointer(skb), skb->csum, 1594 skb_end_pointer(skb), skb->csum,
1584 skb->dev ? skb->dev->name : "<NULL>"); 1595 skb->dev ? skb->dev->name : "<NULL>");
1585 1596
1586 /*
1587 * Save source MAC address before discarding header.
1588 */
1589 port = lport_priv(lport); 1597 port = lport_priv(lport);
1590 if (skb_is_nonlinear(skb)) 1598 if (skb_is_nonlinear(skb))
1591 skb_linearize(skb); /* not ideal */ 1599 skb_linearize(skb); /* not ideal */
1592 mac = eth_hdr(skb)->h_source;
1593 1600
1594 /* 1601 /*
1595 * Frame length checks and setting up the header pointers 1602 * Frame length checks and setting up the header pointers
@@ -1598,7 +1605,7 @@ static void fcoe_recv_frame(struct sk_buff *skb)
1598 hp = (struct fcoe_hdr *) skb_network_header(skb); 1605 hp = (struct fcoe_hdr *) skb_network_header(skb);
1599 fh = (struct fc_frame_header *) skb_transport_header(skb); 1606 fh = (struct fc_frame_header *) skb_transport_header(skb);
1600 1607
1601 stats = fc_lport_get_stats(lport); 1608 stats = per_cpu_ptr(lport->dev_stats, get_cpu());
1602 if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { 1609 if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
1603 if (stats->ErrorFrames < 5) 1610 if (stats->ErrorFrames < 5)
1604 printk(KERN_WARNING "fcoe: FCoE version " 1611 printk(KERN_WARNING "fcoe: FCoE version "
@@ -1607,9 +1614,7 @@ static void fcoe_recv_frame(struct sk_buff *skb)
1607 "initiator supports version " 1614 "initiator supports version "
1608 "%x\n", FC_FCOE_DECAPS_VER(hp), 1615 "%x\n", FC_FCOE_DECAPS_VER(hp),
1609 FC_FCOE_VER); 1616 FC_FCOE_VER);
1610 stats->ErrorFrames++; 1617 goto drop;
1611 kfree_skb(skb);
1612 return;
1613 } 1618 }
1614 1619
1615 skb_pull(skb, sizeof(struct fcoe_hdr)); 1620 skb_pull(skb, sizeof(struct fcoe_hdr));
@@ -1624,16 +1629,12 @@ static void fcoe_recv_frame(struct sk_buff *skb)
1624 fr_sof(fp) = hp->fcoe_sof; 1629 fr_sof(fp) = hp->fcoe_sof;
1625 1630
1626 /* Copy out the CRC and EOF trailer for access */ 1631 /* Copy out the CRC and EOF trailer for access */
1627 if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) { 1632 if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof)))
1628 kfree_skb(skb); 1633 goto drop;
1629 return;
1630 }
1631 fr_eof(fp) = crc_eof.fcoe_eof; 1634 fr_eof(fp) = crc_eof.fcoe_eof;
1632 fr_crc(fp) = crc_eof.fcoe_crc32; 1635 fr_crc(fp) = crc_eof.fcoe_crc32;
1633 if (pskb_trim(skb, fr_len)) { 1636 if (pskb_trim(skb, fr_len))
1634 kfree_skb(skb); 1637 goto drop;
1635 return;
1636 }
1637 1638
1638 /* 1639 /*
1639 * We only check CRC if no offload is available and if it is 1640 * We only check CRC if no offload is available and if it is
@@ -1647,25 +1648,27 @@ static void fcoe_recv_frame(struct sk_buff *skb)
1647 fr_flags(fp) |= FCPHF_CRC_UNCHECKED; 1648 fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
1648 1649
1649 fh = fc_frame_header_get(fp); 1650 fh = fc_frame_header_get(fp);
1650 if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && 1651 if ((fh->fh_r_ctl != FC_RCTL_DD_SOL_DATA ||
1651 fh->fh_type == FC_TYPE_FCP) { 1652 fh->fh_type != FC_TYPE_FCP) &&
1652 fc_exch_recv(lport, fp); 1653 (fr_flags(fp) & FCPHF_CRC_UNCHECKED)) {
1653 return;
1654 }
1655 if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
1656 if (le32_to_cpu(fr_crc(fp)) != 1654 if (le32_to_cpu(fr_crc(fp)) !=
1657 ~crc32(~0, skb->data, fr_len)) { 1655 ~crc32(~0, skb->data, fr_len)) {
1658 if (stats->InvalidCRCCount < 5) 1656 if (stats->InvalidCRCCount < 5)
1659 printk(KERN_WARNING "fcoe: dropping " 1657 printk(KERN_WARNING "fcoe: dropping "
1660 "frame with CRC error\n"); 1658 "frame with CRC error\n");
1661 stats->InvalidCRCCount++; 1659 stats->InvalidCRCCount++;
1662 stats->ErrorFrames++; 1660 goto drop;
1663 fc_frame_free(fp);
1664 return;
1665 } 1661 }
1666 fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; 1662 fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
1667 } 1663 }
1664 put_cpu();
1668 fc_exch_recv(lport, fp); 1665 fc_exch_recv(lport, fp);
1666 return;
1667
1668drop:
1669 stats->ErrorFrames++;
1670 put_cpu();
1671 kfree_skb(skb);
1669} 1672}
1670 1673
1671/** 1674/**
@@ -1835,11 +1838,15 @@ static int fcoe_device_notification(struct notifier_block *notifier,
1835 FCOE_NETDEV_DBG(netdev, "Unknown event %ld " 1838 FCOE_NETDEV_DBG(netdev, "Unknown event %ld "
1836 "from netdev netlink\n", event); 1839 "from netdev netlink\n", event);
1837 } 1840 }
1841
1842 fcoe_link_speed_update(lport);
1843
1838 if (link_possible && !fcoe_link_ok(lport)) 1844 if (link_possible && !fcoe_link_ok(lport))
1839 fcoe_ctlr_link_up(&fcoe->ctlr); 1845 fcoe_ctlr_link_up(&fcoe->ctlr);
1840 else if (fcoe_ctlr_link_down(&fcoe->ctlr)) { 1846 else if (fcoe_ctlr_link_down(&fcoe->ctlr)) {
1841 stats = fc_lport_get_stats(lport); 1847 stats = per_cpu_ptr(lport->dev_stats, get_cpu());
1842 stats->LinkFailureCount++; 1848 stats->LinkFailureCount++;
1849 put_cpu();
1843 fcoe_clean_pending_queue(lport); 1850 fcoe_clean_pending_queue(lport);
1844 } 1851 }
1845out: 1852out:
@@ -1901,13 +1908,19 @@ static int fcoe_disable(const char *buffer, struct kernel_param *kp)
1901 goto out_nodev; 1908 goto out_nodev;
1902 } 1909 }
1903 1910
1904 rtnl_lock(); 1911 if (!rtnl_trylock()) {
1912 dev_put(netdev);
1913 mutex_unlock(&fcoe_config_mutex);
1914 return restart_syscall();
1915 }
1916
1905 fcoe = fcoe_hostlist_lookup_port(netdev); 1917 fcoe = fcoe_hostlist_lookup_port(netdev);
1906 rtnl_unlock(); 1918 rtnl_unlock();
1907 1919
1908 if (fcoe) 1920 if (fcoe) {
1909 fc_fabric_logoff(fcoe->ctlr.lp); 1921 fc_fabric_logoff(fcoe->ctlr.lp);
1910 else 1922 fcoe_ctlr_link_down(&fcoe->ctlr);
1923 } else
1911 rc = -ENODEV; 1924 rc = -ENODEV;
1912 1925
1913 dev_put(netdev); 1926 dev_put(netdev);
@@ -1950,13 +1963,20 @@ static int fcoe_enable(const char *buffer, struct kernel_param *kp)
1950 goto out_nodev; 1963 goto out_nodev;
1951 } 1964 }
1952 1965
1953 rtnl_lock(); 1966 if (!rtnl_trylock()) {
1967 dev_put(netdev);
1968 mutex_unlock(&fcoe_config_mutex);
1969 return restart_syscall();
1970 }
1971
1954 fcoe = fcoe_hostlist_lookup_port(netdev); 1972 fcoe = fcoe_hostlist_lookup_port(netdev);
1955 rtnl_unlock(); 1973 rtnl_unlock();
1956 1974
1957 if (fcoe) 1975 if (fcoe) {
1976 if (!fcoe_link_ok(fcoe->ctlr.lp))
1977 fcoe_ctlr_link_up(&fcoe->ctlr);
1958 rc = fc_fabric_login(fcoe->ctlr.lp); 1978 rc = fc_fabric_login(fcoe->ctlr.lp);
1959 else 1979 } else
1960 rc = -ENODEV; 1980 rc = -ENODEV;
1961 1981
1962 dev_put(netdev); 1982 dev_put(netdev);
@@ -1999,7 +2019,12 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
1999 goto out_nodev; 2019 goto out_nodev;
2000 } 2020 }
2001 2021
2002 rtnl_lock(); 2022 if (!rtnl_trylock()) {
2023 dev_put(netdev);
2024 mutex_unlock(&fcoe_config_mutex);
2025 return restart_syscall();
2026 }
2027
2003 fcoe = fcoe_hostlist_lookup_port(netdev); 2028 fcoe = fcoe_hostlist_lookup_port(netdev);
2004 if (!fcoe) { 2029 if (!fcoe) {
2005 rtnl_unlock(); 2030 rtnl_unlock();
@@ -2008,9 +2033,8 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
2008 } 2033 }
2009 list_del(&fcoe->list); 2034 list_del(&fcoe->list);
2010 fcoe_interface_cleanup(fcoe); 2035 fcoe_interface_cleanup(fcoe);
2011 rtnl_unlock(); 2036 /* RTNL mutex is dropped by fcoe_if_destroy */
2012 fcoe_if_destroy(fcoe->ctlr.lp); 2037 fcoe_if_destroy(fcoe->ctlr.lp);
2013 module_put(THIS_MODULE);
2014 2038
2015out_putdev: 2039out_putdev:
2016 dev_put(netdev); 2040 dev_put(netdev);
@@ -2029,6 +2053,8 @@ static void fcoe_destroy_work(struct work_struct *work)
2029 2053
2030 port = container_of(work, struct fcoe_port, destroy_work); 2054 port = container_of(work, struct fcoe_port, destroy_work);
2031 mutex_lock(&fcoe_config_mutex); 2055 mutex_lock(&fcoe_config_mutex);
2056 rtnl_lock();
2057 /* RTNL mutex is dropped by fcoe_if_destroy */
2032 fcoe_if_destroy(port->lport); 2058 fcoe_if_destroy(port->lport);
2033 mutex_unlock(&fcoe_config_mutex); 2059 mutex_unlock(&fcoe_config_mutex);
2034} 2060}
@@ -2050,6 +2076,12 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
2050 struct net_device *netdev; 2076 struct net_device *netdev;
2051 2077
2052 mutex_lock(&fcoe_config_mutex); 2078 mutex_lock(&fcoe_config_mutex);
2079
2080 if (!rtnl_trylock()) {
2081 mutex_unlock(&fcoe_config_mutex);
2082 return restart_syscall();
2083 }
2084
2053#ifdef CONFIG_FCOE_MODULE 2085#ifdef CONFIG_FCOE_MODULE
2054 /* 2086 /*
2055 * Make sure the module has been initialized, and is not about to be 2087 * Make sure the module has been initialized, and is not about to be
@@ -2058,7 +2090,7 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
2058 */ 2090 */
2059 if (THIS_MODULE->state != MODULE_STATE_LIVE) { 2091 if (THIS_MODULE->state != MODULE_STATE_LIVE) {
2060 rc = -ENODEV; 2092 rc = -ENODEV;
2061 goto out_nodev; 2093 goto out_nomod;
2062 } 2094 }
2063#endif 2095#endif
2064 2096
@@ -2067,7 +2099,6 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
2067 goto out_nomod; 2099 goto out_nomod;
2068 } 2100 }
2069 2101
2070 rtnl_lock();
2071 netdev = fcoe_if_to_netdev(buffer); 2102 netdev = fcoe_if_to_netdev(buffer);
2072 if (!netdev) { 2103 if (!netdev) {
2073 rc = -ENODEV; 2104 rc = -ENODEV;
@@ -2122,35 +2153,27 @@ out_free:
2122out_putdev: 2153out_putdev:
2123 dev_put(netdev); 2154 dev_put(netdev);
2124out_nodev: 2155out_nodev:
2125 rtnl_unlock();
2126 module_put(THIS_MODULE); 2156 module_put(THIS_MODULE);
2127out_nomod: 2157out_nomod:
2158 rtnl_unlock();
2128 mutex_unlock(&fcoe_config_mutex); 2159 mutex_unlock(&fcoe_config_mutex);
2129 return rc; 2160 return rc;
2130} 2161}
2131 2162
2132/** 2163/**
2133 * fcoe_link_ok() - Check if the link is OK for a local port 2164 * fcoe_link_speed_update() - Update the supported and actual link speeds
2134 * @lport: The local port to check link on 2165 * @lport: The local port to update speeds for
2135 *
2136 * Any permanently-disqualifying conditions have been previously checked.
2137 * This also updates the speed setting, which may change with link for 100/1000.
2138 *
2139 * This function should probably be checking for PAUSE support at some point
2140 * in the future. Currently Per-priority-pause is not determinable using
2141 * ethtool, so we shouldn't be restrictive until that problem is resolved.
2142 *
2143 * Returns: 0 if link is OK for use by FCoE.
2144 * 2166 *
2167 * Returns: 0 if the ethtool query was successful
2168 * -1 if the ethtool query failed
2145 */ 2169 */
2146int fcoe_link_ok(struct fc_lport *lport) 2170int fcoe_link_speed_update(struct fc_lport *lport)
2147{ 2171{
2148 struct fcoe_port *port = lport_priv(lport); 2172 struct fcoe_port *port = lport_priv(lport);
2149 struct net_device *netdev = port->fcoe->netdev; 2173 struct net_device *netdev = port->fcoe->netdev;
2150 struct ethtool_cmd ecmd = { ETHTOOL_GSET }; 2174 struct ethtool_cmd ecmd = { ETHTOOL_GSET };
2151 2175
2152 if ((netdev->flags & IFF_UP) && netif_carrier_ok(netdev) && 2176 if (!dev_ethtool_get_settings(netdev, &ecmd)) {
2153 (!dev_ethtool_get_settings(netdev, &ecmd))) {
2154 lport->link_supported_speeds &= 2177 lport->link_supported_speeds &=
2155 ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT); 2178 ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
2156 if (ecmd.supported & (SUPPORTED_1000baseT_Half | 2179 if (ecmd.supported & (SUPPORTED_1000baseT_Half |
@@ -2170,6 +2193,23 @@ int fcoe_link_ok(struct fc_lport *lport)
2170} 2193}
2171 2194
2172/** 2195/**
2196 * fcoe_link_ok() - Check if the link is OK for a local port
2197 * @lport: The local port to check link on
2198 *
2199 * Returns: 0 if link is UP and OK, -1 if not
2200 *
2201 */
2202int fcoe_link_ok(struct fc_lport *lport)
2203{
2204 struct fcoe_port *port = lport_priv(lport);
2205 struct net_device *netdev = port->fcoe->netdev;
2206
2207 if (netif_oper_up(netdev))
2208 return 0;
2209 return -1;
2210}
2211
2212/**
2173 * fcoe_percpu_clean() - Clear all pending skbs for an local port 2213 * fcoe_percpu_clean() - Clear all pending skbs for an local port
2174 * @lport: The local port whose skbs are to be cleared 2214 * @lport: The local port whose skbs are to be cleared
2175 * 2215 *
@@ -2631,3 +2671,25 @@ static void fcoe_get_lesb(struct fc_lport *lport,
2631 lesb->lesb_miss_fka = htonl(mdac); 2671 lesb->lesb_miss_fka = htonl(mdac);
2632 lesb->lesb_fcs_error = htonl(dev_get_stats(netdev)->rx_crc_errors); 2672 lesb->lesb_fcs_error = htonl(dev_get_stats(netdev)->rx_crc_errors);
2633} 2673}
2674
2675/**
2676 * fcoe_set_port_id() - Callback from libfc when Port_ID is set.
2677 * @lport: the local port
2678 * @port_id: the port ID
2679 * @fp: the received frame, if any, that caused the port_id to be set.
2680 *
2681 * This routine handles the case where we received a FLOGI and are
2682 * entering point-to-point mode. We need to call fcoe_ctlr_recv_flogi()
2683 * so it can set the non-mapped mode and gateway address.
2684 *
2685 * The FLOGI LS_ACC is handled by fcoe_flogi_resp().
2686 */
2687static void fcoe_set_port_id(struct fc_lport *lport,
2688 u32 port_id, struct fc_frame *fp)
2689{
2690 struct fcoe_port *port = lport_priv(lport);
2691 struct fcoe_interface *fcoe = port->fcoe;
2692
2693 if (fp && fc_frame_payload_op(fp) == ELS_FLOGI)
2694 fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp);
2695}