diff options
author | Vasanthy Kolluri <vkolluri@cisco.com> | 2010-06-24 06:50:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-25 23:46:40 -0400 |
commit | 383ab92f11dd78d365ed05cf4d83ca2acc069a1f (patch) | |
tree | 484b3957d2a28a7f5a67e37871fc729484e67d59 | |
parent | 99ef563901a18d44a6c2eadd2b958e2e83aeca51 (diff) |
enic: Clean up: Add wrapper routines for firmware devcmd calls
Add wrapper routines that issue devcmds to firmware and ensure that a
devcmd lock is held for each devcmd call.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/enic/enic_main.c | 226 | ||||
-rw-r--r-- | drivers/net/enic/enic_res.c | 23 | ||||
-rw-r--r-- | drivers/net/enic/enic_res.h | 6 | ||||
-rw-r--r-- | drivers/net/enic/vnic_dev.c | 23 | ||||
-rw-r--r-- | drivers/net/enic/vnic_dev.h | 7 |
5 files changed, 201 insertions, 84 deletions
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index d7434b7b4c52..9e0580531143 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c | |||
@@ -145,15 +145,25 @@ static int enic_get_settings(struct net_device *netdev, | |||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | static int enic_dev_fw_info(struct enic *enic, | ||
149 | struct vnic_devcmd_fw_info **fw_info) | ||
150 | { | ||
151 | int err; | ||
152 | |||
153 | spin_lock(&enic->devcmd_lock); | ||
154 | err = vnic_dev_fw_info(enic->vdev, fw_info); | ||
155 | spin_unlock(&enic->devcmd_lock); | ||
156 | |||
157 | return err; | ||
158 | } | ||
159 | |||
148 | static void enic_get_drvinfo(struct net_device *netdev, | 160 | static void enic_get_drvinfo(struct net_device *netdev, |
149 | struct ethtool_drvinfo *drvinfo) | 161 | struct ethtool_drvinfo *drvinfo) |
150 | { | 162 | { |
151 | struct enic *enic = netdev_priv(netdev); | 163 | struct enic *enic = netdev_priv(netdev); |
152 | struct vnic_devcmd_fw_info *fw_info; | 164 | struct vnic_devcmd_fw_info *fw_info; |
153 | 165 | ||
154 | spin_lock(&enic->devcmd_lock); | 166 | enic_dev_fw_info(enic, &fw_info); |
155 | vnic_dev_fw_info(enic->vdev, &fw_info); | ||
156 | spin_unlock(&enic->devcmd_lock); | ||
157 | 167 | ||
158 | strncpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); | 168 | strncpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); |
159 | strncpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); | 169 | strncpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); |
@@ -191,6 +201,17 @@ static int enic_get_sset_count(struct net_device *netdev, int sset) | |||
191 | } | 201 | } |
192 | } | 202 | } |
193 | 203 | ||
204 | static int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats) | ||
205 | { | ||
206 | int err; | ||
207 | |||
208 | spin_lock(&enic->devcmd_lock); | ||
209 | err = vnic_dev_stats_dump(enic->vdev, vstats); | ||
210 | spin_unlock(&enic->devcmd_lock); | ||
211 | |||
212 | return err; | ||
213 | } | ||
214 | |||
194 | static void enic_get_ethtool_stats(struct net_device *netdev, | 215 | static void enic_get_ethtool_stats(struct net_device *netdev, |
195 | struct ethtool_stats *stats, u64 *data) | 216 | struct ethtool_stats *stats, u64 *data) |
196 | { | 217 | { |
@@ -198,9 +219,7 @@ static void enic_get_ethtool_stats(struct net_device *netdev, | |||
198 | struct vnic_stats *vstats; | 219 | struct vnic_stats *vstats; |
199 | unsigned int i; | 220 | unsigned int i; |
200 | 221 | ||
201 | spin_lock(&enic->devcmd_lock); | 222 | enic_dev_stats_dump(enic, &vstats); |
202 | vnic_dev_stats_dump(enic->vdev, &vstats); | ||
203 | spin_unlock(&enic->devcmd_lock); | ||
204 | 223 | ||
205 | for (i = 0; i < enic_n_tx_stats; i++) | 224 | for (i = 0; i < enic_n_tx_stats; i++) |
206 | *(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].offset]; | 225 | *(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].offset]; |
@@ -411,17 +430,14 @@ static void enic_log_q_error(struct enic *enic) | |||
411 | } | 430 | } |
412 | } | 431 | } |
413 | 432 | ||
414 | static void enic_link_check(struct enic *enic) | 433 | static void enic_msglvl_check(struct enic *enic) |
415 | { | 434 | { |
416 | int link_status = vnic_dev_link_status(enic->vdev); | 435 | u32 msg_enable = vnic_dev_msg_lvl(enic->vdev); |
417 | int carrier_ok = netif_carrier_ok(enic->netdev); | ||
418 | 436 | ||
419 | if (link_status && !carrier_ok) { | 437 | if (msg_enable != enic->msg_enable) { |
420 | printk(KERN_INFO PFX "%s: Link UP\n", enic->netdev->name); | 438 | printk(KERN_INFO PFX "%s: msg lvl changed from 0x%x to 0x%x\n", |
421 | netif_carrier_on(enic->netdev); | 439 | enic->netdev->name, enic->msg_enable, msg_enable); |
422 | } else if (!link_status && carrier_ok) { | 440 | enic->msg_enable = msg_enable; |
423 | printk(KERN_INFO PFX "%s: Link DOWN\n", enic->netdev->name); | ||
424 | netif_carrier_off(enic->netdev); | ||
425 | } | 441 | } |
426 | } | 442 | } |
427 | 443 | ||
@@ -439,14 +455,17 @@ static void enic_mtu_check(struct enic *enic) | |||
439 | } | 455 | } |
440 | } | 456 | } |
441 | 457 | ||
442 | static void enic_msglvl_check(struct enic *enic) | 458 | static void enic_link_check(struct enic *enic) |
443 | { | 459 | { |
444 | u32 msg_enable = vnic_dev_msg_lvl(enic->vdev); | 460 | int link_status = vnic_dev_link_status(enic->vdev); |
461 | int carrier_ok = netif_carrier_ok(enic->netdev); | ||
445 | 462 | ||
446 | if (msg_enable != enic->msg_enable) { | 463 | if (link_status && !carrier_ok) { |
447 | printk(KERN_INFO PFX "%s: msg lvl changed from 0x%x to 0x%x\n", | 464 | printk(KERN_INFO PFX "%s: Link UP\n", enic->netdev->name); |
448 | enic->netdev->name, enic->msg_enable, msg_enable); | 465 | netif_carrier_on(enic->netdev); |
449 | enic->msg_enable = msg_enable; | 466 | } else if (!link_status && carrier_ok) { |
467 | printk(KERN_INFO PFX "%s: Link DOWN\n", enic->netdev->name); | ||
468 | netif_carrier_off(enic->netdev); | ||
450 | } | 469 | } |
451 | } | 470 | } |
452 | 471 | ||
@@ -792,9 +811,7 @@ static struct net_device_stats *enic_get_stats(struct net_device *netdev) | |||
792 | struct net_device_stats *net_stats = &netdev->stats; | 811 | struct net_device_stats *net_stats = &netdev->stats; |
793 | struct vnic_stats *stats; | 812 | struct vnic_stats *stats; |
794 | 813 | ||
795 | spin_lock(&enic->devcmd_lock); | 814 | enic_dev_stats_dump(enic, &stats); |
796 | vnic_dev_stats_dump(enic->vdev, &stats); | ||
797 | spin_unlock(&enic->devcmd_lock); | ||
798 | 815 | ||
799 | net_stats->tx_packets = stats->tx.tx_frames_ok; | 816 | net_stats->tx_packets = stats->tx.tx_frames_ok; |
800 | net_stats->tx_bytes = stats->tx.tx_bytes_ok; | 817 | net_stats->tx_bytes = stats->tx.tx_bytes_ok; |
@@ -892,6 +909,41 @@ static int enic_set_mac_address(struct net_device *netdev, void *p) | |||
892 | return -EOPNOTSUPP; | 909 | return -EOPNOTSUPP; |
893 | } | 910 | } |
894 | 911 | ||
912 | static int enic_dev_packet_filter(struct enic *enic, int directed, | ||
913 | int multicast, int broadcast, int promisc, int allmulti) | ||
914 | { | ||
915 | int err; | ||
916 | |||
917 | spin_lock(&enic->devcmd_lock); | ||
918 | err = vnic_dev_packet_filter(enic->vdev, directed, | ||
919 | multicast, broadcast, promisc, allmulti); | ||
920 | spin_unlock(&enic->devcmd_lock); | ||
921 | |||
922 | return err; | ||
923 | } | ||
924 | |||
925 | static int enic_dev_add_multicast_addr(struct enic *enic, u8 *addr) | ||
926 | { | ||
927 | int err; | ||
928 | |||
929 | spin_lock(&enic->devcmd_lock); | ||
930 | err = vnic_dev_add_addr(enic->vdev, addr); | ||
931 | spin_unlock(&enic->devcmd_lock); | ||
932 | |||
933 | return err; | ||
934 | } | ||
935 | |||
936 | static int enic_dev_del_multicast_addr(struct enic *enic, u8 *addr) | ||
937 | { | ||
938 | int err; | ||
939 | |||
940 | spin_lock(&enic->devcmd_lock); | ||
941 | err = vnic_dev_del_addr(enic->vdev, addr); | ||
942 | spin_unlock(&enic->devcmd_lock); | ||
943 | |||
944 | return err; | ||
945 | } | ||
946 | |||
895 | /* netif_tx_lock held, BHs disabled */ | 947 | /* netif_tx_lock held, BHs disabled */ |
896 | static void enic_set_multicast_list(struct net_device *netdev) | 948 | static void enic_set_multicast_list(struct net_device *netdev) |
897 | { | 949 | { |
@@ -911,11 +963,9 @@ static void enic_set_multicast_list(struct net_device *netdev) | |||
911 | if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS) | 963 | if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS) |
912 | mc_count = ENIC_MULTICAST_PERFECT_FILTERS; | 964 | mc_count = ENIC_MULTICAST_PERFECT_FILTERS; |
913 | 965 | ||
914 | spin_lock(&enic->devcmd_lock); | ||
915 | |||
916 | if (enic->flags != flags) { | 966 | if (enic->flags != flags) { |
917 | enic->flags = flags; | 967 | enic->flags = flags; |
918 | vnic_dev_packet_filter(enic->vdev, directed, | 968 | enic_dev_packet_filter(enic, directed, |
919 | multicast, broadcast, promisc, allmulti); | 969 | multicast, broadcast, promisc, allmulti); |
920 | } | 970 | } |
921 | 971 | ||
@@ -938,7 +988,7 @@ static void enic_set_multicast_list(struct net_device *netdev) | |||
938 | mc_addr[j]) == 0) | 988 | mc_addr[j]) == 0) |
939 | break; | 989 | break; |
940 | if (j == mc_count) | 990 | if (j == mc_count) |
941 | enic_del_multicast_addr(enic, enic->mc_addr[i]); | 991 | enic_dev_del_multicast_addr(enic, enic->mc_addr[i]); |
942 | } | 992 | } |
943 | 993 | ||
944 | for (i = 0; i < mc_count; i++) { | 994 | for (i = 0; i < mc_count; i++) { |
@@ -947,7 +997,7 @@ static void enic_set_multicast_list(struct net_device *netdev) | |||
947 | enic->mc_addr[j]) == 0) | 997 | enic->mc_addr[j]) == 0) |
948 | break; | 998 | break; |
949 | if (j == enic->mc_count) | 999 | if (j == enic->mc_count) |
950 | enic_add_multicast_addr(enic, mc_addr[i]); | 1000 | enic_dev_add_multicast_addr(enic, mc_addr[i]); |
951 | } | 1001 | } |
952 | 1002 | ||
953 | /* Save the list to compare against next time | 1003 | /* Save the list to compare against next time |
@@ -957,8 +1007,6 @@ static void enic_set_multicast_list(struct net_device *netdev) | |||
957 | memcpy(enic->mc_addr[i], mc_addr[i], ETH_ALEN); | 1007 | memcpy(enic->mc_addr[i], mc_addr[i], ETH_ALEN); |
958 | 1008 | ||
959 | enic->mc_count = mc_count; | 1009 | enic->mc_count = mc_count; |
960 | |||
961 | spin_unlock(&enic->devcmd_lock); | ||
962 | } | 1010 | } |
963 | 1011 | ||
964 | /* rtnl lock is held */ | 1012 | /* rtnl lock is held */ |
@@ -1264,12 +1312,24 @@ static int enic_rq_alloc_buf_a1(struct vnic_rq *rq) | |||
1264 | return 0; | 1312 | return 0; |
1265 | } | 1313 | } |
1266 | 1314 | ||
1315 | static int enic_dev_hw_version(struct enic *enic, | ||
1316 | enum vnic_dev_hw_version *hw_ver) | ||
1317 | { | ||
1318 | int err; | ||
1319 | |||
1320 | spin_lock(&enic->devcmd_lock); | ||
1321 | err = vnic_dev_hw_version(enic->vdev, hw_ver); | ||
1322 | spin_unlock(&enic->devcmd_lock); | ||
1323 | |||
1324 | return err; | ||
1325 | } | ||
1326 | |||
1267 | static int enic_set_rq_alloc_buf(struct enic *enic) | 1327 | static int enic_set_rq_alloc_buf(struct enic *enic) |
1268 | { | 1328 | { |
1269 | enum vnic_dev_hw_version hw_ver; | 1329 | enum vnic_dev_hw_version hw_ver; |
1270 | int err; | 1330 | int err; |
1271 | 1331 | ||
1272 | err = vnic_dev_hw_version(enic->vdev, &hw_ver); | 1332 | err = enic_dev_hw_version(enic, &hw_ver); |
1273 | if (err) | 1333 | if (err) |
1274 | return err; | 1334 | return err; |
1275 | 1335 | ||
@@ -1603,7 +1663,7 @@ static void enic_synchronize_irqs(struct enic *enic) | |||
1603 | } | 1663 | } |
1604 | } | 1664 | } |
1605 | 1665 | ||
1606 | static int enic_notify_set(struct enic *enic) | 1666 | static int enic_dev_notify_set(struct enic *enic) |
1607 | { | 1667 | { |
1608 | int err; | 1668 | int err; |
1609 | 1669 | ||
@@ -1624,6 +1684,39 @@ static int enic_notify_set(struct enic *enic) | |||
1624 | return err; | 1684 | return err; |
1625 | } | 1685 | } |
1626 | 1686 | ||
1687 | static int enic_dev_notify_unset(struct enic *enic) | ||
1688 | { | ||
1689 | int err; | ||
1690 | |||
1691 | spin_lock(&enic->devcmd_lock); | ||
1692 | err = vnic_dev_notify_unset(enic->vdev); | ||
1693 | spin_unlock(&enic->devcmd_lock); | ||
1694 | |||
1695 | return err; | ||
1696 | } | ||
1697 | |||
1698 | static int enic_dev_enable(struct enic *enic) | ||
1699 | { | ||
1700 | int err; | ||
1701 | |||
1702 | spin_lock(&enic->devcmd_lock); | ||
1703 | err = vnic_dev_enable(enic->vdev); | ||
1704 | spin_unlock(&enic->devcmd_lock); | ||
1705 | |||
1706 | return err; | ||
1707 | } | ||
1708 | |||
1709 | static int enic_dev_disable(struct enic *enic) | ||
1710 | { | ||
1711 | int err; | ||
1712 | |||
1713 | spin_lock(&enic->devcmd_lock); | ||
1714 | err = vnic_dev_disable(enic->vdev); | ||
1715 | spin_unlock(&enic->devcmd_lock); | ||
1716 | |||
1717 | return err; | ||
1718 | } | ||
1719 | |||
1627 | static void enic_notify_timer_start(struct enic *enic) | 1720 | static void enic_notify_timer_start(struct enic *enic) |
1628 | { | 1721 | { |
1629 | switch (vnic_dev_get_intr_mode(enic->vdev)) { | 1722 | switch (vnic_dev_get_intr_mode(enic->vdev)) { |
@@ -1650,7 +1743,7 @@ static int enic_open(struct net_device *netdev) | |||
1650 | return err; | 1743 | return err; |
1651 | } | 1744 | } |
1652 | 1745 | ||
1653 | err = enic_notify_set(enic); | 1746 | err = enic_dev_notify_set(enic); |
1654 | if (err) { | 1747 | if (err) { |
1655 | printk(KERN_ERR PFX | 1748 | printk(KERN_ERR PFX |
1656 | "%s: Failed to alloc notify buffer, aborting.\n", | 1749 | "%s: Failed to alloc notify buffer, aborting.\n", |
@@ -1680,9 +1773,7 @@ static int enic_open(struct net_device *netdev) | |||
1680 | 1773 | ||
1681 | netif_wake_queue(netdev); | 1774 | netif_wake_queue(netdev); |
1682 | napi_enable(&enic->napi); | 1775 | napi_enable(&enic->napi); |
1683 | spin_lock(&enic->devcmd_lock); | 1776 | enic_dev_enable(enic); |
1684 | vnic_dev_enable(enic->vdev); | ||
1685 | spin_unlock(&enic->devcmd_lock); | ||
1686 | 1777 | ||
1687 | for (i = 0; i < enic->intr_count; i++) | 1778 | for (i = 0; i < enic->intr_count; i++) |
1688 | vnic_intr_unmask(&enic->intr[i]); | 1779 | vnic_intr_unmask(&enic->intr[i]); |
@@ -1692,9 +1783,7 @@ static int enic_open(struct net_device *netdev) | |||
1692 | return 0; | 1783 | return 0; |
1693 | 1784 | ||
1694 | err_out_notify_unset: | 1785 | err_out_notify_unset: |
1695 | spin_lock(&enic->devcmd_lock); | 1786 | enic_dev_notify_unset(enic); |
1696 | vnic_dev_notify_unset(enic->vdev); | ||
1697 | spin_unlock(&enic->devcmd_lock); | ||
1698 | err_out_free_intr: | 1787 | err_out_free_intr: |
1699 | enic_free_intr(enic); | 1788 | enic_free_intr(enic); |
1700 | 1789 | ||
@@ -1715,9 +1804,7 @@ static int enic_stop(struct net_device *netdev) | |||
1715 | 1804 | ||
1716 | del_timer_sync(&enic->notify_timer); | 1805 | del_timer_sync(&enic->notify_timer); |
1717 | 1806 | ||
1718 | spin_lock(&enic->devcmd_lock); | 1807 | enic_dev_disable(enic); |
1719 | vnic_dev_disable(enic->vdev); | ||
1720 | spin_unlock(&enic->devcmd_lock); | ||
1721 | napi_disable(&enic->napi); | 1808 | napi_disable(&enic->napi); |
1722 | netif_carrier_off(netdev); | 1809 | netif_carrier_off(netdev); |
1723 | netif_tx_disable(netdev); | 1810 | netif_tx_disable(netdev); |
@@ -1735,9 +1822,7 @@ static int enic_stop(struct net_device *netdev) | |||
1735 | return err; | 1822 | return err; |
1736 | } | 1823 | } |
1737 | 1824 | ||
1738 | spin_lock(&enic->devcmd_lock); | 1825 | enic_dev_notify_unset(enic); |
1739 | vnic_dev_notify_unset(enic->vdev); | ||
1740 | spin_unlock(&enic->devcmd_lock); | ||
1741 | enic_free_intr(enic); | 1826 | enic_free_intr(enic); |
1742 | 1827 | ||
1743 | for (i = 0; i < enic->wq_count; i++) | 1828 | for (i = 0; i < enic->wq_count; i++) |
@@ -1870,15 +1955,31 @@ static int enic_set_niccfg(struct enic *enic) | |||
1870 | const u8 rss_enable = 0; | 1955 | const u8 rss_enable = 0; |
1871 | const u8 tso_ipid_split_en = 0; | 1956 | const u8 tso_ipid_split_en = 0; |
1872 | const u8 ig_vlan_strip_en = 1; | 1957 | const u8 ig_vlan_strip_en = 1; |
1958 | int err; | ||
1873 | 1959 | ||
1874 | /* Enable VLAN tag stripping. RSS not enabled (yet). | 1960 | /* Enable VLAN tag stripping. RSS not enabled (yet). |
1875 | */ | 1961 | */ |
1876 | 1962 | ||
1877 | return enic_set_nic_cfg(enic, | 1963 | spin_lock(&enic->devcmd_lock); |
1964 | err = enic_set_nic_cfg(enic, | ||
1878 | rss_default_cpu, rss_hash_type, | 1965 | rss_default_cpu, rss_hash_type, |
1879 | rss_hash_bits, rss_base_cpu, | 1966 | rss_hash_bits, rss_base_cpu, |
1880 | rss_enable, tso_ipid_split_en, | 1967 | rss_enable, tso_ipid_split_en, |
1881 | ig_vlan_strip_en); | 1968 | ig_vlan_strip_en); |
1969 | spin_unlock(&enic->devcmd_lock); | ||
1970 | |||
1971 | return err; | ||
1972 | } | ||
1973 | |||
1974 | static int enic_dev_hang_notify(struct enic *enic) | ||
1975 | { | ||
1976 | int err; | ||
1977 | |||
1978 | spin_lock(&enic->devcmd_lock); | ||
1979 | err = vnic_dev_hang_notify(enic->vdev); | ||
1980 | spin_unlock(&enic->devcmd_lock); | ||
1981 | |||
1982 | return err; | ||
1882 | } | 1983 | } |
1883 | 1984 | ||
1884 | int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic) | 1985 | int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic) |
@@ -1902,10 +2003,7 @@ static void enic_reset(struct work_struct *work) | |||
1902 | 2003 | ||
1903 | rtnl_lock(); | 2004 | rtnl_lock(); |
1904 | 2005 | ||
1905 | spin_lock(&enic->devcmd_lock); | 2006 | enic_dev_hang_notify(enic); |
1906 | vnic_dev_hang_notify(enic->vdev); | ||
1907 | spin_unlock(&enic->devcmd_lock); | ||
1908 | |||
1909 | enic_stop(enic->netdev); | 2007 | enic_stop(enic->netdev); |
1910 | enic_dev_hang_reset(enic); | 2008 | enic_dev_hang_reset(enic); |
1911 | enic_reset_multicast_list(enic); | 2009 | enic_reset_multicast_list(enic); |
@@ -2047,8 +2145,8 @@ static const struct net_device_ops enic_netdev_ops = { | |||
2047 | .ndo_start_xmit = enic_hard_start_xmit, | 2145 | .ndo_start_xmit = enic_hard_start_xmit, |
2048 | .ndo_get_stats = enic_get_stats, | 2146 | .ndo_get_stats = enic_get_stats, |
2049 | .ndo_validate_addr = eth_validate_addr, | 2147 | .ndo_validate_addr = eth_validate_addr, |
2050 | .ndo_set_multicast_list = enic_set_multicast_list, | ||
2051 | .ndo_set_mac_address = enic_set_mac_address, | 2148 | .ndo_set_mac_address = enic_set_mac_address, |
2149 | .ndo_set_multicast_list = enic_set_multicast_list, | ||
2052 | .ndo_change_mtu = enic_change_mtu, | 2150 | .ndo_change_mtu = enic_change_mtu, |
2053 | .ndo_vlan_rx_register = enic_vlan_rx_register, | 2151 | .ndo_vlan_rx_register = enic_vlan_rx_register, |
2054 | .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid, | 2152 | .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid, |
@@ -2066,6 +2164,17 @@ void enic_dev_deinit(struct enic *enic) | |||
2066 | enic_clear_intr_mode(enic); | 2164 | enic_clear_intr_mode(enic); |
2067 | } | 2165 | } |
2068 | 2166 | ||
2167 | static int enic_dev_stats_clear(struct enic *enic) | ||
2168 | { | ||
2169 | int err; | ||
2170 | |||
2171 | spin_lock(&enic->devcmd_lock); | ||
2172 | err = vnic_dev_stats_clear(enic->vdev); | ||
2173 | spin_unlock(&enic->devcmd_lock); | ||
2174 | |||
2175 | return err; | ||
2176 | } | ||
2177 | |||
2069 | int enic_dev_init(struct enic *enic) | 2178 | int enic_dev_init(struct enic *enic) |
2070 | { | 2179 | { |
2071 | struct net_device *netdev = enic->netdev; | 2180 | struct net_device *netdev = enic->netdev; |
@@ -2110,6 +2219,10 @@ int enic_dev_init(struct enic *enic) | |||
2110 | 2219 | ||
2111 | enic_init_vnic_resources(enic); | 2220 | enic_init_vnic_resources(enic); |
2112 | 2221 | ||
2222 | /* Clear LIF stats | ||
2223 | */ | ||
2224 | enic_dev_stats_clear(enic); | ||
2225 | |||
2113 | err = enic_set_rq_alloc_buf(enic); | 2226 | err = enic_set_rq_alloc_buf(enic); |
2114 | if (err) { | 2227 | if (err) { |
2115 | printk(KERN_ERR PFX | 2228 | printk(KERN_ERR PFX |
@@ -2293,6 +2406,11 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2293 | } | 2406 | } |
2294 | } | 2407 | } |
2295 | 2408 | ||
2409 | /* Setup devcmd lock | ||
2410 | */ | ||
2411 | |||
2412 | spin_lock_init(&enic->devcmd_lock); | ||
2413 | |||
2296 | err = enic_dev_init(enic); | 2414 | err = enic_dev_init(enic); |
2297 | if (err) { | 2415 | if (err) { |
2298 | printk(KERN_ERR PFX | 2416 | printk(KERN_ERR PFX |
@@ -2300,7 +2418,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2300 | goto err_out_dev_close; | 2418 | goto err_out_dev_close; |
2301 | } | 2419 | } |
2302 | 2420 | ||
2303 | /* Setup notification timer, HW reset task, and locks | 2421 | /* Setup notification timer, HW reset task, and wq locks |
2304 | */ | 2422 | */ |
2305 | 2423 | ||
2306 | init_timer(&enic->notify_timer); | 2424 | init_timer(&enic->notify_timer); |
@@ -2312,8 +2430,6 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2312 | for (i = 0; i < enic->wq_count; i++) | 2430 | for (i = 0; i < enic->wq_count; i++) |
2313 | spin_lock_init(&enic->wq_lock[i]); | 2431 | spin_lock_init(&enic->wq_lock[i]); |
2314 | 2432 | ||
2315 | spin_lock_init(&enic->devcmd_lock); | ||
2316 | |||
2317 | /* Register net device | 2433 | /* Register net device |
2318 | */ | 2434 | */ |
2319 | 2435 | ||
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c index 9b18840cba96..04cfc4e3f063 100644 --- a/drivers/net/enic/enic_res.c +++ b/drivers/net/enic/enic_res.c | |||
@@ -103,17 +103,7 @@ int enic_get_vnic_config(struct enic *enic) | |||
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |
105 | 105 | ||
106 | void enic_add_multicast_addr(struct enic *enic, u8 *addr) | 106 | int enic_add_vlan(struct enic *enic, u16 vlanid) |
107 | { | ||
108 | vnic_dev_add_addr(enic->vdev, addr); | ||
109 | } | ||
110 | |||
111 | void enic_del_multicast_addr(struct enic *enic, u8 *addr) | ||
112 | { | ||
113 | vnic_dev_del_addr(enic->vdev, addr); | ||
114 | } | ||
115 | |||
116 | void enic_add_vlan(struct enic *enic, u16 vlanid) | ||
117 | { | 107 | { |
118 | u64 a0 = vlanid, a1 = 0; | 108 | u64 a0 = vlanid, a1 = 0; |
119 | int wait = 1000; | 109 | int wait = 1000; |
@@ -122,9 +112,11 @@ void enic_add_vlan(struct enic *enic, u16 vlanid) | |||
122 | err = vnic_dev_cmd(enic->vdev, CMD_VLAN_ADD, &a0, &a1, wait); | 112 | err = vnic_dev_cmd(enic->vdev, CMD_VLAN_ADD, &a0, &a1, wait); |
123 | if (err) | 113 | if (err) |
124 | printk(KERN_ERR PFX "Can't add vlan id, %d\n", err); | 114 | printk(KERN_ERR PFX "Can't add vlan id, %d\n", err); |
115 | |||
116 | return err; | ||
125 | } | 117 | } |
126 | 118 | ||
127 | void enic_del_vlan(struct enic *enic, u16 vlanid) | 119 | int enic_del_vlan(struct enic *enic, u16 vlanid) |
128 | { | 120 | { |
129 | u64 a0 = vlanid, a1 = 0; | 121 | u64 a0 = vlanid, a1 = 0; |
130 | int wait = 1000; | 122 | int wait = 1000; |
@@ -133,6 +125,8 @@ void enic_del_vlan(struct enic *enic, u16 vlanid) | |||
133 | err = vnic_dev_cmd(enic->vdev, CMD_VLAN_DEL, &a0, &a1, wait); | 125 | err = vnic_dev_cmd(enic->vdev, CMD_VLAN_DEL, &a0, &a1, wait); |
134 | if (err) | 126 | if (err) |
135 | printk(KERN_ERR PFX "Can't delete vlan id, %d\n", err); | 127 | printk(KERN_ERR PFX "Can't delete vlan id, %d\n", err); |
128 | |||
129 | return err; | ||
136 | } | 130 | } |
137 | 131 | ||
138 | int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, | 132 | int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, |
@@ -304,11 +298,6 @@ void enic_init_vnic_resources(struct enic *enic) | |||
304 | enic->config.intr_timer_type, | 298 | enic->config.intr_timer_type, |
305 | mask_on_assertion); | 299 | mask_on_assertion); |
306 | } | 300 | } |
307 | |||
308 | /* Clear LIF stats | ||
309 | */ | ||
310 | |||
311 | vnic_dev_stats_clear(enic->vdev); | ||
312 | } | 301 | } |
313 | 302 | ||
314 | int enic_alloc_vnic_resources(struct enic *enic) | 303 | int enic_alloc_vnic_resources(struct enic *enic) |
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h index 494664f7fccc..3f6e039c2fd2 100644 --- a/drivers/net/enic/enic_res.h +++ b/drivers/net/enic/enic_res.h | |||
@@ -131,10 +131,8 @@ static inline void enic_queue_rq_desc(struct vnic_rq *rq, | |||
131 | struct enic; | 131 | struct enic; |
132 | 132 | ||
133 | int enic_get_vnic_config(struct enic *); | 133 | int enic_get_vnic_config(struct enic *); |
134 | void enic_add_multicast_addr(struct enic *enic, u8 *addr); | 134 | int enic_add_vlan(struct enic *enic, u16 vlanid); |
135 | void enic_del_multicast_addr(struct enic *enic, u8 *addr); | 135 | int enic_del_vlan(struct enic *enic, u16 vlanid); |
136 | void enic_add_vlan(struct enic *enic, u16 vlanid); | ||
137 | void enic_del_vlan(struct enic *enic, u16 vlanid); | ||
138 | int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, | 136 | int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, |
139 | u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en, | 137 | u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en, |
140 | u8 ig_vlan_strip_en); | 138 | u8 ig_vlan_strip_en); |
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index c93012f2faa9..bebadb325b9c 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c | |||
@@ -550,7 +550,7 @@ int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr) | |||
550 | return 0; | 550 | return 0; |
551 | } | 551 | } |
552 | 552 | ||
553 | void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, | 553 | int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, |
554 | int broadcast, int promisc, int allmulti) | 554 | int broadcast, int promisc, int allmulti) |
555 | { | 555 | { |
556 | u64 a0, a1 = 0; | 556 | u64 a0, a1 = 0; |
@@ -566,6 +566,8 @@ void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, | |||
566 | err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &a0, &a1, wait); | 566 | err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &a0, &a1, wait); |
567 | if (err) | 567 | if (err) |
568 | printk(KERN_ERR "Can't set packet filter\n"); | 568 | printk(KERN_ERR "Can't set packet filter\n"); |
569 | |||
570 | return err; | ||
569 | } | 571 | } |
570 | 572 | ||
571 | int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) | 573 | int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) |
@@ -670,22 +672,25 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) | |||
670 | return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr); | 672 | return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr); |
671 | } | 673 | } |
672 | 674 | ||
673 | void vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) | 675 | int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) |
674 | { | 676 | { |
675 | u64 a0, a1; | 677 | u64 a0, a1; |
676 | int wait = 1000; | 678 | int wait = 1000; |
679 | int err; | ||
677 | 680 | ||
678 | a0 = 0; /* paddr = 0 to unset notify buffer */ | 681 | a0 = 0; /* paddr = 0 to unset notify buffer */ |
679 | a1 = 0x0000ffff00000000ULL; /* intr num = -1 to unreg for intr */ | 682 | a1 = 0x0000ffff00000000ULL; /* intr num = -1 to unreg for intr */ |
680 | a1 += sizeof(struct vnic_devcmd_notify); | 683 | a1 += sizeof(struct vnic_devcmd_notify); |
681 | 684 | ||
682 | vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); | 685 | err = vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); |
683 | vdev->notify = NULL; | 686 | vdev->notify = NULL; |
684 | vdev->notify_pa = 0; | 687 | vdev->notify_pa = 0; |
685 | vdev->notify_sz = 0; | 688 | vdev->notify_sz = 0; |
689 | |||
690 | return err; | ||
686 | } | 691 | } |
687 | 692 | ||
688 | void vnic_dev_notify_unset(struct vnic_dev *vdev) | 693 | int vnic_dev_notify_unset(struct vnic_dev *vdev) |
689 | { | 694 | { |
690 | if (vdev->notify) { | 695 | if (vdev->notify) { |
691 | pci_free_consistent(vdev->pdev, | 696 | pci_free_consistent(vdev->pdev, |
@@ -694,7 +699,7 @@ void vnic_dev_notify_unset(struct vnic_dev *vdev) | |||
694 | vdev->notify_pa); | 699 | vdev->notify_pa); |
695 | } | 700 | } |
696 | 701 | ||
697 | vnic_dev_notify_unsetcmd(vdev); | 702 | return vnic_dev_notify_unsetcmd(vdev); |
698 | } | 703 | } |
699 | 704 | ||
700 | static int vnic_dev_notify_ready(struct vnic_dev *vdev) | 705 | static int vnic_dev_notify_ready(struct vnic_dev *vdev) |
@@ -839,6 +844,14 @@ u32 vnic_dev_notify_status(struct vnic_dev *vdev) | |||
839 | return vdev->notify_copy.status; | 844 | return vdev->notify_copy.status; |
840 | } | 845 | } |
841 | 846 | ||
847 | u32 vnic_dev_uif(struct vnic_dev *vdev) | ||
848 | { | ||
849 | if (!vnic_dev_notify_ready(vdev)) | ||
850 | return 0; | ||
851 | |||
852 | return vdev->notify_copy.uif; | ||
853 | } | ||
854 | |||
842 | void vnic_dev_set_intr_mode(struct vnic_dev *vdev, | 855 | void vnic_dev_set_intr_mode(struct vnic_dev *vdev, |
843 | enum vnic_dev_intr_mode intr_mode) | 856 | enum vnic_dev_intr_mode intr_mode) |
844 | { | 857 | { |
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h index 4980615fcee2..3a2968180641 100644 --- a/drivers/net/enic/vnic_dev.h +++ b/drivers/net/enic/vnic_dev.h | |||
@@ -101,7 +101,7 @@ int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, | |||
101 | int vnic_dev_stats_clear(struct vnic_dev *vdev); | 101 | int vnic_dev_stats_clear(struct vnic_dev *vdev); |
102 | int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats); | 102 | int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats); |
103 | int vnic_dev_hang_notify(struct vnic_dev *vdev); | 103 | int vnic_dev_hang_notify(struct vnic_dev *vdev); |
104 | void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, | 104 | int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, |
105 | int broadcast, int promisc, int allmulti); | 105 | int broadcast, int promisc, int allmulti); |
106 | int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr); | 106 | int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr); |
107 | int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr); | 107 | int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr); |
@@ -110,14 +110,15 @@ int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr); | |||
110 | int vnic_dev_notify_setcmd(struct vnic_dev *vdev, | 110 | int vnic_dev_notify_setcmd(struct vnic_dev *vdev, |
111 | void *notify_addr, dma_addr_t notify_pa, u16 intr); | 111 | void *notify_addr, dma_addr_t notify_pa, u16 intr); |
112 | int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr); | 112 | int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr); |
113 | void vnic_dev_notify_unsetcmd(struct vnic_dev *vdev); | 113 | int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev); |
114 | void vnic_dev_notify_unset(struct vnic_dev *vdev); | 114 | int vnic_dev_notify_unset(struct vnic_dev *vdev); |
115 | int vnic_dev_link_status(struct vnic_dev *vdev); | 115 | int vnic_dev_link_status(struct vnic_dev *vdev); |
116 | u32 vnic_dev_port_speed(struct vnic_dev *vdev); | 116 | u32 vnic_dev_port_speed(struct vnic_dev *vdev); |
117 | u32 vnic_dev_msg_lvl(struct vnic_dev *vdev); | 117 | u32 vnic_dev_msg_lvl(struct vnic_dev *vdev); |
118 | u32 vnic_dev_mtu(struct vnic_dev *vdev); | 118 | u32 vnic_dev_mtu(struct vnic_dev *vdev); |
119 | u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev); | 119 | u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev); |
120 | u32 vnic_dev_notify_status(struct vnic_dev *vdev); | 120 | u32 vnic_dev_notify_status(struct vnic_dev *vdev); |
121 | u32 vnic_dev_uif(struct vnic_dev *vdev); | ||
121 | int vnic_dev_close(struct vnic_dev *vdev); | 122 | int vnic_dev_close(struct vnic_dev *vdev); |
122 | int vnic_dev_enable(struct vnic_dev *vdev); | 123 | int vnic_dev_enable(struct vnic_dev *vdev); |
123 | int vnic_dev_disable(struct vnic_dev *vdev); | 124 | int vnic_dev_disable(struct vnic_dev *vdev); |