Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6978729f authored by Edward Cree's avatar Edward Cree Committed by David S. Miller
Browse files

sfc: support rx-fcs and rx-all



Ethernet FCS inclusion (rx-fcs) is supported on EF10 NICs, conditional on
 a firmware capability bit (MC_CMD_GET_CAPABILITIES_OUT_RX_INCLUDE_FCS).
To receive frames with bad FCS (rx-all) we just don't return the discard
 flag EFX_RX_PKT_DISCARD from efx_ef10_handle_rx_event_errors() or
 efx_farch_handle_rx_not_ok().

Signed-off-by: default avatarEdward Cree <ecree@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e0337f92
Loading
Loading
Loading
Loading
+12 −4
Original line number Original line Diff line number Diff line
@@ -674,6 +674,10 @@ static int efx_ef10_probe(struct efx_nic *efx)
	efx->rx_packet_len_offset =
	efx->rx_packet_len_offset =
		ES_DZ_RX_PREFIX_PKTLEN_OFST - ES_DZ_RX_PREFIX_SIZE;
		ES_DZ_RX_PREFIX_PKTLEN_OFST - ES_DZ_RX_PREFIX_SIZE;


	if (nic_data->datapath_caps &
	    (1 << MC_CMD_GET_CAPABILITIES_OUT_RX_INCLUDE_FCS_LBN))
		efx->net_dev->hw_features |= NETIF_F_RXFCS;

	rc = efx_mcdi_port_get_number(efx);
	rc = efx_mcdi_port_get_number(efx);
	if (rc < 0)
	if (rc < 0)
		goto fail5;
		goto fail5;
@@ -3199,12 +3203,16 @@ static u16 efx_ef10_handle_rx_event_errors(struct efx_channel *channel,
					   const efx_qword_t *event)
					   const efx_qword_t *event)
{
{
	struct efx_nic *efx = channel->efx;
	struct efx_nic *efx = channel->efx;
	bool handled = false;


	if (EFX_QWORD_FIELD(*event, ESF_DZ_RX_ECRC_ERR)) {
	if (EFX_QWORD_FIELD(*event, ESF_DZ_RX_ECRC_ERR)) {
		if (!(efx->net_dev->features & NETIF_F_RXALL)) {
			if (!efx->loopback_selftest)
			if (!efx->loopback_selftest)
				channel->n_rx_eth_crc_err += n_packets;
				channel->n_rx_eth_crc_err += n_packets;
			return EFX_RX_PKT_DISCARD;
			return EFX_RX_PKT_DISCARD;
		}
		}
		handled = true;
	}
	if (EFX_QWORD_FIELD(*event, ESF_DZ_RX_IPCKSUM_ERR)) {
	if (EFX_QWORD_FIELD(*event, ESF_DZ_RX_IPCKSUM_ERR)) {
		if (unlikely(rx_encap_hdr != ESE_EZ_ENCAP_HDR_VXLAN &&
		if (unlikely(rx_encap_hdr != ESE_EZ_ENCAP_HDR_VXLAN &&
			     rx_l3_class != ESE_DZ_L3_CLASS_IP4 &&
			     rx_l3_class != ESE_DZ_L3_CLASS_IP4 &&
@@ -3274,7 +3282,7 @@ static u16 efx_ef10_handle_rx_event_errors(struct efx_channel *channel,
		return 0;
		return 0;
	}
	}


	WARN_ON(1); /* No error bits were recognised */
	WARN_ON(!handled); /* No error bits were recognised */
	return 0;
	return 0;
}
}


+10 −4
Original line number Original line Diff line number Diff line
@@ -2315,8 +2315,11 @@ static int efx_set_features(struct net_device *net_dev, netdev_features_t data)
			return rc;
			return rc;
	}
	}


	/* If Rx VLAN filter is changed, update filters via mac_reconfigure */
	/* If Rx VLAN filter is changed, update filters via mac_reconfigure.
	if ((net_dev->features ^ data) & NETIF_F_HW_VLAN_CTAG_FILTER) {
	 * If rx-fcs is changed, mac_reconfigure updates that too.
	 */
	if ((net_dev->features ^ data) & (NETIF_F_HW_VLAN_CTAG_FILTER |
					  NETIF_F_RXFCS)) {
		/* efx_set_rx_mode() will schedule MAC work to update filters
		/* efx_set_rx_mode() will schedule MAC work to update filters
		 * when a new features are finally set in net_dev.
		 * when a new features are finally set in net_dev.
		 */
		 */
@@ -3242,7 +3245,7 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)


	/* Determine netdevice features */
	/* Determine netdevice features */
	net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
	net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
			      NETIF_F_TSO | NETIF_F_RXCSUM);
			      NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_RXALL);
	if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
	if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
		net_dev->features |= NETIF_F_TSO6;
		net_dev->features |= NETIF_F_TSO6;
	/* Check whether device supports TSO */
	/* Check whether device supports TSO */
@@ -3253,7 +3256,10 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
				   NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
				   NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
				   NETIF_F_RXCSUM);
				   NETIF_F_RXCSUM);


	net_dev->hw_features = net_dev->features & ~efx->fixed_features;
	net_dev->hw_features |= net_dev->features & ~efx->fixed_features;

	/* Disable receiving frames with bad FCS, by default. */
	net_dev->features &= ~NETIF_F_RXALL;


	/* Disable VLAN filtering by default.  It may be enforced if
	/* Disable VLAN filtering by default.  It may be enforced if
	 * the feature is fixed (i.e. VLAN filters are required to
	 * the feature is fixed (i.e. VLAN filters are required to
+4 −0
Original line number Original line Diff line number Diff line
@@ -927,6 +927,10 @@ static u16 efx_farch_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
	}
	}
#endif
#endif


	if (efx->net_dev->features & NETIF_F_RXALL)
		/* don't discard frame for CRC error */
		rx_ev_eth_crc_err = false;

	/* The frame must be discarded if any of these are true. */
	/* The frame must be discarded if any of these are true. */
	return (rx_ev_eth_crc_err | rx_ev_frm_trunc |
	return (rx_ev_eth_crc_err | rx_ev_frm_trunc |
		rx_ev_tobe_disc | rx_ev_pause_frm) ?
		rx_ev_tobe_disc | rx_ev_pause_frm) ?
+4 −0
Original line number Original line Diff line number Diff line
@@ -1029,6 +1029,10 @@ int efx_mcdi_set_mac(struct efx_nic *efx)
	MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_REJECT,
	MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_REJECT,
			      SET_MAC_IN_REJECT_UNCST, efx->unicast_filter);
			      SET_MAC_IN_REJECT_UNCST, efx->unicast_filter);


	MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_FLAGS,
			      SET_MAC_IN_FLAG_INCLUDE_FCS,
			      !!(efx->net_dev->features & NETIF_F_RXFCS));

	switch (efx->wanted_fc) {
	switch (efx->wanted_fc) {
	case EFX_FC_RX | EFX_FC_TX:
	case EFX_FC_RX | EFX_FC_TX:
		fcntl = MC_CMD_FCNTL_BIDIR;
		fcntl = MC_CMD_FCNTL_BIDIR;