summaryrefslogtreecommitdiffstats
path: root/sys/arm/ti
diff options
context:
space:
mode:
authorloos <loos@FreeBSD.org>2017-01-25 16:10:35 +0000
committerloos <loos@FreeBSD.org>2017-01-25 16:10:35 +0000
commitb5cbbe50637744715b178f220f98119de3bcd104 (patch)
tree2a5dc5915c485808e432e97b13d29511132a279a /sys/arm/ti
parent72df66a5f4981a4b7241edc19b00a710b4300f75 (diff)
downloadFreeBSD-src-b5cbbe50637744715b178f220f98119de3bcd104.zip
FreeBSD-src-b5cbbe50637744715b178f220f98119de3bcd104.tar.gz
MFC r312411:
Handle the set capabilities ioctl, letting the hardware checksum be disabled (Hi netmap!). Only remove the CRC bytes from packets when the hardware tell us to do so. Fixes the 'discard frame w/o leading ethernet header' issues. Sponsored by: Rubicon Communications, LLC (Netgate)
Diffstat (limited to 'sys/arm/ti')
-rw-r--r--sys/arm/ti/cpsw/if_cpsw.c27
-rw-r--r--sys/arm/ti/cpsw/if_cpswreg.h1
2 files changed, 23 insertions, 5 deletions
diff --git a/sys/arm/ti/cpsw/if_cpsw.c b/sys/arm/ti/cpsw/if_cpsw.c
index c1b8233..0b47028 100644
--- a/sys/arm/ti/cpsw/if_cpsw.c
+++ b/sys/arm/ti/cpsw/if_cpsw.c
@@ -1396,6 +1396,16 @@ cpswp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
ifr = (struct ifreq *)data;
switch (command) {
+ case SIOCSIFCAP:
+ changed = ifp->if_capenable ^ ifr->ifr_reqcap;
+ if (changed & IFCAP_HWCSUM) {
+ if ((ifr->ifr_reqcap & changed) & IFCAP_HWCSUM)
+ ifp->if_capenable |= IFCAP_HWCSUM;
+ else
+ ifp->if_capenable &= ~IFCAP_HWCSUM;
+ }
+ error = 0;
+ break;
case SIOCSIFFLAGS:
CPSW_PORT_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
@@ -1633,15 +1643,22 @@ cpsw_rx_dequeue(struct cpsw_softc *sc)
/* TODO: track SOP/EOP bits to assemble a full mbuf
out of received fragments. */
slot->mbuf->m_data += bd.bufoff;
- slot->mbuf->m_len = bd.pktlen - 4;
- slot->mbuf->m_pkthdr.len = bd.pktlen - 4;
- slot->mbuf->m_flags |= M_PKTHDR;
- slot->mbuf->m_pkthdr.rcvif = psc->ifp;
+ slot->mbuf->m_len = bd.buflen;
+ if (bd.flags & CPDMA_BD_SOP) {
+ slot->mbuf->m_pkthdr.len = bd.pktlen;
+ slot->mbuf->m_pkthdr.rcvif = psc->ifp;
+ slot->mbuf->m_flags |= M_PKTHDR;
+ }
+ slot->mbuf->m_next = NULL;
slot->mbuf->m_nextpkt = NULL;
+ if (bd.flags & CPDMA_BD_PASS_CRC)
+ m_adj(slot->mbuf, -ETHER_CRC_LEN);
if ((psc->ifp->if_capenable & IFCAP_RXCSUM) != 0) {
/* check for valid CRC by looking into pkt_err[5:4] */
- if ((bd.flags & CPDMA_BD_PKT_ERR_MASK) == 0) {
+ if ((bd.flags &
+ (CPDMA_BD_SOP | CPDMA_BD_PKT_ERR_MASK)) ==
+ CPDMA_BD_SOP) {
slot->mbuf->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
slot->mbuf->m_pkthdr.csum_flags |= CSUM_IP_VALID;
slot->mbuf->m_pkthdr.csum_data = 0xffff;
diff --git a/sys/arm/ti/cpsw/if_cpswreg.h b/sys/arm/ti/cpsw/if_cpswreg.h
index 6d6a647..c0ee358 100644
--- a/sys/arm/ti/cpsw/if_cpswreg.h
+++ b/sys/arm/ti/cpsw/if_cpswreg.h
@@ -191,6 +191,7 @@
#define CPDMA_BD_OWNER (1 << 13)
#define CPDMA_BD_EOQ (1 << 12)
#define CPDMA_BD_TDOWNCMPLT (1 << 11)
+#define CPDMA_BD_PASS_CRC (1 << 10)
#define CPDMA_BD_PKT_ERR_MASK (3 << 4)
#define CPDMA_BD_TO_PORT (1 << 4)
#define CPDMA_BD_PORT_MASK 3
OpenPOWER on IntegriCloud