From: Sepherosa Ziehau Date: Thu, 23 Apr 2015 12:21:58 +0000 (+0800) Subject: emx: Add errata workaround for multiple TX queues X-Git-Tag: v4.2.0rc~309 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/57f26b356b7b50aab2bbb0dec9adf665ee6220af emx: Add errata workaround for multiple TX queues This makes multiple TX queues work on 82574. Information-from: Sean Bruno Tested-with: 82571, 82574, I217 --- diff --git a/share/man/man4/em.4 b/share/man/man4/em.4 index e982cb7923..c303574d4c 100644 --- a/share/man/man4/em.4 +++ b/share/man/man4/em.4 @@ -78,7 +78,7 @@ the .Nm emx driver will try enabling 2 reception queues if there are multiple CPUs on the system. -For 82571, 82572, I217 and I218 +For 82571, 82572, 82574, I217 and I218 the .Nm emx driver could be configured to enable 2 transmission queues. diff --git a/sys/dev/netif/emx/if_emx.c b/sys/dev/netif/emx/if_emx.c index aa79ea3381..821c2b8280 100644 --- a/sys/dev/netif/emx/if_emx.c +++ b/sys/dev/netif/emx/if_emx.c @@ -661,7 +661,8 @@ emx_attach(device_t dev) if (sc->hw.mac.type == e1000_82571 || sc->hw.mac.type == e1000_82572 || sc->hw.mac.type == e1000_80003es2lan || - sc->hw.mac.type == e1000_pch_lpt) + sc->hw.mac.type == e1000_pch_lpt || + sc->hw.mac.type == e1000_82574) tx_ring_max = EMX_NTX_RING; sc->tx_ring_cnt = device_getenv_int(dev, "txr", emx_txr); sc->tx_ring_cnt = if_ring_count2(sc->tx_ring_cnt, tx_ring_max); @@ -2283,7 +2284,7 @@ emx_init_tx_ring(struct emx_txdata *tdata) static void emx_init_tx_unit(struct emx_softc *sc) { - uint32_t tctl, tarc, tipg = 0; + uint32_t tctl, tarc, tipg = 0, txdctl; int i; for (i = 0; i < sc->tx_ring_inuse; ++i) { @@ -2328,6 +2329,14 @@ emx_init_tx_unit(struct emx_softc *sc) E1000_WRITE_REG(&sc->hw, E1000_TIDV, 1); E1000_WRITE_REG(&sc->hw, E1000_TADV, 0); + /* + * Errata workaround (obtained from Linux). This is necessary + * to make multiple TX queues work on 82574. + * XXX can't find it in any published errata though. + */ + txdctl = E1000_READ_REG(&sc->hw, E1000_TXDCTL(0)); + E1000_WRITE_REG(&sc->hw, E1000_TXDCTL(1), txdctl); + if (sc->hw.mac.type == e1000_82571 || sc->hw.mac.type == e1000_82572) { tarc = E1000_READ_REG(&sc->hw, E1000_TARC(0));