Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/cadence Add hardware checksumming support.
details: https://anonhg.NetBSD.org/src/rev/eca020924f16
branches: trunk
changeset: 340148:eca020924f16
user: rjs <rjs%NetBSD.org@localhost>
date: Mon Aug 24 18:51:37 2015 +0000
description:
Add hardware checksumming support.
diffstat:
sys/dev/cadence/cemacreg.h | 33 +++++++++++++--------
sys/dev/cadence/if_cemac.c | 68 +++++++++++++++++++++++++++++++++++++++++----
2 files changed, 81 insertions(+), 20 deletions(-)
diffs (187 lines):
diff -r a8db5825ff27 -r eca020924f16 sys/dev/cadence/cemacreg.h
--- a/sys/dev/cadence/cemacreg.h Mon Aug 24 18:40:57 2015 +0000
+++ b/sys/dev/cadence/cemacreg.h Mon Aug 24 18:51:37 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cemacreg.h,v 1.2 2015/08/13 14:51:35 rjs Exp $ */
+/* $NetBSD: cemacreg.h,v 1.3 2015/08/24 18:51:37 rjs Exp $ */
/*-
* Copyright (c) 2015 Genetec Corporation. All rights reserved.
@@ -164,6 +164,7 @@
#define GEM_CFG_CLK_64 __SHIFTIN(4, GEM_CFG_CLK)
#define GEM_CFG_CLK_96 __SHIFTIN(5, GEM_CFG_CLK)
#define GEM_CFG_DBW __BITS(22, 21)
+#define GEM_CFG_RX_CHKSUM_OFFLD_EN __BIT(24)
/* Status Register bits: */
#define ETH_SR_IDLE 0x0004U /* 1 = PHY logic is running */
@@ -244,30 +245,36 @@
#define ETH_RDSC_F_USED 0x00000001U
/* frame info bits: */
-#define ETH_RDSC_I_BCAST 0x80000000U
-#define ETH_RDSC_I_MULTICAST 0x40000000U
-#define ETH_RDSC_I_UNICAST 0x20000000U
+#define ETH_RDSC_I_BCAST __BIT(31)
+#define ETH_RDSC_I_MULTICAST __BIT(30)
+#define ETH_RDSC_I_UNICAST __BIT(29)
#define ETH_RDSC_I_VLAN 0x10000000U
#define ETH_RDSC_I_UNKNOWN_SRC 0x08000000U
#define ETH_RDSC_I_MATCH1 0x04000000U
#define ETH_RDSC_I_MATCH2 0x02000000U
#define ETH_RDSC_I_MATCH3 0x01000000U
#define ETH_RDSC_I_MATCH4 0x00800000U
-#define ETH_RDSC_I_LEN 0x000007FFU
+#define ETH_RDSC_I_CHKSUM __BITS(23, 22)
+#define ETH_RDSC_I_CHKSUM_NONE __SHIFTIN(0, ETH_RDSC_I_CHKSUM)
+#define ETH_RDSC_I_CHKSUM_IP __SHIFTIN(1, ETH_RDSC_I_CHKSUM)
+#define ETH_RDSC_I_CHKSUM_TCP __SHIFTIN(2, ETH_RDSC_I_CHKSUM)
+#define ETH_RDSC_I_CHKSUM_UDP __SHIFTIN(3, ETH_RDSC_I_CHKSUM)
+#define ETH_RDSC_I_LEN __BITS(13, 0)
#define ETH_TDSC_I_USED __BIT(31) /* done transmitting */
#define ETH_TDSC_I_WRAP __BIT(30) /* end of descr ring */
#define ETH_TDSC_I_RETRY_ERR __BIT(29)
#define ETH_TDSC_I_AHB_ERR __BIT(27)
#define ETH_TDSC_I_LATE_COLL __BIT(26)
-#define ETH_TDSC_I_CKSUM_GEN_STAT_MASK __BIT(20)
-#define ETH_TDSC_I_CKSUM_GEN_STAT_VLAN_HDR_ERR __BIT(20)
-#define ETH_TDSC_I_CKSUM_GEN_STAT_SNAP_HDR_ERR __BIT(20)
-#define ETH_TDSC_I_CKSUM_GEN_STAT_IP_HDR_ERR __BIT(20)
-#define ETH_TDSC_I_CKSUM_GEN_STAT_UNKNOWN_TYPE __BIT(20)
-#define ETH_TDSC_I_CKSUM_GEN_STAT_UNSUPP_FRAG __BIT(20)
-#define ETH_TDSC_I_CKSUM_GEN_STAT_NOT_TCPUDP __BIT(20)
-#define ETH_TDSC_I_CKSUM_GEN_STAT_SHORT_PKT __BIT(20)
+#define ETH_TDSC_I_CHKSUM __BITS(22, 20)
+#define ETH_TDSC_I_CHKSUM_GEN_STAT_NO_ERR __SHIFTIN(0, ETH_TDSC_I_CHKSUM)
+#define ETH_TDSC_I_CHKSUM_GEN_STAT_VLAN_HDR_ERR __SHIFTIN(1, ETH_TDSC_I_CHKSUM)
+#define ETH_TDSC_I_CHKSUM_GEN_STAT_SNAP_HDR_ERR __SHIFTIN(2, ETH_TDSC_I_CHKSUM)
+#define ETH_TDSC_I_CHKSUM_GEN_STAT_IP_HDR_ERR __SHIFTIN(3, ETH_TDSC_I_CHKSUM)
+#define ETH_TDSC_I_CHKSUM_GEN_STAT_UNKNOWN_TYPE __SHIFTIN(4, ETH_TDSC_I_CHKSUM)
+#define ETH_TDSC_I_CHKSUM_GEN_STAT_UNSUPP_FRAG __SHIFTIN(5, ETH_TDSC_I_CHKSUM)
+#define ETH_TDSC_I_CHKSUM_GEN_STAT_NOT_TCPUDP __SHIFTIN(6, ETH_TDSC_I_CHKSUM)
+#define ETH_TDSC_I_CHKSUM_GEN_STAT_SHORT_PKT __SHIFTIN(7, ETH_TDSC_I_CHKSUM)
#define ETH_TDSC_I_NO_CRC_APPENDED __BIT(16)
#define ETH_TDSC_I_LAST_BUF __BIT(15) /* last buf in frame */
#define ETH_TDSC_I_LEN __BITS(13, 0)
diff -r a8db5825ff27 -r eca020924f16 sys/dev/cadence/if_cemac.c
--- a/sys/dev/cadence/if_cemac.c Mon Aug 24 18:40:57 2015 +0000
+++ b/sys/dev/cadence/if_cemac.c Mon Aug 24 18:51:37 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_cemac.c,v 1.6 2015/08/24 18:40:57 rjs Exp $ */
+/* $NetBSD: if_cemac.c,v 1.7 2015/08/24 18:51:37 rjs Exp $ */
/*
* Copyright (c) 2015 Genetec Corporation. All rights reserved.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_cemac.c,v 1.6 2015/08/24 18:40:57 rjs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_cemac.c,v 1.7 2015/08/24 18:51:37 rjs Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -322,7 +322,7 @@
uint32_t nfo;
DPRINTFN(2,("#2 RDSC[%i].INFO=0x%08X\n", sc->rxqi % RX_QLEN, sc->RDSC[sc->rxqi % RX_QLEN].Info));
while (sc->RDSC[(bi = sc->rxqi % RX_QLEN)].Addr & ETH_RDSC_F_USED) {
- int fl;
+ int fl, csum;
struct mbuf *m;
nfo = sc->RDSC[bi].Info;
@@ -339,6 +339,23 @@
sc->rxq[bi].m->m_pkthdr.rcvif = ifp;
sc->rxq[bi].m->m_pkthdr.len =
sc->rxq[bi].m->m_len = fl;
+ switch (nfo & ETH_RDSC_I_CHKSUM) {
+ case ETH_RDSC_I_CHKSUM_IP:
+ csum = M_CSUM_IPv4;
+ break;
+ case ETH_RDSC_I_CHKSUM_UDP:
+ csum = M_CSUM_IPv4 | M_CSUM_UDPv4 |
+ M_CSUM_UDPv6;
+ break;
+ case ETH_RDSC_I_CHKSUM_TCP:
+ csum = M_CSUM_IPv4 | M_CSUM_TCPv4 |
+ M_CSUM_TCPv6;
+ break;
+ default:
+ csum = 0;
+ break;
+ }
+ sc->rxq[bi].m->m_pkthdr.csum_flags = csum;
bpf_mtap(ifp, sc->rxq[bi].m);
DPRINTFN(2,("received %u bytes packet\n", fl));
(*ifp->if_input)(ifp, sc->rxq[bi].m);
@@ -579,6 +596,16 @@
| ETH_CTL_CSR | ETH_CTL_MPE);
#endif
/*
+ * We can support hardware checksumming.
+ */
+ ifp->if_capabilities |=
+ IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx |
+ IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx |
+ IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx |
+ IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_TCPv6_Rx |
+ IFCAP_CSUM_UDPv6_Tx | IFCAP_CSUM_UDPv6_Rx;
+
+ /*
* We can support 802.1Q VLAN-sized frames.
*/
sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
@@ -726,10 +753,16 @@
break;
default:
error = ether_ioctl(ifp, cmd, data);
- if (error == ENETRESET) {
- if (ifp->if_flags & IFF_RUNNING)
- cemac_setaddr(ifp);
- error = 0;
+ if (error != ENETRESET)
+ break;
+ error = 0;
+
+ if (cmd == SIOCSIFCAP) {
+ error = (*ifp->if_init)(ifp);
+ } else if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI)
+ ;
+ else if (ifp->if_flags & IFF_RUNNING) {
+ cemac_setaddr(ifp);
}
}
splx(s);
@@ -856,10 +889,31 @@
cemac_ifinit(struct ifnet *ifp)
{
struct cemac_softc *sc = ifp->if_softc;
+ uint32_t dma, cfg;
int s = splnet();
callout_stop(&sc->cemac_tick_ch);
+ if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) {
+
+ if (ifp->if_capenable &
+ (IFCAP_CSUM_IPv4_Tx |
+ IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx |
+ IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx)) {
+ dma = CEMAC_READ(GEM_DMA_CFG);
+ dma |= GEM_DMA_CFG_CHKSUM_GEN_OFFLOAD_EN;
+ CEMAC_WRITE(GEM_DMA_CFG, dma);
+ }
+ if (ifp->if_capenable &
+ (IFCAP_CSUM_IPv4_Rx |
+ IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx |
+ IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx)) {
+ cfg = CEMAC_READ(ETH_CFG);
+ cfg |= GEM_CFG_RX_CHKSUM_OFFLD_EN;
+ CEMAC_WRITE(ETH_CFG, cfg);
+ }
+ }
+
// enable interrupts
CEMAC_WRITE(ETH_IDR, -1);
CEMAC_WRITE(ETH_IER, ETH_ISR_RCOM | ETH_ISR_TBRE | ETH_ISR_TIDLE
Home |
Main Index |
Thread Index |
Old Index