aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoopa Prabhu <roprabhu@cisco.com>2011-09-21 23:44:33 -0400
committerDavid S. Miller <davem@davemloft.net>2011-09-27 01:10:23 -0400
commit8749b427f213e14303dfef4c1b9770f05f67916d (patch)
treedceb58406cf84eb9c5b8f9cc82e261b60997985f
parent7a269ffad72f3604b8982fa09c387670e0d2ee14 (diff)
enic: Add SRIOV support
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> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/cisco/enic/enic.h11
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c48
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 ce76d9a8ca6e..13ff78e5a582 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -32,7 +32,7 @@
32 32
33#define DRV_NAME "enic" 33#define DRV_NAME "enic"
34#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" 34#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
35#define DRV_VERSION "2.1.1.24" 35#define DRV_VERSION "2.1.1.28"
36#define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" 36#define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc"
37 37
38#define ENIC_BARS_MAX 6 38#define ENIC_BARS_MAX 6
@@ -49,6 +49,10 @@ struct enic_msix_entry {
49 void *devid; 49 void *devid;
50}; 50};
51 51
52/* priv_flags */
53#define ENIC_SRIOV_ENABLED (1 << 0)
54
55/* enic port profile set flags */
52#define ENIC_PORT_REQUEST_APPLIED (1 << 0) 56#define ENIC_PORT_REQUEST_APPLIED (1 << 0)
53#define ENIC_SET_REQUEST (1 << 1) 57#define ENIC_SET_REQUEST (1 << 1)
54#define ENIC_SET_NAME (1 << 2) 58#define ENIC_SET_NAME (1 << 2)
@@ -83,11 +87,15 @@ struct enic {
83 u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN]; 87 u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN];
84 u8 uc_addr[ENIC_UNICAST_PERFECT_FILTERS][ETH_ALEN]; 88 u8 uc_addr[ENIC_UNICAST_PERFECT_FILTERS][ETH_ALEN];
85 unsigned int flags; 89 unsigned int flags;
90 unsigned int priv_flags;
86 unsigned int mc_count; 91 unsigned int mc_count;
87 unsigned int uc_count; 92 unsigned int uc_count;
88 u32 port_mtu; 93 u32 port_mtu;
89 u32 rx_coalesce_usecs; 94 u32 rx_coalesce_usecs;
90 u32 tx_coalesce_usecs; 95 u32 tx_coalesce_usecs;
96#ifdef CONFIG_PCI_IOV
97 u32 num_vfs;
98#endif
91 struct enic_port_profile pp; 99 struct enic_port_profile pp;
92 100
93 /* work queue cache line section */ 101 /* work queue cache line section */
@@ -120,5 +128,6 @@ static inline struct device *enic_get_dev(struct enic *enic)
120} 128}
121 129
122void enic_reset_addr_lists(struct enic *enic); 130void enic_reset_addr_lists(struct enic *enic);
131int enic_sriov_enabled(struct enic *enic);
123 132
124#endif /* _ENIC_H_ */ 133#endif /* _ENIC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 19c9272b8f12..eced800c3429 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)
127 return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN; 127 return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN;
128} 128}
129 129
130int enic_sriov_enabled(struct enic *enic)
131{
132 return (enic->priv_flags & ENIC_SRIOV_ENABLED) ? 1 : 0;
133}
134
130static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq) 135static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq)
131{ 136{
132 return rq; 137 return rq;
@@ -2240,6 +2245,9 @@ static int __devinit enic_probe(struct pci_dev *pdev,
2240 int using_dac = 0; 2245 int using_dac = 0;
2241 unsigned int i; 2246 unsigned int i;
2242 int err; 2247 int err;
2248#ifdef CONFIG_PCI_IOV
2249 int pos = 0;
2250#endif
2243 2251
2244 /* Allocate net device structure and initialize. Private 2252 /* Allocate net device structure and initialize. Private
2245 * instance data is initialized to zero. 2253 * instance data is initialized to zero.
@@ -2331,13 +2339,32 @@ static int __devinit enic_probe(struct pci_dev *pdev,
2331 goto err_out_iounmap; 2339 goto err_out_iounmap;
2332 } 2340 }
2333 2341
2342#ifdef CONFIG_PCI_IOV
2343 /* Get number of subvnics */
2344 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
2345 if (pos) {
2346 pci_read_config_word(pdev, pos + PCI_SRIOV_TOTAL_VF,
2347 (u16 *)&enic->num_vfs);
2348 if (enic->num_vfs) {
2349 err = pci_enable_sriov(pdev, enic->num_vfs);
2350 if (err) {
2351 dev_err(dev, "SRIOV enable failed, aborting."
2352 " pci_enable_sriov() returned %d\n",
2353 err);
2354 goto err_out_vnic_unregister;
2355 }
2356 enic->priv_flags |= ENIC_SRIOV_ENABLED;
2357 }
2358 }
2359
2360#endif
2334 /* Issue device open to get device in known state 2361 /* Issue device open to get device in known state
2335 */ 2362 */
2336 2363
2337 err = enic_dev_open(enic); 2364 err = enic_dev_open(enic);
2338 if (err) { 2365 if (err) {
2339 dev_err(dev, "vNIC dev open failed, aborting\n"); 2366 dev_err(dev, "vNIC dev open failed, aborting\n");
2340 goto err_out_vnic_unregister; 2367 goto err_out_disable_sriov;
2341 } 2368 }
2342 2369
2343 /* Setup devcmd lock 2370 /* Setup devcmd lock
@@ -2404,6 +2431,12 @@ static int __devinit enic_probe(struct pci_dev *pdev,
2404 enic->port_mtu = enic->config.mtu; 2431 enic->port_mtu = enic->config.mtu;
2405 (void)enic_change_mtu(netdev, enic->port_mtu); 2432 (void)enic_change_mtu(netdev, enic->port_mtu);
2406 2433
2434#ifdef CONFIG_PCI_IOV
2435 if (enic_is_dynamic(enic) && pdev->is_virtfn &&
2436 is_zero_ether_addr(enic->mac_addr))
2437 random_ether_addr(enic->mac_addr);
2438#endif
2439
2407 err = enic_set_mac_addr(netdev, enic->mac_addr); 2440 err = enic_set_mac_addr(netdev, enic->mac_addr);
2408 if (err) { 2441 if (err) {
2409 dev_err(dev, "Invalid MAC address, aborting\n"); 2442 dev_err(dev, "Invalid MAC address, aborting\n");
@@ -2455,8 +2488,15 @@ err_out_dev_deinit:
2455 enic_dev_deinit(enic); 2488 enic_dev_deinit(enic);
2456err_out_dev_close: 2489err_out_dev_close:
2457 vnic_dev_close(enic->vdev); 2490 vnic_dev_close(enic->vdev);
2491err_out_disable_sriov:
2492#ifdef CONFIG_PCI_IOV
2493 if (enic_sriov_enabled(enic)) {
2494 pci_disable_sriov(pdev);
2495 enic->priv_flags &= ~ENIC_SRIOV_ENABLED;
2496 }
2458err_out_vnic_unregister: 2497err_out_vnic_unregister:
2459 vnic_dev_unregister(enic->vdev); 2498 vnic_dev_unregister(enic->vdev);
2499#endif
2460err_out_iounmap: 2500err_out_iounmap:
2461 enic_iounmap(enic); 2501 enic_iounmap(enic);
2462err_out_release_regions: 2502err_out_release_regions:
@@ -2482,6 +2522,12 @@ static void __devexit enic_remove(struct pci_dev *pdev)
2482 unregister_netdev(netdev); 2522 unregister_netdev(netdev);
2483 enic_dev_deinit(enic); 2523 enic_dev_deinit(enic);
2484 vnic_dev_close(enic->vdev); 2524 vnic_dev_close(enic->vdev);
2525#ifdef CONFIG_PCI_IOV
2526 if (enic_sriov_enabled(enic)) {
2527 pci_disable_sriov(pdev);
2528 enic->priv_flags &= ~ENIC_SRIOV_ENABLED;
2529 }
2530#endif
2485 vnic_dev_unregister(enic->vdev); 2531 vnic_dev_unregister(enic->vdev);
2486 enic_iounmap(enic); 2532 enic_iounmap(enic);
2487 pci_release_regions(pdev); 2533 pci_release_regions(pdev);