diff options
author | Roopa Prabhu <roprabhu@cisco.com> | 2011-09-21 23:44:33 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-09-27 01:10:23 -0400 |
commit | 8749b427f213e14303dfef4c1b9770f05f67916d (patch) | |
tree | dceb58406cf84eb9c5b8f9cc82e261b60997985f | |
parent | 7a269ffad72f3604b8982fa09c387670e0d2ee14 (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.h | 11 | ||||
-rw-r--r-- | 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 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 | ||
122 | void enic_reset_addr_lists(struct enic *enic); | 130 | void enic_reset_addr_lists(struct enic *enic); |
131 | int 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 | ||
130 | int enic_sriov_enabled(struct enic *enic) | ||
131 | { | ||
132 | return (enic->priv_flags & ENIC_SRIOV_ENABLED) ? 1 : 0; | ||
133 | } | ||
134 | |||
130 | static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq) | 135 | static 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); |
2456 | err_out_dev_close: | 2489 | err_out_dev_close: |
2457 | vnic_dev_close(enic->vdev); | 2490 | vnic_dev_close(enic->vdev); |
2491 | err_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 | } | ||
2458 | err_out_vnic_unregister: | 2497 | err_out_vnic_unregister: |
2459 | vnic_dev_unregister(enic->vdev); | 2498 | vnic_dev_unregister(enic->vdev); |
2499 | #endif | ||
2460 | err_out_iounmap: | 2500 | err_out_iounmap: |
2461 | enic_iounmap(enic); | 2501 | enic_iounmap(enic); |
2462 | err_out_release_regions: | 2502 | err_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); |