Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ixl/ixl_txrx.c
Show First 20 Lines • Show All 241 Lines • ▼ Show 20 Lines | ixl_xmit(struct ixl_queue *que, struct mbuf **m_headp) | ||||
int i, j, error, nsegs, maxsegs; | int i, j, error, nsegs, maxsegs; | ||||
int first, last = 0; | int first, last = 0; | ||||
u16 vtag = 0; | u16 vtag = 0; | ||||
u32 cmd, off; | u32 cmd, off; | ||||
bus_dmamap_t map; | bus_dmamap_t map; | ||||
bus_dma_tag_t tag; | bus_dma_tag_t tag; | ||||
bus_dma_segment_t segs[IXL_MAX_TSO_SEGS]; | bus_dma_segment_t segs[IXL_MAX_TSO_SEGS]; | ||||
cmd = off = 0; | cmd = off = 0; | ||||
m_head = *m_headp; | m_head = *m_headp; | ||||
/* | /* | ||||
* Important to capture the first descriptor | * Important to capture the first descriptor | ||||
* used because it will contain the index of | * used because it will contain the index of | ||||
* the one we tell the hardware to report back | * the one we tell the hardware to report back | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 366 Lines • ▼ Show 20 Lines | |||||
#ifdef INET6 | #ifdef INET6 | ||||
struct ip6_hdr *ip6; | struct ip6_hdr *ip6; | ||||
#endif | #endif | ||||
int elen, ip_hlen = 0, tcp_hlen; | int elen, ip_hlen = 0, tcp_hlen; | ||||
u16 etype; | u16 etype; | ||||
u8 ipproto = 0; | u8 ipproto = 0; | ||||
bool tso = FALSE; | bool tso = FALSE; | ||||
/* Set up the TSO context descriptor if required */ | /* Set up the TSO context descriptor if required */ | ||||
if (mp->m_pkthdr.csum_flags & CSUM_TSO) { | if (mp->m_pkthdr.csum_flags & CSUM_TSO) { | ||||
tso = ixl_tso_setup(que, mp); | tso = ixl_tso_setup(que, mp); | ||||
if (tso) | if (tso) | ||||
++que->tso; | ++que->tso; | ||||
else | else | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | #ifdef INET6 | ||||
case ETHERTYPE_IPV6: | case ETHERTYPE_IPV6: | ||||
ip6 = (struct ip6_hdr *)(mp->m_data + elen); | ip6 = (struct ip6_hdr *)(mp->m_data + elen); | ||||
if (ip6->ip6_nxt != IPPROTO_TCP) | if (ip6->ip6_nxt != IPPROTO_TCP) | ||||
return (ENXIO); | return (ENXIO); | ||||
ip_hlen = sizeof(struct ip6_hdr); | ip_hlen = sizeof(struct ip6_hdr); | ||||
th = (struct tcphdr *)((caddr_t)ip6 + ip_hlen); | th = (struct tcphdr *)((caddr_t)ip6 + ip_hlen); | ||||
th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0); | th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0); | ||||
tcp_hlen = th->th_off << 2; | tcp_hlen = th->th_off << 2; | ||||
/* | |||||
* The corresponding flag is set by the stack in the IPv4 | |||||
* TSO case, but not in IPv6 (at least in FreeBSD 10.2). | |||||
* So, set it here because the rest of the flow requires it. | |||||
*/ | |||||
mp->m_pkthdr.csum_flags |= CSUM_TCP_IPV6; | |||||
break; | break; | ||||
#endif | #endif | ||||
#ifdef INET | #ifdef INET | ||||
case ETHERTYPE_IP: | case ETHERTYPE_IP: | ||||
ip = (struct ip *)(mp->m_data + elen); | ip = (struct ip *)(mp->m_data + elen); | ||||
if (ip->ip_p != IPPROTO_TCP) | if (ip->ip_p != IPPROTO_TCP) | ||||
return (ENXIO); | return (ENXIO); | ||||
ip->ip_sum = 0; | ip->ip_sum = 0; | ||||
▲ Show 20 Lines • Show All 794 Lines • ▼ Show 20 Lines | else | ||||
vtag = 0; | vtag = 0; | ||||
/* | /* | ||||
** Make sure bad packets are discarded, | ** Make sure bad packets are discarded, | ||||
** note that only EOP descriptor has valid | ** note that only EOP descriptor has valid | ||||
** error results. | ** error results. | ||||
*/ | */ | ||||
if (eop && (error & (1 << I40E_RX_DESC_ERROR_RXE_SHIFT))) { | if (eop && (error & (1 << I40E_RX_DESC_ERROR_RXE_SHIFT))) { | ||||
rxr->discarded++; | rxr->desc_errs++; | ||||
ixl_rx_discard(rxr, i); | ixl_rx_discard(rxr, i); | ||||
goto next_desc; | goto next_desc; | ||||
} | } | ||||
/* Prefetch the next buffer */ | /* Prefetch the next buffer */ | ||||
if (!eop) { | if (!eop) { | ||||
nextp = i + 1; | nextp = i + 1; | ||||
if (nextp == que->num_desc) | if (nextp == que->num_desc) | ||||
▲ Show 20 Lines • Show All 238 Lines • Show Last 20 Lines |