hyperv/hn: Simplify per-packet-info construction.

MFC after:	1 week
Sponsored by:	Microsoft
Differential Revision:	https://reviews.freebsd.org/D7794
This commit is contained in:
Sepherosa Ziehau 2016-09-07 06:02:29 +00:00
parent 61ac564fd0
commit b44fb279e8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305525
5 changed files with 51 additions and 72 deletions

View File

@ -142,12 +142,12 @@ __FBSDID("$FreeBSD$");
#define HN_RING_CNT_DEF_MAX 8
#define HN_RNDIS_PKT_LEN \
(sizeof(struct rndis_packet_msg) + \
RNDIS_HASHVAL_PPI_SIZE + \
RNDIS_VLAN_PPI_SIZE + \
RNDIS_TSO_PPI_SIZE + \
RNDIS_CSUM_PPI_SIZE)
#define HN_RNDIS_PKT_LEN \
(sizeof(struct rndis_packet_msg) + \
HN_RNDIS_PKTINFO_SIZE(HN_NDIS_HASH_VALUE_SIZE) + \
HN_RNDIS_PKTINFO_SIZE(NDIS_VLAN_INFO_SIZE) + \
HN_RNDIS_PKTINFO_SIZE(NDIS_LSO2_INFO_SIZE) + \
HN_RNDIS_PKTINFO_SIZE(NDIS_TXCSUM_INFO_SIZE))
#define HN_RNDIS_PKT_BOUNDARY PAGE_SIZE
#define HN_RNDIS_PKT_ALIGN CACHE_LINE_SIZE
@ -865,10 +865,9 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
int error, nsegs, i;
struct mbuf *m_head = *m_head0;
struct rndis_packet_msg *pkt;
rndis_per_packet_info *rppi;
struct rndis_hash_value *hash_value;
uint32_t send_buf_section_idx;
int send_buf_section_size, pktlen;
uint32_t *pi_data;
/*
* extension points to the area reserved for the
@ -889,21 +888,14 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
* dispatch the TX done event for this packet back to this TX
* ring's channel.
*/
rppi = hv_set_rppi_data(pkt, RNDIS_HASHVAL_PPI_SIZE,
nbl_hash_value);
hash_value = (struct rndis_hash_value *)((uint8_t *)rppi +
rppi->per_packet_info_offset);
hash_value->hash_value = txr->hn_tx_idx;
pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN,
HN_NDIS_HASH_VALUE_SIZE, HN_NDIS_PKTINFO_TYPE_HASHVAL);
*pi_data = txr->hn_tx_idx;
if (m_head->m_flags & M_VLANTAG) {
ndis_8021q_info *rppi_vlan_info;
rppi = hv_set_rppi_data(pkt, RNDIS_VLAN_PPI_SIZE,
ieee_8021q_info);
rppi_vlan_info = (ndis_8021q_info *)((uint8_t *)rppi +
rppi->per_packet_info_offset);
rppi_vlan_info->u1.value = NDIS_VLAN_INFO_MAKE(
pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN,
NDIS_VLAN_INFO_SIZE, NDIS_PKTINFO_TYPE_VLAN);
*pi_data = NDIS_VLAN_INFO_MAKE(
EVL_VLANOFTAG(m_head->m_pkthdr.ether_vtag),
EVL_PRIOFTAG(m_head->m_pkthdr.ether_vtag),
EVL_CFIOFTAG(m_head->m_pkthdr.ether_vtag));
@ -911,7 +903,6 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
if (m_head->m_pkthdr.csum_flags & CSUM_TSO) {
#if defined(INET6) || defined(INET)
rndis_tcp_tso_info *tso_info;
struct ether_vlan_header *eh;
int ether_len;
@ -924,12 +915,8 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
else
ether_len = ETHER_HDR_LEN;
rppi = hv_set_rppi_data(pkt, RNDIS_TSO_PPI_SIZE,
tcp_large_send_info);
tso_info = (rndis_tcp_tso_info *)((uint8_t *)rppi +
rppi->per_packet_info_offset);
pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN,
NDIS_LSO2_INFO_SIZE, NDIS_PKTINFO_TYPE_LSO);
#ifdef INET
if (m_head->m_pkthdr.csum_flags & CSUM_IP_TSO) {
struct ip *ip =
@ -942,7 +929,7 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
ip->ip_sum = 0;
th->th_sum = in_pseudo(ip->ip_src.s_addr,
ip->ip_dst.s_addr, htons(IPPROTO_TCP));
tso_info->value = NDIS_LSO2_INFO_MAKEIPV4(0,
*pi_data = NDIS_LSO2_INFO_MAKEIPV4(0,
m_head->m_pkthdr.tso_segsz);
}
#endif
@ -957,27 +944,23 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
ip6->ip6_plen = 0;
th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0);
tso_info->value = NDIS_LSO2_INFO_MAKEIPV6(0,
*pi_data = NDIS_LSO2_INFO_MAKEIPV6(0,
m_head->m_pkthdr.tso_segsz);
}
#endif
#endif /* INET6 || INET */
} else if (m_head->m_pkthdr.csum_flags & txr->hn_csum_assist) {
rndis_tcp_ip_csum_info *csum_info;
pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN,
NDIS_TXCSUM_INFO_SIZE, NDIS_PKTINFO_TYPE_CSUM);
*pi_data = NDIS_TXCSUM_INFO_IPV4;
rppi = hv_set_rppi_data(pkt, RNDIS_CSUM_PPI_SIZE,
tcpip_chksum_info);
csum_info = (rndis_tcp_ip_csum_info *)((uint8_t *)rppi +
rppi->per_packet_info_offset);
csum_info->value = NDIS_TXCSUM_INFO_IPV4;
if (m_head->m_pkthdr.csum_flags & CSUM_IP)
csum_info->value |= NDIS_TXCSUM_INFO_IPCS;
*pi_data |= NDIS_TXCSUM_INFO_IPCS;
if (m_head->m_pkthdr.csum_flags & CSUM_TCP)
csum_info->value |= NDIS_TXCSUM_INFO_TCPCS;
*pi_data |= NDIS_TXCSUM_INFO_TCPCS;
else if (m_head->m_pkthdr.csum_flags & CSUM_UDP)
csum_info->value |= NDIS_TXCSUM_INFO_UDPCS;
*pi_data |= NDIS_TXCSUM_INFO_UDPCS;
}
pktlen = pkt->rm_pktinfooffset + pkt->rm_pktinfolen;

View File

@ -569,18 +569,6 @@ typedef struct rndis_tcp_tso_info_ {
};
} rndis_tcp_tso_info;
#define RNDIS_HASHVAL_PPI_SIZE (sizeof(rndis_per_packet_info) + \
sizeof(struct rndis_hash_value))
#define RNDIS_VLAN_PPI_SIZE (sizeof(rndis_per_packet_info) + \
sizeof(ndis_8021q_info))
#define RNDIS_CSUM_PPI_SIZE (sizeof(rndis_per_packet_info) + \
sizeof(rndis_tcp_ip_csum_info))
#define RNDIS_TSO_PPI_SIZE (sizeof(rndis_per_packet_info) + \
sizeof(rndis_tcp_tso_info))
/*
* Format of Information buffer passed in a SetRequest for the OID
* OID_GEN_RNDIS_CONFIG_PARAMETER.
@ -900,8 +888,5 @@ int netvsc_recv(struct hn_rx_ring *rxr, const void *data, int dlen,
const struct hn_recvinfo *info);
void netvsc_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr);
void* hv_set_rppi_data(struct rndis_packet_msg *pkt, uint32_t rppi_size,
int pkt_type);
#endif /* __HV_RNDIS_H__ */

View File

@ -102,19 +102,15 @@ hn_rndis_rid(struct hn_softc *sc)
return ((rid & 0xffff) << 16);
}
/*
* Set the Per-Packet-Info with the specified type
*/
void *
hv_set_rppi_data(struct rndis_packet_msg *pkt, uint32_t rppi_size, int pkt_type)
hn_rndis_pktinfo_append(struct rndis_packet_msg *pkt, size_t pktsize,
size_t pi_dlen, uint32_t pi_type)
{
rndis_per_packet_info *rppi;
const size_t pi_size = HN_RNDIS_PKTINFO_SIZE(pi_dlen);
struct rndis_pktinfo *pi;
/* Data immediately follow per-packet-info. */
pkt->rm_dataoffset += rppi_size;
/* Update RNDIS packet msg length */
pkt->rm_len += rppi_size;
KASSERT((pi_size & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK) == 0,
("unaligned pktinfo size %zu, pktinfo dlen %zu", pi_size, pi_dlen));
/*
* Per-packet-info does not move; it only grows.
@ -123,15 +119,23 @@ hv_set_rppi_data(struct rndis_packet_msg *pkt, uint32_t rppi_size, int pkt_type)
* rm_pktinfooffset in this phase counts from the beginning
* of rndis_packet_msg.
*/
rppi = (rndis_per_packet_info *)((uint8_t *)pkt +
pkt->rm_pktinfooffset + pkt->rm_pktinfolen);
pkt->rm_pktinfolen += rppi_size;
KASSERT(pkt->rm_pktinfooffset + pkt->rm_pktinfolen + pi_size <= pktsize,
("%u pktinfo overflows RNDIS packet msg", pi_type));
pi = (struct rndis_pktinfo *)((uint8_t *)pkt + pkt->rm_pktinfooffset +
pkt->rm_pktinfolen);
pkt->rm_pktinfolen += pi_size;
rppi->size = rppi_size;
rppi->type = pkt_type;
rppi->per_packet_info_offset = sizeof(rndis_per_packet_info);
pi->rm_size = pi_size;
pi->rm_type = pi_type;
pi->rm_pktinfooffset = RNDIS_PKTINFO_OFFSET;
return (rppi);
/* Data immediately follow per-packet-info. */
pkt->rm_dataoffset += pi_size;
/* Update RNDIS packet msg length */
pkt->rm_len += pi_size;
return (pi->rm_data);
}
/*

View File

@ -221,4 +221,8 @@ CTASSERT(sizeof(struct hn_nvs_rndis_ack) >= HN_NVS_REQSIZE_MIN);
#define HN_NDIS_HASH_VALUE_SIZE sizeof(uint32_t)
#define HN_NDIS_PKTINFO_TYPE_HASHVAL NDIS_PKTINFO_TYPE_PKT_CANCELID
/* Per-packet-info size */
#define HN_RNDIS_PKTINFO_SIZE(dlen) \
__offsetof(struct rndis_pktinfo, rm_data[dlen])
#endif /* !_IF_HNREG_H_ */

View File

@ -121,6 +121,9 @@ void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc,
uint32_t hn_chim_alloc(struct hn_softc *sc);
void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx);
void *hn_rndis_pktinfo_append(struct rndis_packet_msg *,
size_t pktsize, size_t pi_dlen, uint32_t pi_type);
extern struct hn_send_ctx hn_send_ctx_none;
#endif /* !_IF_HNVAR_H_ */