summaryrefslogtreecommitdiffstats
path: root/sys/dev/sfxge
diff options
context:
space:
mode:
authorarybchik <arybchik@FreeBSD.org>2017-01-09 08:07:18 +0000
committerarybchik <arybchik@FreeBSD.org>2017-01-09 08:07:18 +0000
commit13ff76b912efb400c1ef20401491bcd0b3f9c0e8 (patch)
treefc53a1eb0b6204d3ab440d06764e14f3fbf9dd66 /sys/dev/sfxge
parentc0e3c22de45913cdb03edf2e7efdafc6daf2d081 (diff)
downloadFreeBSD-src-13ff76b912efb400c1ef20401491bcd0b3f9c0e8.zip
FreeBSD-src-13ff76b912efb400c1ef20401491bcd0b3f9c0e8.tar.gz
MFC r311640
sfxge(4): allow DMA descs to cross 4k boundary on EF10 Siena has limitation on maximum byte count and 4k boundary crosssing (which is stricter than maximum byte count). EF10 has limitation on maximum byte count only. Sponsored by: Solarflare Communications, Inc.
Diffstat (limited to 'sys/dev/sfxge')
-rwxr-xr-xsys/dev/sfxge/common/ef10_tx.c9
-rw-r--r--sys/dev/sfxge/common/efx.h7
-rw-r--r--sys/dev/sfxge/common/efx_tx.c16
-rw-r--r--sys/dev/sfxge/common/hunt_nic.c4
-rw-r--r--sys/dev/sfxge/common/medford_nic.c4
-rw-r--r--sys/dev/sfxge/common/siena_nic.c4
-rw-r--r--sys/dev/sfxge/sfxge_tx.c7
7 files changed, 41 insertions, 10 deletions
diff --git a/sys/dev/sfxge/common/ef10_tx.c b/sys/dev/sfxge/common/ef10_tx.c
index 2b0ec5e..e39b271 100755
--- a/sys/dev/sfxge/common/ef10_tx.c
+++ b/sys/dev/sfxge/common/ef10_tx.c
@@ -438,8 +438,9 @@ ef10_tx_qpost(
size_t offset;
efx_qword_t qword;
- /* Fragments must not span 4k boundaries. */
- EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= (addr + size));
+ /* No limitations on boundary crossing */
+ EFSYS_ASSERT(size <=
+ etp->et_enp->en_nic_cfg.enc_tx_dma_desc_size_max);
id = added++ & etp->et_mask;
offset = id * sizeof (efx_qword_t);
@@ -584,8 +585,8 @@ ef10_tx_qdesc_dma_create(
__in boolean_t eop,
__out efx_desc_t *edp)
{
- /* Fragments must not span 4k boundaries. */
- EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= addr + size);
+ /* No limitations on boundary crossing */
+ EFSYS_ASSERT(size <= etp->et_enp->en_nic_cfg.enc_tx_dma_desc_size_max);
EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
efsys_dma_addr_t, addr,
diff --git a/sys/dev/sfxge/common/efx.h b/sys/dev/sfxge/common/efx.h
index 53c7a15..0f91b4f 100644
--- a/sys/dev/sfxge/common/efx.h
+++ b/sys/dev/sfxge/common/efx.h
@@ -1154,6 +1154,13 @@ typedef struct efx_nic_cfg_s {
uint32_t enc_rx_batch_max;
/* Number of rx descriptors the hardware requires for a push. */
uint32_t enc_rx_push_align;
+ /* Maximum amount of data in DMA descriptor */
+ uint32_t enc_tx_dma_desc_size_max;
+ /*
+ * Boundary which DMA descriptor data must not cross or 0 if no
+ * limitation.
+ */
+ uint32_t enc_tx_dma_desc_boundary;
/*
* Maximum number of bytes into the packet the TCP header can start for
* the hardware to apply TSO packet edits.
diff --git a/sys/dev/sfxge/common/efx_tx.c b/sys/dev/sfxge/common/efx_tx.c
index 8c06d4f..cb976af 100644
--- a/sys/dev/sfxge/common/efx_tx.c
+++ b/sys/dev/sfxge/common/efx_tx.c
@@ -748,8 +748,12 @@ siena_tx_qpost(
size_t size = ebp->eb_size;
efsys_dma_addr_t end = start + size;
- /* Fragments must not span 4k boundaries. */
- EFSYS_ASSERT(P2ROUNDUP(start + 1, 4096) >= end);
+ /*
+ * Fragments must not span 4k boundaries.
+ * Here it is a stricter requirement than the maximum length.
+ */
+ EFSYS_ASSERT(P2ROUNDUP(start + 1,
+ etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= end);
EFX_TX_DESC(etp, start, size, ebp->eb_eop, added);
}
@@ -1009,8 +1013,12 @@ siena_tx_qdesc_dma_create(
__in boolean_t eop,
__out efx_desc_t *edp)
{
- /* Fragments must not span 4k boundaries. */
- EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= addr + size);
+ /*
+ * Fragments must not span 4k boundaries.
+ * Here it is a stricter requirement than the maximum length.
+ */
+ EFSYS_ASSERT(P2ROUNDUP(addr + 1,
+ etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= addr + size);
EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
efsys_dma_addr_t, addr,
diff --git a/sys/dev/sfxge/common/hunt_nic.c b/sys/dev/sfxge/common/hunt_nic.c
index 14d6c1f..477fa76 100644
--- a/sys/dev/sfxge/common/hunt_nic.c
+++ b/sys/dev/sfxge/common/hunt_nic.c
@@ -304,6 +304,10 @@ hunt_board_cfg(
/* Alignment for WPTR updates */
encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN;
+ encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT);
+ /* No boundary crossing limits */
+ encp->enc_tx_dma_desc_boundary = 0;
+
/*
* Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
* MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
diff --git a/sys/dev/sfxge/common/medford_nic.c b/sys/dev/sfxge/common/medford_nic.c
index ea937e4..f883bf7 100644
--- a/sys/dev/sfxge/common/medford_nic.c
+++ b/sys/dev/sfxge/common/medford_nic.c
@@ -301,6 +301,10 @@ medford_board_cfg(
/* Alignment for WPTR updates */
encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN;
+ encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT);
+ /* No boundary crossing limits */
+ encp->enc_tx_dma_desc_boundary = 0;
+
/*
* Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
* MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
diff --git a/sys/dev/sfxge/common/siena_nic.c b/sys/dev/sfxge/common/siena_nic.c
index 331d5a5..39922a7 100644
--- a/sys/dev/sfxge/common/siena_nic.c
+++ b/sys/dev/sfxge/common/siena_nic.c
@@ -138,6 +138,10 @@ siena_board_cfg(
/* Alignment for WPTR updates */
encp->enc_rx_push_align = 1;
+ encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
+ /* Fragments must not span 4k boundaries. */
+ encp->enc_tx_dma_desc_boundary = 4096;
+
/* Resource limits */
rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
if (rc != 0) {
diff --git a/sys/dev/sfxge/sfxge_tx.c b/sys/dev/sfxge/sfxge_tx.c
index 68a91c4..4e31aec 100644
--- a/sys/dev/sfxge/sfxge_tx.c
+++ b/sys/dev/sfxge/sfxge_tx.c
@@ -1720,6 +1720,7 @@ static int
sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
enum sfxge_txq_type type, unsigned int evq_index)
{
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp);
char name[16];
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
struct sysctl_oid *txq_node;
@@ -1750,9 +1751,11 @@ sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
&txq->buf_base_id);
/* Create a DMA tag for packet mappings. */
- if (bus_dma_tag_create(sc->parent_dma_tag, 1, 0x1000,
+ if (bus_dma_tag_create(sc->parent_dma_tag, 1,
+ encp->enc_tx_dma_desc_boundary,
MIN(0x3FFFFFFFFFFFUL, BUS_SPACE_MAXADDR), BUS_SPACE_MAXADDR, NULL,
- NULL, 0x11000, SFXGE_TX_MAPPING_MAX_SEG, 0x1000, 0, NULL, NULL,
+ NULL, 0x11000, SFXGE_TX_MAPPING_MAX_SEG,
+ encp->enc_tx_dma_desc_size_max, 0, NULL, NULL,
&txq->packet_dma_tag) != 0) {
device_printf(sc->dev, "Couldn't allocate txq DMA tag\n");
rc = ENOMEM;
OpenPOWER on IntegriCloud