Commit f64780e3 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue

Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2022-09-19 (iavf, i40e)

Norbert adds checking of buffer size for Rx buffer checks in iavf.

Michal corrects setting of max MTU in iavf to account for MTU data provided
by PF, fixes i40e to set VF max MTU, and resolves lack of rate limiting
when value was less than divisor for i40e.

* '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue:
  i40e: Fix set max_tx_rate when it is lower than 1 Mbps
  i40e: Fix VF set max MTU size
  iavf: Fix set max MTU size with port VLAN and jumbo frames
  iavf: Fix bad page state
====================

Link: https://lore.kernel.org/r/20220919223428.572091-1-anthony.l.nguyen@intel.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 375a6833 198eb7e1
...@@ -5908,6 +5908,26 @@ static int i40e_get_link_speed(struct i40e_vsi *vsi) ...@@ -5908,6 +5908,26 @@ static int i40e_get_link_speed(struct i40e_vsi *vsi)
} }
} }
/**
* i40e_bw_bytes_to_mbits - Convert max_tx_rate from bytes to mbits
* @vsi: Pointer to vsi structure
* @max_tx_rate: max TX rate in bytes to be converted into Mbits
*
* Helper function to convert units before send to set BW limit
**/
static u64 i40e_bw_bytes_to_mbits(struct i40e_vsi *vsi, u64 max_tx_rate)
{
if (max_tx_rate < I40E_BW_MBPS_DIVISOR) {
dev_warn(&vsi->back->pdev->dev,
"Setting max tx rate to minimum usable value of 50Mbps.\n");
max_tx_rate = I40E_BW_CREDIT_DIVISOR;
} else {
do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
}
return max_tx_rate;
}
/** /**
* i40e_set_bw_limit - setup BW limit for Tx traffic based on max_tx_rate * i40e_set_bw_limit - setup BW limit for Tx traffic based on max_tx_rate
* @vsi: VSI to be configured * @vsi: VSI to be configured
...@@ -5930,10 +5950,10 @@ int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate) ...@@ -5930,10 +5950,10 @@ int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate)
max_tx_rate, seid); max_tx_rate, seid);
return -EINVAL; return -EINVAL;
} }
if (max_tx_rate && max_tx_rate < 50) { if (max_tx_rate && max_tx_rate < I40E_BW_CREDIT_DIVISOR) {
dev_warn(&pf->pdev->dev, dev_warn(&pf->pdev->dev,
"Setting max tx rate to minimum usable value of 50Mbps.\n"); "Setting max tx rate to minimum usable value of 50Mbps.\n");
max_tx_rate = 50; max_tx_rate = I40E_BW_CREDIT_DIVISOR;
} }
/* Tx rate credits are in values of 50Mbps, 0 is disabled */ /* Tx rate credits are in values of 50Mbps, 0 is disabled */
...@@ -8224,9 +8244,9 @@ static int i40e_setup_tc(struct net_device *netdev, void *type_data) ...@@ -8224,9 +8244,9 @@ static int i40e_setup_tc(struct net_device *netdev, void *type_data)
if (i40e_is_tc_mqprio_enabled(pf)) { if (i40e_is_tc_mqprio_enabled(pf)) {
if (vsi->mqprio_qopt.max_rate[0]) { if (vsi->mqprio_qopt.max_rate[0]) {
u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0]; u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi,
vsi->mqprio_qopt.max_rate[0]);
do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate); ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);
if (!ret) { if (!ret) {
u64 credits = max_tx_rate; u64 credits = max_tx_rate;
...@@ -10971,10 +10991,10 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired) ...@@ -10971,10 +10991,10 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
} }
if (vsi->mqprio_qopt.max_rate[0]) { if (vsi->mqprio_qopt.max_rate[0]) {
u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0]; u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi,
vsi->mqprio_qopt.max_rate[0]);
u64 credits = 0; u64 credits = 0;
do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate); ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);
if (ret) if (ret)
goto end_unlock; goto end_unlock;
......
...@@ -2038,6 +2038,25 @@ static void i40e_del_qch(struct i40e_vf *vf) ...@@ -2038,6 +2038,25 @@ static void i40e_del_qch(struct i40e_vf *vf)
} }
} }
/**
* i40e_vc_get_max_frame_size
* @vf: pointer to the VF
*
* Max frame size is determined based on the current port's max frame size and
* whether a port VLAN is configured on this VF. The VF is not aware whether
* it's in a port VLAN so the PF needs to account for this in max frame size
* checks and sending the max frame size to the VF.
**/
static u16 i40e_vc_get_max_frame_size(struct i40e_vf *vf)
{
u16 max_frame_size = vf->pf->hw.phy.link_info.max_frame_size;
if (vf->port_vlan_id)
max_frame_size -= VLAN_HLEN;
return max_frame_size;
}
/** /**
* i40e_vc_get_vf_resources_msg * i40e_vc_get_vf_resources_msg
* @vf: pointer to the VF info * @vf: pointer to the VF info
...@@ -2139,6 +2158,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg) ...@@ -2139,6 +2158,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf; vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf;
vfres->rss_key_size = I40E_HKEY_ARRAY_SIZE; vfres->rss_key_size = I40E_HKEY_ARRAY_SIZE;
vfres->rss_lut_size = I40E_VF_HLUT_ARRAY_SIZE; vfres->rss_lut_size = I40E_VF_HLUT_ARRAY_SIZE;
vfres->max_mtu = i40e_vc_get_max_frame_size(vf);
if (vf->lan_vsi_idx) { if (vf->lan_vsi_idx) {
vfres->vsi_res[0].vsi_id = vf->lan_vsi_id; vfres->vsi_res[0].vsi_id = vf->lan_vsi_id;
......
...@@ -1393,7 +1393,7 @@ static struct sk_buff *iavf_build_skb(struct iavf_ring *rx_ring, ...@@ -1393,7 +1393,7 @@ static struct sk_buff *iavf_build_skb(struct iavf_ring *rx_ring,
#endif #endif
struct sk_buff *skb; struct sk_buff *skb;
if (!rx_buffer) if (!rx_buffer || !size)
return NULL; return NULL;
/* prefetch first cache line of first page */ /* prefetch first cache line of first page */
va = page_address(rx_buffer->page) + rx_buffer->page_offset; va = page_address(rx_buffer->page) + rx_buffer->page_offset;
...@@ -1551,7 +1551,7 @@ static int iavf_clean_rx_irq(struct iavf_ring *rx_ring, int budget) ...@@ -1551,7 +1551,7 @@ static int iavf_clean_rx_irq(struct iavf_ring *rx_ring, int budget)
/* exit if we failed to retrieve a buffer */ /* exit if we failed to retrieve a buffer */
if (!skb) { if (!skb) {
rx_ring->rx_stats.alloc_buff_failed++; rx_ring->rx_stats.alloc_buff_failed++;
if (rx_buffer) if (rx_buffer && size)
rx_buffer->pagecnt_bias++; rx_buffer->pagecnt_bias++;
break; break;
} }
......
...@@ -269,11 +269,14 @@ int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter) ...@@ -269,11 +269,14 @@ int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter)
void iavf_configure_queues(struct iavf_adapter *adapter) void iavf_configure_queues(struct iavf_adapter *adapter)
{ {
struct virtchnl_vsi_queue_config_info *vqci; struct virtchnl_vsi_queue_config_info *vqci;
struct virtchnl_queue_pair_info *vqpi; int i, max_frame = adapter->vf_res->max_mtu;
int pairs = adapter->num_active_queues; int pairs = adapter->num_active_queues;
int i, max_frame = IAVF_MAX_RXBUFFER; struct virtchnl_queue_pair_info *vqpi;
size_t len; size_t len;
if (max_frame > IAVF_MAX_RXBUFFER || !max_frame)
max_frame = IAVF_MAX_RXBUFFER;
if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) { if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
/* bail because we already have a command pending */ /* bail because we already have a command pending */
dev_err(&adapter->pdev->dev, "Cannot configure queues, command %d pending\n", dev_err(&adapter->pdev->dev, "Cannot configure queues, command %d pending\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment