summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2010-02-26 18:18:02 +0000
committeryongari <yongari@FreeBSD.org>2010-02-26 18:18:02 +0000
commit2d905c940ccc2b41cf1710d829eb70890f0b05ae (patch)
treed3a963d49075200aa5f716e7745be5d9b5ab28f6
parentc6210b95bd330b1ebc91576e8574146223992440 (diff)
downloadFreeBSD-src-2d905c940ccc2b41cf1710d829eb70890f0b05ae.zip
FreeBSD-src-2d905c940ccc2b41cf1710d829eb70890f0b05ae.tar.gz
Optimize inserting LE for TX checksum computation. Controller does
not require checksum LE configuration if checksum start and write position is the same as before. So keep track last checksum start and write position and insert new LE whenever the position is changed. This reduces number of LEs used in TX path as well as slightly enhance TX performance.
-rw-r--r--sys/dev/msk/if_msk.c26
-rw-r--r--sys/dev/msk/if_mskreg.h1
2 files changed, 17 insertions, 10 deletions
diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
index 38c73f7..0d141d1 100644
--- a/sys/dev/msk/if_msk.c
+++ b/sys/dev/msk/if_msk.c
@@ -738,6 +738,7 @@ msk_init_tx_ring(struct msk_if_softc *sc_if)
int i;
sc_if->msk_cdata.msk_tso_mtu = 0;
+ sc_if->msk_cdata.msk_last_csum = 0;
sc_if->msk_cdata.msk_tx_prod = 0;
sc_if->msk_cdata.msk_tx_cons = 0;
sc_if->msk_cdata.msk_tx_cnt = 0;
@@ -2530,7 +2531,7 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
struct mbuf *m;
bus_dmamap_t map;
bus_dma_segment_t txsegs[MSK_MAXTXSEGS];
- uint32_t control, prod, si;
+ uint32_t control, csum, prod, si;
uint16_t offset, tcp_offset, tso_mtu;
int error, i, nseg, tso;
@@ -2709,17 +2710,22 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) != 0)
control |= CALSUM;
else {
- tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
- tx_le->msk_addr = htole32(((tcp_offset +
- m->m_pkthdr.csum_data) & 0xffff) |
- ((uint32_t)tcp_offset << 16));
- tx_le->msk_control = htole32(1 << 16 |
- (OP_TCPLISW | HW_OWNER));
- control = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
+ control |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
control |= UDPTCP;
- sc_if->msk_cdata.msk_tx_cnt++;
- MSK_INC(prod, MSK_TX_RING_CNT);
+ /* Checksum write position. */
+ csum = (tcp_offset + m->m_pkthdr.csum_data) & 0xffff;
+ /* Checksum start position. */
+ csum |= (uint32_t)tcp_offset << 16;
+ if (csum != sc_if->msk_cdata.msk_last_csum) {
+ tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
+ tx_le->msk_addr = htole32(csum);
+ tx_le->msk_control = htole32(1 << 16 |
+ (OP_TCPLISW | HW_OWNER));
+ sc_if->msk_cdata.msk_tx_cnt++;
+ MSK_INC(prod, MSK_TX_RING_CNT);
+ sc_if->msk_cdata.msk_last_csum = csum;
+ }
}
}
diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h
index 2f4e216..75056b6 100644
--- a/sys/dev/msk/if_mskreg.h
+++ b/sys/dev/msk/if_mskreg.h
@@ -2361,6 +2361,7 @@ struct msk_chain_data {
bus_dmamap_t msk_jumbo_rx_ring_map;
bus_dmamap_t msk_jumbo_rx_sparemap;
uint16_t msk_tso_mtu;
+ uint32_t msk_last_csum;
int msk_tx_prod;
int msk_tx_cons;
int msk_tx_cnt;
OpenPOWER on IntegriCloud