]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/linux/0007-Drivers-net-hyperv-Enable-offloads-on-the-host.patch
make.sh limit build to 23 parallel threads.
[ipfire-2.x.git] / src / patches / linux / 0007-Drivers-net-hyperv-Enable-offloads-on-the-host.patch
CommitLineData
a7b0967d
MT
1From 6b15b5f37e976a5f3840c7ea59560e10c6251250 Mon Sep 17 00:00:00 2001
2From: KY Srinivasan <kys@microsoft.com>
3Date: Sat, 8 Mar 2014 19:23:15 -0800
4Subject: [PATCH 07/25] Drivers: net: hyperv: Enable offloads on the host
5
6Prior to enabling guest side offloads, enable the offloads on the host.
7
8Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
9Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
10Signed-off-by: David S. Miller <davem@davemloft.net>
11---
12 drivers/net/hyperv/hyperv_net.h | 55 +++++++++++++++++++++++++++
13 drivers/net/hyperv/rndis_filter.c | 80 +++++++++++++++++++++++++++++++++++++++
14 2 files changed, 135 insertions(+)
15
16diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
17index 694bf7cada90..8bc4e766589b 100644
18--- a/drivers/net/hyperv/hyperv_net.h
19+++ b/drivers/net/hyperv/hyperv_net.h
20@@ -721,6 +721,61 @@ struct ndis_pkt_8021q_info {
21 };
22 };
23
24+struct ndis_oject_header {
25+ u8 type;
26+ u8 revision;
27+ u16 size;
28+};
29+
30+#define NDIS_OBJECT_TYPE_DEFAULT 0x80
31+#define NDIS_OFFLOAD_PARAMETERS_REVISION_3 3
32+#define NDIS_OFFLOAD_PARAMETERS_NO_CHANGE 0
33+#define NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED 1
34+#define NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED 2
35+#define NDIS_OFFLOAD_PARAMETERS_LSOV1_ENABLED 2
36+#define NDIS_OFFLOAD_PARAMETERS_RSC_DISABLED 1
37+#define NDIS_OFFLOAD_PARAMETERS_RSC_ENABLED 2
38+#define NDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED 1
39+#define NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED 2
40+#define NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED 3
41+#define NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED 4
42+
43+/*
44+ * New offload OIDs for NDIS 6
45+ */
46+#define OID_TCP_OFFLOAD_CURRENT_CONFIG 0xFC01020B /* query only */
47+#define OID_TCP_OFFLOAD_PARAMETERS 0xFC01020C /* set only */
48+#define OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES 0xFC01020D/* query only */
49+#define OID_TCP_CONNECTION_OFFLOAD_CURRENT_CONFIG 0xFC01020E /* query only */
50+#define OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES 0xFC01020F /* query */
51+#define OID_OFFLOAD_ENCAPSULATION 0x0101010A /* set/query */
52+
53+struct ndis_offload_params {
54+ struct ndis_oject_header header;
55+ u8 ip_v4_csum;
56+ u8 tcp_ip_v4_csum;
57+ u8 udp_ip_v4_csum;
58+ u8 tcp_ip_v6_csum;
59+ u8 udp_ip_v6_csum;
60+ u8 lso_v1;
61+ u8 ip_sec_v1;
62+ u8 lso_v2_ipv4;
63+ u8 lso_v2_ipv6;
64+ u8 tcp_connection_ip_v4;
65+ u8 tcp_connection_ip_v6;
66+ u32 flags;
67+ u8 ip_sec_v2;
68+ u8 ip_sec_v2_ip_v4;
69+ struct {
70+ u8 rsc_ip_v4;
71+ u8 rsc_ip_v6;
72+ };
73+ struct {
74+ u8 encapsulated_packet_task_offload;
75+ u8 encapsulation_types;
76+ };
77+};
78+
79 #define NDIS_VLAN_PPI_SIZE (sizeof(struct rndis_per_packet_info) + \
80 sizeof(struct ndis_pkt_8021q_info))
81
82diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
83index dcbf144ea7da..9b02f21097a7 100644
84--- a/drivers/net/hyperv/rndis_filter.c
85+++ b/drivers/net/hyperv/rndis_filter.c
86@@ -627,6 +627,61 @@ cleanup:
87 return ret;
88 }
89
90+int rndis_filter_set_offload_params(struct hv_device *hdev,
91+ struct ndis_offload_params *req_offloads)
92+{
93+ struct netvsc_device *nvdev = hv_get_drvdata(hdev);
94+ struct rndis_device *rdev = nvdev->extension;
95+ struct net_device *ndev = nvdev->ndev;
96+ struct rndis_request *request;
97+ struct rndis_set_request *set;
98+ struct ndis_offload_params *offload_params;
99+ struct rndis_set_complete *set_complete;
100+ u32 extlen = sizeof(struct ndis_offload_params);
101+ int ret, t;
102+
103+ request = get_rndis_request(rdev, RNDIS_MSG_SET,
104+ RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
105+ if (!request)
106+ return -ENOMEM;
107+
108+ set = &request->request_msg.msg.set_req;
109+ set->oid = OID_TCP_OFFLOAD_PARAMETERS;
110+ set->info_buflen = extlen;
111+ set->info_buf_offset = sizeof(struct rndis_set_request);
112+ set->dev_vc_handle = 0;
113+
114+ offload_params = (struct ndis_offload_params *)((ulong)set +
115+ set->info_buf_offset);
116+ *offload_params = *req_offloads;
117+ offload_params->header.type = NDIS_OBJECT_TYPE_DEFAULT;
118+ offload_params->header.revision = NDIS_OFFLOAD_PARAMETERS_REVISION_3;
119+ offload_params->header.size = extlen;
120+
121+ ret = rndis_filter_send_request(rdev, request);
122+ if (ret != 0)
123+ goto cleanup;
124+
125+ t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
126+ if (t == 0) {
127+ netdev_err(ndev, "timeout before we got aOFFLOAD set response...\n");
128+ /* can't put_rndis_request, since we may still receive a
129+ * send-completion.
130+ */
131+ return -EBUSY;
132+ } else {
133+ set_complete = &request->response_msg.msg.set_complete;
134+ if (set_complete->status != RNDIS_STATUS_SUCCESS) {
135+ netdev_err(ndev, "Fail to set MAC on host side:0x%x\n",
136+ set_complete->status);
137+ ret = -EINVAL;
138+ }
139+ }
140+
141+cleanup:
142+ put_rndis_request(rdev, request);
143+ return ret;
144+}
145
146 static int rndis_filter_query_device_link_status(struct rndis_device *dev)
147 {
148@@ -826,6 +881,7 @@ int rndis_filter_device_add(struct hv_device *dev,
149 struct netvsc_device *net_device;
150 struct rndis_device *rndis_device;
151 struct netvsc_device_info *device_info = additional_info;
152+ struct ndis_offload_params offloads;
153
154 rndis_device = get_rndis_device();
155 if (!rndis_device)
156@@ -865,6 +921,26 @@ int rndis_filter_device_add(struct hv_device *dev,
157
158 memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
159
160+ /* Turn on the offloads; the host supports all of the relevant
161+ * offloads.
162+ */
163+ memset(&offloads, 0, sizeof(struct ndis_offload_params));
164+ /* A value of zero means "no change"; now turn on what we
165+ * want.
166+ */
167+ offloads.ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
168+ offloads.tcp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
169+ offloads.udp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
170+ offloads.tcp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
171+ offloads.udp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
172+ offloads.lso_v2_ipv4 = NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
173+
174+
175+ ret = rndis_filter_set_offload_params(dev, &offloads);
176+ if (ret)
177+ goto err_dev_remv;
178+
179+
180 rndis_filter_query_device_link_status(rndis_device);
181
182 device_info->link_state = rndis_device->link_state;
183@@ -874,6 +950,10 @@ int rndis_filter_device_add(struct hv_device *dev,
184 device_info->link_state ? "down" : "up");
185
186 return ret;
187+
188+err_dev_remv:
189+ rndis_filter_device_remove(dev);
190+ return ret;
191 }
192
193 void rndis_filter_device_remove(struct hv_device *dev)
194--
1952.4.3
196