aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorWilliams, Mitch A <mitch.a.williams@intel.com>2010-02-09 20:44:05 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-12 19:56:08 -0500
commitebc08a6f47ee76ecad8e9f26c26e6ec9b46ca659 (patch)
tree08c46bdb0ae7ad752876a5cfdfd2350e0c53196d /net/core
parent95c26df829ba4a25f40595cadb4c9433883cbe28 (diff)
rtnetlink: Add VF config code to rtnetlink
Add code to allow rtnetlink clients to query and set VF information through the PF driver. Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/rtnetlink.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 62f3878a6010..42da96a4eeee 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -35,6 +35,7 @@
35#include <linux/security.h> 35#include <linux/security.h>
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/if_addr.h> 37#include <linux/if_addr.h>
38#include <linux/pci.h>
38 39
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
40#include <asm/system.h> 41#include <asm/system.h>
@@ -580,6 +581,15 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
580 a->tx_compressed = b->tx_compressed; 581 a->tx_compressed = b->tx_compressed;
581}; 582};
582 583
584static inline int rtnl_vfinfo_size(const struct net_device *dev)
585{
586 if (dev->dev.parent && dev_is_pci(dev->dev.parent))
587 return dev_num_vf(dev->dev.parent) *
588 sizeof(struct ifla_vf_info);
589 else
590 return 0;
591}
592
583static inline size_t if_nlmsg_size(const struct net_device *dev) 593static inline size_t if_nlmsg_size(const struct net_device *dev)
584{ 594{
585 return NLMSG_ALIGN(sizeof(struct ifinfomsg)) 595 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
@@ -597,6 +607,8 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
597 + nla_total_size(4) /* IFLA_MASTER */ 607 + nla_total_size(4) /* IFLA_MASTER */
598 + nla_total_size(1) /* IFLA_OPERSTATE */ 608 + nla_total_size(1) /* IFLA_OPERSTATE */
599 + nla_total_size(1) /* IFLA_LINKMODE */ 609 + nla_total_size(1) /* IFLA_LINKMODE */
610 + nla_total_size(4) /* IFLA_NUM_VF */
611 + nla_total_size(rtnl_vfinfo_size(dev)) /* IFLA_VFINFO */
600 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */ 612 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
601} 613}
602 614
@@ -665,6 +677,17 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
665 stats = dev_get_stats(dev); 677 stats = dev_get_stats(dev);
666 copy_rtnl_link_stats(nla_data(attr), stats); 678 copy_rtnl_link_stats(nla_data(attr), stats);
667 679
680 if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {
681 int i;
682 struct ifla_vf_info ivi;
683
684 NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
685 for (i = 0; i < dev_num_vf(dev->dev.parent); i++) {
686 if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
687 break;
688 NLA_PUT(skb, IFLA_VFINFO, sizeof(ivi), &ivi);
689 }
690 }
668 if (dev->rtnl_link_ops) { 691 if (dev->rtnl_link_ops) {
669 if (rtnl_link_fill(skb, dev) < 0) 692 if (rtnl_link_fill(skb, dev) < 0)
670 goto nla_put_failure; 693 goto nla_put_failure;
@@ -725,6 +748,12 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
725 [IFLA_LINKINFO] = { .type = NLA_NESTED }, 748 [IFLA_LINKINFO] = { .type = NLA_NESTED },
726 [IFLA_NET_NS_PID] = { .type = NLA_U32 }, 749 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
727 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, 750 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 },
751 [IFLA_VF_MAC] = { .type = NLA_BINARY,
752 .len = sizeof(struct ifla_vf_mac) },
753 [IFLA_VF_VLAN] = { .type = NLA_BINARY,
754 .len = sizeof(struct ifla_vf_vlan) },
755 [IFLA_VF_TX_RATE] = { .type = NLA_BINARY,
756 .len = sizeof(struct ifla_vf_tx_rate) },
728}; 757};
729EXPORT_SYMBOL(ifla_policy); 758EXPORT_SYMBOL(ifla_policy);
730 759
@@ -898,6 +927,44 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
898 write_unlock_bh(&dev_base_lock); 927 write_unlock_bh(&dev_base_lock);
899 } 928 }
900 929
930 if (tb[IFLA_VF_MAC]) {
931 struct ifla_vf_mac *ivm;
932 ivm = nla_data(tb[IFLA_VF_MAC]);
933 write_lock_bh(&dev_base_lock);
934 if (ops->ndo_set_vf_mac)
935 err = ops->ndo_set_vf_mac(dev, ivm->vf, ivm->mac);
936 write_unlock_bh(&dev_base_lock);
937 if (err < 0)
938 goto errout;
939 modified = 1;
940 }
941
942 if (tb[IFLA_VF_VLAN]) {
943 struct ifla_vf_vlan *ivv;
944 ivv = nla_data(tb[IFLA_VF_VLAN]);
945 write_lock_bh(&dev_base_lock);
946 if (ops->ndo_set_vf_vlan)
947 err = ops->ndo_set_vf_vlan(dev, ivv->vf,
948 (u16)ivv->vlan,
949 (u8)ivv->qos);
950 write_unlock_bh(&dev_base_lock);
951 if (err < 0)
952 goto errout;
953 modified = 1;
954 }
955 err = 0;
956
957 if (tb[IFLA_VF_TX_RATE]) {
958 struct ifla_vf_tx_rate *ivt;
959 ivt = nla_data(tb[IFLA_VF_TX_RATE]);
960 write_lock_bh(&dev_base_lock);
961 if (ops->ndo_set_vf_tx_rate)
962 err = ops->ndo_set_vf_tx_rate(dev, ivt->vf, ivt->rate);
963 write_unlock_bh(&dev_base_lock);
964 if (err < 0)
965 goto errout;
966 modified = 1;
967 }
901 err = 0; 968 err = 0;
902 969
903errout: 970errout: