summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarybchik <arybchik@FreeBSD.org>2016-01-14 14:35:46 +0000
committerarybchik <arybchik@FreeBSD.org>2016-01-14 14:35:46 +0000
commit73ae6a20799dd833416f8e7b89ed784d0251f3b3 (patch)
tree0e75f4ec7e3bcf7793cd0c5762a92c4774b3e296
parentdb40521c991765381053de8d0f1cb409b9835872 (diff)
downloadFreeBSD-src-73ae6a20799dd833416f8e7b89ed784d0251f3b3.zip
FreeBSD-src-73ae6a20799dd833416f8e7b89ed784d0251f3b3.tar.gz
MFC r291747
sfxge: [EF10] support RxQ scattering control If, for example, a VF is configured to use a 1500 byte MTU, but the port it is attached to is set to 9000 bytes, overlength frames can be received by the VF. As Huntington scatters by default, these overlength packets would be scattered across several descriptors, with all except the last having the CONT bit set. To avoid this, disable scatter when creating RXQs if the firmware supports doing so, which all recent versions do. Then we only get a single descriptor from an overlength frame. This will have the CONT bit set to indicate it was truncated, so we can discard it. Submitted by: Mark Spender <mspender at solarflare.com> Sponsored by: Solarflare Communications, Inc.
-rw-r--r--sys/dev/sfxge/common/efx.h1
-rw-r--r--sys/dev/sfxge/common/hunt_ev.c6
-rw-r--r--sys/dev/sfxge/common/hunt_nic.c8
-rw-r--r--sys/dev/sfxge/common/hunt_rx.c32
4 files changed, 35 insertions, 12 deletions
diff --git a/sys/dev/sfxge/common/efx.h b/sys/dev/sfxge/common/efx.h
index 95d2f61..d33d478c 100644
--- a/sys/dev/sfxge/common/efx.h
+++ b/sys/dev/sfxge/common/efx.h
@@ -1174,6 +1174,7 @@ typedef struct efx_nic_cfg_s {
boolean_t enc_hw_tx_insert_vlan_enabled;
/* Datapath firmware vadapter/vport/vswitch support */
boolean_t enc_datapath_cap_evb;
+ boolean_t enc_rx_disable_scatter_supported;
/* External port identifier */
uint8_t enc_external_port;
} efx_nic_cfg_t;
diff --git a/sys/dev/sfxge/common/hunt_ev.c b/sys/dev/sfxge/common/hunt_ev.c
index 71d85c5..f9fbc81 100644
--- a/sys/dev/sfxge/common/hunt_ev.c
+++ b/sys/dev/sfxge/common/hunt_ev.c
@@ -528,10 +528,14 @@ hunt_ev_rx(
if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CONT) != 0) {
/*
+ * This may be part of a scattered frame, or it may be a
+ * truncated frame if scatter is disabled on this RXQ.
+ * Overlength frames can be received if e.g. a VF is configured
+ * for 1500 MTU but connected to a port set to 9000 MTU
+ * (see bug56567).
* FIXME: There is not yet any driver that supports scatter on
* Huntington. Scatter support is required for OSX.
*/
- EFSYS_ASSERT(0);
flags |= EFX_PKT_CONT;
}
diff --git a/sys/dev/sfxge/common/hunt_nic.c b/sys/dev/sfxge/common/hunt_nic.c
index 3fcaae5..b41eb40 100644
--- a/sys/dev/sfxge/common/hunt_nic.c
+++ b/sys/dev/sfxge/common/hunt_nic.c
@@ -920,6 +920,14 @@ hunt_get_datapath_caps(
encp->enc_rx_batching_enabled = B_FALSE;
}
+ /* Check if the firmware supports disabling scatter on RXQs */
+ if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
+ GET_CAPABILITIES_OUT_RX_DISABLE_SCATTER) == 1) {
+ encp->enc_rx_disable_scatter_supported = B_TRUE;
+ } else {
+ encp->enc_rx_disable_scatter_supported = B_FALSE;
+ }
+
return (0);
fail2:
diff --git a/sys/dev/sfxge/common/hunt_rx.c b/sys/dev/sfxge/common/hunt_rx.c
index e173a23..6fdc747 100644
--- a/sys/dev/sfxge/common/hunt_rx.c
+++ b/sys/dev/sfxge/common/hunt_rx.c
@@ -46,7 +46,8 @@ efx_mcdi_init_rxq(
__in uint32_t target_evq,
__in uint32_t label,
__in uint32_t instance,
- __in efsys_mem_t *esmp)
+ __in efsys_mem_t *esmp,
+ __in boolean_t disable_scatter)
{
efx_mcdi_req_t req;
uint8_t payload[
@@ -71,12 +72,13 @@ efx_mcdi_init_rxq(
MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_TARGET_EVQ, target_evq);
MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_LABEL, label);
MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_INSTANCE, instance);
- MCDI_IN_POPULATE_DWORD_5(req, INIT_RXQ_IN_FLAGS,
- INIT_RXQ_IN_FLAG_BUFF_MODE, 0,
- INIT_RXQ_IN_FLAG_HDR_SPLIT, 0,
- INIT_RXQ_IN_FLAG_TIMESTAMP, 0,
- INIT_RXQ_IN_CRC_MODE, 0,
- INIT_RXQ_IN_FLAG_PREFIX, 1);
+ MCDI_IN_POPULATE_DWORD_6(req, INIT_RXQ_IN_FLAGS,
+ INIT_RXQ_IN_FLAG_BUFF_MODE, 0,
+ INIT_RXQ_IN_FLAG_HDR_SPLIT, 0,
+ INIT_RXQ_IN_FLAG_TIMESTAMP, 0,
+ INIT_RXQ_IN_CRC_MODE, 0,
+ INIT_RXQ_IN_FLAG_PREFIX, 1,
+ INIT_RXQ_IN_FLAG_DISABLE_SCATTER, disable_scatter);
MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_OWNER_ID, 0);
MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_PORT_ID, EVB_PORT_ID_ASSIGNED);
@@ -685,6 +687,7 @@ hunt_rx_qcreate(
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_rc_t rc;
+ boolean_t disable_scatter;
_NOTE(ARGUNUSED(erp))
@@ -704,14 +707,21 @@ hunt_rx_qcreate(
goto fail2;
}
+ /* Scatter can only be disabled if the firmware supports doing so */
+ if ((type != EFX_RXQ_TYPE_SCATTER) &&
+ enp->en_nic_cfg.enc_rx_disable_scatter_supported) {
+ disable_scatter = B_TRUE;
+ } else {
+ disable_scatter = B_FALSE;
+ }
+
/*
- * FIXME: Siena code handles different queue types (default, header
- * split, scatter); we'll need to do something more here later, but
- * all that stuff is TBD for now.
+ * Note: EFX_RXQ_TYPE_SPLIT_HEADER and EFX_RXQ_TYPE_SPLIT_PAYLOAD are
+ * not supported here.
*/
if ((rc = efx_mcdi_init_rxq(enp, n, eep->ee_index, label, index,
- esmp)) != 0)
+ esmp, disable_scatter)) != 0)
goto fail3;
erp->er_eep = eep;
OpenPOWER on IntegriCloud