Skip to content

Commit

Permalink
ice: Account for port VLAN in VF max packet size calculation
Browse files Browse the repository at this point in the history
Currently if an AVF driver doesn't account for the possibility of a
port VLAN when determining its max packet size then packets at MTU will
be dropped. It is not the VF driver's responsibility to account for a
port VLAN so fix this. To fix this, do the following:

1. Add a function that determines the max packet size a VF is allowed by
   using the port's max packet size and whether the VF is in a port
   VLAN. If a port VLAN is configured then a VF's max packet size will
   always be the port's max packet size minus VLAN_HLEN. Otherwise it
   will be the port's max packet size.

2. Use this function to verify the max packet size from the VF.

3. If there is a port VLAN configured then add 4 bytes (VLAN_HLEN) to
   the VF's max packet size configuration.

Also, the VIRTCHNL_OP_GET_VF_RESOURCES message provides the capability
to communicate a VF's max packet size. Use the new function for this
purpose.

Fixes: 1071a83 ("ice: Implement virtchnl commands for AVF support")
Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
  • Loading branch information
Brett Creeley authored and Tony Nguyen committed Feb 22, 2021
1 parent 37b52be commit a6aa7c8
Showing 1 changed file with 32 additions and 1 deletion.
33 changes: 32 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1918,6 +1918,29 @@ static int ice_vc_get_ver_msg(struct ice_vf *vf, u8 *msg)
sizeof(struct virtchnl_version_info));
}

/**
* ice_vc_get_max_frame_size - get max frame size allowed for VF
* @vf: VF used to determine max frame size
*
* 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 ice_vc_get_max_frame_size(struct ice_vf *vf)
{
struct ice_vsi *vsi = vf->pf->vsi[vf->lan_vsi_idx];
struct ice_port_info *pi = vsi->port_info;
u16 max_frame_size;

max_frame_size = pi->phy.link_info.max_frame_size;

if (vf->port_vlan_info)
max_frame_size -= VLAN_HLEN;

return max_frame_size;
}

/**
* ice_vc_get_vf_res_msg
* @vf: pointer to the VF info
Expand Down Expand Up @@ -2000,6 +2023,7 @@ static int ice_vc_get_vf_res_msg(struct ice_vf *vf, u8 *msg)
vfres->max_vectors = pf->num_msix_per_vf;
vfres->rss_key_size = ICE_VSIQF_HKEY_ARRAY_SIZE;
vfres->rss_lut_size = ICE_VSIQF_HLUT_ARRAY_SIZE;
vfres->max_mtu = ice_vc_get_max_frame_size(vf);

vfres->vsi_res[0].vsi_id = vf->lan_vsi_num;
vfres->vsi_res[0].vsi_type = VIRTCHNL_VSI_SRIOV;
Expand Down Expand Up @@ -2998,6 +3022,8 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)

/* copy Rx queue info from VF into VSI */
if (qpi->rxq.ring_len > 0) {
u16 max_frame_size = ice_vc_get_max_frame_size(vf);

num_rxq++;
vsi->rx_rings[i]->dma = qpi->rxq.dma_ring_addr;
vsi->rx_rings[i]->count = qpi->rxq.ring_len;
Expand All @@ -3010,14 +3036,19 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
}
vsi->rx_buf_len = qpi->rxq.databuffer_size;
vsi->rx_rings[i]->rx_buf_len = vsi->rx_buf_len;
if (qpi->rxq.max_pkt_size >= (16 * 1024) ||
if (qpi->rxq.max_pkt_size > max_frame_size ||
qpi->rxq.max_pkt_size < 64) {
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
goto error_param;
}
}

vsi->max_frame = qpi->rxq.max_pkt_size;
/* add space for the port VLAN since the VF driver is not
* expected to account for it in the MTU calculation
*/
if (vf->port_vlan_info)
vsi->max_frame += VLAN_HLEN;
}

/* VF can request to configure less than allocated queues or default
Expand Down

0 comments on commit a6aa7c8

Please sign in to comment.