mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-19 10:53:58 +00:00
cxgbe(4): support for IPv6 hardware checksumming (rx and tx).
This commit is contained in:
parent
3de8393d5b
commit
9600bf00bb
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=237799
@ -822,7 +822,7 @@ cxgbe_probe(device_t dev)
|
||||
|
||||
#define T4_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | \
|
||||
IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO | \
|
||||
IFCAP_VLAN_HWTSO)
|
||||
IFCAP_VLAN_HWTSO | IFCAP_HWCSUM_IPV6)
|
||||
#define T4_CAP_ENABLE (T4_CAP & ~IFCAP_TSO6)
|
||||
|
||||
static int
|
||||
@ -856,7 +856,8 @@ cxgbe_attach(device_t dev)
|
||||
ifp->if_capabilities |= IFCAP_TOE4;
|
||||
#endif
|
||||
ifp->if_capenable = T4_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;
|
||||
|
||||
/* Initialize ifmedia for this port */
|
||||
ifmedia_init(&pi->media, IFM_IMASK, cxgbe_media_change,
|
||||
@ -1028,30 +1029,50 @@ cxgbe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data)
|
||||
|
||||
if (IFCAP_TSO & 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");
|
||||
}
|
||||
}
|
||||
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_TSO4) {
|
||||
ifp->if_capenable ^= IFCAP_TSO4;
|
||||
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");
|
||||
rc = EAGAIN;
|
||||
goto fail;
|
||||
}
|
||||
} 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");
|
||||
rc = 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");
|
||||
rc = EAGAIN;
|
||||
goto fail;
|
||||
}
|
||||
ifp->if_capenable ^= IFCAP_TSO6;
|
||||
}
|
||||
if (mask & IFCAP_LRO) {
|
||||
#ifdef INET
|
||||
|
@ -1054,15 +1054,23 @@ t4_eth_rx(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m0)
|
||||
m0->m_flags |= M_FLOWID;
|
||||
m0->m_pkthdr.flowid = rss->hash_val;
|
||||
|
||||
if (cpl->csum_calc && !cpl->err_vec &&
|
||||
ifp->if_capenable & IFCAP_RXCSUM) {
|
||||
m0->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED |
|
||||
CSUM_IP_VALID | CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
|
||||
if (cpl->ip_frag)
|
||||
if (cpl->csum_calc && !cpl->err_vec) {
|
||||
if (ifp->if_capenable & IFCAP_RXCSUM &&
|
||||
cpl->l2info & htobe32(F_RXF_IP)) {
|
||||
m0->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED |
|
||||
CSUM_IP_VALID | CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
|
||||
rxq->rxcsum++;
|
||||
} else if (ifp->if_capenable & IFCAP_RXCSUM_IPV6 &&
|
||||
cpl->l2info & htobe32(F_RXF_IP6)) {
|
||||
m0->m_pkthdr.csum_flags |= (CSUM_DATA_VALID_IPV6 |
|
||||
CSUM_PSEUDO_HDR);
|
||||
rxq->rxcsum++;
|
||||
}
|
||||
|
||||
if (__predict_false(cpl->ip_frag))
|
||||
m0->m_pkthdr.csum_data = be16toh(cpl->csum);
|
||||
else
|
||||
m0->m_pkthdr.csum_data = 0xffff;
|
||||
rxq->rxcsum++;
|
||||
}
|
||||
|
||||
if (cpl->vlan_ex) {
|
||||
@ -2827,9 +2835,11 @@ write_txpkt_wr(struct port_info *pi, struct sge_txq *txq, struct mbuf *m,
|
||||
ctrl1 = 0;
|
||||
if (!(m->m_pkthdr.csum_flags & CSUM_IP))
|
||||
ctrl1 |= F_TXPKT_IPCSUM_DIS;
|
||||
if (!(m->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP)))
|
||||
if (!(m->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP | CSUM_UDP_IPV6 |
|
||||
CSUM_TCP_IPV6)))
|
||||
ctrl1 |= F_TXPKT_L4CSUM_DIS;
|
||||
if (m->m_pkthdr.csum_flags & (CSUM_IP | CSUM_TCP | CSUM_UDP))
|
||||
if (m->m_pkthdr.csum_flags & (CSUM_IP | CSUM_TCP | CSUM_UDP |
|
||||
CSUM_UDP_IPV6 | CSUM_TCP_IPV6))
|
||||
txq->txcsum++; /* some hardware assistance provided */
|
||||
|
||||
/* VLAN tag insertion */
|
||||
|
Loading…
Reference in New Issue
Block a user