aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom
diff options
context:
space:
mode:
authorAriel Elior <ariele@broadcom.com>2013-03-11 01:17:46 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-12 07:54:23 -0400
commit3c76feff68559bf9ec08d4d86abe57bc56a9847a (patch)
treeaf826ebde6b7f036fc916739cf87a47b5518446d /drivers/net/ethernet/broadcom
parent3ec9f9ca79757c54b12f87e51a6664ba1e597b17 (diff)
bnx2x: Control number of vfs dynamically
1. Support sysfs interface for getting the maximal number of virtual functions of a given physical function. 2. Support sysfs interface for getting and setting the current number of virtual functions. Signed-off-by: Ariel Elior <ariele@broadcom.com> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c36
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c87
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h10
4 files changed, 91 insertions, 44 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index d62d037b2928..33fbdfdc8e12 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1281,6 +1281,8 @@ struct bnx2x {
1281 dma_addr_t pf2vf_bulletin_mapping; 1281 dma_addr_t pf2vf_bulletin_mapping;
1282 1282
1283 struct pf_vf_bulletin_content old_bulletin; 1283 struct pf_vf_bulletin_content old_bulletin;
1284
1285 u16 requested_nr_virtfn;
1284#endif /* CONFIG_BNX2X_SRIOV */ 1286#endif /* CONFIG_BNX2X_SRIOV */
1285 1287
1286 struct net_device *dev; 1288 struct net_device *dev;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 9be9b0373ca9..f685d2e77fcb 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -9546,8 +9546,10 @@ sp_rtnl_not_reset:
9546 9546
9547 /* enable SR-IOV if applicable */ 9547 /* enable SR-IOV if applicable */
9548 if (IS_SRIOV(bp) && test_and_clear_bit(BNX2X_SP_RTNL_ENABLE_SRIOV, 9548 if (IS_SRIOV(bp) && test_and_clear_bit(BNX2X_SP_RTNL_ENABLE_SRIOV,
9549 &bp->sp_rtnl_state)) 9549 &bp->sp_rtnl_state)) {
9550 bnx2x_disable_sriov(bp);
9550 bnx2x_enable_sriov(bp); 9551 bnx2x_enable_sriov(bp);
9552 }
9551} 9553}
9552 9554
9553static void bnx2x_period_task(struct work_struct *work) 9555static void bnx2x_period_task(struct work_struct *work)
@@ -11423,26 +11425,6 @@ static int bnx2x_init_bp(struct bnx2x *bp)
11423 * net_device service functions 11425 * net_device service functions
11424 */ 11426 */
11425 11427
11426static int bnx2x_open_epilog(struct bnx2x *bp)
11427{
11428 /* Enable sriov via delayed work. This must be done via delayed work
11429 * because it causes the probe of the vf devices to be run, which invoke
11430 * register_netdevice which must have rtnl lock taken. As we are holding
11431 * the lock right now, that could only work if the probe would not take
11432 * the lock. However, as the probe of the vf may be called from other
11433 * contexts as well (such as passthrough to vm failes) it can't assume
11434 * the lock is being held for it. Using delayed work here allows the
11435 * probe code to simply take the lock (i.e. wait for it to be released
11436 * if it is being held).
11437 */
11438 smp_mb__before_clear_bit();
11439 set_bit(BNX2X_SP_RTNL_ENABLE_SRIOV, &bp->sp_rtnl_state);
11440 smp_mb__after_clear_bit();
11441 schedule_delayed_work(&bp->sp_rtnl_task, 0);
11442
11443 return 0;
11444}
11445
11446/* called with rtnl_lock */ 11428/* called with rtnl_lock */
11447static int bnx2x_open(struct net_device *dev) 11429static int bnx2x_open(struct net_device *dev)
11448{ 11430{
@@ -12498,13 +12480,8 @@ static int bnx2x_init_one(struct pci_dev *pdev,
12498 goto init_one_exit; 12480 goto init_one_exit;
12499 } 12481 }
12500 12482
12501 /* Enable SRIOV if capability found in configuration space. 12483 /* Enable SRIOV if capability found in configuration space */
12502 * Once the generic SR-IOV framework makes it in from the 12484 rc = bnx2x_iov_init_one(bp, int_mode, BNX2X_MAX_NUM_OF_VFS);
12503 * pci tree this will be revised, to allow dynamic control
12504 * over the number of VFs. Right now, change the num of vfs
12505 * param below to enable SR-IOV.
12506 */
12507 rc = bnx2x_iov_init_one(bp, int_mode, 0/*num vfs*/);
12508 if (rc) 12485 if (rc)
12509 goto init_one_exit; 12486 goto init_one_exit;
12510 12487
@@ -12820,6 +12797,9 @@ static struct pci_driver bnx2x_pci_driver = {
12820 .suspend = bnx2x_suspend, 12797 .suspend = bnx2x_suspend,
12821 .resume = bnx2x_resume, 12798 .resume = bnx2x_resume,
12822 .err_handler = &bnx2x_err_handler, 12799 .err_handler = &bnx2x_err_handler,
12800#ifdef CONFIG_BNX2X_SRIOV
12801 .sriov_configure = bnx2x_sriov_configure,
12802#endif
12823}; 12803};
12824 12804
12825static int __init bnx2x_init(void) 12805static int __init bnx2x_init(void)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 7b234e41fea8..df930e30e1b1 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -1467,7 +1467,6 @@ static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid)
1467 return bnx2x_is_pcie_pending(dev); 1467 return bnx2x_is_pcie_pending(dev);
1468 1468
1469unknown_dev: 1469unknown_dev:
1470 BNX2X_ERR("Unknown device\n");
1471 return false; 1470 return false;
1472} 1471}
1473 1472
@@ -1972,8 +1971,10 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param,
1972 if (iov->total == 0) 1971 if (iov->total == 0)
1973 goto failed; 1972 goto failed;
1974 1973
1975 /* calculate the actual number of VFs */ 1974 iov->nr_virtfn = min_t(u16, iov->total, num_vfs_param);
1976 iov->nr_virtfn = min_t(u16, iov->total, (u16)num_vfs_param); 1975
1976 DP(BNX2X_MSG_IOV, "num_vfs_param was %d, nr_virtfn was %d\n",
1977 num_vfs_param, iov->nr_virtfn);
1977 1978
1978 /* allocate the vf array */ 1979 /* allocate the vf array */
1979 bp->vfdb->vfs = kzalloc(sizeof(struct bnx2x_virtf) * 1980 bp->vfdb->vfs = kzalloc(sizeof(struct bnx2x_virtf) *
@@ -3020,21 +3021,47 @@ void bnx2x_unlock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf,
3020 vf->op_current = CHANNEL_TLV_NONE; 3021 vf->op_current = CHANNEL_TLV_NONE;
3021} 3022}
3022 3023
3023void bnx2x_enable_sriov(struct bnx2x *bp) 3024int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs_param)
3024{ 3025{
3025 int rc = 0;
3026 3026
3027 /* disbale sriov in case it is still enabled */ 3027 struct bnx2x *bp = netdev_priv(pci_get_drvdata(dev));
3028 pci_disable_sriov(bp->pdev);
3029 DP(BNX2X_MSG_IOV, "sriov disabled\n");
3030 3028
3031 /* enable sriov */ 3029 DP(BNX2X_MSG_IOV, "bnx2x_sriov_configure called with %d, BNX2X_NR_VIRTFN(bp) was %d\n",
3032 DP(BNX2X_MSG_IOV, "vf num (%d)\n", (bp->vfdb->sriov.nr_virtfn)); 3030 num_vfs_param, BNX2X_NR_VIRTFN(bp));
3033 rc = pci_enable_sriov(bp->pdev, (bp->vfdb->sriov.nr_virtfn)); 3031
3034 if (rc) 3032 /* HW channel is only operational when PF is up */
3033 if (bp->state != BNX2X_STATE_OPEN) {
3034 BNX2X_ERR("VF num configurtion via sysfs not supported while PF is down");
3035 return -EINVAL;
3036 }
3037
3038 /* we are always bound by the total_vfs in the configuration space */
3039 if (num_vfs_param > BNX2X_NR_VIRTFN(bp)) {
3040 BNX2X_ERR("truncating requested number of VFs (%d) down to maximum allowed (%d)\n",
3041 num_vfs_param, BNX2X_NR_VIRTFN(bp));
3042 num_vfs_param = BNX2X_NR_VIRTFN(bp);
3043 }
3044
3045 bp->requested_nr_virtfn = num_vfs_param;
3046 if (num_vfs_param == 0) {
3047 pci_disable_sriov(dev);
3048 return 0;
3049 } else {
3050 return bnx2x_enable_sriov(bp);
3051 }
3052}
3053
3054int bnx2x_enable_sriov(struct bnx2x *bp)
3055{
3056 int rc = 0, req_vfs = bp->requested_nr_virtfn;
3057
3058 rc = pci_enable_sriov(bp->pdev, req_vfs);
3059 if (rc) {
3035 BNX2X_ERR("pci_enable_sriov failed with %d\n", rc); 3060 BNX2X_ERR("pci_enable_sriov failed with %d\n", rc);
3036 else 3061 return rc;
3037 DP(BNX2X_MSG_IOV, "sriov enabled\n"); 3062 }
3063 DP(BNX2X_MSG_IOV, "sriov enabled (%d vfs)\n", req_vfs);
3064 return req_vfs;
3038} 3065}
3039 3066
3040void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) 3067void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp)
@@ -3050,6 +3077,11 @@ void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp)
3050 } 3077 }
3051} 3078}
3052 3079
3080void bnx2x_disable_sriov(struct bnx2x *bp)
3081{
3082 pci_disable_sriov(bp->pdev);
3083}
3084
3053static int bnx2x_vf_ndo_sanity(struct bnx2x *bp, int vfidx, 3085static int bnx2x_vf_ndo_sanity(struct bnx2x *bp, int vfidx,
3054 struct bnx2x_virtf *vf) 3086 struct bnx2x_virtf *vf)
3055{ 3087{
@@ -3087,6 +3119,10 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx,
3087 rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf); 3119 rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf);
3088 if (rc) 3120 if (rc)
3089 return rc; 3121 return rc;
3122 if (!mac_obj || !vlan_obj || !bulletin) {
3123 BNX2X_ERR("VF partially initialized\n");
3124 return -EINVAL;
3125 }
3090 3126
3091 ivi->vf = vfidx; 3127 ivi->vf = vfidx;
3092 ivi->qos = 0; 3128 ivi->qos = 0;
@@ -3405,3 +3441,26 @@ alloc_mem_err:
3405 sizeof(union pf_vf_bulletin)); 3441 sizeof(union pf_vf_bulletin));
3406 return -ENOMEM; 3442 return -ENOMEM;
3407} 3443}
3444
3445int bnx2x_open_epilog(struct bnx2x *bp)
3446{
3447 /* Enable sriov via delayed work. This must be done via delayed work
3448 * because it causes the probe of the vf devices to be run, which invoke
3449 * register_netdevice which must have rtnl lock taken. As we are holding
3450 * the lock right now, that could only work if the probe would not take
3451 * the lock. However, as the probe of the vf may be called from other
3452 * contexts as well (such as passthrough to vm failes) it can't assume
3453 * the lock is being held for it. Using delayed work here allows the
3454 * probe code to simply take the lock (i.e. wait for it to be released
3455 * if it is being held). We only want to do this if the number of VFs
3456 * was set before PF driver was loaded.
3457 */
3458 if (IS_SRIOV(bp) && BNX2X_NR_VIRTFN(bp)) {
3459 smp_mb__before_clear_bit();
3460 set_bit(BNX2X_SP_RTNL_ENABLE_SRIOV, &bp->sp_rtnl_state);
3461 smp_mb__after_clear_bit();
3462 schedule_delayed_work(&bp->sp_rtnl_task, 0);
3463 }
3464
3465 return 0;
3466}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
index 33d49516fcea..a10bdb2fd900 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
@@ -753,12 +753,15 @@ static inline int bnx2x_vf_ustorm_prods_offset(struct bnx2x *bp,
753enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp); 753enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp);
754void bnx2x_vf_map_doorbells(struct bnx2x *bp); 754void bnx2x_vf_map_doorbells(struct bnx2x *bp);
755int bnx2x_vf_pci_alloc(struct bnx2x *bp); 755int bnx2x_vf_pci_alloc(struct bnx2x *bp);
756void bnx2x_enable_sriov(struct bnx2x *bp); 756int bnx2x_enable_sriov(struct bnx2x *bp);
757void bnx2x_disable_sriov(struct bnx2x *bp);
757static inline int bnx2x_vf_headroom(struct bnx2x *bp) 758static inline int bnx2x_vf_headroom(struct bnx2x *bp)
758{ 759{
759 return bp->vfdb->sriov.nr_virtfn * BNX2X_CLIENTS_PER_VF; 760 return bp->vfdb->sriov.nr_virtfn * BNX2X_CLIENTS_PER_VF;
760} 761}
761void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp); 762void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp);
763int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs);
764int bnx2x_open_epilog(struct bnx2x *bp);
762 765
763#else /* CONFIG_BNX2X_SRIOV */ 766#else /* CONFIG_BNX2X_SRIOV */
764 767
@@ -781,7 +784,8 @@ static inline void bnx2x_iov_init_dmae(struct bnx2x *bp) {}
781static inline int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, 784static inline int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param,
782 int num_vfs_param) {return 0; } 785 int num_vfs_param) {return 0; }
783static inline void bnx2x_iov_remove_one(struct bnx2x *bp) {} 786static inline void bnx2x_iov_remove_one(struct bnx2x *bp) {}
784static inline void bnx2x_enable_sriov(struct bnx2x *bp) {} 787static inline int bnx2x_enable_sriov(struct bnx2x *bp) {return 0; }
788static inline void bnx2x_disable_sriov(struct bnx2x *bp) {}
785static inline int bnx2x_vfpf_acquire(struct bnx2x *bp, 789static inline int bnx2x_vfpf_acquire(struct bnx2x *bp,
786 u8 tx_count, u8 rx_count) {return 0; } 790 u8 tx_count, u8 rx_count) {return 0; }
787static inline int bnx2x_vfpf_release(struct bnx2x *bp) {return 0; } 791static inline int bnx2x_vfpf_release(struct bnx2x *bp) {return 0; }
@@ -807,6 +811,8 @@ static inline enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp
807static inline int bnx2x_vf_map_doorbells(struct bnx2x *bp) {return 0; } 811static inline int bnx2x_vf_map_doorbells(struct bnx2x *bp) {return 0; }
808static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; } 812static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; }
809static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {} 813static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {}
814static inline int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs) {return 0; }
815static inline int bnx2x_open_epilog(struct bnx2x *bp) {return 0; }
810 816
811#endif /* CONFIG_BNX2X_SRIOV */ 817#endif /* CONFIG_BNX2X_SRIOV */
812#endif /* bnx2x_sriov.h */ 818#endif /* bnx2x_sriov.h */