netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [net-next-2.6 PATCH 0/3] enic: updates to version 2.1.1.28
@ 2011-09-22 13:44 Roopa Prabhu
  2011-09-22 13:44 ` [net-next-2.6 PATCH 1/3] enic: Add SRIOV support Roopa Prabhu
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Roopa Prabhu @ 2011-09-22 13:44 UTC (permalink / raw)
  To: netdev; +Cc: davem

This patch series implements the following enic driver updates:

01/3 - Add SRIOV support
02/3 - Helper code for SRIOV proxy commands
03/3 - Add support for port profile association on a enic SRIOV VF

Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: Sujith Sankar <ssujith@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [net-next-2.6 PATCH 1/3] enic: Add SRIOV support
  2011-09-22 13:44 [net-next-2.6 PATCH 0/3] enic: updates to version 2.1.1.28 Roopa Prabhu
@ 2011-09-22 13:44 ` Roopa Prabhu
  2011-09-22 13:44 ` [net-next-2.6 PATCH 2/3] enic: Helper code for SRIOV proxy commands Roopa Prabhu
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Roopa Prabhu @ 2011-09-22 13:44 UTC (permalink / raw)
  To: netdev; +Cc: davem

From: Roopa Prabhu <roprabhu@cisco.com>

This patch adds support to enable SRIOV on enic devices. Enic SRIOV VF's are dynamic vnics and will use the same driver code as dynamic vnics.

Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: Sujith Sankar <ssujith@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
---
 drivers/net/ethernet/cisco/enic/enic.h      |   11 ++++++
 drivers/net/ethernet/cisco/enic/enic_main.c |   48 ++++++++++++++++++++++++++-
 2 files changed, 57 insertions(+), 2 deletions(-)


diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index ce76d9a..13ff78e 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -32,7 +32,7 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION		"2.1.1.24"
+#define DRV_VERSION		"2.1.1.28"
 #define DRV_COPYRIGHT		"Copyright 2008-2011 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX		6
@@ -49,6 +49,10 @@ struct enic_msix_entry {
 	void *devid;
 };
 
+/* priv_flags */
+#define ENIC_SRIOV_ENABLED		(1 << 0)
+
+/* enic port profile set flags */
 #define ENIC_PORT_REQUEST_APPLIED	(1 << 0)
 #define ENIC_SET_REQUEST		(1 << 1)
 #define ENIC_SET_NAME			(1 << 2)
@@ -83,11 +87,15 @@ struct enic {
 	u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN];
 	u8 uc_addr[ENIC_UNICAST_PERFECT_FILTERS][ETH_ALEN];
 	unsigned int flags;
+	unsigned int priv_flags;
 	unsigned int mc_count;
 	unsigned int uc_count;
 	u32 port_mtu;
 	u32 rx_coalesce_usecs;
 	u32 tx_coalesce_usecs;
+#ifdef CONFIG_PCI_IOV
+	u32 num_vfs;
+#endif
 	struct enic_port_profile pp;
 
 	/* work queue cache line section */
@@ -120,5 +128,6 @@ static inline struct device *enic_get_dev(struct enic *enic)
 }
 
 void enic_reset_addr_lists(struct enic *enic);
+int enic_sriov_enabled(struct enic *enic);
 
 #endif /* _ENIC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index c751c25..ad6580e 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -127,6 +127,11 @@ static int enic_is_dynamic(struct enic *enic)
 	return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN;
 }
 
+int enic_sriov_enabled(struct enic *enic)
+{
+	return (enic->priv_flags & ENIC_SRIOV_ENABLED) ? 1 : 0;
+}
+
 static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq)
 {
 	return rq;
@@ -2240,6 +2245,9 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 	int using_dac = 0;
 	unsigned int i;
 	int err;
+#ifdef CONFIG_PCI_IOV
+	int pos = 0;
+#endif
 
 	/* Allocate net device structure and initialize.  Private
 	 * instance data is initialized to zero.
@@ -2331,13 +2339,32 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 		goto err_out_iounmap;
 	}
 
+#ifdef CONFIG_PCI_IOV
+	/* Get number of subvnics */
+	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
+	if (pos) {
+		pci_read_config_word(pdev, pos + PCI_SRIOV_TOTAL_VF,
+			(u16 *)&enic->num_vfs);
+		if (enic->num_vfs) {
+			err = pci_enable_sriov(pdev, enic->num_vfs);
+			if (err) {
+				dev_err(dev, "SRIOV enable failed, aborting."
+					" pci_enable_sriov() returned %d\n",
+					err);
+				goto err_out_vnic_unregister;
+			}
+			enic->priv_flags |= ENIC_SRIOV_ENABLED;
+		}
+	}
+
+#endif
 	/* Issue device open to get device in known state
 	 */
 
 	err = enic_dev_open(enic);
 	if (err) {
 		dev_err(dev, "vNIC dev open failed, aborting\n");
-		goto err_out_vnic_unregister;
+		goto err_out_disable_sriov;
 	}
 
 	/* Setup devcmd lock
@@ -2404,6 +2431,12 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 	enic->port_mtu = enic->config.mtu;
 	(void)enic_change_mtu(netdev, enic->port_mtu);
 
+#ifdef CONFIG_PCI_IOV
+	if (enic_is_dynamic(enic) && pdev->is_virtfn &&
+		is_zero_ether_addr(enic->mac_addr))
+		random_ether_addr(enic->mac_addr);
+#endif
+
 	err = enic_set_mac_addr(netdev, enic->mac_addr);
 	if (err) {
 		dev_err(dev, "Invalid MAC address, aborting\n");
@@ -2455,8 +2488,15 @@ err_out_dev_deinit:
 	enic_dev_deinit(enic);
 err_out_dev_close:
 	vnic_dev_close(enic->vdev);
+err_out_disable_sriov:
+#ifdef CONFIG_PCI_IOV
+	if (enic_sriov_enabled(enic)) {
+		pci_disable_sriov(pdev);
+		enic->priv_flags &= ~ENIC_SRIOV_ENABLED;
+	}
 err_out_vnic_unregister:
 	vnic_dev_unregister(enic->vdev);
+#endif
 err_out_iounmap:
 	enic_iounmap(enic);
 err_out_release_regions:
@@ -2482,6 +2522,12 @@ static void __devexit enic_remove(struct pci_dev *pdev)
 		unregister_netdev(netdev);
 		enic_dev_deinit(enic);
 		vnic_dev_close(enic->vdev);
+#ifdef CONFIG_PCI_IOV
+		if (enic_sriov_enabled(enic)) {
+			pci_disable_sriov(pdev);
+			enic->priv_flags &= ~ENIC_SRIOV_ENABLED;
+		}
+#endif
 		vnic_dev_unregister(enic->vdev);
 		enic_iounmap(enic);
 		pci_release_regions(pdev);

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [net-next-2.6 PATCH 2/3] enic: Helper code for SRIOV proxy commands
  2011-09-22 13:44 [net-next-2.6 PATCH 0/3] enic: updates to version 2.1.1.28 Roopa Prabhu
  2011-09-22 13:44 ` [net-next-2.6 PATCH 1/3] enic: Add SRIOV support Roopa Prabhu
@ 2011-09-22 13:44 ` Roopa Prabhu
  2011-09-22 13:44 ` [net-next-2.6 PATCH 3/3] enic: Add support for port profile association on a enic SRIOV VF Roopa Prabhu
  2011-09-27  5:13 ` [net-next-2.6 PATCH 0/3] enic: updates to version 2.1.1.28 David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Roopa Prabhu @ 2011-09-22 13:44 UTC (permalink / raw)
  To: netdev; +Cc: davem

From: Roopa Prabhu <roprabhu@cisco.com>

This patch adds helper functions to use PF as proxy for SRIOV VF firmware
commands.

Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: Sujith Sankar <ssujith@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
---
 drivers/net/ethernet/cisco/enic/enic.h      |    1 +
 drivers/net/ethernet/cisco/enic/enic_dev.h  |   19 ++++++++++++++++++
 drivers/net/ethernet/cisco/enic/enic_main.c |    9 +++++++++
 drivers/net/ethernet/cisco/enic/vnic_dev.c  |   28 ++++++++++++++++++++++-----
 drivers/net/ethernet/cisco/enic/vnic_dev.h  |    2 ++
 5 files changed, 54 insertions(+), 5 deletions(-)


diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index 13ff78e..8c5cfb5 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -129,5 +129,6 @@ static inline struct device *enic_get_dev(struct enic *enic)
 
 void enic_reset_addr_lists(struct enic *enic);
 int enic_sriov_enabled(struct enic *enic);
+int enic_is_valid_vf(struct enic *enic, int vf);
 
 #endif /* _ENIC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic_dev.h b/drivers/net/ethernet/cisco/enic/enic_dev.h
index ff8e87f..1f83a47 100644
--- a/drivers/net/ethernet/cisco/enic/enic_dev.h
+++ b/drivers/net/ethernet/cisco/enic/enic_dev.h
@@ -19,6 +19,25 @@
 #ifndef _ENIC_DEV_H_
 #define _ENIC_DEV_H_
 
+#include "vnic_dev.h"
+
+/*
+ * Calls the devcmd function given by argument vnicdevcmdfn.
+ * If vf argument is valid, it proxies the devcmd
+ */
+#define ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnicdevcmdfn, ...) \
+	do { \
+		spin_lock(&enic->devcmd_lock); \
+		if (enic_is_valid_vf(enic, vf)) { \
+			vnic_dev_cmd_proxy_by_index_start(enic->vdev, vf); \
+			err = vnicdevcmdfn(enic->vdev, ##__VA_ARGS__); \
+			vnic_dev_cmd_proxy_end(enic->vdev); \
+		} else { \
+			err = vnicdevcmdfn(enic->vdev, ##__VA_ARGS__); \
+		} \
+		spin_unlock(&enic->devcmd_lock); \
+	} while (0)
+
 int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info);
 int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats);
 int enic_dev_add_station_addr(struct enic *enic);
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index ad6580e..154cb99 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -132,6 +132,15 @@ int enic_sriov_enabled(struct enic *enic)
 	return (enic->priv_flags & ENIC_SRIOV_ENABLED) ? 1 : 0;
 }
 
+int enic_is_valid_vf(struct enic *enic, int vf)
+{
+#ifdef CONFIG_PCI_IOV
+	return vf >= 0 && vf < enic->num_vfs;
+#else
+	return 0;
+#endif
+}
+
 static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq)
 {
 	return rq;
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.c b/drivers/net/ethernet/cisco/enic/vnic_dev.c
index 8c4c8cf..31e7f9b 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_dev.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.c
@@ -32,6 +32,7 @@
 enum vnic_proxy_type {
 	PROXY_NONE,
 	PROXY_BY_BDF,
+	PROXY_BY_INDEX,
 };
 
 struct vnic_res {
@@ -328,20 +329,21 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	return -ETIMEDOUT;
 }
 
-static int vnic_dev_cmd_proxy_by_bdf(struct vnic_dev *vdev,
-	enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait)
+static int vnic_dev_cmd_proxy(struct vnic_dev *vdev,
+	enum vnic_devcmd_cmd proxy_cmd, enum vnic_devcmd_cmd cmd,
+	u64 *a0, u64 *a1, int wait)
 {
 	u32 status;
 	int err;
 
 	memset(vdev->args, 0, sizeof(vdev->args));
 
-	vdev->args[0] = vdev->proxy_index; /* bdf */
+	vdev->args[0] = vdev->proxy_index;
 	vdev->args[1] = cmd;
 	vdev->args[2] = *a0;
 	vdev->args[3] = *a1;
 
-	err = _vnic_dev_cmd(vdev, CMD_PROXY_BY_BDF, wait);
+	err = _vnic_dev_cmd(vdev, proxy_cmd, wait);
 	if (err)
 		return err;
 
@@ -376,14 +378,30 @@ static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev,
 	return err;
 }
 
+void vnic_dev_cmd_proxy_by_index_start(struct vnic_dev *vdev, u16 index)
+{
+	vdev->proxy = PROXY_BY_INDEX;
+	vdev->proxy_index = index;
+}
+
+void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev)
+{
+	vdev->proxy = PROXY_NONE;
+	vdev->proxy_index = 0;
+}
+
 int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	u64 *a0, u64 *a1, int wait)
 {
 	memset(vdev->args, 0, sizeof(vdev->args));
 
 	switch (vdev->proxy) {
+	case PROXY_BY_INDEX:
+		return vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_INDEX, cmd,
+				a0, a1, wait);
 	case PROXY_BY_BDF:
-		return vnic_dev_cmd_proxy_by_bdf(vdev, cmd, a0, a1, wait);
+		return vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_BDF, cmd,
+				a0, a1, wait);
 	case PROXY_NONE:
 	default:
 		return vnic_dev_cmd_no_proxy(vdev, cmd, a0, a1, wait);
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.h b/drivers/net/ethernet/cisco/enic/vnic_dev.h
index 852b698..6a138b6 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_dev.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.h
@@ -85,6 +85,8 @@ void vnic_dev_free_desc_ring(struct vnic_dev *vdev,
 	struct vnic_dev_ring *ring);
 int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	u64 *a0, u64 *a1, int wait);
+void vnic_dev_cmd_proxy_by_index_start(struct vnic_dev *vdev, u16 index);
+void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev);
 int vnic_dev_fw_info(struct vnic_dev *vdev,
 	struct vnic_devcmd_fw_info **fw_info);
 int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [net-next-2.6 PATCH 3/3] enic: Add support for port profile association on a enic SRIOV VF
  2011-09-22 13:44 [net-next-2.6 PATCH 0/3] enic: updates to version 2.1.1.28 Roopa Prabhu
  2011-09-22 13:44 ` [net-next-2.6 PATCH 1/3] enic: Add SRIOV support Roopa Prabhu
  2011-09-22 13:44 ` [net-next-2.6 PATCH 2/3] enic: Helper code for SRIOV proxy commands Roopa Prabhu
@ 2011-09-22 13:44 ` Roopa Prabhu
  2011-09-27  5:13 ` [net-next-2.6 PATCH 0/3] enic: updates to version 2.1.1.28 David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Roopa Prabhu @ 2011-09-22 13:44 UTC (permalink / raw)
  To: netdev; +Cc: davem

From: Roopa Prabhu <roprabhu@cisco.com>

This patch touchs most of the enic port profile handling code.
Tried to break it into sub patches without success.

The patch mainly does the following:
- Port profile operations for a SRIOV VF are modified to work
  only via its PF
- Changes the port profile static struct in struct enic to a pointer.
  This is because a SRIOV PF has to now hold the port profile information
  for all its VF's
- Moved address registration for VF's during port profile ASSOCIATE time
- Most changes in port profile handling code are changes related to indexing
  into the port profile struct array of a PF for the VF port profile
  information

Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: Sujith Sankar <ssujith@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
---
 drivers/net/ethernet/cisco/enic/enic.h      |    3 
 drivers/net/ethernet/cisco/enic/enic_main.c |  118 ++++++++++-------
 drivers/net/ethernet/cisco/enic/enic_pp.c   |  192 +++++++++++++++++++++------
 drivers/net/ethernet/cisco/enic/enic_pp.h   |   15 ++
 4 files changed, 232 insertions(+), 96 deletions(-)


diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index 8c5cfb5..fe0c29a 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -96,7 +96,7 @@ struct enic {
 #ifdef CONFIG_PCI_IOV
 	u32 num_vfs;
 #endif
-	struct enic_port_profile pp;
+	struct enic_port_profile *pp;
 
 	/* work queue cache line section */
 	____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX];
@@ -130,5 +130,6 @@ static inline struct device *enic_get_dev(struct enic *enic)
 void enic_reset_addr_lists(struct enic *enic);
 int enic_sriov_enabled(struct enic *enic);
 int enic_is_valid_vf(struct enic *enic, int vf);
+int enic_is_dynamic(struct enic *enic);
 
 #endif /* _ENIC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 154cb99..bf95348 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -122,7 +122,7 @@ 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)
+int enic_is_dynamic(struct enic *enic)
 {
 	return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN;
 }
@@ -1054,15 +1054,15 @@ static void enic_tx_timeout(struct net_device *netdev)
 static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
 {
 	struct enic *enic = netdev_priv(netdev);
+	struct enic_port_profile *pp;
+	int err;
 
-	if (vf != PORT_SELF_VF)
-		return -EOPNOTSUPP;
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
 
-	/* Ignore the vf argument for now. We can assume the request
-	 * is coming on a vf.
-	 */
 	if (is_valid_ether_addr(mac)) {
-		memcpy(enic->pp.vf_mac, mac, ETH_ALEN);
+		memcpy(pp->vf_mac, mac, ETH_ALEN);
 		return 0;
 	} else
 		return -EINVAL;
@@ -1073,71 +1073,74 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
 {
 	struct enic *enic = netdev_priv(netdev);
 	struct enic_port_profile prev_pp;
+	struct enic_port_profile *pp;
 	int err = 0, restore_pp = 1;
 
-	/* don't support VFs, yet */
-	if (vf != PORT_SELF_VF)
-		return -EOPNOTSUPP;
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
 
 	if (!port[IFLA_PORT_REQUEST])
 		return -EOPNOTSUPP;
 
-	memcpy(&prev_pp, &enic->pp, sizeof(enic->pp));
-	memset(&enic->pp, 0, sizeof(enic->pp));
+	memcpy(&prev_pp, pp, sizeof(*enic->pp));
+	memset(pp, 0, sizeof(*enic->pp));
 
-	enic->pp.set |= ENIC_SET_REQUEST;
-	enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
+	pp->set |= ENIC_SET_REQUEST;
+	pp->request = nla_get_u8(port[IFLA_PORT_REQUEST]);
 
 	if (port[IFLA_PORT_PROFILE]) {
-		enic->pp.set |= ENIC_SET_NAME;
-		memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]),
+		pp->set |= ENIC_SET_NAME;
+		memcpy(pp->name, nla_data(port[IFLA_PORT_PROFILE]),
 			PORT_PROFILE_MAX);
 	}
 
 	if (port[IFLA_PORT_INSTANCE_UUID]) {
-		enic->pp.set |= ENIC_SET_INSTANCE;
-		memcpy(enic->pp.instance_uuid,
+		pp->set |= ENIC_SET_INSTANCE;
+		memcpy(pp->instance_uuid,
 			nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
 	}
 
 	if (port[IFLA_PORT_HOST_UUID]) {
-		enic->pp.set |= ENIC_SET_HOST;
-		memcpy(enic->pp.host_uuid,
+		pp->set |= ENIC_SET_HOST;
+		memcpy(pp->host_uuid,
 			nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
 	}
 
 	/* Special case handling: mac came from IFLA_VF_MAC */
 	if (!is_zero_ether_addr(prev_pp.vf_mac))
-		memcpy(enic->pp.mac_addr, prev_pp.vf_mac, ETH_ALEN);
+		memcpy(pp->mac_addr, prev_pp.vf_mac, ETH_ALEN);
 
-		if (is_zero_ether_addr(netdev->dev_addr))
-			random_ether_addr(netdev->dev_addr);
+	if (vf == PORT_SELF_VF && is_zero_ether_addr(netdev->dev_addr))
+		random_ether_addr(netdev->dev_addr);
 
-	err = enic_process_set_pp_request(enic, &prev_pp, &restore_pp);
+	err = enic_process_set_pp_request(enic, vf, &prev_pp, &restore_pp);
 	if (err) {
 		if (restore_pp) {
 			/* Things are still the way they were: Implicit
 			 * DISASSOCIATE failed
 			 */
-			memcpy(&enic->pp, &prev_pp, sizeof(enic->pp));
+			memcpy(pp, &prev_pp, sizeof(*pp));
 		} else {
-			memset(&enic->pp, 0, sizeof(enic->pp));
-			memset(netdev->dev_addr, 0, ETH_ALEN);
+			memset(pp, 0, sizeof(*pp));
+			if (vf == PORT_SELF_VF)
+				memset(netdev->dev_addr, 0, ETH_ALEN);
 		}
 	} else {
 		/* Set flag to indicate that the port assoc/disassoc
 		 * request has been sent out to fw
 		 */
-		enic->pp.set |= ENIC_PORT_REQUEST_APPLIED;
+		pp->set |= ENIC_PORT_REQUEST_APPLIED;
 
 		/* If DISASSOCIATE, clean up all assigned/saved macaddresses */
-		if (enic->pp.request == PORT_REQUEST_DISASSOCIATE) {
-			memset(enic->pp.mac_addr, 0, ETH_ALEN);
-			memset(netdev->dev_addr, 0, ETH_ALEN);
+		if (pp->request == PORT_REQUEST_DISASSOCIATE) {
+			memset(pp->mac_addr, 0, ETH_ALEN);
+			if (vf == PORT_SELF_VF)
+				memset(netdev->dev_addr, 0, ETH_ALEN);
 		}
 	}
 
-	memset(enic->pp.vf_mac, 0, ETH_ALEN);
+	memset(pp->vf_mac, 0, ETH_ALEN);
 
 	return err;
 }
@@ -1147,26 +1150,31 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,
 {
 	struct enic *enic = netdev_priv(netdev);
 	u16 response = PORT_PROFILE_RESPONSE_SUCCESS;
+	struct enic_port_profile *pp;
 	int err;
 
-	if (!(enic->pp.set & ENIC_PORT_REQUEST_APPLIED))
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
+
+	if (!(pp->set & ENIC_PORT_REQUEST_APPLIED))
 		return -ENODATA;
 
-	err = enic_process_get_pp_request(enic, enic->pp.request, &response);
+	err = enic_process_get_pp_request(enic, vf, pp->request, &response);
 	if (err)
 		return err;
 
-	NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request);
+	NLA_PUT_U16(skb, IFLA_PORT_REQUEST, pp->request);
 	NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response);
-	if (enic->pp.set & ENIC_SET_NAME)
+	if (pp->set & ENIC_SET_NAME)
 		NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX,
-			enic->pp.name);
-	if (enic->pp.set & ENIC_SET_INSTANCE)
+			pp->name);
+	if (pp->set & ENIC_SET_INSTANCE)
 		NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX,
-			enic->pp.instance_uuid);
-	if (enic->pp.set & ENIC_SET_HOST)
+			pp->instance_uuid);
+	if (pp->set & ENIC_SET_HOST)
 		NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX,
-			enic->pp.host_uuid);
+			pp->host_uuid);
 
 	return 0;
 
@@ -1600,10 +1608,9 @@ static int enic_open(struct net_device *netdev)
 	for (i = 0; i < enic->rq_count; i++)
 		vnic_rq_enable(&enic->rq[i]);
 
-	if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr))
-		enic_dev_add_addr(enic, enic->pp.mac_addr);
-	else
+	if (!enic_is_dynamic(enic))
 		enic_dev_add_station_addr(enic);
+
 	enic_set_rx_mode(netdev);
 
 	netif_wake_queue(netdev);
@@ -1651,9 +1658,8 @@ static int enic_stop(struct net_device *netdev)
 
 	netif_carrier_off(netdev);
 	netif_tx_disable(netdev);
-	if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr))
-		enic_dev_del_addr(enic, enic->pp.mac_addr);
-	else
+
+	if (!enic_is_dynamic(enic))
 		enic_dev_del_station_addr(enic);
 
 	for (i = 0; i < enic->wq_count; i++) {
@@ -2143,6 +2149,9 @@ static const struct net_device_ops enic_netdev_ops = {
 	.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	= enic_set_vf_port,
+	.ndo_get_vf_port	= enic_get_vf_port,
+	.ndo_set_vf_mac		= enic_set_vf_mac,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= enic_poll_controller,
 #endif
@@ -2254,6 +2263,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 	int using_dac = 0;
 	unsigned int i;
 	int err;
+	int num_pps = 1;
 #ifdef CONFIG_PCI_IOV
 	int pos = 0;
 #endif
@@ -2363,17 +2373,26 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 				goto err_out_vnic_unregister;
 			}
 			enic->priv_flags |= ENIC_SRIOV_ENABLED;
+			num_pps = enic->num_vfs;
 		}
 	}
 
 #endif
+	/* Allocate structure for port profiles */
+	enic->pp = kzalloc(num_pps * sizeof(*enic->pp), GFP_KERNEL);
+	if (!enic->pp) {
+		pr_err("port profile alloc failed, aborting\n");
+		err = -ENOMEM;
+		goto err_out_disable_sriov;
+	}
+
 	/* Issue device open to get device in known state
 	 */
 
 	err = enic_dev_open(enic);
 	if (err) {
 		dev_err(dev, "vNIC dev open failed, aborting\n");
-		goto err_out_disable_sriov;
+		goto err_out_free_pp;
 	}
 
 	/* Setup devcmd lock
@@ -2497,6 +2516,8 @@ err_out_dev_deinit:
 	enic_dev_deinit(enic);
 err_out_dev_close:
 	vnic_dev_close(enic->vdev);
+err_out_free_pp:
+	kfree(enic->pp);
 err_out_disable_sriov:
 #ifdef CONFIG_PCI_IOV
 	if (enic_sriov_enabled(enic)) {
@@ -2537,6 +2558,7 @@ static void __devexit enic_remove(struct pci_dev *pdev)
 			enic->priv_flags &= ~ENIC_SRIOV_ENABLED;
 		}
 #endif
+		kfree(enic->pp);
 		vnic_dev_unregister(enic->vdev);
 		enic_iounmap(enic);
 		pci_release_regions(pdev);
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.c b/drivers/net/ethernet/cisco/enic/enic_pp.c
index ffaa75d..22bf03a 100644
--- a/drivers/net/ethernet/cisco/enic/enic_pp.c
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.c
@@ -29,10 +29,47 @@
 #include "enic_res.h"
 #include "enic.h"
 #include "enic_dev.h"
+#include "enic_pp.h"
 
-static int enic_set_port_profile(struct enic *enic)
+/*
+ * Checks validity of vf index that came in
+ * port profile request
+ */
+int enic_is_valid_pp_vf(struct enic *enic, int vf, int *err)
+{
+	if (vf != PORT_SELF_VF) {
+#ifdef CONFIG_PCI_IOV
+		if (enic_sriov_enabled(enic)) {
+			if (vf < 0 || vf >= enic->num_vfs) {
+				*err = -EINVAL;
+				goto err_out;
+			}
+		} else {
+			*err = -EOPNOTSUPP;
+			goto err_out;
+		}
+#else
+		*err = -EOPNOTSUPP;
+		goto err_out;
+#endif
+	}
+
+	if (vf == PORT_SELF_VF && !enic_is_dynamic(enic)) {
+		*err = -EOPNOTSUPP;
+		goto err_out;
+	}
+
+	*err = 0;
+	return 1;
+
+err_out:
+	return 0;
+}
+
+static int enic_set_port_profile(struct enic *enic, int vf)
 {
 	struct net_device *netdev = enic->netdev;
+	struct enic_port_profile *pp;
 	struct vic_provinfo *vp;
 	const u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
 	const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX);
@@ -41,7 +78,11 @@ static int enic_set_port_profile(struct enic *enic)
 	u8 *client_mac;
 	int err;
 
-	if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name))
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
+
+	if (!(pp->set & ENIC_SET_NAME) || !strlen(pp->name))
 		return -EINVAL;
 
 	vp = vic_provinfo_alloc(GFP_KERNEL, oui,
@@ -51,12 +92,18 @@ static int enic_set_port_profile(struct enic *enic)
 
 	VIC_PROVINFO_ADD_TLV(vp,
 		VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR,
-		strlen(enic->pp.name) + 1, enic->pp.name);
+		strlen(pp->name) + 1, pp->name);
 
-	if (!is_zero_ether_addr(enic->pp.mac_addr))
-		client_mac = enic->pp.mac_addr;
-	else
+	if (!is_zero_ether_addr(pp->mac_addr)) {
+		client_mac = pp->mac_addr;
+	} else if (vf == PORT_SELF_VF) {
 		client_mac = netdev->dev_addr;
+	} else {
+		netdev_err(netdev, "Cannot find pp mac address "
+			"for VF %d\n", vf);
+		err = -EINVAL;
+		goto add_tlv_failure;
+	}
 
 	VIC_PROVINFO_ADD_TLV(vp,
 		VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR,
@@ -67,15 +114,15 @@ static int enic_set_port_profile(struct enic *enic)
 		VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR,
 		sizeof(client_mac_str), client_mac_str);
 
-	if (enic->pp.set & ENIC_SET_INSTANCE) {
-		sprintf(uuid_str, "%pUB", enic->pp.instance_uuid);
+	if (pp->set & ENIC_SET_INSTANCE) {
+		sprintf(uuid_str, "%pUB", pp->instance_uuid);
 		VIC_PROVINFO_ADD_TLV(vp,
 			VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR,
 			sizeof(uuid_str), uuid_str);
 	}
 
-	if (enic->pp.set & ENIC_SET_HOST) {
-		sprintf(uuid_str, "%pUB", enic->pp.host_uuid);
+	if (pp->set & ENIC_SET_HOST) {
+		sprintf(uuid_str, "%pUB", pp->host_uuid);
 		VIC_PROVINFO_ADD_TLV(vp,
 			VIC_GENERIC_PROV_TLV_HOST_UUID_STR,
 			sizeof(uuid_str), uuid_str);
@@ -85,7 +132,9 @@ static int enic_set_port_profile(struct enic *enic)
 		VIC_GENERIC_PROV_TLV_OS_TYPE,
 		sizeof(os_type), &os_type);
 
-	err = enic_dev_status_to_errno(enic_dev_init_prov2(enic, vp));
+	ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_init_prov2, (u8 *)vp,
+		vic_provinfo_size(vp));
+	err = enic_dev_status_to_errno(err);
 
 add_tlv_failure:
 	vic_provinfo_free(vp);
@@ -93,15 +142,16 @@ add_tlv_failure:
 	return err;
 }
 
-static int enic_unset_port_profile(struct enic *enic)
+static int enic_unset_port_profile(struct enic *enic, int vf)
 {
 	int err;
 
-	err = enic_vnic_dev_deinit(enic);
+	ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_deinit);
 	if (err)
 		return enic_dev_status_to_errno(err);
 
-	enic_reset_addr_lists(enic);
+	if (vf == PORT_SELF_VF)
+		enic_reset_addr_lists(enic);
 
 	return 0;
 }
@@ -115,17 +165,18 @@ static int enic_are_pp_different(struct enic_port_profile *pp1,
 		!!memcmp(pp1->mac_addr, pp2->mac_addr, ETH_ALEN);
 }
 
-static int enic_pp_preassociate(struct enic *enic,
+static int enic_pp_preassociate(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp);
-static int enic_pp_disassociate(struct enic *enic,
+static int enic_pp_disassociate(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp);
-static int enic_pp_preassociate_rr(struct enic *enic,
+static int enic_pp_preassociate_rr(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp);
-static int enic_pp_associate(struct enic *enic,
+static int enic_pp_associate(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp);
 
-static int (*enic_pp_handlers[])(struct enic *enic,
-		struct enic_port_profile *prev_state, int *restore_pp) = {
+static int (*enic_pp_handlers[])(struct enic *enic, int vf,
+		struct enic_port_profile *prev_state,
+		int *restore_pp) = {
 	[PORT_REQUEST_PREASSOCIATE]	= enic_pp_preassociate,
 	[PORT_REQUEST_PREASSOCIATE_RR]	= enic_pp_preassociate_rr,
 	[PORT_REQUEST_ASSOCIATE]	= enic_pp_associate,
@@ -135,28 +186,49 @@ static int (*enic_pp_handlers[])(struct enic *enic,
 static const int enic_pp_handlers_count =
 			sizeof(enic_pp_handlers)/sizeof(*enic_pp_handlers);
 
-static int enic_pp_preassociate(struct enic *enic,
+static int enic_pp_preassociate(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp)
 {
 	return -EOPNOTSUPP;
 }
 
-static int enic_pp_disassociate(struct enic *enic,
+static int enic_pp_disassociate(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp)
 {
-	return enic_unset_port_profile(enic);
+	struct net_device *netdev = enic->netdev;
+	struct enic_port_profile *pp;
+	int err;
+
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
+
+	/* Deregister mac addresses */
+	if (!is_zero_ether_addr(pp->mac_addr))
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_del_addr,
+			pp->mac_addr);
+	else if (!is_zero_ether_addr(netdev->dev_addr))
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_del_addr,
+			netdev->dev_addr);
+
+	return enic_unset_port_profile(enic, vf);
 }
 
-static int enic_pp_preassociate_rr(struct enic *enic,
+static int enic_pp_preassociate_rr(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp)
 {
+	struct enic_port_profile *pp;
 	int err;
 	int active = 0;
 
-	if (enic->pp.request != PORT_REQUEST_ASSOCIATE) {
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
+
+	if (pp->request != PORT_REQUEST_ASSOCIATE) {
 		/* If pre-associate is not part of an associate.
 		We always disassociate first */
-		err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](enic,
+		err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](enic, vf,
 			prev_pp, restore_pp);
 		if (err)
 			return err;
@@ -166,29 +238,39 @@ static int enic_pp_preassociate_rr(struct enic *enic,
 
 	*restore_pp = 0;
 
-	err = enic_set_port_profile(enic);
+	err = enic_set_port_profile(enic, vf);
 	if (err)
 		return err;
 
 	/* If pre-associate is not part of an associate. */
-	if (enic->pp.request != PORT_REQUEST_ASSOCIATE)
-		err = enic_dev_status_to_errno(enic_dev_enable2(enic, active));
+	if (pp->request != PORT_REQUEST_ASSOCIATE) {
+		/* Enable device as standby */
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_enable2,
+			active);
+		err = enic_dev_status_to_errno(err);
+	}
 
 	return err;
 }
 
-static int enic_pp_associate(struct enic *enic,
+static int enic_pp_associate(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp)
 {
+	struct net_device *netdev = enic->netdev;
+	struct enic_port_profile *pp;
 	int err;
 	int active = 1;
 
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
+
 	/* Check if a pre-associate was called before */
 	if (prev_pp->request != PORT_REQUEST_PREASSOCIATE_RR ||
 		(prev_pp->request == PORT_REQUEST_PREASSOCIATE_RR &&
-			enic_are_pp_different(prev_pp, &enic->pp))) {
+			enic_are_pp_different(prev_pp, pp))) {
 		err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](
-			enic, prev_pp, restore_pp);
+			enic, vf, prev_pp, restore_pp);
 		if (err)
 			return err;
 
@@ -196,28 +278,48 @@ static int enic_pp_associate(struct enic *enic,
 	}
 
 	err = enic_pp_handlers[PORT_REQUEST_PREASSOCIATE_RR](
-			enic, prev_pp, restore_pp);
+			enic, vf, prev_pp, restore_pp);
 	if (err)
 		return err;
 
 	*restore_pp = 0;
 
-	return enic_dev_status_to_errno(enic_dev_enable2(enic, active));
+	/* Enable device as active */
+	ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_enable2, active);
+	err = enic_dev_status_to_errno(err);
+	if (err)
+		return err;
+
+	/* Register mac address */
+	if (!is_zero_ether_addr(pp->mac_addr))
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_add_addr,
+			pp->mac_addr);
+	else if (!is_zero_ether_addr(netdev->dev_addr))
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_add_addr,
+			netdev->dev_addr);
+
+	return 0;
 }
 
-int enic_process_set_pp_request(struct enic *enic,
+int enic_process_set_pp_request(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp)
 {
-	if (enic->pp.request < enic_pp_handlers_count
-		&& enic_pp_handlers[enic->pp.request])
-		return enic_pp_handlers[enic->pp.request](enic,
-			prev_pp, restore_pp);
-	else
+	struct enic_port_profile *pp;
+	int err;
+
+	ENIC_PP_BY_INDEX(enic, vf, pp, &err);
+	if (err)
+		return err;
+
+	if (pp->request >= enic_pp_handlers_count
+		|| !enic_pp_handlers[pp->request])
 		return -EOPNOTSUPP;
+
+	return enic_pp_handlers[pp->request](enic, vf, prev_pp, restore_pp);
 }
 
-int enic_process_get_pp_request(struct enic *enic, int request,
-	u16 *response)
+int enic_process_get_pp_request(struct enic *enic, int vf,
+	int request, u16 *response)
 {
 	int err, status = ERR_SUCCESS;
 
@@ -225,11 +327,13 @@ int enic_process_get_pp_request(struct enic *enic, int request,
 
 	case PORT_REQUEST_PREASSOCIATE_RR:
 	case PORT_REQUEST_ASSOCIATE:
-		err = enic_dev_enable2_done(enic, &status);
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic,
+			vnic_dev_enable2_done, &status);
 		break;
 
 	case PORT_REQUEST_DISASSOCIATE:
-		err = enic_dev_deinit_done(enic, &status);
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic,
+			vnic_dev_deinit_done, &status);
 		break;
 
 	default:
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.h b/drivers/net/ethernet/cisco/enic/enic_pp.h
index 699e365..a09ff39 100644
--- a/drivers/net/ethernet/cisco/enic/enic_pp.h
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.h
@@ -19,9 +19,18 @@
 #ifndef _ENIC_PP_H_
 #define _ENIC_PP_H_
 
-int enic_process_set_pp_request(struct enic *enic,
+#define ENIC_PP_BY_INDEX(enic, vf, pp, err) \
+	do { \
+		if (enic_is_valid_pp_vf(enic, vf, err)) \
+			pp = (vf == PORT_SELF_VF) ? enic->pp : enic->pp + vf; \
+		else \
+			pp = NULL; \
+	} while (0)
+
+int enic_process_set_pp_request(struct enic *enic, int vf,
 	struct enic_port_profile *prev_pp, int *restore_pp);
-int enic_process_get_pp_request(struct enic *enic, int request,
-	u16 *response);
+int enic_process_get_pp_request(struct enic *enic, int vf,
+	int request, u16 *response);
+int enic_is_valid_pp_vf(struct enic *enic, int vf, int *err);
 
 #endif /* _ENIC_PP_H_ */

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [net-next-2.6 PATCH 0/3] enic: updates to version 2.1.1.28
  2011-09-22 13:44 [net-next-2.6 PATCH 0/3] enic: updates to version 2.1.1.28 Roopa Prabhu
                   ` (2 preceding siblings ...)
  2011-09-22 13:44 ` [net-next-2.6 PATCH 3/3] enic: Add support for port profile association on a enic SRIOV VF Roopa Prabhu
@ 2011-09-27  5:13 ` David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2011-09-27  5:13 UTC (permalink / raw)
  To: roprabhu; +Cc: netdev

From: Roopa Prabhu <roprabhu@cisco.com>
Date: Thu, 22 Sep 2011 06:44:27 -0700

> This patch series implements the following enic driver updates:
> 
> 01/3 - Add SRIOV support
> 02/3 - Helper code for SRIOV proxy commands
> 03/3 - Add support for port profile association on a enic SRIOV VF
> 
> Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
> Signed-off-by: Sujith Sankar <ssujith@cisco.com>
> Signed-off-by: Christian Benvenuti <benve@cisco.com>
> Signed-off-by: David Wang <dwang2@cisco.com>

All applied, thank you.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-09-27  5:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-22 13:44 [net-next-2.6 PATCH 0/3] enic: updates to version 2.1.1.28 Roopa Prabhu
2011-09-22 13:44 ` [net-next-2.6 PATCH 1/3] enic: Add SRIOV support Roopa Prabhu
2011-09-22 13:44 ` [net-next-2.6 PATCH 2/3] enic: Helper code for SRIOV proxy commands Roopa Prabhu
2011-09-22 13:44 ` [net-next-2.6 PATCH 3/3] enic: Add support for port profile association on a enic SRIOV VF Roopa Prabhu
2011-09-27  5:13 ` [net-next-2.6 PATCH 0/3] enic: updates to version 2.1.1.28 David Miller

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).