Commit dddd406d authored by Jesse Brandeburg's avatar Jesse Brandeburg Committed by Tony Nguyen
Browse files

ice: Implement control of FCS/CRC stripping



The driver can allow the user to configure whether the CRC aka the FCS
(Frame Check Sequence) is DMA'd to the host as part of the receive
buffer.  The driver usually wants this feature disabled so that the
hardware checks the FCS and strips it in order to save PCI bandwidth.

Control the reception of FCS to the host using the command:
ethtool -K eth0 rx-fcs <on|off>

The default shown in ethtool -k eth0 | grep fcs; should be "off", as the
hardware will drop any frame with a bad checksum, and DMA of the
checksum is useless overhead especially for small packets.

Testing Hints:
test the FCS/CRC arrives with received packets using
tcpdump -nnpi eth0 -xxxx
and it should show crc data as the last 4 bytes of the packet. Can also
use wireshark to turn on CRC checking and check the data is correct.

Signed-off-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Co-developed-by: default avatarGrzegorz Nitka <grzegorz.nitka@intel.com>
Signed-off-by: default avatarGrzegorz Nitka <grzegorz.nitka@intel.com>
Co-developed-by: default avatarBenjamin Mikailenko <benjamin.mikailenko@intel.com>
Signed-off-by: default avatarBenjamin Mikailenko <benjamin.mikailenko@intel.com>
Co-developed-by: default avatarAnatolii Gerasymenko <anatolii.gerasymenko@intel.com>
Signed-off-by: default avatarAnatolii Gerasymenko <anatolii.gerasymenko@intel.com>
Tested-by: Gurucharan <gurucharanx.g@intel.com> (A Contingent worker at Intel)
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent e34cfee6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -854,6 +854,7 @@ ice_fetch_u64_stats_per_ring(struct u64_stats_sync *syncp,
			     struct ice_q_stats stats, u64 *pkts, u64 *bytes);
int ice_up(struct ice_vsi *vsi);
int ice_down(struct ice_vsi *vsi);
int ice_down_up(struct ice_vsi *vsi);
int ice_vsi_cfg(struct ice_vsi *vsi);
struct ice_vsi *ice_lb_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi);
int ice_vsi_determine_xdp_res(struct ice_vsi *vsi);
+1 −1
Original line number Diff line number Diff line
@@ -417,7 +417,7 @@ static int ice_setup_rx_ctx(struct ice_rx_ring *ring)
	/* Strip the Ethernet CRC bytes before the packet is posted to host
	 * memory.
	 */
	rlan_ctx.crcstrip = 1;
	rlan_ctx.crcstrip = !(ring->flags & ICE_RX_FLAGS_CRC_STRIP_DIS);

	/* L2TSEL flag defines the reported L2 Tags in the receive descriptor
	 * and it needs to remain 1 for non-DVM capable configurations to not
+1 −4
Original line number Diff line number Diff line
@@ -1289,10 +1289,7 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags)
	}
	if (test_bit(ICE_FLAG_LEGACY_RX, change_flags)) {
		/* down and up VSI so that changes of Rx cfg are reflected. */
		if (!test_and_set_bit(ICE_VSI_DOWN, vsi->state)) {
			ice_down(vsi);
			ice_up(vsi);
		}
		ice_down_up(vsi);
	}
	/* don't allow modification of this flag when a single VF is in
	 * promiscuous mode because it's not supported
+22 −0
Original line number Diff line number Diff line
@@ -1562,6 +1562,22 @@ void ice_vsi_manage_rss_lut(struct ice_vsi *vsi, bool ena)
	kfree(lut);
}

/**
 * ice_vsi_cfg_crc_strip - Configure CRC stripping for a VSI
 * @vsi: VSI to be configured
 * @disable: set to true to have FCS / CRC in the frame data
 */
void ice_vsi_cfg_crc_strip(struct ice_vsi *vsi, bool disable)
{
	int i;

	ice_for_each_rxq(vsi, i)
		if (disable)
			vsi->rx_rings[i]->flags |= ICE_RX_FLAGS_CRC_STRIP_DIS;
		else
			vsi->rx_rings[i]->flags &= ~ICE_RX_FLAGS_CRC_STRIP_DIS;
}

/**
 * ice_vsi_cfg_rss_lut_key - Configure RSS params for a VSI
 * @vsi: VSI to be configured
@@ -3277,6 +3293,12 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
			 */
			if (test_bit(ICE_FLAG_RSS_ENA, pf->flags))
				ice_vsi_cfg_rss_lut_key(vsi);

		/* disable or enable CRC stripping */
		if (vsi->netdev)
			ice_vsi_cfg_crc_strip(vsi, !!(vsi->netdev->features &
					      NETIF_F_RXFCS));

		break;
	case ICE_VSI_VF:
		ret = ice_vsi_alloc_q_vectors(vsi);
+2 −0
Original line number Diff line number Diff line
@@ -89,6 +89,8 @@ void ice_vsi_free_tx_rings(struct ice_vsi *vsi);

void ice_vsi_manage_rss_lut(struct ice_vsi *vsi, bool ena);

void ice_vsi_cfg_crc_strip(struct ice_vsi *vsi, bool disable);

void ice_update_tx_ring_stats(struct ice_tx_ring *ring, u64 pkts, u64 bytes);

void ice_update_rx_ring_stats(struct ice_rx_ring *ring, u64 pkts, u64 bytes);
Loading