Date: Tue, 2 Jun 2009 04:59:29 +0000 (UTC) From: Pyun YongHyeon <yongari@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r193298 - head/sys/dev/msk Message-ID: <200906020459.n524xTE5003101@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: yongari Date: Tue Jun 2 04:59:29 2009 New Revision: 193298 URL: http://svn.freebsd.org/changeset/base/193298 Log: Add Rx checksum offloading support for Yukon FE+ and Yukon Extreme. These controllers use newer descriptor format and the new descriptor format uses status LE to indicate the status of checksum. Rx checksummed value used in previous controllers were very cryptic and I failed to understand how to use them. In addition most controllers in previous generations had Rx checksum offloading bug. While I'm here introduce a MSK_FLAG_NORX_CSUM flag to bypass checking Rx checksum offloading as Yukon FE+ A0 has status LE bug. Modified: head/sys/dev/msk/if_msk.c head/sys/dev/msk/if_mskreg.h Modified: head/sys/dev/msk/if_msk.c ============================================================================== --- head/sys/dev/msk/if_msk.c Tue Jun 2 04:47:28 2009 (r193297) +++ head/sys/dev/msk/if_msk.c Tue Jun 2 04:59:29 2009 (r193298) @@ -258,8 +258,8 @@ static void msk_intr_hwerr(struct msk_so #ifndef __NO_STRICT_ALIGNMENT static __inline void msk_fixup_rx(struct mbuf *); #endif -static void msk_rxeof(struct msk_if_softc *, uint32_t, int); -static void msk_jumbo_rxeof(struct msk_if_softc *, uint32_t, int); +static void msk_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int); +static void msk_jumbo_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int); static void msk_txeof(struct msk_if_softc *, int); static int msk_encap(struct msk_if_softc *, struct mbuf **); static void msk_tx_task(void *, int); @@ -267,6 +267,7 @@ static void msk_start(struct ifnet *); static int msk_ioctl(struct ifnet *, u_long, caddr_t); static void msk_set_prefetch(struct msk_softc *, int, bus_addr_t, uint32_t); static void msk_set_rambuffer(struct msk_if_softc *); +static void msk_set_tx_stfwd(struct msk_if_softc *); static void msk_init(void *); static void msk_init_locked(struct msk_if_softc *); static void msk_stop(struct msk_if_softc *); @@ -991,12 +992,17 @@ msk_ioctl(struct ifnet *ifp, u_long comm else ifp->if_hwassist &= ~MSK_CSUM_FEATURES; } + if ((mask & IFCAP_RXCSUM) != 0 && + (IFCAP_RXCSUM & ifp->if_capabilities) != 0) + ifp->if_capenable ^= IFCAP_RXCSUM; if ((mask & IFCAP_VLAN_HWTAGGING) != 0 && (IFCAP_VLAN_HWTAGGING & ifp->if_capabilities) != 0) { ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; msk_setvlan(sc_if, ifp); } - + if ((mask & IFCAP_VLAN_HWCSUM) != 0 && + (IFCAP_VLAN_HWCSUM & ifp->if_capabilities) != 0) + ifp->if_capenable ^= IFCAP_VLAN_HWCSUM; if ((mask & IFCAP_TSO4) != 0 && (IFCAP_TSO4 & ifp->if_capabilities) != 0) { ifp->if_capenable ^= IFCAP_TSO4; @@ -1492,6 +1498,13 @@ msk_attach(device_t dev) * make Rx checksum offload work on Yukon II hardware. */ ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_TSO4; + /* + * Enable Rx checksum offloading if controller support new + * descriptor format. + */ + if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0 && + (sc_if->msk_flags & MSK_FLAG_NORX_CSUM) == 0) + ifp->if_capabilities |= IFCAP_RXCSUM; ifp->if_hwassist = MSK_CSUM_FEATURES | CSUM_TSO; ifp->if_capenable = ifp->if_capabilities; ifp->if_ioctl = msk_ioctl; @@ -1535,6 +1548,13 @@ msk_attach(device_t dev) * for VLAN interface. */ ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; + /* + * Enable Rx checksum offloading for VLAN taggedd frames + * if controller support new descriptor format. + */ + if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0 && + (sc_if->msk_flags & MSK_FLAG_NORX_CSUM) == 0) + ifp->if_capabilities |= IFCAP_VLAN_HWCSUM; } ifp->if_capenable = ifp->if_capabilities; @@ -1711,7 +1731,8 @@ mskc_attach(device_t dev) * Just pass received frames to upper stack with * minimal test and let upper stack handle them. */ - sc->msk_pflags |= MSK_FLAG_NOHWVLAN | MSK_FLAG_NORXCHK; + sc->msk_pflags |= MSK_FLAG_NOHWVLAN | + MSK_FLAG_NORXCHK | MSK_FLAG_NORX_CSUM; } break; case CHIP_ID_YUKON_XL: @@ -2942,7 +2963,8 @@ msk_fixup_rx(struct mbuf *m) #endif static void -msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, int len) +msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control, + int len) { struct mbuf *m; struct ifnet *ifp; @@ -2994,6 +3016,18 @@ msk_rxeof(struct msk_if_softc *sc_if, ui msk_fixup_rx(m); #endif ifp->if_ipackets++; + if ((ifp->if_capenable & IFCAP_RXCSUM) != 0 && + (control & (CSS_IPV4 | CSS_IPFRAG)) == CSS_IPV4) { + m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED; + if ((control & CSS_IPV4_CSUM_OK) != 0) + m->m_pkthdr.csum_flags |= CSUM_IP_VALID; + if ((control & (CSS_TCP | CSS_UDP)) != 0 && + (control & (CSS_TCPUDP_CSUM_OK)) != 0) { + m->m_pkthdr.csum_flags |= CSUM_DATA_VALID | + CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + } + } /* Check for VLAN tagged packets. */ if ((status & GMR_FS_VLAN) != 0 && (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) { @@ -3010,7 +3044,8 @@ msk_rxeof(struct msk_if_softc *sc_if, ui } static void -msk_jumbo_rxeof(struct msk_if_softc *sc_if, uint32_t status, int len) +msk_jumbo_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control, + int len) { struct mbuf *m; struct ifnet *ifp; @@ -3051,6 +3086,18 @@ msk_jumbo_rxeof(struct msk_if_softc *sc_ msk_fixup_rx(m); #endif ifp->if_ipackets++; + if ((ifp->if_capenable & IFCAP_RXCSUM) != 0 && + (control & (CSS_IPV4 | CSS_IPFRAG)) == CSS_IPV4) { + m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED; + if ((control & CSS_IPV4_CSUM_OK) != 0) + m->m_pkthdr.csum_flags |= CSUM_IP_VALID; + if ((control & (CSS_TCP | CSS_UDP)) != 0 && + (control & (CSS_TCPUDP_CSUM_OK)) != 0) { + m->m_pkthdr.csum_flags |= CSUM_DATA_VALID | + CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + } + } /* Check for VLAN tagged packets. */ if ((status & GMR_FS_VLAN) != 0 && (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) { @@ -3379,9 +3426,9 @@ msk_handle_events(struct msk_softc *sc) case OP_RXSTAT: if (sc_if->msk_framesize > (MCLBYTES - MSK_RX_BUF_ALIGN)) - msk_jumbo_rxeof(sc_if, status, len); + msk_jumbo_rxeof(sc_if, status, control, len); else - msk_rxeof(sc_if, status, len); + msk_rxeof(sc_if, status, control, len); rxprog++; /* * Because there is no way to sync single Rx LE Modified: head/sys/dev/msk/if_mskreg.h ============================================================================== --- head/sys/dev/msk/if_mskreg.h Tue Jun 2 04:47:28 2009 (r193297) +++ head/sys/dev/msk/if_mskreg.h Tue Jun 2 04:59:29 2009 (r193298) @@ -2255,8 +2255,19 @@ struct msk_stat_desc { #define OP_PUTIDX 0x70000000 #define STLE_OP_MASK 0xff000000 +#define STLE_CSS_MASK 0x00ff0000 #define STLE_LEN_MASK 0x0000ffff +/* CSS defined in status LE(valid for descriptor V2 format). */ +#define CSS_TCPUDP_CSUM_OK 0x00800000 +#define CSS_UDP 0x00400000 +#define CSS_TCP 0x00200000 +#define CSS_IPFRAG 0x00100000 +#define CSS_IPV6 0x00080000 +#define CSS_IPV4_CSUM_OK 0x00040000 +#define CSS_IPV4 0x00020000 +#define CSS_PORT 0x00010000 + /* Descriptor Bit Definition */ /* TxCtrl Transmit Buffer Control Field */ /* RxCtrl Receive Buffer Control Field */ @@ -2505,6 +2516,7 @@ struct msk_if_softc { #define MSK_FLAG_AUTOTX_CSUM 0x0080 #define MSK_FLAG_NOHWVLAN 0x0100 #define MSK_FLAG_NORXCHK 0x0200 +#define MSK_FLAG_NORX_CSUM 0x0400 #define MSK_FLAG_SUSPEND 0x2000 #define MSK_FLAG_DETACH 0x4000 #define MSK_FLAG_LINK 0x8000
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906020459.n524xTE5003101>