@@ -3810,17 +3810,20 @@ static void be_disable_vxlan_offloads(struct be_adapter *adapter)
38103810}
38113811#endif
38123812
3813- static u16 be_calculate_vf_qs (struct be_adapter * adapter , u16 num_vfs )
3813+ static void be_calculate_vf_res (struct be_adapter * adapter , u16 num_vfs ,
3814+ struct be_resources * vft_res )
38143815{
38153816 struct be_resources res = adapter -> pool_res ;
3817+ u32 vf_if_cap_flags = res .vf_if_cap_flags ;
3818+ struct be_resources res_mod = {0 };
38163819 u16 num_vf_qs = 1 ;
38173820
38183821 /* Distribute the queue resources among the PF and it's VFs
38193822 * Do not distribute queue resources in multi-channel configuration.
38203823 */
38213824 if (num_vfs && !be_is_mc (adapter )) {
3822- /* Divide the qpairs evenly among the VFs and the PF, capped
3823- * at VF-EQ-count. Any remainder qpairs belong to the PF.
3825+ /* Divide the rx queues evenly among the VFs and the PF, capped
3826+ * at VF-EQ-count. Any remainder queues belong to the PF.
38243827 */
38253828 num_vf_qs = min (SH_VF_MAX_NIC_EQS ,
38263829 res .max_rss_qs / (num_vfs + 1 ));
@@ -3832,13 +3835,62 @@ static u16 be_calculate_vf_qs(struct be_adapter *adapter, u16 num_vfs)
38323835 if (num_vfs >= MAX_RSS_IFACES )
38333836 num_vf_qs = 1 ;
38343837 }
3835- return num_vf_qs ;
3838+
3839+ /* Resource with fields set to all '1's by GET_PROFILE_CONFIG cmd,
3840+ * which are modifiable using SET_PROFILE_CONFIG cmd.
3841+ */
3842+ be_cmd_get_profile_config (adapter , & res_mod , RESOURCE_MODIFIABLE , 0 );
3843+
3844+ /* If RSS IFACE capability flags are modifiable for a VF, set the
3845+ * capability flag as valid and set RSS and DEFQ_RSS IFACE flags if
3846+ * more than 1 RSSQ is available for a VF.
3847+ * Otherwise, provision only 1 queue pair for VF.
3848+ */
3849+ if (res_mod .vf_if_cap_flags & BE_IF_FLAGS_RSS ) {
3850+ vft_res -> flags |= BIT (IF_CAPS_FLAGS_VALID_SHIFT );
3851+ if (num_vf_qs > 1 ) {
3852+ vf_if_cap_flags |= BE_IF_FLAGS_RSS ;
3853+ if (res .if_cap_flags & BE_IF_FLAGS_DEFQ_RSS )
3854+ vf_if_cap_flags |= BE_IF_FLAGS_DEFQ_RSS ;
3855+ } else {
3856+ vf_if_cap_flags &= ~(BE_IF_FLAGS_RSS |
3857+ BE_IF_FLAGS_DEFQ_RSS );
3858+ }
3859+ } else {
3860+ num_vf_qs = 1 ;
3861+ }
3862+
3863+ if (res_mod .vf_if_cap_flags & BE_IF_FLAGS_VLAN_PROMISCUOUS ) {
3864+ vft_res -> flags |= BIT (IF_CAPS_FLAGS_VALID_SHIFT );
3865+ vf_if_cap_flags &= ~BE_IF_FLAGS_VLAN_PROMISCUOUS ;
3866+ }
3867+
3868+ vft_res -> vf_if_cap_flags = vf_if_cap_flags ;
3869+ vft_res -> max_rx_qs = num_vf_qs ;
3870+ vft_res -> max_rss_qs = num_vf_qs ;
3871+ vft_res -> max_tx_qs = res .max_tx_qs / (num_vfs + 1 );
3872+ vft_res -> max_cq_count = res .max_cq_count / (num_vfs + 1 );
3873+
3874+ /* Distribute unicast MACs, VLANs, IFACE count and MCCQ count equally
3875+ * among the PF and it's VFs, if the fields are changeable
3876+ */
3877+ if (res_mod .max_uc_mac == FIELD_MODIFIABLE )
3878+ vft_res -> max_uc_mac = res .max_uc_mac / (num_vfs + 1 );
3879+
3880+ if (res_mod .max_vlans == FIELD_MODIFIABLE )
3881+ vft_res -> max_vlans = res .max_vlans / (num_vfs + 1 );
3882+
3883+ if (res_mod .max_iface_count == FIELD_MODIFIABLE )
3884+ vft_res -> max_iface_count = res .max_iface_count / (num_vfs + 1 );
3885+
3886+ if (res_mod .max_mcc_count == FIELD_MODIFIABLE )
3887+ vft_res -> max_mcc_count = res .max_mcc_count / (num_vfs + 1 );
38363888}
38373889
38383890static int be_clear (struct be_adapter * adapter )
38393891{
38403892 struct pci_dev * pdev = adapter -> pdev ;
3841- u16 num_vf_qs ;
3893+ struct be_resources vft_res = { 0 } ;
38423894
38433895 be_cancel_worker (adapter );
38443896
@@ -3850,11 +3902,12 @@ static int be_clear(struct be_adapter *adapter)
38503902 */
38513903 if (skyhawk_chip (adapter ) && be_physfn (adapter ) &&
38523904 !pci_vfs_assigned (pdev )) {
3853- num_vf_qs = be_calculate_vf_qs (adapter ,
3854- pci_sriov_get_totalvfs (pdev ));
3905+ be_calculate_vf_res (adapter ,
3906+ pci_sriov_get_totalvfs (pdev ),
3907+ & vft_res );
38553908 be_cmd_set_sriov_config (adapter , adapter -> pool_res ,
38563909 pci_sriov_get_totalvfs (pdev ),
3857- num_vf_qs );
3910+ & vft_res );
38583911 }
38593912
38603913#ifdef CONFIG_BE2NET_VXLAN
@@ -4144,7 +4197,7 @@ static int be_get_sriov_config(struct be_adapter *adapter)
41444197static void be_alloc_sriov_res (struct be_adapter * adapter )
41454198{
41464199 int old_vfs = pci_num_vf (adapter -> pdev );
4147- u16 num_vf_qs ;
4200+ struct be_resources vft_res = { 0 } ;
41484201 int status ;
41494202
41504203 be_get_sriov_config (adapter );
@@ -4158,9 +4211,9 @@ static void be_alloc_sriov_res(struct be_adapter *adapter)
41584211 * Also, this is done by FW in Lancer chip.
41594212 */
41604213 if (skyhawk_chip (adapter ) && be_max_vfs (adapter ) && !old_vfs ) {
4161- num_vf_qs = be_calculate_vf_qs (adapter , 0 );
4214+ be_calculate_vf_res (adapter , 0 , & vft_res );
41624215 status = be_cmd_set_sriov_config (adapter , adapter -> pool_res , 0 ,
4163- num_vf_qs );
4216+ & vft_res );
41644217 if (status )
41654218 dev_err (& adapter -> pdev -> dev ,
41664219 "Failed to optimize SRIOV resources\n" );
@@ -5552,7 +5605,7 @@ static void be_eeh_resume(struct pci_dev *pdev)
55525605static int be_pci_sriov_configure (struct pci_dev * pdev , int num_vfs )
55535606{
55545607 struct be_adapter * adapter = pci_get_drvdata (pdev );
5555- u16 num_vf_qs ;
5608+ struct be_resources vft_res = { 0 } ;
55565609 int status ;
55575610
55585611 if (!num_vfs )
@@ -5575,9 +5628,10 @@ static int be_pci_sriov_configure(struct pci_dev *pdev, int num_vfs)
55755628 * Also, this is done by FW in Lancer chip.
55765629 */
55775630 if (skyhawk_chip (adapter ) && !pci_num_vf (pdev )) {
5578- num_vf_qs = be_calculate_vf_qs (adapter , adapter -> num_vfs );
5631+ be_calculate_vf_res (adapter , adapter -> num_vfs ,
5632+ & vft_res );
55795633 status = be_cmd_set_sriov_config (adapter , adapter -> pool_res ,
5580- adapter -> num_vfs , num_vf_qs );
5634+ adapter -> num_vfs , & vft_res );
55815635 if (status )
55825636 dev_err (& pdev -> dev ,
55835637 "Failed to optimize SR-IOV resources\n" );
0 commit comments