net/vmxnet3: guess MSS if not provided in LRO mode
Not so old variants of vmxnet3 do not provide MSS value along with LRO packet. When this case happens, try to guess MSS value with information at hand. Signed-off-by: Didier Pallard <didier.pallard@6wind.com> Acked-by: Yong Wang <yongwang@vmware.com>
This commit is contained in:
parent
73c1f32c96
commit
ae2705b80d
@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
|
||||
#
|
||||
LIB = librte_pmd_vmxnet3_uio.a
|
||||
|
||||
CFLAGS += -DALLOW_EXPERIMENTAL_API
|
||||
CFLAGS += -O3
|
||||
CFLAGS += $(WERROR_FLAGS)
|
||||
|
||||
|
@ -570,6 +570,8 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
|
||||
uint32_t i;
|
||||
int ret;
|
||||
|
||||
hw->mtu = mtu;
|
||||
|
||||
shared->magic = VMXNET3_REV1_MAGIC;
|
||||
devRead->misc.driverInfo.version = VMXNET3_DRIVER_VERSION_NUM;
|
||||
|
||||
|
@ -87,6 +87,7 @@ struct vmxnet3_hw {
|
||||
|
||||
uint64_t queueDescPA;
|
||||
uint16_t queue_desc_len;
|
||||
uint16_t mtu;
|
||||
|
||||
VMXNET3_RSSConf *rss_conf;
|
||||
uint64_t rss_confPA;
|
||||
|
@ -646,6 +646,59 @@ vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t *rxq, uint8_t ring_id)
|
||||
return i;
|
||||
}
|
||||
|
||||
/* MSS not provided by vmxnet3, guess one with available information */
|
||||
static uint16_t
|
||||
vmxnet3_guess_mss(struct vmxnet3_hw *hw, const Vmxnet3_RxCompDesc *rcd,
|
||||
struct rte_mbuf *rxm)
|
||||
{
|
||||
uint32_t hlen, slen;
|
||||
struct ipv4_hdr *ipv4_hdr;
|
||||
struct ipv6_hdr *ipv6_hdr;
|
||||
struct tcp_hdr *tcp_hdr;
|
||||
char *ptr;
|
||||
|
||||
RTE_ASSERT(rcd->tcp);
|
||||
|
||||
ptr = rte_pktmbuf_mtod(rxm, char *);
|
||||
slen = rte_pktmbuf_data_len(rxm);
|
||||
hlen = sizeof(struct ether_hdr);
|
||||
|
||||
if (rcd->v4) {
|
||||
if (unlikely(slen < hlen + sizeof(struct ipv4_hdr)))
|
||||
return hw->mtu - sizeof(struct ipv4_hdr)
|
||||
- sizeof(struct tcp_hdr);
|
||||
|
||||
ipv4_hdr = (struct ipv4_hdr *)(ptr + hlen);
|
||||
hlen += (ipv4_hdr->version_ihl & IPV4_HDR_IHL_MASK) *
|
||||
IPV4_IHL_MULTIPLIER;
|
||||
} else if (rcd->v6) {
|
||||
if (unlikely(slen < hlen + sizeof(struct ipv6_hdr)))
|
||||
return hw->mtu - sizeof(struct ipv6_hdr) -
|
||||
sizeof(struct tcp_hdr);
|
||||
|
||||
ipv6_hdr = (struct ipv6_hdr *)(ptr + hlen);
|
||||
hlen += sizeof(struct ipv6_hdr);
|
||||
if (unlikely(ipv6_hdr->proto != IPPROTO_TCP)) {
|
||||
int frag;
|
||||
|
||||
rte_net_skip_ip6_ext(ipv6_hdr->proto, rxm,
|
||||
&hlen, &frag);
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(slen < hlen + sizeof(struct tcp_hdr)))
|
||||
return hw->mtu - hlen - sizeof(struct tcp_hdr) +
|
||||
sizeof(struct ether_hdr);
|
||||
|
||||
tcp_hdr = (struct tcp_hdr *)(ptr + hlen);
|
||||
hlen += (tcp_hdr->data_off & 0xf0) >> 2;
|
||||
|
||||
if (rxm->udata64 > 1)
|
||||
return (rte_pktmbuf_pkt_len(rxm) - hlen +
|
||||
rxm->udata64 - 1) / rxm->udata64;
|
||||
else
|
||||
return hw->mtu - hlen + sizeof(struct ether_hdr);
|
||||
}
|
||||
|
||||
/* Receive side checksum and other offloads */
|
||||
static inline void
|
||||
@ -667,6 +720,7 @@ vmxnet3_rx_offload(struct vmxnet3_hw *hw, const Vmxnet3_RxCompDesc *rcd,
|
||||
(const Vmxnet3_RxCompDescExt *)rcd;
|
||||
|
||||
rxm->tso_segsz = rcde->mss;
|
||||
rxm->udata64 = rcde->segCnt;
|
||||
ol_flags |= PKT_RX_LRO;
|
||||
}
|
||||
} else { /* Offloads set in eop */
|
||||
@ -730,6 +784,11 @@ vmxnet3_rx_offload(struct vmxnet3_hw *hw, const Vmxnet3_RxCompDesc *rcd,
|
||||
} else {
|
||||
packet_type |= RTE_PTYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Old variants of vmxnet3 do not provide MSS */
|
||||
if ((ol_flags & PKT_RX_LRO) && rxm->tso_segsz == 0)
|
||||
rxm->tso_segsz = vmxnet3_guess_mss(hw,
|
||||
rcd, rxm);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user