summaryrefslogtreecommitdiffstats
path: root/sys/dev/msk
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2009-06-02 04:35:44 +0000
committeryongari <yongari@FreeBSD.org>2009-06-02 04:35:44 +0000
commit493c3c966072849c324b35b3d2c72f2ddc8648f0 (patch)
treef991d243407ef8b8839b7f3ac5085b4291cec66b /sys/dev/msk
parentf27a08a589cf7f329010cf7834a9a0143dc7b1b2 (diff)
downloadFreeBSD-src-493c3c966072849c324b35b3d2c72f2ddc8648f0.zip
FreeBSD-src-493c3c966072849c324b35b3d2c72f2ddc8648f0.tar.gz
Add frame parser capability of Yukon FE+ and Yukon Extreme. With
this feature hardware automatically computes TCP/UDP payload offset. Introduce MSK_FLAG_AUTOTX_CSUM to mark the capability. Yukon Extreme B0 revision is known to have a silicon for the feature so disable it. Yukon Extreme B0 still can do Tx checksum offloading but CPU have to compute TCP/UDP payload offset. To enable traditional checksum offloading, disable automatic Tx checksum calculation capability. Yukon Extreme A0 revision could not use store-and-forward mode for jumbo frames(silicon bug) so disable Tx checksum offloading for jumbo frames. I believe controllers that have MSK_FLAG_AUTOTX_CSUM capability or new descriptor format do not have Tx checksum offload bug so disable checksum offloading workaround for for short frames. Tested by: jhb, Warren Block ( wblock <> wonkity dot com )
Diffstat (limited to 'sys/dev/msk')
-rw-r--r--sys/dev/msk/if_msk.c55
-rw-r--r--sys/dev/msk/if_mskreg.h5
2 files changed, 47 insertions, 13 deletions
diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
index 316770e..4a98b64 100644
--- a/sys/dev/msk/if_msk.c
+++ b/sys/dev/msk/if_msk.c
@@ -1676,7 +1676,21 @@ mskc_attach(device_t dev)
break;
case CHIP_ID_YUKON_EX:
sc->msk_clock = 125; /* 125 Mhz */
- sc->msk_pflags |= MSK_FLAG_JUMBO | MSK_FLAG_DESCV2;
+ sc->msk_pflags |= MSK_FLAG_JUMBO | MSK_FLAG_DESCV2 |
+ MSK_FLAG_AUTOTX_CSUM;
+ /*
+ * Yukon Extreme seems to have silicon bug for
+ * automatic Tx checksum calculation capability.
+ */
+ if (sc->msk_hw_rev == CHIP_REV_YU_EX_B0)
+ sc->msk_pflags &= ~MSK_FLAG_AUTOTX_CSUM;
+ /*
+ * Yukon Extreme A0 could not use store-and-forward
+ * for jumbo frames, so disable Tx checksum
+ * offloading for jumbo frames.
+ */
+ if (sc->msk_hw_rev == CHIP_REV_YU_EX_A0)
+ sc->msk_pflags |= MSK_FLAG_JUMBO_NOCSUM;
break;
case CHIP_ID_YUKON_FE:
sc->msk_clock = 100; /* 100 Mhz */
@@ -1684,7 +1698,8 @@ mskc_attach(device_t dev)
break;
case CHIP_ID_YUKON_FE_P:
sc->msk_clock = 50; /* 50 Mhz */
- sc->msk_pflags |= MSK_FLAG_FASTETHER | MSK_FLAG_DESCV2;
+ sc->msk_pflags |= MSK_FLAG_FASTETHER | MSK_FLAG_DESCV2 |
+ MSK_FLAG_AUTOTX_CSUM;
if (sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) {
/*
* XXX
@@ -2477,8 +2492,10 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
tcp_offset = offset = 0;
m = *m_head;
- if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
- (m->m_pkthdr.csum_flags & (MSK_CSUM_FEATURES | CSUM_TSO)) != 0) {
+ if (((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) == 0 &&
+ (m->m_pkthdr.csum_flags & MSK_CSUM_FEATURES) != 0) ||
+ ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
+ (m->m_pkthdr.csum_flags & CSUM_TSO) != 0)) {
/*
* Since mbuf has no protocol specific structure information
* in it we have to inspect protocol information here to
@@ -2537,9 +2554,12 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
* resort to S/W checksum routine when we encounter short
* TCP frames.
* Short UDP packets appear to be handled correctly by
- * Yukon II.
+ * Yukon II. Also I assume this bug does not happen on
+ * controllers that use newer descriptor format or
+ * automatic Tx checksum calaulcation.
*/
- if (m->m_pkthdr.len < MSK_MIN_FRAMELEN &&
+ if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) == 0 &&
+ (m->m_pkthdr.len < MSK_MIN_FRAMELEN) &&
(m->m_pkthdr.csum_flags & CSUM_TCP) != 0) {
m = m_pullup(m, offset + sizeof(struct tcphdr));
if (m == NULL) {
@@ -2640,7 +2660,7 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
}
/* Check if we have to handle checksum offload. */
if (tso == 0 && (m->m_pkthdr.csum_flags & MSK_CSUM_FEATURES) != 0) {
- if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0)
+ if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) != 0)
control |= CALSUM;
else {
tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
@@ -3784,10 +3804,23 @@ msk_init_locked(struct msk_if_softc *sc_if)
CSR_WRITE_4(sc, Q_ADDR(sc_if->msk_txq, Q_CSR), BMU_OPER_INIT);
CSR_WRITE_4(sc, Q_ADDR(sc_if->msk_txq, Q_CSR), BMU_FIFO_OP_ON);
CSR_WRITE_2(sc, Q_ADDR(sc_if->msk_txq, Q_WM), MSK_BMU_TX_WM);
- if (sc->msk_hw_id == CHIP_ID_YUKON_EC_U &&
- sc->msk_hw_rev == CHIP_REV_YU_EC_U_A0) {
- /* Fix for Yukon-EC Ultra: set BMU FIFO level */
- CSR_WRITE_2(sc, Q_ADDR(sc_if->msk_txq, Q_AL), MSK_ECU_TXFF_LEV);
+ switch (sc->msk_hw_id) {
+ case CHIP_ID_YUKON_EC_U:
+ if (sc->msk_hw_rev == CHIP_REV_YU_EC_U_A0) {
+ /* Fix for Yukon-EC Ultra: set BMU FIFO level */
+ CSR_WRITE_2(sc, Q_ADDR(sc_if->msk_txq, Q_AL),
+ MSK_ECU_TXFF_LEV);
+ }
+ break;
+ case CHIP_ID_YUKON_EX:
+ /*
+ * Yukon Extreme seems to have silicon bug for
+ * automatic Tx checksum calculation capability.
+ */
+ if (sc->msk_hw_rev == CHIP_REV_YU_EX_B0)
+ CSR_WRITE_4(sc, Q_ADDR(sc_if->msk_txq, Q_F),
+ F_TX_CHK_AUTO_OFF);
+ break;
}
/* Setup Rx Queue Bus Memory Interface. */
diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h
index e0de8a4..8f5797b 100644
--- a/sys/dev/msk/if_mskreg.h
+++ b/sys/dev/msk/if_mskreg.h
@@ -2502,8 +2502,9 @@ struct msk_if_softc {
#define MSK_FLAG_JUMBO_NOCSUM 0x0010
#define MSK_FLAG_RAMBUF 0x0020
#define MSK_FLAG_DESCV2 0x0040
-#define MSK_FLAG_NOHWVLAN 0x0080
-#define MSK_FLAG_NORXCHK 0x0100
+#define MSK_FLAG_AUTOTX_CSUM 0x0080
+#define MSK_FLAG_NOHWVLAN 0x0100
+#define MSK_FLAG_NORXCHK 0x0200
#define MSK_FLAG_SUSPEND 0x2000
#define MSK_FLAG_DETACH 0x4000
#define MSK_FLAG_LINK 0x8000
OpenPOWER on IntegriCloud