Date: Sat, 30 Jun 2012 02:11:54 +0000 (UTC) From: Navdeep Parhar <np@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r237832 - head/sys/dev/cxgb Message-ID: <201206300211.q5U2BsNW084013@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: np Date: Sat Jun 30 02:11:53 2012 New Revision: 237832 URL: http://svn.freebsd.org/changeset/base/237832 Log: cxgb(4): IPv6 rx/tx hw checksum, IPv6 TSO and LRO too. (Some parts already worked, this makes it complete). Modified: head/sys/dev/cxgb/cxgb_adapter.h head/sys/dev/cxgb/cxgb_main.c head/sys/dev/cxgb/cxgb_sge.c Modified: head/sys/dev/cxgb/cxgb_adapter.h ============================================================================== --- head/sys/dev/cxgb/cxgb_adapter.h Sat Jun 30 02:05:09 2012 (r237831) +++ head/sys/dev/cxgb/cxgb_adapter.h Sat Jun 30 02:11:53 2012 (r237832) @@ -265,15 +265,6 @@ struct sge_txq { struct sg_ent txq_sgl[TX_MAX_SEGS / 2 + 1]; }; - -enum { - SGE_PSTAT_TSO, /* # of TSO requests */ - SGE_PSTAT_RX_CSUM_GOOD, /* # of successful RX csum offloads */ - SGE_PSTAT_TX_CSUM, /* # of TX checksum offloads */ - SGE_PSTAT_VLANEX, /* # of VLAN tag extractions */ - SGE_PSTAT_VLANINS, /* # of VLAN tag insertions */ -}; - #define SGE_PSTAT_MAX (SGE_PSTAT_VLANINS+1) #define QS_EXITING 0x1 @@ -288,7 +279,6 @@ struct sge_qset { struct lro_state lro; struct sge_txq txq[SGE_TXQ_PER_SET]; uint32_t txq_stopped; /* which Tx queues are stopped */ - uint64_t port_stats[SGE_PSTAT_MAX]; struct port_info *port; struct adapter *adap; int idx; /* qset # */ @@ -538,7 +528,7 @@ int t3_sge_reset_adapter(adapter_t *); int t3_sge_init_port(struct port_info *); void t3_free_tx_desc(struct sge_qset *qs, int n, int qid); -void t3_rx_eth(struct adapter *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad); +void t3_rx_eth(struct adapter *adap, struct mbuf *m, int ethpad); void t3_add_attach_sysctls(adapter_t *sc); void t3_add_configured_sysctls(adapter_t *sc); Modified: head/sys/dev/cxgb/cxgb_main.c ============================================================================== --- head/sys/dev/cxgb/cxgb_main.c Sat Jun 30 02:05:09 2012 (r237831) +++ head/sys/dev/cxgb/cxgb_main.c Sat Jun 30 02:11:53 2012 (r237832) @@ -986,7 +986,7 @@ cxgb_makedev(struct port_info *pi) #define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | \ IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO | \ - IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE) + IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE | IFCAP_HWCSUM_IPV6) #define CXGB_CAP_ENABLE CXGB_CAP static int @@ -1027,7 +1027,8 @@ cxgb_port_attach(device_t dev) ifp->if_capabilities |= IFCAP_TOE4; #endif ifp->if_capenable = CXGB_CAP_ENABLE; - ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO; + ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO | + CSUM_UDP_IPV6 | CSUM_TCP_IPV6; /* * Disable TSO on 4-port - it isn't supported by the firmware. @@ -1950,31 +1951,52 @@ fail: ifp->if_capenable ^= IFCAP_TXCSUM; ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP); - if (IFCAP_TSO & ifp->if_capenable && + if (IFCAP_TSO4 & ifp->if_capenable && !(IFCAP_TXCSUM & ifp->if_capenable)) { - ifp->if_capenable &= ~IFCAP_TSO; - ifp->if_hwassist &= ~CSUM_TSO; + ifp->if_capenable &= ~IFCAP_TSO4; if_printf(ifp, - "tso disabled due to -txcsum.\n"); + "tso4 disabled due to -txcsum.\n"); + } + } + if (mask & IFCAP_TXCSUM_IPV6) { + ifp->if_capenable ^= IFCAP_TXCSUM_IPV6; + ifp->if_hwassist ^= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6); + + if (IFCAP_TSO6 & ifp->if_capenable && + !(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) { + ifp->if_capenable &= ~IFCAP_TSO6; + if_printf(ifp, + "tso6 disabled due to -txcsum6.\n"); } } if (mask & IFCAP_RXCSUM) ifp->if_capenable ^= IFCAP_RXCSUM; - if (mask & IFCAP_TSO) { - ifp->if_capenable ^= IFCAP_TSO; + if (mask & IFCAP_RXCSUM_IPV6) + ifp->if_capenable ^= IFCAP_RXCSUM_IPV6; - if (IFCAP_TSO & ifp->if_capenable) { - if (IFCAP_TXCSUM & ifp->if_capenable) - ifp->if_hwassist |= CSUM_TSO; - else { - ifp->if_capenable &= ~IFCAP_TSO; - ifp->if_hwassist &= ~CSUM_TSO; - if_printf(ifp, - "enable txcsum first.\n"); - error = EAGAIN; - } - } else - ifp->if_hwassist &= ~CSUM_TSO; + /* + * Note that we leave CSUM_TSO alone (it is always set). The + * kernel takes both IFCAP_TSOx and CSUM_TSO into account before + * sending a TSO request our way, so it's sufficient to toggle + * IFCAP_TSOx only. + */ + if (mask & IFCAP_TSO4) { + if (!(IFCAP_TSO4 & ifp->if_capenable) && + !(IFCAP_TXCSUM & ifp->if_capenable)) { + if_printf(ifp, "enable txcsum first.\n"); + error = EAGAIN; + goto fail; + } + ifp->if_capenable ^= IFCAP_TSO4; + } + if (mask & IFCAP_TSO6) { + if (!(IFCAP_TSO6 & ifp->if_capenable) && + !(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) { + if_printf(ifp, "enable txcsum6 first.\n"); + error = EAGAIN; + goto fail; + } + ifp->if_capenable ^= IFCAP_TSO6; } if (mask & IFCAP_LRO) { ifp->if_capenable ^= IFCAP_LRO; Modified: head/sys/dev/cxgb/cxgb_sge.c ============================================================================== --- head/sys/dev/cxgb/cxgb_sge.c Sat Jun 30 02:05:09 2012 (r237831) +++ head/sys/dev/cxgb/cxgb_sge.c Sat Jun 30 02:11:53 2012 (r237832) @@ -1432,7 +1432,8 @@ t3_encap(struct sge_qset *qs, struct mbu cntrl |= V_TXPKT_OPCODE(CPL_TX_PKT); if (__predict_false(!(cflags & CSUM_IP))) cntrl |= F_TXPKT_IPCSUM_DIS; - if (__predict_false(!(cflags & (CSUM_TCP | CSUM_UDP)))) + if (__predict_false(!(cflags & (CSUM_TCP | CSUM_UDP | + CSUM_UDP_IPV6 | CSUM_TCP_IPV6)))) cntrl |= F_TXPKT_L4CSUM_DIS; hflit[0] = htonl(cntrl); @@ -1547,7 +1548,8 @@ t3_encap(struct sge_qset *qs, struct mbu cntrl |= V_TXPKT_OPCODE(CPL_TX_PKT); if (__predict_false(!(m0->m_pkthdr.csum_flags & CSUM_IP))) cntrl |= F_TXPKT_IPCSUM_DIS; - if (__predict_false(!(m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP)))) + if (__predict_false(!(m0->m_pkthdr.csum_flags & (CSUM_TCP | + CSUM_UDP | CSUM_UDP_IPV6 | CSUM_TCP_IPV6)))) cntrl |= F_TXPKT_L4CSUM_DIS; cpl->cntrl = htonl(cntrl); cpl->len = htonl(mlen | 0x80000000); @@ -2620,20 +2622,12 @@ err: * will also be taken into account here. */ void -t3_rx_eth(struct adapter *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad) +t3_rx_eth(struct adapter *adap, struct mbuf *m, int ethpad) { struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(mtod(m, uint8_t *) + ethpad); struct port_info *pi = &adap->port[adap->rxpkt_map[cpl->iff]]; struct ifnet *ifp = pi->ifp; - if ((ifp->if_capenable & IFCAP_RXCSUM) && !cpl->fragment && - cpl->csum_valid && cpl->csum == 0xffff) { - m->m_pkthdr.csum_flags = (CSUM_IP_CHECKED|CSUM_IP_VALID); - rspq_to_qset(rq)->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++; - m->m_pkthdr.csum_flags = (CSUM_IP_CHECKED|CSUM_IP_VALID|CSUM_DATA_VALID|CSUM_PSEUDO_HDR); - m->m_pkthdr.csum_data = 0xffff; - } - if (cpl->vlan_valid) { m->m_pkthdr.ether_vtag = ntohs(cpl->vlan); m->m_flags |= M_VLANTAG; @@ -2647,6 +2641,30 @@ t3_rx_eth(struct adapter *adap, struct s m->m_pkthdr.len -= (sizeof(*cpl) + ethpad); m->m_len -= (sizeof(*cpl) + ethpad); m->m_data += (sizeof(*cpl) + ethpad); + + if (!cpl->fragment && cpl->csum_valid && cpl->csum == 0xffff) { + struct ether_header *eh = mtod(m, void *); + uint16_t eh_type; + + if (eh->ether_type == htons(ETHERTYPE_VLAN)) { + struct ether_vlan_header *evh = mtod(m, void *); + + eh_type = evh->evl_proto; + } else + eh_type = eh->ether_type; + + if (ifp->if_capenable & IFCAP_RXCSUM && + eh_type == htons(ETHERTYPE_IP)) { + m->m_pkthdr.csum_flags = (CSUM_IP_CHECKED | + CSUM_IP_VALID | CSUM_DATA_VALID | CSUM_PSEUDO_HDR); + m->m_pkthdr.csum_data = 0xffff; + } else if (ifp->if_capenable & IFCAP_RXCSUM_IPV6 && + eh_type == htons(ETHERTYPE_IPV6)) { + m->m_pkthdr.csum_flags = (CSUM_DATA_VALID_IPV6 | + CSUM_PSEUDO_HDR); + m->m_pkthdr.csum_data = 0xffff; + } + } } /** @@ -2913,7 +2931,7 @@ process_responses(adapter_t *adap, struc } else if (eth && eop) { struct mbuf *m = mh->mh_head; - t3_rx_eth(adap, rspq, m, ethpad); + t3_rx_eth(adap, m, ethpad); /* * The T304 sends incoming packets on any qset. If LRO
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206300211.q5U2BsNW084013>