summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2016-03-01 04:59:18 +0000
committersephe <sephe@FreeBSD.org>2016-03-01 04:59:18 +0000
commit65d6c54a61e6a072bf74f79f14efa0bc0954ab5e (patch)
tree913b5ce7f410c28bdb6fbb8262b4f5f17a783e0a
parent32011582e1a91d218e8e9d652ff8e0aa00d00f25 (diff)
downloadFreeBSD-src-65d6c54a61e6a072bf74f79f14efa0bc0954ab5e.zip
FreeBSD-src-65d6c54a61e6a072bf74f79f14efa0bc0954ab5e.tar.gz
hyperv/hn: Set hash per-packet-info for each packet transmission
So that the host could dispatch the TX done back to this TX ring's owner channel MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5498
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.h1
-rw-r--r--sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c15
-rw-r--r--sys/dev/hyperv/netvsc/hv_rndis.h9
3 files changed, 25 insertions, 0 deletions
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h
index 8a16770..040dd05d 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.h
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h
@@ -1039,6 +1039,7 @@ struct hn_tx_ring {
struct buf_ring *hn_mbuf_br;
int hn_oactive;
+ int hn_tx_idx;
struct mtx hn_tx_lock;
struct hn_softc *hn_sc;
diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
index 1b04966..b9de3be 100644
--- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -138,6 +138,7 @@ __FBSDID("$FreeBSD$");
#define HN_RNDIS_MSG_LEN \
(sizeof(rndis_msg) + \
+ RNDIS_HASH_PPI_SIZE + \
RNDIS_VLAN_PPI_SIZE + \
RNDIS_TSO_PPI_SIZE + \
RNDIS_CSUM_PPI_SIZE)
@@ -737,6 +738,7 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
rndis_msg *rndis_mesg;
rndis_packet *rndis_pkt;
rndis_per_packet_info *rppi;
+ struct ndis_hash_info *hash_info;
uint32_t rndis_msg_size;
packet = &txd->netvsc_pkt;
@@ -761,6 +763,18 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet);
+ /*
+ * Set the hash info for this packet, so that the host could
+ * dispatch the TX done event for this packet back to this TX
+ * ring's channel.
+ */
+ rndis_msg_size += RNDIS_HASH_PPI_SIZE;
+ rppi = hv_set_rppi_data(rndis_mesg, RNDIS_HASH_PPI_SIZE,
+ nbl_hash_value);
+ hash_info = (struct ndis_hash_info *)((uint8_t *)rppi +
+ rppi->per_packet_info_offset);
+ hash_info->hash = txr->hn_tx_idx;
+
if (m_head->m_flags & M_VLANTAG) {
ndis_8021q_info *rppi_vlan_info;
@@ -2148,6 +2162,7 @@ hn_create_tx_ring(struct hn_softc *sc, int id)
int error, i;
txr->hn_sc = sc;
+ txr->hn_tx_idx = id;
#ifndef HN_USE_TXDESC_BUFRING
mtx_init(&txr->hn_txlist_spin, "hn txlist", NULL, MTX_SPIN);
diff --git a/sys/dev/hyperv/netvsc/hv_rndis.h b/sys/dev/hyperv/netvsc/hv_rndis.h
index 44782ec..db0004e 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis.h
+++ b/sys/dev/hyperv/netvsc/hv_rndis.h
@@ -608,6 +608,8 @@ typedef enum ndis_per_pkt_infotype_ {
max_perpkt_info
} ndis_per_pkt_infotype;
+#define nbl_hash_value pkt_cancel_id
+
typedef struct ndis_8021q_info_ {
union {
struct {
@@ -620,6 +622,10 @@ typedef struct ndis_8021q_info_ {
} u1;
} ndis_8021q_info;
+struct ndis_hash_info {
+ uint32_t hash;
+} __packed;
+
struct rndis_object_header {
uint8_t type;
uint8_t revision;
@@ -713,6 +719,9 @@ typedef struct rndis_tcp_tso_info_ {
};
} rndis_tcp_tso_info;
+#define RNDIS_HASH_PPI_SIZE (sizeof(rndis_per_packet_info) + \
+ sizeof(struct ndis_hash_info))
+
#define RNDIS_VLAN_PPI_SIZE (sizeof(rndis_per_packet_info) + \
sizeof(ndis_8021q_info))
OpenPOWER on IntegriCloud