summaryrefslogtreecommitdiffstats
path: root/sys/dev/hyperv
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2016-10-17 06:16:08 +0000
committersephe <sephe@FreeBSD.org>2016-10-17 06:16:08 +0000
commit04af2d53bcdb5ba4ab8de46e29119586664c52d7 (patch)
treef8fd8625e4328db171740ff8e50ccdf43d9e783f /sys/dev/hyperv
parente16656542b57b4d4fe856d75b8cbd89a72f3d984 (diff)
downloadFreeBSD-src-04af2d53bcdb5ba4ab8de46e29119586664c52d7.zip
FreeBSD-src-04af2d53bcdb5ba4ab8de46e29119586664c52d7.tar.gz
MFC 304327,304329,304330
304327 hyperv/hn: Pass RX packet info to netvsc_recv. This paves to nuke netvsc_packet, which does not serves much purpose now. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7541 304329 hyperv/hn: Constify RNDIS messages on RX path. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7542 304330 hyperv/hn: Get rid of the useless netvsc_packet Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7544
Diffstat (limited to 'sys/dev/hyperv')
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.c25
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.h7
-rw-r--r--sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c50
-rw-r--r--sys/dev/hyperv/netvsc/hv_rndis.h7
-rw-r--r--sys/dev/hyperv/netvsc/hv_rndis_filter.c69
-rw-r--r--sys/dev/hyperv/netvsc/hv_rndis_filter.h4
-rw-r--r--sys/dev/hyperv/netvsc/if_hnvar.h13
7 files changed, 72 insertions, 103 deletions
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c
index 65c4e6d..c96538c 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c
@@ -66,7 +66,7 @@ static int hv_nv_connect_to_vsp(struct hn_softc *sc);
static void hv_nv_on_send_completion(netvsc_dev *net_dev,
struct vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt);
static void hv_nv_on_receive_completion(struct vmbus_channel *chan,
- uint64_t tid, uint32_t status);
+ uint64_t tid);
static void hv_nv_on_receive(netvsc_dev *net_dev,
struct hn_rx_ring *rxr, struct vmbus_channel *chan,
const struct vmbus_chanpkt_hdr *pkt);
@@ -844,11 +844,8 @@ hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr,
{
const struct vmbus_chanpkt_rxbuf *pkt;
const struct hn_nvs_hdr *nvs_hdr;
- netvsc_packet vsc_pkt;
- netvsc_packet *net_vsc_pkt = &vsc_pkt;
int count = 0;
int i = 0;
- int status = HN_NVS_STATUS_OK;
/* Make sure that this is a RNDIS message. */
nvs_hdr = VMBUS_CHANPKT_CONST_DATA(pkthdr);
@@ -870,16 +867,9 @@ hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr,
/* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
for (i = 0; i < count; i++) {
- net_vsc_pkt->status = HN_NVS_STATUS_OK;
- net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf +
- pkt->cp_rxbuf[i].rb_ofs);
- net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len;
-
- hv_rf_on_receive(net_dev, rxr, net_vsc_pkt);
-
- /* XXX pretty broken; whack it */
- if (net_vsc_pkt->status != HN_NVS_STATUS_OK)
- status = HN_NVS_STATUS_FAILED;
+ hv_rf_on_receive(net_dev, rxr,
+ (const uint8_t *)net_dev->rx_buf + pkt->cp_rxbuf[i].rb_ofs,
+ pkt->cp_rxbuf[i].rb_len);
}
/*
@@ -887,7 +877,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr,
* messages (not just data messages) will trigger a response
* message back to the host.
*/
- hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid, status);
+ hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid);
}
/*
@@ -896,15 +886,14 @@ hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr,
* Send a receive completion packet to RNDIS device (ie NetVsp)
*/
static void
-hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid,
- uint32_t status)
+hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid)
{
struct hn_nvs_rndis_ack ack;
int retries = 0;
int ret = 0;
ack.nvs_type = HN_NVS_TYPE_RNDIS_ACK;
- ack.nvs_status = status;
+ ack.nvs_status = HN_NVS_STATUS_OK;
retry_send_cmplt:
/* Send the completion */
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h
index e80146e..abb2407 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.h
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h
@@ -274,13 +274,6 @@ typedef void (*pfn_on_send_rx_completion)(struct vmbus_channel *, void *);
#define BITS_PER_LONG 32
#endif
-typedef struct netvsc_packet_ {
- uint16_t vlan_tci;
- uint32_t status;
- uint32_t tot_data_buf_len;
- void *data;
-} netvsc_packet;
-
typedef struct {
uint8_t mac_addr[6]; /* Assumption unsigned long */
uint8_t link_state;
diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
index 77e254d..8201ac2 100644
--- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -1277,10 +1277,8 @@ hn_lro_rx(struct lro_ctrl *lc, struct mbuf *m)
* Note: This is no longer used as a callback
*/
int
-netvsc_recv(struct hn_rx_ring *rxr, netvsc_packet *packet,
- const rndis_tcp_ip_csum_info *csum_info,
- const struct rndis_hash_info *hash_info,
- const struct rndis_hash_value *hash_value)
+netvsc_recv(struct hn_rx_ring *rxr, const void *data, int dlen,
+ const struct hn_recvinfo *info)
{
struct ifnet *ifp = rxr->hn_ifp;
struct mbuf *m_new;
@@ -1293,17 +1291,16 @@ netvsc_recv(struct hn_rx_ring *rxr, netvsc_packet *packet,
/*
* Bail out if packet contains more data than configured MTU.
*/
- if (packet->tot_data_buf_len > (ifp->if_mtu + ETHER_HDR_LEN)) {
+ if (dlen > (ifp->if_mtu + ETHER_HDR_LEN)) {
return (0);
- } else if (packet->tot_data_buf_len <= MHLEN) {
+ } else if (dlen <= MHLEN) {
m_new = m_gethdr(M_NOWAIT, MT_DATA);
if (m_new == NULL) {
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
return (0);
}
- memcpy(mtod(m_new, void *), packet->data,
- packet->tot_data_buf_len);
- m_new->m_pkthdr.len = m_new->m_len = packet->tot_data_buf_len;
+ memcpy(mtod(m_new, void *), data, dlen);
+ m_new->m_pkthdr.len = m_new->m_len = dlen;
rxr->hn_small_pkts++;
} else {
/*
@@ -1313,7 +1310,7 @@ netvsc_recv(struct hn_rx_ring *rxr, netvsc_packet *packet,
* if looped around to the Hyper-V TX channel, so avoid them.
*/
size = MCLBYTES;
- if (packet->tot_data_buf_len > MCLBYTES) {
+ if (dlen > MCLBYTES) {
/* 4096 */
size = MJUMPAGESIZE;
}
@@ -1324,7 +1321,7 @@ netvsc_recv(struct hn_rx_ring *rxr, netvsc_packet *packet,
return (0);
}
- hv_m_append(m_new, packet->tot_data_buf_len, packet->data);
+ hv_m_append(m_new, dlen, data);
}
m_new->m_pkthdr.rcvif = ifp;
@@ -1332,28 +1329,28 @@ netvsc_recv(struct hn_rx_ring *rxr, netvsc_packet *packet,
do_csum = 0;
/* receive side checksum offload */
- if (csum_info != NULL) {
+ if (info->csum_info != NULL) {
/* IP csum offload */
- if (csum_info->receive.ip_csum_succeeded && do_csum) {
+ if (info->csum_info->receive.ip_csum_succeeded && do_csum) {
m_new->m_pkthdr.csum_flags |=
(CSUM_IP_CHECKED | CSUM_IP_VALID);
rxr->hn_csum_ip++;
}
/* TCP/UDP csum offload */
- if ((csum_info->receive.tcp_csum_succeeded ||
- csum_info->receive.udp_csum_succeeded) && do_csum) {
+ if ((info->csum_info->receive.tcp_csum_succeeded ||
+ info->csum_info->receive.udp_csum_succeeded) && do_csum) {
m_new->m_pkthdr.csum_flags |=
(CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
m_new->m_pkthdr.csum_data = 0xffff;
- if (csum_info->receive.tcp_csum_succeeded)
+ if (info->csum_info->receive.tcp_csum_succeeded)
rxr->hn_csum_tcp++;
else
rxr->hn_csum_udp++;
}
- if (csum_info->receive.ip_csum_succeeded &&
- csum_info->receive.tcp_csum_succeeded)
+ if (info->csum_info->receive.ip_csum_succeeded &&
+ info->csum_info->receive.tcp_csum_succeeded)
do_lro = 1;
} else {
const struct ether_header *eh;
@@ -1409,19 +1406,18 @@ netvsc_recv(struct hn_rx_ring *rxr, netvsc_packet *packet,
}
}
skip:
- if ((packet->vlan_tci != 0) &&
- (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
- m_new->m_pkthdr.ether_vtag = packet->vlan_tci;
+ if (info->vlan_info != NULL) {
+ m_new->m_pkthdr.ether_vtag = info->vlan_info->u1.s1.vlan_id;
m_new->m_flags |= M_VLANTAG;
}
- if (hash_info != NULL && hash_value != NULL) {
+ if (info->hash_info != NULL && info->hash_value != NULL) {
rxr->hn_rss_pkts++;
- m_new->m_pkthdr.flowid = hash_value->hash_value;
- if ((hash_info->hash_info & NDIS_HASH_FUNCTION_MASK) ==
+ m_new->m_pkthdr.flowid = info->hash_value->hash_value;
+ if ((info->hash_info->hash_info & NDIS_HASH_FUNCTION_MASK) ==
NDIS_HASH_FUNCTION_TOEPLITZ) {
uint32_t type =
- (hash_info->hash_info & NDIS_HASH_TYPE_MASK);
+ (info->hash_info->hash_info & NDIS_HASH_TYPE_MASK);
switch (type) {
case NDIS_HASH_IPV4:
@@ -1450,8 +1446,8 @@ skip:
}
}
} else {
- if (hash_value != NULL) {
- m_new->m_pkthdr.flowid = hash_value->hash_value;
+ if (info->hash_value != NULL) {
+ m_new->m_pkthdr.flowid = info->hash_value->hash_value;
} else {
m_new->m_pkthdr.flowid = rxr->hn_rx_idx;
hash_type = M_HASHTYPE_OPAQUE;
diff --git a/sys/dev/hyperv/netvsc/hv_rndis.h b/sys/dev/hyperv/netvsc/hv_rndis.h
index 6527668..cdddf88 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis.h
+++ b/sys/dev/hyperv/netvsc/hv_rndis.h
@@ -1088,11 +1088,10 @@ typedef struct rndismp_rx_bufs_info_ {
*/
struct hn_rx_ring;
struct hn_tx_ring;
+struct hn_recvinfo;
-int netvsc_recv(struct hn_rx_ring *rxr,
- netvsc_packet *packet, const rndis_tcp_ip_csum_info *csum_info,
- const struct rndis_hash_info *hash_info,
- const struct rndis_hash_value *hash_value);
+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(rndis_msg *rndis_mesg,
diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c
index 3a73c8c..29b5e75 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c
+++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c
@@ -52,13 +52,6 @@ __FBSDID("$FreeBSD$");
#include <dev/hyperv/netvsc/hv_rndis_filter.h>
#include <dev/hyperv/netvsc/if_hnreg.h>
-struct hv_rf_recvinfo {
- const ndis_8021q_info *vlan_info;
- const rndis_tcp_ip_csum_info *csum_info;
- const struct rndis_hash_info *hash_info;
- const struct rndis_hash_value *hash_value;
-};
-
#define HV_RF_RECVINFO_VLAN 0x1
#define HV_RF_RECVINFO_CSUM 0x2
#define HV_RF_RECVINFO_HASHINF 0x4
@@ -74,11 +67,12 @@ struct hv_rf_recvinfo {
*/
static int hv_rf_send_request(rndis_device *device, rndis_request *request,
uint32_t message_type);
-static void hv_rf_receive_response(rndis_device *device, rndis_msg *response);
+static void hv_rf_receive_response(rndis_device *device,
+ const rndis_msg *response);
static void hv_rf_receive_indicate_status(rndis_device *device,
- rndis_msg *response);
-static void hv_rf_receive_data(struct hn_rx_ring *rxr, rndis_msg *message,
- netvsc_packet *pkt);
+ const rndis_msg *response);
+static void hv_rf_receive_data(struct hn_rx_ring *rxr,
+ const void *data, int dlen);
static int hv_rf_query_device(rndis_device *device, uint32_t oid,
void *result, uint32_t *result_size);
static inline int hv_rf_query_device_mac(rndis_device *device);
@@ -302,7 +296,7 @@ sendit:
* RNDIS filter receive response
*/
static void
-hv_rf_receive_response(rndis_device *device, rndis_msg *response)
+hv_rf_receive_response(rndis_device *device, const rndis_msg *response)
{
rndis_request *request = NULL;
rndis_request *next_request;
@@ -424,9 +418,9 @@ cleanup:
* RNDIS filter receive indicate status
*/
static void
-hv_rf_receive_indicate_status(rndis_device *device, rndis_msg *response)
+hv_rf_receive_indicate_status(rndis_device *device, const rndis_msg *response)
{
- rndis_indicate_status *indicate = &response->msg.indicate_status;
+ const rndis_indicate_status *indicate = &response->msg.indicate_status;
switch(indicate->status) {
case RNDIS_STATUS_MEDIA_CONNECT:
@@ -444,7 +438,7 @@ hv_rf_receive_indicate_status(rndis_device *device, rndis_msg *response)
}
static int
-hv_rf_find_recvinfo(const rndis_packet *rpkt, struct hv_rf_recvinfo *info)
+hv_rf_find_recvinfo(const rndis_packet *rpkt, struct hn_recvinfo *info)
{
const rndis_per_packet_info *ppi;
uint32_t mask, len;
@@ -525,12 +519,12 @@ skip:
* RNDIS filter receive data
*/
static void
-hv_rf_receive_data(struct hn_rx_ring *rxr, rndis_msg *message,
- netvsc_packet *pkt)
+hv_rf_receive_data(struct hn_rx_ring *rxr, const void *data, int dlen)
{
- rndis_packet *rndis_pkt;
+ const rndis_msg *message = data;
+ const rndis_packet *rndis_pkt;
uint32_t data_offset;
- struct hv_rf_recvinfo info;
+ struct hn_recvinfo info;
rndis_pkt = &message->msg.packet;
@@ -542,30 +536,22 @@ hv_rf_receive_data(struct hn_rx_ring *rxr, rndis_msg *message,
/* Remove rndis header, then pass data packet up the stack */
data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
- pkt->tot_data_buf_len -= data_offset;
- if (pkt->tot_data_buf_len < rndis_pkt->data_length) {
- pkt->status = HN_NVS_STATUS_FAILED;
+ dlen -= data_offset;
+ if (dlen < rndis_pkt->data_length) {
if_printf(rxr->hn_ifp,
"total length %u is less than data length %u\n",
- pkt->tot_data_buf_len, rndis_pkt->data_length);
+ dlen, rndis_pkt->data_length);
return;
}
- pkt->tot_data_buf_len = rndis_pkt->data_length;
- pkt->data = (void *)((unsigned long)pkt->data + data_offset);
+ dlen = rndis_pkt->data_length;
+ data = (const uint8_t *)data + data_offset;
if (hv_rf_find_recvinfo(rndis_pkt, &info)) {
- pkt->status = HN_NVS_STATUS_FAILED;
if_printf(rxr->hn_ifp, "recvinfo parsing failed\n");
return;
}
-
- if (info.vlan_info != NULL)
- pkt->vlan_tci = info.vlan_info->u1.s1.vlan_id;
- else
- pkt->vlan_tci = 0;
-
- netvsc_recv(rxr, pkt, info.csum_info, info.hash_info, info.hash_value);
+ netvsc_recv(rxr, data, dlen, &info);
}
/*
@@ -573,30 +559,25 @@ hv_rf_receive_data(struct hn_rx_ring *rxr, rndis_msg *message,
*/
int
hv_rf_on_receive(netvsc_dev *net_dev,
- struct hn_rx_ring *rxr, netvsc_packet *pkt)
+ struct hn_rx_ring *rxr, const void *data, int dlen)
{
rndis_device *rndis_dev;
- rndis_msg *rndis_hdr;
+ const rndis_msg *rndis_hdr;
/* Make sure the rndis device state is initialized */
- if (net_dev->extension == NULL) {
- pkt->status = HN_NVS_STATUS_FAILED;
+ if (net_dev->extension == NULL)
return (ENODEV);
- }
rndis_dev = (rndis_device *)net_dev->extension;
- if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
- pkt->status = HN_NVS_STATUS_FAILED;
+ if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED)
return (EINVAL);
- }
-
- rndis_hdr = pkt->data;
+ rndis_hdr = data;
switch (rndis_hdr->ndis_msg_type) {
/* data message */
case REMOTE_NDIS_PACKET_MSG:
- hv_rf_receive_data(rxr, rndis_hdr, pkt);
+ hv_rf_receive_data(rxr, data, dlen);
break;
/* completion messages */
case REMOTE_NDIS_INITIALIZE_CMPLT:
diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.h b/sys/dev/hyperv/netvsc/hv_rndis_filter.h
index ebfda20..325d082 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis_filter.h
+++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.h
@@ -115,8 +115,8 @@ typedef struct rndis_device_ {
struct hn_softc;
struct hn_rx_ring;
-int hv_rf_on_receive(netvsc_dev *net_dev,
- struct hn_rx_ring *rxr, netvsc_packet *pkt);
+int hv_rf_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr,
+ const void *data, int dlen);
void hv_rf_receive_rollup(netvsc_dev *net_dev);
void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr);
int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int nchan,
diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h
index 706131a..c1a9a95 100644
--- a/sys/dev/hyperv/netvsc/if_hnvar.h
+++ b/sys/dev/hyperv/netvsc/if_hnvar.h
@@ -35,7 +35,6 @@
#include <dev/hyperv/netvsc/if_hnreg.h>
struct netvsc_dev_;
-struct nvsp_msg_;
struct vmbus_channel;
struct hn_send_ctx;
@@ -51,6 +50,18 @@ struct hn_send_ctx {
int hn_chim_sz;
};
+struct rndis_hash_info;
+struct rndix_hash_value;
+struct ndis_8021q_info_;
+struct rndis_tcp_ip_csum_info_;
+
+struct hn_recvinfo {
+ const struct ndis_8021q_info_ *vlan_info;
+ const struct rndis_tcp_ip_csum_info_ *csum_info;
+ const struct rndis_hash_info *hash_info;
+ const struct rndis_hash_value *hash_value;
+};
+
#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
{ \
.hn_cb = cb, \
OpenPOWER on IntegriCloud