* [net-next-2.6 PATCH 0/3] Add port-profile netlink support
@ 2010-05-04 4:53 Scott Feldman
2010-05-04 4:53 ` [net-next-2.6 PATCH 1/3] Add netdev/netlink port-profile support (take IV, was iovnl) Scott Feldman
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Scott Feldman @ 2010-05-04 4:53 UTC (permalink / raw)
To: davem; +Cc: netdev, chrisw, arnd
The following series adds port-profile netlink support and adds an
implementation to Cisco's enic netdev driver:
1/3: Adds port-profile netlink RTM_SETLINK/RTM_GETLINK support, and
adds matching netdev ops net_{set|get}_vf_port_profile.
2/3: Adds enic support for net_{set|get}_vf_port_profile for enic
dynamic devices.
3/3: (please don't apply) Enables SR-IOV support for enic to
illustrate support for port-profile netlink using SR-IOV-
compliant devices.
The SETLINK/GETLINK support follows the model for other IFLA_VF_* msgs used
for SR-IOV devices where the receipent of the netlink msg is the PF, but the
target is the VF.
The intent of this patch set is to cover both definitions of port-profile
as defined by Cisco's enic use and as defined by VSI discover protocol (VDP),
used in VEPA implemenations. While both definitions are based on pre-
standards, the concept of a port-profile to be applied to an external switch
port on behalf of a virtual machine interface is common, as well as many
of the fields defining the protocols.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu<roprabhu@cisco.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [net-next-2.6 PATCH 1/3] Add netdev/netlink port-profile support (take IV, was iovnl)
2010-05-04 4:53 [net-next-2.6 PATCH 0/3] Add port-profile netlink support Scott Feldman
@ 2010-05-04 4:53 ` Scott Feldman
2010-05-04 4:53 ` [net-next-2.6 PATCH 2/3] Add ndo_{set|get}_vf_port_profile op support for enic dynamic vnics Scott Feldman
2010-05-04 4:53 ` [net-next-2.6 PATCH 3/3] Add SR-IOV support to enic (please don't apply this patch) Scott Feldman
2 siblings, 0 replies; 4+ messages in thread
From: Scott Feldman @ 2010-05-04 4:53 UTC (permalink / raw)
To: davem; +Cc: netdev, chrisw, arnd
From: Scott Feldman <scofeldm@cisco.com>
Add new netdev ops ndo_{set|get}_vf_port_profile to allow setting of
port-profile on a netdev interface. Extends netlink socket RTM_SETLINK/
RTM_GETLINK with new sub cmd called IFLA_VF_PORT_PROFILE (added to end of
IFLA_cmd list).
A port-profile is used to configure/enable the external switch port backing
the netdev interface, not to configure the host-facing side of the netdev. A
port-profile is an identifier known to the switch. How port-profiles are
installed on the switch or how available port-profiles are made know to the
host is outside the scope of this patch.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg (more about that later)
communicates with the switch, and the switch port backing the host netdev
interface is configured/enabled based on the settings defined by the port-
profile. What those settings comprise, and how those settings are managed is
again outside the scope of this patch, since this patch only deals with the
first step in the flow.
Since we're using netlink sockets, the receiver of the RTM_SETLINK msg can
be in kernel- or user-space. For kernel-space recipient, rtnetlink.c, the
new ndo_set_vf_port_profile netdev op is called to set the port-profile.
User-space recipients can decide how they comminucate the IFLA_VF_PORT_PROFILE
to the external switch.
There is a RTM_GETLINK cmd to to return port-profile setting of an
interface and to also return the status of the last port-profile.
IFLA_VF_PORT_PROFILE is modeled after the existing IFLA_VF_* cmd where a
VF number is passed in to identify the virtual function (VF) of an SR-IOV-
capable device. In this case, the target of IFLA_VF_PORT_PROFILE msg is the
netdev physical function (PF) device. The PF will apply the port-profile
to the VF. IFLA_VF_PORT_PROFILE can also be used for devices that don't
adhere to SR-IOV and can apply the port-profile directly to the netdev
target. In this case, the VF number is ignored.
Passing in a NULL port-profile is used to delete the port-profile association.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu<roprabhu@cisco.com>
---
include/linux/if_link.h | 25 +++++++++++++++++++++++++
include/linux/netdevice.h | 10 ++++++++++
net/core/rtnetlink.c | 41 ++++++++++++++++++++++++++++++++++++++++-
3 files changed, 75 insertions(+), 1 deletions(-)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index cfd420b..d763358 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -116,6 +116,7 @@ enum {
IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */
IFLA_VFINFO,
IFLA_STATS64,
+ IFLA_VF_PORT_PROFILE,
__IFLA_MAX
};
@@ -259,4 +260,28 @@ struct ifla_vf_info {
__u32 qos;
__u32 tx_rate;
};
+
+enum {
+ IFLA_VF_PORT_PROFILE_STATUS_UNKNOWN,
+ IFLA_VF_PORT_PROFILE_STATUS_SUCCESS,
+ IFLA_VF_PORT_PROFILE_STATUS_INPROGRESS,
+ IFLA_VF_PORT_PROFILE_STATUS_ERROR,
+};
+
+#define IFLA_VF_PORT_PROFILE_MAX 40
+#define IFLA_VF_UUID_MAX 40
+#define IFLA_VF_CLIENT_NAME_MAX 40
+
+struct ifla_vf_port_profile {
+ __u32 vf;
+ __u32 flags;
+ __u32 status;
+ __u8 port_profile[IFLA_VF_PORT_PROFILE_MAX];
+ __u8 mac[32]; /* MAX_ADDR_LEN */
+ /* UUID e.g. "CEEFD3B1-9E11-11DE-BDFD-000BAB01C0FB" */
+ __u8 host_uuid[IFLA_VF_UUID_MAX];
+ __u8 client_uuid[IFLA_VF_UUID_MAX];
+ __u8 client_name[IFLA_VF_CLIENT_NAME_MAX]; /* e.g. "vm0-eth1" */
+};
+
#endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 3c5ed5f..949abdb 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -696,6 +696,10 @@ struct netdev_rx_queue {
* int (*ndo_set_vf_tx_rate)(struct net_device *dev, int vf, int rate);
* int (*ndo_get_vf_config)(struct net_device *dev,
* int vf, struct ifla_vf_info *ivf);
+ * int (*ndo_set_vf_port_profile)(struct net_device *dev, int vf,
+ * struct ifla_vf_port_profile *ivp);
+ * int (*ndo_get_vf_port_profile)(struct net_device *dev, int vf,
+ * struct ifla_vf_port_profile *ivp);
*/
#define HAVE_NET_DEVICE_OPS
struct net_device_ops {
@@ -744,6 +748,12 @@ struct net_device_ops {
int (*ndo_get_vf_config)(struct net_device *dev,
int vf,
struct ifla_vf_info *ivf);
+ int (*ndo_set_vf_port_profile)(
+ struct net_device *dev, int vf,
+ struct ifla_vf_port_profile *ivp);
+ int (*ndo_get_vf_port_profile)(
+ struct net_device *dev, int vf,
+ struct ifla_vf_port_profile *ivp);
#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
int (*ndo_fcoe_enable)(struct net_device *dev);
int (*ndo_fcoe_disable)(struct net_device *dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 78c8598..82420c9 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -747,17 +747,42 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
goto nla_put_failure;
copy_rtnl_link_stats64(nla_data(attr), stats);
+ if (dev->dev.parent)
+ NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
+ else
+ NLA_PUT_U32(skb, IFLA_NUM_VF, 0);
+
if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {
int i;
struct ifla_vf_info ivi;
- NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
for (i = 0; i < dev_num_vf(dev->dev.parent); i++) {
if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
break;
NLA_PUT(skb, IFLA_VFINFO, sizeof(ivi), &ivi);
}
}
+
+ if (dev->netdev_ops->ndo_get_vf_port_profile) {
+ struct ifla_vf_port_profile ivp;
+
+ if (dev->dev.parent) {
+ int i;
+
+ for (i = 0; i < dev_num_vf(dev->dev.parent); i++) {
+ if (dev->netdev_ops->ndo_get_vf_port_profile(
+ dev, i, &ivp))
+ break;
+ NLA_PUT(skb, IFLA_VF_PORT_PROFILE,
+ sizeof(ivp), &ivp);
+ }
+ } else if (!dev->netdev_ops->ndo_get_vf_port_profile(dev,
+ 0, &ivp)) {
+ NLA_PUT(skb, IFLA_VF_PORT_PROFILE,
+ sizeof(ivp), &ivp);
+ }
+ }
+
if (dev->rtnl_link_ops) {
if (rtnl_link_fill(skb, dev) < 0)
goto nla_put_failure;
@@ -824,6 +849,8 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
.len = sizeof(struct ifla_vf_vlan) },
[IFLA_VF_TX_RATE] = { .type = NLA_BINARY,
.len = sizeof(struct ifla_vf_tx_rate) },
+ [IFLA_VF_PORT_PROFILE] = { .type = NLA_BINARY,
+ .len = sizeof(struct ifla_vf_port_profile)},
};
EXPORT_SYMBOL(ifla_policy);
@@ -1028,6 +1055,18 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
}
err = 0;
+ if (tb[IFLA_VF_PORT_PROFILE]) {
+ struct ifla_vf_port_profile *ivp;
+ ivp = nla_data(tb[IFLA_VF_PORT_PROFILE]);
+ err = -EOPNOTSUPP;
+ if (ops->ndo_set_vf_port_profile)
+ err = ops->ndo_set_vf_port_profile(dev, ivp->vf, ivp);
+ if (err < 0)
+ goto errout;
+ modified = 1;
+ }
+ err = 0;
+
errout:
if (err < 0 && modified && net_ratelimit())
printk(KERN_WARNING "A link change request failed with "
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [net-next-2.6 PATCH 2/3] Add ndo_{set|get}_vf_port_profile op support for enic dynamic vnics
2010-05-04 4:53 [net-next-2.6 PATCH 0/3] Add port-profile netlink support Scott Feldman
2010-05-04 4:53 ` [net-next-2.6 PATCH 1/3] Add netdev/netlink port-profile support (take IV, was iovnl) Scott Feldman
@ 2010-05-04 4:53 ` Scott Feldman
2010-05-04 4:53 ` [net-next-2.6 PATCH 3/3] Add SR-IOV support to enic (please don't apply this patch) Scott Feldman
2 siblings, 0 replies; 4+ messages in thread
From: Scott Feldman @ 2010-05-04 4:53 UTC (permalink / raw)
To: davem; +Cc: netdev, chrisw, arnd
From: Scott Feldman <scofeldm@cisco.com>
Add enic ndo_{set|get}_vf_port_profile ops to support setting/getting
port-profile for enic dynamic devices. Enic dynamic devices are just like
normal enic eth devices except dynamic enics require an extra configuration
step to assign a port-profile identifier to the interface before the
interface is useable. Once a port-profile is assigned, link comes up on the
interface and is ready for I/O. The port-profile is used to configure the
network port assigned to the interface. The network port configuration
includes VLAN membership, QoS policies, and port security settings typical
of a data center network.
A dynamic enic is assigned a default random mac address. If no mac address
parameter is specified in the ndo_set_vf_port_profile op, the default random
mac address is used when assigning the port-profile. Otherwise the mac
address specified in the op is used.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu<roprabhu@cisco.com>
---
drivers/net/enic/Makefile | 2
drivers/net/enic/enic.h | 3 -
drivers/net/enic/enic_main.c | 200 +++++++++++++++++++++++++++++++++++++-----
drivers/net/enic/vnic_dev.c | 50 +++++++++++
drivers/net/enic/vnic_dev.h | 3 +
drivers/net/enic/vnic_vic.c | 73 +++++++++++++++
drivers/net/enic/vnic_vic.h | 59 ++++++++++++
7 files changed, 363 insertions(+), 27 deletions(-)
diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index 391c3bc..e7b6c31 100644
--- a/drivers/net/enic/Makefile
+++ b/drivers/net/enic/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_ENIC) := enic.o
enic-y := enic_main.o vnic_cq.o vnic_intr.o vnic_wq.o \
- enic_res.o vnic_dev.o vnic_rq.o
+ enic_res.o vnic_dev.o vnic_rq.o vnic_vic.o
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 5fa56f1..718033f 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -34,7 +34,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION "1.3.1.1"
+#define DRV_VERSION "1.3.1.1-pp"
#define DRV_COPYRIGHT "Copyright 2008-2009 Cisco Systems, Inc"
#define PFX DRV_NAME ": "
@@ -95,6 +95,7 @@ struct enic {
u32 port_mtu;
u32 rx_coalesce_usecs;
u32 tx_coalesce_usecs;
+ struct ifla_vf_port_profile pp;
/* work queue cache line section */
____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX];
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 1232887..8e5e46b 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -29,6 +29,7 @@
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
+#include <linux/if_link.h>
#include <linux/ethtool.h>
#include <linux/in.h>
#include <linux/ip.h>
@@ -40,6 +41,7 @@
#include "vnic_dev.h"
#include "vnic_intr.h"
#include "vnic_stats.h"
+#include "vnic_vic.h"
#include "enic_res.h"
#include "enic.h"
@@ -49,10 +51,12 @@
#define ENIC_DESC_MAX_SPLITS (MAX_TSO / WQ_ENET_MAX_DESC_LEN + 1)
#define PCI_DEVICE_ID_CISCO_VIC_ENET 0x0043 /* ethernet vnic */
+#define PCI_DEVICE_ID_CISCO_VIC_ENET_DYN 0x0044 /* enet dynamic vnic */
/* Supported devices */
static DEFINE_PCI_DEVICE_TABLE(enic_id_table) = {
{ PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET) },
+ { PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET_DYN) },
{ 0, } /* end of table */
};
@@ -113,6 +117,11 @@ static const struct enic_stat enic_rx_stats[] = {
static const unsigned int enic_n_tx_stats = ARRAY_SIZE(enic_tx_stats);
static const unsigned int enic_n_rx_stats = ARRAY_SIZE(enic_rx_stats);
+static int enic_is_dynamic(struct enic *enic)
+{
+ return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN;
+}
+
static int enic_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
@@ -810,14 +819,24 @@ static void enic_reset_mcaddrs(struct enic *enic)
static int enic_set_mac_addr(struct net_device *netdev, char *addr)
{
- if (!is_valid_ether_addr(addr))
- return -EADDRNOTAVAIL;
+ struct enic *enic = netdev_priv(netdev);
- memcpy(netdev->dev_addr, addr, netdev->addr_len);
+ if (enic_is_dynamic(enic)) {
+ random_ether_addr(netdev->dev_addr);
+ } else {
+ if (!is_valid_ether_addr(addr))
+ return -EADDRNOTAVAIL;
+ memcpy(netdev->dev_addr, addr, netdev->addr_len);
+ }
return 0;
}
+static int enic_set_mac_address(struct net_device *netdev, void *p)
+{
+ return -EOPNOTSUPP;
+}
+
/* netif_tx_lock held, BHs disabled */
static void enic_set_multicast_list(struct net_device *netdev)
{
@@ -922,6 +941,131 @@ static void enic_tx_timeout(struct net_device *netdev)
schedule_work(&enic->reset);
}
+static int enic_vnic_dev_deinit(struct enic *enic)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_deinit(enic->vdev);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
+static int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_init_prov(enic->vdev,
+ (u8 *)vp, vic_provinfo_size(vp));
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
+static int enic_dev_init_done(struct enic *enic, int *done, int *error)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_init_done(enic->vdev, done, error);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
+static int enic_provinfo_add_tlv_str(struct vic_provinfo *vp, u16 type,
+ u16 max_length, char *str)
+{
+ if (!str)
+ return 0;
+
+ if (strlen(str) + 1 > max_length)
+ return 0;
+
+ return vic_provinfo_add_tlv(vp, type, strlen(str) + 1, str);
+}
+
+static int enic_set_vf_port_profile(struct net_device *netdev, int vf,
+ struct ifla_vf_port_profile *ivp)
+{
+ struct enic *enic = netdev_priv(netdev);
+ struct vic_provinfo *vp;
+ u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
+ u8 *mac = ivp->mac;
+ int err;
+
+ if (!enic_is_dynamic(enic))
+ return -EOPNOTSUPP;
+
+ memset(&enic->pp, 0, sizeof(enic->pp));
+
+ enic_vnic_dev_deinit(enic);
+
+ if (strlen(ivp->port_profile) == 0)
+ return 0;
+
+ if (is_zero_ether_addr(mac))
+ mac = netdev->dev_addr;
+
+ if (!is_valid_ether_addr(mac))
+ return -EADDRNOTAVAIL;
+
+ vp = vic_provinfo_alloc(GFP_KERNEL, oui, VIC_PROVINFO_LINUX_TYPE);
+ if (!vp)
+ return -ENOMEM;
+
+ enic_provinfo_add_tlv_str(vp, VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR,
+ IFLA_VF_PORT_PROFILE_MAX, ivp->port_profile);
+ vic_provinfo_add_tlv(vp, VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR,
+ ETH_ALEN, mac);
+ enic_provinfo_add_tlv_str(vp, VIC_LINUX_PROV_TLV_HOST_UUID_STR,
+ IFLA_VF_UUID_MAX, ivp->host_uuid);
+ enic_provinfo_add_tlv_str(vp, VIC_LINUX_PROV_TLV_CLIENT_UUID_STR,
+ IFLA_VF_UUID_MAX, ivp->client_uuid);
+ enic_provinfo_add_tlv_str(vp, VIC_LINUX_PROV_TLV_CLIENT_NAME_STR,
+ IFLA_VF_CLIENT_NAME_MAX, ivp->client_name);
+
+ err = enic_dev_init_prov(enic, vp);
+ if (err)
+ goto err_out;
+
+ memcpy(&enic->pp, ivp, sizeof(enic->pp));
+
+err_out:
+ vic_provinfo_free(vp);
+
+ return err;
+}
+
+static int enic_get_vf_port_profile(struct net_device *netdev, int vf,
+ struct ifla_vf_port_profile *ivp)
+{
+ struct enic *enic = netdev_priv(netdev);
+ int err, error, done;
+
+ if (!enic_is_dynamic(enic))
+ return -EOPNOTSUPP;
+
+ enic->pp.status = IFLA_VF_PORT_PROFILE_STATUS_UNKNOWN;
+
+ err = enic_dev_init_done(enic, &done, &error);
+
+ if (err || error)
+ enic->pp.status = IFLA_VF_PORT_PROFILE_STATUS_ERROR;
+
+ if (!done)
+ enic->pp.status = IFLA_VF_PORT_PROFILE_STATUS_INPROGRESS;
+
+ if (!error)
+ enic->pp.status = IFLA_VF_PORT_PROFILE_STATUS_SUCCESS;
+
+ memcpy(ivp, &enic->pp, sizeof(enic->pp));
+
+ return 0;
+}
+
static void enic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf)
{
struct enic *enic = vnic_dev_priv(rq->vdev);
@@ -1440,10 +1584,12 @@ static int enic_open(struct net_device *netdev)
for (i = 0; i < enic->rq_count; i++)
vnic_rq_enable(&enic->rq[i]);
- spin_lock(&enic->devcmd_lock);
- enic_add_station_addr(enic);
- spin_unlock(&enic->devcmd_lock);
- enic_set_multicast_list(netdev);
+ if (!enic_is_dynamic(enic)) {
+ spin_lock(&enic->devcmd_lock);
+ enic_add_station_addr(enic);
+ spin_unlock(&enic->devcmd_lock);
+ enic_set_multicast_list(netdev);
+ }
netif_wake_queue(netdev);
napi_enable(&enic->napi);
@@ -1775,20 +1921,22 @@ static void enic_clear_intr_mode(struct enic *enic)
}
static const struct net_device_ops enic_netdev_ops = {
- .ndo_open = enic_open,
- .ndo_stop = enic_stop,
- .ndo_start_xmit = enic_hard_start_xmit,
- .ndo_get_stats = enic_get_stats,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_set_multicast_list = enic_set_multicast_list,
- .ndo_change_mtu = enic_change_mtu,
- .ndo_vlan_rx_register = enic_vlan_rx_register,
- .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid,
- .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid,
- .ndo_tx_timeout = enic_tx_timeout,
+ .ndo_open = enic_open,
+ .ndo_stop = enic_stop,
+ .ndo_start_xmit = enic_hard_start_xmit,
+ .ndo_get_stats = enic_get_stats,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = enic_set_multicast_list,
+ .ndo_set_mac_address = enic_set_mac_address,
+ .ndo_change_mtu = enic_change_mtu,
+ .ndo_vlan_rx_register = enic_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid,
+ .ndo_tx_timeout = enic_tx_timeout,
+ .ndo_set_vf_port_profile = enic_set_vf_port_profile,
+ .ndo_get_vf_port_profile = enic_get_vf_port_profile,
#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = enic_poll_controller,
+ .ndo_poll_controller = enic_poll_controller,
#endif
};
@@ -2010,11 +2158,13 @@ static int __devinit enic_probe(struct pci_dev *pdev,
netif_carrier_off(netdev);
- err = vnic_dev_init(enic->vdev, 0);
- if (err) {
- printk(KERN_ERR PFX
- "vNIC dev init failed, aborting.\n");
- goto err_out_dev_close;
+ if (!enic_is_dynamic(enic)) {
+ err = vnic_dev_init(enic->vdev, 0);
+ if (err) {
+ printk(KERN_ERR PFX
+ "vNIC dev init failed, aborting.\n");
+ goto err_out_dev_close;
+ }
}
err = enic_dev_init(enic);
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index d43a9d4..e351b0f 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -682,6 +682,56 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
return r;
}
+int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err)
+{
+ u64 a0 = 0, a1 = 0;
+ int wait = 1000;
+ int ret;
+
+ *done = 0;
+
+ ret = vnic_dev_cmd(vdev, CMD_INIT_STATUS, &a0, &a1, wait);
+ if (ret)
+ return ret;
+
+ *done = (a0 == 0);
+
+ *err = (a0 == 0) ? a1 : 0;
+
+ return 0;
+}
+
+int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len)
+{
+ u64 a0, a1 = len;
+ int wait = 1000;
+ u64 prov_pa;
+ void *prov_buf;
+ int ret;
+
+ prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa);
+ if (!prov_buf)
+ return -ENOMEM;
+
+ memcpy(prov_buf, buf, len);
+
+ a0 = prov_pa;
+
+ ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO, &a0, &a1, wait);
+
+ pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa);
+
+ return ret;
+}
+
+int vnic_dev_deinit(struct vnic_dev *vdev)
+{
+ u64 a0 = 0, a1 = 0;
+ int wait = 1000;
+
+ return vnic_dev_cmd(vdev, CMD_DEINIT, &a0, &a1, wait);
+}
+
int vnic_dev_link_status(struct vnic_dev *vdev)
{
if (vdev->linkstatus)
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index f5be640..27f5a5a 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -124,6 +124,9 @@ int vnic_dev_disable(struct vnic_dev *vdev);
int vnic_dev_open(struct vnic_dev *vdev, int arg);
int vnic_dev_open_done(struct vnic_dev *vdev, int *done);
int vnic_dev_init(struct vnic_dev *vdev, int arg);
+int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err);
+int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len);
+int vnic_dev_deinit(struct vnic_dev *vdev);
int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg);
int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done);
void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
diff --git a/drivers/net/enic/vnic_vic.c b/drivers/net/enic/vnic_vic.c
new file mode 100644
index 0000000..d769772
--- /dev/null
+++ b/drivers/net/enic/vnic_vic.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2010 Cisco Systems, Inc. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include "vnic_vic.h"
+
+struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, u8 *oui, u8 type)
+{
+ struct vic_provinfo *vp = kzalloc(VIC_PROVINFO_MAX_DATA, flags);
+
+ if (!vp || !oui)
+ return NULL;
+
+ memcpy(vp->oui, oui, sizeof(vp->oui));
+ vp->type = type;
+ vp->length = htonl(sizeof(vp->num_tlvs));
+
+ return vp;
+}
+
+void vic_provinfo_free(struct vic_provinfo *vp)
+{
+ kfree(vp);
+}
+
+int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
+ void *value)
+{
+ struct vic_provinfo_tlv *tlv;
+
+ if (!vp || !value)
+ return -EINVAL;
+
+ if (ntohl(vp->length) + sizeof(*tlv) + length >
+ VIC_PROVINFO_MAX_TLV_DATA)
+ return -ENOMEM;
+
+ tlv = (struct vic_provinfo_tlv *)((u8 *)vp->tlv +
+ ntohl(vp->length) - sizeof(vp->num_tlvs));
+
+ tlv->type = htons(type);
+ tlv->length = htons(length);
+ memcpy(tlv->value, value, length);
+
+ vp->num_tlvs = htonl(ntohl(vp->num_tlvs) + 1);
+ vp->length = htonl(ntohl(vp->length) + sizeof(*tlv) + length);
+
+ return 0;
+}
+
+size_t vic_provinfo_size(struct vic_provinfo *vp)
+{
+ return vp ? ntohl(vp->length) + sizeof(*vp) - sizeof(vp->num_tlvs) : 0;
+}
diff --git a/drivers/net/enic/vnic_vic.h b/drivers/net/enic/vnic_vic.h
new file mode 100644
index 0000000..085c2a2
--- /dev/null
+++ b/drivers/net/enic/vnic_vic.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2010 Cisco Systems, Inc. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef _VNIC_VIC_H_
+#define _VNIC_VIC_H_
+
+/* Note: All integer fields in NETWORK byte order */
+
+/* Note: String field lengths include null char */
+
+#define VIC_PROVINFO_CISCO_OUI { 0x00, 0x00, 0x0c }
+#define VIC_PROVINFO_LINUX_TYPE 0x2
+
+enum vic_linux_prov_tlv_type {
+ VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR = 0,
+ VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR = 1, /* u8[6] */
+ VIC_LINUX_PROV_TLV_CLIENT_NAME_STR = 2,
+ VIC_LINUX_PROV_TLV_HOST_UUID_STR = 8,
+ VIC_LINUX_PROV_TLV_CLIENT_UUID_STR = 9,
+};
+
+struct vic_provinfo {
+ u8 oui[3]; /* OUI of data provider */
+ u8 type; /* provider-specific type */
+ u32 length; /* length of data below */
+ u32 num_tlvs; /* number of tlvs */
+ struct vic_provinfo_tlv {
+ u16 type;
+ u16 length;
+ u8 value[0];
+ } tlv[0];
+} __attribute__ ((packed));
+
+#define VIC_PROVINFO_MAX_DATA 1385
+#define VIC_PROVINFO_MAX_TLV_DATA (VIC_PROVINFO_MAX_DATA - \
+ sizeof(struct vic_provinfo))
+
+struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, u8 *oui, u8 type);
+void vic_provinfo_free(struct vic_provinfo *vp);
+int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
+ void *value);
+size_t vic_provinfo_size(struct vic_provinfo *vp);
+
+#endif /* _VNIC_VIC_H_ */
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [net-next-2.6 PATCH 3/3] Add SR-IOV support to enic (please don't apply this patch)
2010-05-04 4:53 [net-next-2.6 PATCH 0/3] Add port-profile netlink support Scott Feldman
2010-05-04 4:53 ` [net-next-2.6 PATCH 1/3] Add netdev/netlink port-profile support (take IV, was iovnl) Scott Feldman
2010-05-04 4:53 ` [net-next-2.6 PATCH 2/3] Add ndo_{set|get}_vf_port_profile op support for enic dynamic vnics Scott Feldman
@ 2010-05-04 4:53 ` Scott Feldman
2 siblings, 0 replies; 4+ messages in thread
From: Scott Feldman @ 2010-05-04 4:53 UTC (permalink / raw)
To: davem; +Cc: netdev, chrisw, arnd
From: Scott Feldman <scofeldm@cisco.com>
This patch is to illustrate how port-profiles will be assigned to VFs in
a compliant SR-IOV enic device. Here the VF devices are dynamic enics and
the PF device is a "static" enic device. Only the PF device resonds to
ndo_vf_{set|get}_port_profile to set/get the port-profile on a VF. It's
not possible to set a port-profile on a PF since PFs have an immutable port
assignment on the external switch, established when the PF was provisioned.
The same driver (enic) is used for both PFs and VFs devices. The PF
enables N number of VFs based on a PF configuration parameter assigned
when the PF is provisioned.
While this patch is functionally complete, we (Cisco) need to do more testing
before we can cliam full SR-IOV support in Linux, so we ask that this patch
not be applied at this time. it is provide with this patch set for
illustrative purposes only to show how the port-profile netlink API would
be used for a SR-IOV compliant device that supports port-profiles.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu<roprabhu@cisco.com>
---
drivers/net/enic/enic.h | 5 +-
drivers/net/enic/enic_main.c | 96 +++++++++++++++++++++++++++++++-----------
drivers/net/enic/enic_res.c | 3 +
drivers/net/enic/vnic_dev.c | 12 +++--
drivers/net/enic/vnic_dev.h | 6 +--
drivers/net/enic/vnic_enet.h | 1
6 files changed, 86 insertions(+), 37 deletions(-)
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 718033f..4d00e5e 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -34,7 +34,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION "1.3.1.1-pp"
+#define DRV_VERSION "1.3.1.1-sr-iov"
#define DRV_COPYRIGHT "Copyright 2008-2009 Cisco Systems, Inc"
#define PFX DRV_NAME ": "
@@ -95,7 +95,8 @@ struct enic {
u32 port_mtu;
u32 rx_coalesce_usecs;
u32 tx_coalesce_usecs;
- struct ifla_vf_port_profile pp;
+ struct ifla_vf_port_profile *pp;
+ unsigned int vf_count;
/* work queue cache line section */
____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX];
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 8e5e46b..1488431 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -941,35 +941,36 @@ static void enic_tx_timeout(struct net_device *netdev)
schedule_work(&enic->reset);
}
-static int enic_vnic_dev_deinit(struct enic *enic)
+static int enic_vnic_dev_deinit(struct enic *enic, int vf)
{
int err;
spin_lock(&enic->devcmd_lock);
- err = vnic_dev_deinit(enic->vdev);
+ err = vnic_dev_deinit(enic->vdev, vf);
spin_unlock(&enic->devcmd_lock);
return err;
}
-static int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp)
+static int enic_dev_init_prov(struct enic *enic, int vf,
+ struct vic_provinfo *vp)
{
int err;
spin_lock(&enic->devcmd_lock);
- err = vnic_dev_init_prov(enic->vdev,
+ err = vnic_dev_init_prov(enic->vdev, vf,
(u8 *)vp, vic_provinfo_size(vp));
spin_unlock(&enic->devcmd_lock);
return err;
}
-static int enic_dev_init_done(struct enic *enic, int *done, int *error)
+static int enic_dev_init_done(struct enic *enic, int vf, int *done, int *error)
{
int err;
spin_lock(&enic->devcmd_lock);
- err = vnic_dev_init_done(enic->vdev, done, error);
+ err = vnic_dev_init_done(enic->vdev, vf, done, error);
spin_unlock(&enic->devcmd_lock);
return err;
@@ -993,23 +994,22 @@ static int enic_set_vf_port_profile(struct net_device *netdev, int vf,
struct enic *enic = netdev_priv(netdev);
struct vic_provinfo *vp;
u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
- u8 *mac = ivp->mac;
int err;
- if (!enic_is_dynamic(enic))
+ if (enic_is_dynamic(enic))
return -EOPNOTSUPP;
- memset(&enic->pp, 0, sizeof(enic->pp));
+ if (vf < 0 || vf >= enic->vf_count)
+ return -EOPNOTSUPP;
+
+ memset(&enic->pp[vf], 0, sizeof(enic->pp[vf]));
- enic_vnic_dev_deinit(enic);
+ enic_vnic_dev_deinit(enic, vf);
if (strlen(ivp->port_profile) == 0)
return 0;
- if (is_zero_ether_addr(mac))
- mac = netdev->dev_addr;
-
- if (!is_valid_ether_addr(mac))
+ if (!is_valid_ether_addr(ipv->mac))
return -EADDRNOTAVAIL;
vp = vic_provinfo_alloc(GFP_KERNEL, oui, VIC_PROVINFO_LINUX_TYPE);
@@ -1019,7 +1019,7 @@ static int enic_set_vf_port_profile(struct net_device *netdev, int vf,
enic_provinfo_add_tlv_str(vp, VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR,
IFLA_VF_PORT_PROFILE_MAX, ivp->port_profile);
vic_provinfo_add_tlv(vp, VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR,
- ETH_ALEN, mac);
+ ETH_ALEN, ivp->mac);
enic_provinfo_add_tlv_str(vp, VIC_LINUX_PROV_TLV_HOST_UUID_STR,
IFLA_VF_UUID_MAX, ivp->host_uuid);
enic_provinfo_add_tlv_str(vp, VIC_LINUX_PROV_TLV_CLIENT_UUID_STR,
@@ -1027,11 +1027,11 @@ static int enic_set_vf_port_profile(struct net_device *netdev, int vf,
enic_provinfo_add_tlv_str(vp, VIC_LINUX_PROV_TLV_CLIENT_NAME_STR,
IFLA_VF_CLIENT_NAME_MAX, ivp->client_name);
- err = enic_dev_init_prov(enic, vp);
+ err = enic_dev_init_prov(enic, vf, vp);
if (err)
goto err_out;
- memcpy(&enic->pp, ivp, sizeof(enic->pp));
+ memcpy(&enic->pp[vf], ivp, sizeof(enic->pp[vf]));
err_out:
vic_provinfo_free(vp);
@@ -1045,23 +1045,26 @@ static int enic_get_vf_port_profile(struct net_device *netdev, int vf,
struct enic *enic = netdev_priv(netdev);
int err, error, done;
- if (!enic_is_dynamic(enic))
+ if (enic_is_dynamic(enic))
+ return -EOPNOTSUPP;
+
+ if (vf < 0 || vf >= enic->vf_count)
return -EOPNOTSUPP;
- enic->pp.status = IFLA_VF_PORT_PROFILE_STATUS_UNKNOWN;
+ enic->pp[vf].status = IFLA_VF_PORT_PROFILE_STATUS_UNKNOWN;
- err = enic_dev_init_done(enic, &done, &error);
+ err = enic_dev_init_done(enic, vf, &done, &error);
if (err || error)
- enic->pp.status = IFLA_VF_PORT_PROFILE_STATUS_ERROR;
+ enic->pp[vf].status = IFLA_VF_PORT_PROFILE_STATUS_ERROR;
if (!done)
- enic->pp.status = IFLA_VF_PORT_PROFILE_STATUS_INPROGRESS;
+ enic->pp[vf].status = IFLA_VF_PORT_PROFILE_STATUS_INPROGRESS;
if (!error)
- enic->pp.status = IFLA_VF_PORT_PROFILE_STATUS_SUCCESS;
+ enic->pp[vf].status = IFLA_VF_PORT_PROFILE_STATUS_SUCCESS;
- memcpy(ivp, &enic->pp, sizeof(enic->pp));
+ memcpy(ivp, &enic->pp[vf], sizeof(enic->pp[vf]));
return 0;
}
@@ -2023,6 +2026,37 @@ err_out_free_vnic_resources:
return err;
}
+static int enic_enable_vfs(struct enic *enic)
+{
+ int err;
+
+ enic->vf_count = enic->config.vf_count;
+
+ enic->pp = kzalloc(enic->vf_count *
+ sizeof(struct ifla_vf_port_profile), GFP_KERNEL);
+ if (!enic->pp)
+ return -ENOMEM;
+
+ if (enic->pdev->is_physfn && enic->vf_count > 0) {
+
+ err = pci_enable_sriov(enic->pdev, enic->vf_count);
+ if (err) {
+ kfree(enic->pp);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static void enic_disable_vfs(struct enic *enic)
+{
+ if (enic->pdev->is_physfn && enic->vf_count > 0)
+ pci_disable_sriov(enic->pdev);
+ kfree(enic->pp);
+ enic->vf_count = 0;
+}
+
static void enic_iounmap(struct enic *enic)
{
unsigned int i;
@@ -2174,6 +2208,13 @@ static int __devinit enic_probe(struct pci_dev *pdev,
goto err_out_dev_close;
}
+ err = enic_enable_vfs(enic);
+ if (err) {
+ printk(KERN_ERR PFX
+ "SR-IOV VF enable failed, aborting.\n");
+ goto err_out_dev_deinit;
+ }
+
/* Setup notification timer, HW reset task, and locks
*/
@@ -2198,7 +2239,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
if (err) {
printk(KERN_ERR PFX
"Invalid MAC address, aborting.\n");
- goto err_out_dev_deinit;
+ goto err_out_disable_vfs;
}
enic->tx_coalesce_usecs = enic->config.intr_timer_usec;
@@ -2234,11 +2275,13 @@ static int __devinit enic_probe(struct pci_dev *pdev,
if (err) {
printk(KERN_ERR PFX
"Cannot register net device, aborting.\n");
- goto err_out_dev_deinit;
+ goto err_out_disable_vfs;
}
return 0;
+err_out_disable_vfs:
+ enic_disable_vfs(enic);
err_out_dev_deinit:
enic_dev_deinit(enic);
err_out_dev_close:
@@ -2267,6 +2310,7 @@ static void __devexit enic_remove(struct pci_dev *pdev)
flush_scheduled_work();
unregister_netdev(netdev);
+ enic_disable_vfs(enic);
enic_dev_deinit(enic);
vnic_dev_close(enic->vdev);
vnic_dev_unregister(enic->vdev);
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 02839bf..dfb37f2 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -69,6 +69,7 @@ int enic_get_vnic_config(struct enic *enic)
GET_CONFIG(intr_timer_type);
GET_CONFIG(intr_mode);
GET_CONFIG(intr_timer_usec);
+ GET_CONFIG(vf_count);
c->wq_desc_count =
min_t(u32, ENIC_MAX_WQ_DESCS,
@@ -99,6 +100,8 @@ int enic_get_vnic_config(struct enic *enic)
c->mtu, ENIC_SETTING(enic, TXCSUM),
ENIC_SETTING(enic, RXCSUM), ENIC_SETTING(enic, TSO),
ENIC_SETTING(enic, LRO), c->intr_timer_usec);
+ if (c->vf_count)
+ printk(KERN_INFO PFX "vNIC SR-IOV VF count %d\n", c->vf_count);
return 0;
}
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index e351b0f..261d5f0 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -682,9 +682,9 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
return r;
}
-int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err)
+int vnic_dev_init_done(struct vnic_dev *vdev, u16 vf, int *done, int *err)
{
- u64 a0 = 0, a1 = 0;
+ u64 a0 = vf, a1 = 0;
int wait = 1000;
int ret;
@@ -701,9 +701,9 @@ int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err)
return 0;
}
-int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len)
+int vnic_dev_init_prov(struct vnic_dev *vdev, u16 vf, u8 *buf, u32 len)
{
- u64 a0, a1 = len;
+ u64 a0, a1 = (u64)len | ((u64)vf << 32);
int wait = 1000;
u64 prov_pa;
void *prov_buf;
@@ -724,9 +724,9 @@ int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len)
return ret;
}
-int vnic_dev_deinit(struct vnic_dev *vdev)
+int vnic_dev_deinit(struct vnic_dev *vdev, u16 vf)
{
- u64 a0 = 0, a1 = 0;
+ u64 a0 = vf, a1 = 0;
int wait = 1000;
return vnic_dev_cmd(vdev, CMD_DEINIT, &a0, &a1, wait);
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index 27f5a5a..d508187 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -124,9 +124,9 @@ int vnic_dev_disable(struct vnic_dev *vdev);
int vnic_dev_open(struct vnic_dev *vdev, int arg);
int vnic_dev_open_done(struct vnic_dev *vdev, int *done);
int vnic_dev_init(struct vnic_dev *vdev, int arg);
-int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err);
-int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len);
-int vnic_dev_deinit(struct vnic_dev *vdev);
+int vnic_dev_init_done(struct vnic_dev *vdev, u16 vf, int *done, int *err);
+int vnic_dev_init_prov(struct vnic_dev *vdev, u16 vf, u8 *buf, u32 len);
+int vnic_dev_deinit(struct vnic_dev *vdev, u16 vf);
int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg);
int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done);
void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
diff --git a/drivers/net/enic/vnic_enet.h b/drivers/net/enic/vnic_enet.h
index 8eeb675..466a7b3 100644
--- a/drivers/net/enic/vnic_enet.h
+++ b/drivers/net/enic/vnic_enet.h
@@ -35,6 +35,7 @@ struct vnic_enet_config {
u8 intr_mode;
char devname[16];
u32 intr_timer_usec;
+ u16 vf_count;
};
#define VENETF_TSO 0x1 /* TSO enabled */
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-05-04 4:53 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-04 4:53 [net-next-2.6 PATCH 0/3] Add port-profile netlink support Scott Feldman
2010-05-04 4:53 ` [net-next-2.6 PATCH 1/3] Add netdev/netlink port-profile support (take IV, was iovnl) Scott Feldman
2010-05-04 4:53 ` [net-next-2.6 PATCH 2/3] Add ndo_{set|get}_vf_port_profile op support for enic dynamic vnics Scott Feldman
2010-05-04 4:53 ` [net-next-2.6 PATCH 3/3] Add SR-IOV support to enic (please don't apply this patch) Scott Feldman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).