mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
MFp4 bz_ipv6_fast:
Add TSO6 and LRO/IPv6 support. Fix the module Makefile to at least properly inlcude opt_inet6.h and allow builds without INET or INET6. Sponsored by: The FreeBSD Foundation Sponsored by: iXsystems Reviewed by: gnn (as part of the whole) MFC After: 3 days
This commit is contained in:
parent
47cfa99a50
commit
e2c0161e2e
2 changed files with 80 additions and 29 deletions
|
|
@ -162,7 +162,7 @@ static void ixgbe_dma_free(struct adapter *, struct ixgbe_dma_alloc *);
|
|||
static void ixgbe_add_rx_process_limit(struct adapter *, const char *,
|
||||
const char *, int *, int);
|
||||
static bool ixgbe_tx_ctx_setup(struct tx_ring *, struct mbuf *);
|
||||
static bool ixgbe_tso_setup(struct tx_ring *, struct mbuf *, u32 *);
|
||||
static bool ixgbe_tso_setup(struct tx_ring *, struct mbuf *, u32 *, u32 *);
|
||||
static void ixgbe_set_ivar(struct adapter *, u8, u8, s8);
|
||||
static void ixgbe_configure_ivars(struct adapter *);
|
||||
static u8 * ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
|
||||
|
|
@ -997,6 +997,8 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
|
|||
ifp->if_capenable ^= IFCAP_HWCSUM;
|
||||
if (mask & IFCAP_TSO4)
|
||||
ifp->if_capenable ^= IFCAP_TSO4;
|
||||
if (mask & IFCAP_TSO6)
|
||||
ifp->if_capenable ^= IFCAP_TSO6;
|
||||
if (mask & IFCAP_LRO)
|
||||
ifp->if_capenable ^= IFCAP_LRO;
|
||||
if (mask & IFCAP_VLAN_HWTAGGING)
|
||||
|
|
@ -1061,7 +1063,7 @@ ixgbe_init_locked(struct adapter *adapter)
|
|||
|
||||
/* Set the various hardware offload abilities */
|
||||
ifp->if_hwassist = 0;
|
||||
if (ifp->if_capenable & IFCAP_TSO4)
|
||||
if (ifp->if_capenable & IFCAP_TSO)
|
||||
ifp->if_hwassist |= CSUM_TSO;
|
||||
if (ifp->if_capenable & IFCAP_TXCSUM) {
|
||||
ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
|
||||
|
|
@ -1767,9 +1769,8 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp)
|
|||
** a packet.
|
||||
*/
|
||||
if (m_head->m_pkthdr.csum_flags & CSUM_TSO) {
|
||||
if (ixgbe_tso_setup(txr, m_head, &paylen)) {
|
||||
if (ixgbe_tso_setup(txr, m_head, &paylen, &olinfo_status)) {
|
||||
cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
|
||||
olinfo_status |= IXGBE_TXD_POPTS_IXSM << 8;
|
||||
olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8;
|
||||
olinfo_status |= paylen << IXGBE_ADVTXD_PAYLEN_SHIFT;
|
||||
++adapter->tso_tx;
|
||||
|
|
@ -2562,7 +2563,7 @@ ixgbe_setup_interface(device_t dev, struct adapter *adapter)
|
|||
*/
|
||||
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
|
||||
|
||||
ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4 | IFCAP_VLAN_HWCSUM;
|
||||
ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO | IFCAP_VLAN_HWCSUM;
|
||||
ifp->if_capabilities |= IFCAP_JUMBO_MTU;
|
||||
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING
|
||||
| IFCAP_VLAN_HWTSO
|
||||
|
|
@ -3234,6 +3235,7 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp)
|
|||
case ETHERTYPE_IPV6:
|
||||
ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
|
||||
ip_hlen = sizeof(struct ip6_hdr);
|
||||
/* XXX-BZ this will go badly in case of ext hdrs. */
|
||||
ipproto = ip6->ip6_nxt;
|
||||
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6;
|
||||
break;
|
||||
|
|
@ -3292,17 +3294,23 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp)
|
|||
*
|
||||
**********************************************************************/
|
||||
static bool
|
||||
ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen)
|
||||
ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen,
|
||||
u32 *olinfo_status)
|
||||
{
|
||||
struct adapter *adapter = txr->adapter;
|
||||
struct ixgbe_adv_tx_context_desc *TXD;
|
||||
struct ixgbe_tx_buf *tx_buffer;
|
||||
u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
|
||||
u32 mss_l4len_idx = 0;
|
||||
u16 vtag = 0;
|
||||
int ctxd, ehdrlen, hdrlen, ip_hlen, tcp_hlen;
|
||||
u32 mss_l4len_idx = 0, len;
|
||||
u16 vtag = 0, eh_type;
|
||||
int ctxd, ehdrlen, ip_hlen, tcp_hlen;
|
||||
struct ether_vlan_header *eh;
|
||||
#ifdef INET6
|
||||
struct ip6_hdr *ip6;
|
||||
#endif
|
||||
#ifdef INET
|
||||
struct ip *ip;
|
||||
#endif
|
||||
struct tcphdr *th;
|
||||
|
||||
|
||||
|
|
@ -3311,32 +3319,62 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen)
|
|||
* Jump over vlan headers if already present
|
||||
*/
|
||||
eh = mtod(mp, struct ether_vlan_header *);
|
||||
if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN))
|
||||
if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
|
||||
ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
|
||||
else
|
||||
eh_type = eh->evl_proto;
|
||||
} else {
|
||||
ehdrlen = ETHER_HDR_LEN;
|
||||
eh_type = eh->evl_encap_proto;
|
||||
}
|
||||
|
||||
/* Ensure we have at least the IP+TCP header in the first mbuf. */
|
||||
if (mp->m_len < ehdrlen + sizeof(struct ip) + sizeof(struct tcphdr))
|
||||
return FALSE;
|
||||
len = ehdrlen + sizeof(struct tcphdr);
|
||||
switch (ntohs(eh_type)) {
|
||||
#ifdef INET6
|
||||
case ETHERTYPE_IPV6:
|
||||
if (mp->m_len < len + sizeof(struct ip6_hdr))
|
||||
return FALSE;
|
||||
ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
|
||||
/* XXX-BZ For now we do not pretend to support ext. hdrs. */
|
||||
if (ip6->ip6_nxt != IPPROTO_TCP)
|
||||
return FALSE;
|
||||
ip_hlen = sizeof(struct ip6_hdr);
|
||||
th = (struct tcphdr *)((caddr_t)ip6 + ip_hlen);
|
||||
th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0);
|
||||
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6;
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET
|
||||
case ETHERTYPE_IP:
|
||||
if (mp->m_len < len + sizeof(struct ip))
|
||||
return FALSE;
|
||||
ip = (struct ip *)(mp->m_data + ehdrlen);
|
||||
if (ip->ip_p != IPPROTO_TCP)
|
||||
return FALSE;
|
||||
ip->ip_sum = 0;
|
||||
ip_hlen = ip->ip_hl << 2;
|
||||
th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
|
||||
th->th_sum = in_pseudo(ip->ip_src.s_addr,
|
||||
ip->ip_dst.s_addr, htons(IPPROTO_TCP));
|
||||
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
|
||||
/* Tell transmit desc to also do IPv4 checksum. */
|
||||
*olinfo_status |= IXGBE_TXD_POPTS_IXSM << 8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
panic("%s: CSUM_TSO but no supported IP version (0x%04x)",
|
||||
__func__, ntohs(eh_type));
|
||||
break;
|
||||
}
|
||||
|
||||
ctxd = txr->next_avail_desc;
|
||||
tx_buffer = &txr->tx_buffers[ctxd];
|
||||
TXD = (struct ixgbe_adv_tx_context_desc *) &txr->tx_base[ctxd];
|
||||
|
||||
ip = (struct ip *)(mp->m_data + ehdrlen);
|
||||
if (ip->ip_p != IPPROTO_TCP)
|
||||
return FALSE; /* 0 */
|
||||
ip->ip_sum = 0;
|
||||
ip_hlen = ip->ip_hl << 2;
|
||||
th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
|
||||
th->th_sum = in_pseudo(ip->ip_src.s_addr,
|
||||
ip->ip_dst.s_addr, htons(IPPROTO_TCP));
|
||||
tcp_hlen = th->th_off << 2;
|
||||
hdrlen = ehdrlen + ip_hlen + tcp_hlen;
|
||||
|
||||
/* This is used in the transmit desc in encap */
|
||||
*paylen = mp->m_pkthdr.len - hdrlen;
|
||||
*paylen = mp->m_pkthdr.len - ehdrlen - ip_hlen - tcp_hlen;
|
||||
|
||||
/* VLAN MACLEN IPLEN */
|
||||
if (mp->m_flags & M_VLANTAG) {
|
||||
|
|
@ -3351,10 +3389,8 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen)
|
|||
/* ADV DTYPE TUCMD */
|
||||
type_tucmd_mlhl |= IXGBE_ADVTXD_DCMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT;
|
||||
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
|
||||
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
|
||||
TXD->type_tucmd_mlhl |= htole32(type_tucmd_mlhl);
|
||||
|
||||
|
||||
/* MSS L4LEN IDX */
|
||||
mss_l4len_idx |= (mp->m_pkthdr.tso_segsz << IXGBE_ADVTXD_MSS_SHIFT);
|
||||
mss_l4len_idx |= (tcp_hlen << IXGBE_ADVTXD_L4LEN_SHIFT);
|
||||
|
|
@ -4295,15 +4331,17 @@ ixgbe_rx_input(struct rx_ring *rxr, struct ifnet *ifp, struct mbuf *m, u32 ptype
|
|||
{
|
||||
|
||||
/*
|
||||
* ATM LRO is only for IPv4/TCP packets and TCP checksum of the packet
|
||||
* ATM LRO is only for IP/TCP packets and TCP checksum of the packet
|
||||
* should be computed by hardware. Also it should not have VLAN tag in
|
||||
* ethernet header.
|
||||
* ethernet header. In case of IPv6 we do not yet support ext. hdrs.
|
||||
*/
|
||||
if (rxr->lro_enabled &&
|
||||
(ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 &&
|
||||
(ptype & IXGBE_RXDADV_PKTTYPE_ETQF) == 0 &&
|
||||
(ptype & (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP)) ==
|
||||
(IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP) &&
|
||||
((ptype & (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP)) ==
|
||||
(IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP) ||
|
||||
(ptype & (IXGBE_RXDADV_PKTTYPE_IPV6 | IXGBE_RXDADV_PKTTYPE_TCP)) ==
|
||||
(IXGBE_RXDADV_PKTTYPE_IPV6 | IXGBE_RXDADV_PKTTYPE_TCP)) &&
|
||||
(m->m_pkthdr.csum_flags & (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) ==
|
||||
(CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) {
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -2,10 +2,23 @@
|
|||
.PATH: ${.CURDIR}/../../dev/ixgbe
|
||||
KMOD = ixgbe
|
||||
SRCS = device_if.h bus_if.h pci_if.h
|
||||
SRCS += opt_inet.h opt_inet6.h
|
||||
SRCS += ixgbe.c ixv.c
|
||||
# Shared source
|
||||
SRCS += ixgbe_common.c ixgbe_api.c ixgbe_phy.c ixgbe_mbx.c ixgbe_vf.c
|
||||
SRCS += ixgbe_82599.c ixgbe_82598.c ixgbe_x540.c
|
||||
CFLAGS+= -I${.CURDIR}/../../dev/ixgbe -DSMP -DIXGBE_FDIR
|
||||
|
||||
.if !defined(KERNBUILDDIR)
|
||||
.if ${MK_INET_SUPPORT} != "no"
|
||||
opt_inet.h:
|
||||
@echo "#define INET 1" > ${.TARGET}
|
||||
.endif
|
||||
|
||||
.if ${MK_INET6_SUPPORT} != "no"
|
||||
opt_inet6.h:
|
||||
@echo "#define INET6 1" > ${.TARGET}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
|
|
|||
Loading…
Reference in a new issue