sfxge: support Rx checksum offloads disabling

We can't disable it in HW, but we can ignore result.
Discard Rx descriptor checksum flags if Rx checksum offload is off.

Reviewed by:    gnn
Sponsored by:   Solarflare Communications, Inc.
MFC after:      2 days
Differential Revision: https://reviews.freebsd.org/D2544
This commit is contained in:
Andrew Rybchenko 2015-05-16 05:36:40 +00:00
parent 8e7e3163be
commit b5bae9f4f2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=282996
2 changed files with 30 additions and 14 deletions

View File

@ -65,8 +65,7 @@ __FBSDID("$FreeBSD$");
IFCAP_JUMBO_MTU | IFCAP_LRO | \
IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE | IFCAP_HWSTATS)
#define SFXGE_CAP_ENABLE SFXGE_CAP
#define SFXGE_CAP_FIXED (IFCAP_VLAN_MTU | IFCAP_RXCSUM | IFCAP_VLAN_HWCSUM | \
IFCAP_RXCSUM_IPV6 | \
#define SFXGE_CAP_FIXED (IFCAP_VLAN_MTU | IFCAP_VLAN_HWCSUM | \
IFCAP_JUMBO_MTU | IFCAP_LINKSTATE | IFCAP_HWSTATS)
MALLOC_DEFINE(M_SFXGE, "sfxge", "Solarflare 10GigE driver");

View File

@ -795,7 +795,8 @@ void
sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop)
{
struct sfxge_softc *sc = rxq->sc;
int lro_enabled = sc->ifnet->if_capenable & IFCAP_LRO;
int if_capenable = sc->ifnet->if_capenable;
int lro_enabled = if_capenable & IFCAP_LRO;
unsigned int index;
struct sfxge_evq *evq;
unsigned int completed;
@ -825,21 +826,37 @@ sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop)
prefetch_read_many(mtod(m, caddr_t));
/* Check for loopback packets */
if (!(rx_desc->flags & EFX_PKT_IPV4) &&
!(rx_desc->flags & EFX_PKT_IPV6)) {
struct ether_header *etherhp;
switch (rx_desc->flags & (EFX_PKT_IPV4 | EFX_PKT_IPV6)) {
case EFX_PKT_IPV4:
if (~if_capenable & IFCAP_RXCSUM)
rx_desc->flags &=
~(EFX_CKSUM_IPV4 | EFX_CKSUM_TCPUDP);
break;
case EFX_PKT_IPV6:
if (~if_capenable & IFCAP_RXCSUM_IPV6)
rx_desc->flags &= ~EFX_CKSUM_TCPUDP;
break;
case 0:
/* Check for loopback packets */
{
struct ether_header *etherhp;
/*LINTED*/
etherhp = mtod(m, struct ether_header *);
/*LINTED*/
etherhp = mtod(m, struct ether_header *);
if (etherhp->ether_type ==
htons(SFXGE_ETHERTYPE_LOOPBACK)) {
EFSYS_PROBE(loopback);
if (etherhp->ether_type ==
htons(SFXGE_ETHERTYPE_LOOPBACK)) {
EFSYS_PROBE(loopback);
rxq->loopback++;
goto discard;
rxq->loopback++;
goto discard;
}
}
break;
default:
KASSERT(B_FALSE,
("Rx descriptor with both IPv4 and IPv6 flags"));
goto discard;
}
/* Pass packet up the stack or into LRO (pipelined) */