diff options
author | Giuseppe Cavallaro <peppe.cavallaro@st.com> | 2016-02-29 14:27:38 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-03-02 14:21:33 -0500 |
commit | 0e80bdc9a72df3b31a9fc2012102a6cc8d664e93 (patch) | |
tree | c83e948287802fa31a5b298a4b5fc6aec7342670 /drivers/net/ethernet/stmicro/stmmac/norm_desc.c | |
parent | fbc80823a93c57f2310dacfabfea6c76424552b6 (diff) |
stmmac: first frame prep at the end of xmit routine
This patch is to fill the first descriptor just before granting
the DMA engine so at the end of the xmit.
The patch takes care about the algorithm adopted to mitigate the
interrupts, then it fixes the last segment in case of no fragments.
Moreover, this new implementation does not pass any "ter" field when
prepare the descriptors because this is not necessary.
The patch also details the memory barrier in the xmit.
As final results, this patch guarantees the same performances
but fixing a case if small datagram are sent. In fact, this
kind of test is impacted if no coalesce is done.
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/norm_desc.c')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c index 122fb5ad234b..e13228f115f0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c @@ -195,10 +195,15 @@ static void ndesc_release_tx_desc(struct dma_desc *p, int mode) static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, bool csum_flag, int mode, bool tx_own, - bool ls_ic) + bool ls) { unsigned int tdes1 = p->des1; + if (mode == STMMAC_CHAIN_MODE) + norm_set_tx_desc_len_on_chain(p, len); + else + norm_set_tx_desc_len_on_ring(p, len); + if (is_fs) tdes1 |= TDES1_FIRST_SEGMENT; else @@ -209,23 +214,18 @@ static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, else tdes1 &= ~(TX_CIC_FULL << TDES1_CHECKSUM_INSERTION_SHIFT); + if (ls) + tdes1 |= TDES1_LAST_SEGMENT; + if (tx_own) tdes1 |= TDES0_OWN; - if (ls_ic) - tdes1 |= TDES1_LAST_SEGMENT | TDES1_INTERRUPT; - p->des1 = tdes1; - - if (mode == STMMAC_CHAIN_MODE) - norm_set_tx_desc_len_on_chain(p, len); - else - norm_set_tx_desc_len_on_ring(p, len); } -static void ndesc_clear_tx_ic(struct dma_desc *p) +static void ndesc_set_tx_ic(struct dma_desc *p) { - p->des1 &= ~TDES1_INTERRUPT; + p->des1 |= TDES1_INTERRUPT; } static int ndesc_get_rx_frame_len(struct dma_desc *p, int rx_coe_type) @@ -288,7 +288,7 @@ const struct stmmac_desc_ops ndesc_ops = { .get_tx_owner = ndesc_get_tx_owner, .release_tx_desc = ndesc_release_tx_desc, .prepare_tx_desc = ndesc_prepare_tx_desc, - .clear_tx_ic = ndesc_clear_tx_ic, + .set_tx_ic = ndesc_set_tx_ic, .get_tx_ls = ndesc_get_tx_ls, .set_tx_owner = ndesc_set_tx_owner, .set_rx_owner = ndesc_set_rx_owner, |