Author: whu
Date: Wed Jun 24 06:01:29 2015
New Revision: 284746
URL: https://svnweb.freebsd.org/changeset/base/284746
Log:
TSO and checksum offloading support for Netvsc driver on Hyper-V.
Submitted by: whu
Reviewed by: royger
Approved by: royger
MFC after:1 week
Relnotes: yes
Sponsored by: Microsoft OSTC
Differential Revision:https://reviews.freebsd.org/D2517
Modified:
head/sys/dev/hyperv/include/hyperv.h
head/sys/dev/hyperv/netvsc/hv_net_vsc.c
head/sys/dev/hyperv/netvsc/hv_net_vsc.h
head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
head/sys/dev/hyperv/netvsc/hv_rndis.h
head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
head/sys/dev/hyperv/netvsc/hv_rndis_filter.h
Modified: head/sys/dev/hyperv/include/hyperv.h
==
--- head/sys/dev/hyperv/include/hyperv.hWed Jun 24 01:48:44 2015
(r284745)
+++ head/sys/dev/hyperv/include/hyperv.hWed Jun 24 06:01:29 2015
(r284746)
@@ -107,7 +107,7 @@ typedef uint8_t hv_bool_uint8_t;
#define HV_MAX_PIPE_USER_DEFINED_BYTES 116
-#define HV_MAX_PAGE_BUFFER_COUNT 16
+#define HV_MAX_PAGE_BUFFER_COUNT 32
#define HV_MAX_MULTIPAGE_BUFFER_COUNT 32
#define HV_ALIGN_UP(value, align) \
Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.c
==
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Jun 24 01:48:44 2015
(r284745)
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Jun 24 06:01:29 2015
(r284746)
@@ -49,6 +49,7 @@
#include "hv_rndis.h"
#include "hv_rndis_filter.h"
+MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
/*
* Forward declarations
@@ -59,13 +60,10 @@ static int hv_nv_init_rx_buffer_with_ne
static int hv_nv_destroy_send_buffer(netvsc_dev *net_dev);
static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
static int hv_nv_connect_to_vsp(struct hv_device *device);
-static void hv_nv_on_send_completion(struct hv_device *device,
-hv_vm_packet_descriptor *pkt);
-static void hv_nv_on_receive(struct hv_device *device,
-hv_vm_packet_descriptor *pkt);
-static void hv_nv_send_receive_completion(struct hv_device *device,
- uint64_t tid);
-
+static void hv_nv_on_send_completion(netvsc_dev *net_dev,
+struct hv_device *device, hv_vm_packet_descriptor *pkt);
+static void hv_nv_on_receive(netvsc_dev *net_dev,
+struct hv_device *device, hv_vm_packet_descriptor *pkt);
/*
*
@@ -76,7 +74,7 @@ hv_nv_alloc_net_device(struct hv_device
netvsc_dev *net_dev;
hn_softc_t *sc = device_get_softc(device->device);
- net_dev = malloc(sizeof(netvsc_dev), M_DEVBUF, M_NOWAIT | M_ZERO);
+ net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_NOWAIT | M_ZERO);
if (net_dev == NULL) {
return (NULL);
}
@@ -128,6 +126,34 @@ hv_nv_get_inbound_net_device(struct hv_d
return (net_dev);
}
+int
+hv_nv_get_next_send_section(netvsc_dev *net_dev)
+{
+ unsigned long bitsmap_words = net_dev->bitsmap_words;
+ unsigned long *bitsmap = net_dev->send_section_bitsmap;
+ unsigned long idx;
+ int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
+ int i;
+
+ for (i = 0; i < bitsmap_words; i++) {
+ idx = ffs(~bitsmap[i]);
+ if (0 == idx)
+ continue;
+
+ idx--;
+ if (i * BITS_PER_LONG + idx >= net_dev->send_section_count)
+ return (ret);
+
+ if (synch_test_and_set_bit(idx, &bitsmap[i]))
+ continue;
+
+ ret = i * BITS_PER_LONG + idx;
+ break;
+ }
+
+ return (ret);
+}
+
/*
* Net VSC initialize receive buffer with net VSP
*
@@ -146,12 +172,8 @@ hv_nv_init_rx_buffer_with_net_vsp(struct
return (ENODEV);
}
- net_dev->rx_buf = contigmalloc(net_dev->rx_buf_size, M_DEVBUF,
+ net_dev->rx_buf = contigmalloc(net_dev->rx_buf_size, M_NETVSC,
M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
- if (net_dev->rx_buf == NULL) {
- ret = ENOMEM;
- goto cleanup;
- }
/*
* Establish the GPADL handle for this buffer on this channel.
@@ -202,7 +224,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct
init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;
net_dev->rx_sections = malloc(net_dev->rx_section_count *
- sizeof(nvsp_1_rx_buf_section), M_DEVBUF, M_NOWAIT);
+ sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_NOWAIT);
if (net_dev->rx_sections == NULL) {
ret = EINVAL;
goto cleanup;
@@ -246,7 +268,7 @@ hv_nv_init_send_buffer_with_net_vsp(stru