1 /*
2 * Copyright (c) 2009, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Haiyang Zhang <haiyangz@microsoft.com>
18 * Hank Janssen <hjanssen@microsoft.com>
19 */
20 #include <linux/kernel.h>
21 #include <linux/sched.h>
22 #include <linux/wait.h>
23 #include <linux/highmem.h>
24 #include <linux/slab.h>
25 #include <linux/io.h>
26 #include <linux/if_ether.h>
27 #include <linux/netdevice.h>
28 #include <linux/if_vlan.h>
29 #include <linux/nls.h>
30
31 #include "hyperv_net.h"
32
33
34 #define RNDIS_EXT_LEN PAGE_SIZE
35 struct rndis_request {
36 struct list_head list_ent;
37 struct completion wait_event;
38
39 struct rndis_message response_msg;
40 /*
41 * The buffer for extended info after the RNDIS response message. It's
42 * referenced based on the data offset in the RNDIS message. Its size
43 * is enough for current needs, and should be sufficient for the near
44 * future.
45 */
46 u8 response_ext[RNDIS_EXT_LEN];
47
48 /* Simplify allocation by having a netvsc packet inline */
49 struct hv_netvsc_packet pkt;
50 /* Set 2 pages for rndis requests crossing page boundary */
51 struct hv_page_buffer buf[2];
52
53 struct rndis_message request_msg;
54 /*
55 * The buffer for the extended info after the RNDIS request message.
56 * It is referenced and sized in a similar way as response_ext.
57 */
58 u8 request_ext[RNDIS_EXT_LEN];
59 };
60
get_rndis_device(void)61 static struct rndis_device *get_rndis_device(void)
62 {
63 struct rndis_device *device;
64
65 device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL);
66 if (!device)
67 return NULL;
68
69 spin_lock_init(&device->request_lock);
70
71 INIT_LIST_HEAD(&device->req_list);
72
73 device->state = RNDIS_DEV_UNINITIALIZED;
74
75 return device;
76 }
77
get_rndis_request(struct rndis_device * dev,u32 msg_type,u32 msg_len)78 static struct rndis_request *get_rndis_request(struct rndis_device *dev,
79 u32 msg_type,
80 u32 msg_len)
81 {
82 struct rndis_request *request;
83 struct rndis_message *rndis_msg;
84 struct rndis_set_request *set;
85 unsigned long flags;
86
87 request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL);
88 if (!request)
89 return NULL;
90
91 init_completion(&request->wait_event);
92
93 rndis_msg = &request->request_msg;
94 rndis_msg->ndis_msg_type = msg_type;
95 rndis_msg->msg_len = msg_len;
96
97 request->pkt.q_idx = 0;
98
99 /*
100 * Set the request id. This field is always after the rndis header for
101 * request/response packet types so we just used the SetRequest as a
102 * template
103 */
104 set = &rndis_msg->msg.set_req;
105 set->req_id = atomic_inc_return(&dev->new_req_id);
106
107 /* Add to the request list */
108 spin_lock_irqsave(&dev->request_lock, flags);
109 list_add_tail(&request->list_ent, &dev->req_list);
110 spin_unlock_irqrestore(&dev->request_lock, flags);
111
112 return request;
113 }
114
put_rndis_request(struct rndis_device * dev,struct rndis_request * req)115 static void put_rndis_request(struct rndis_device *dev,
116 struct rndis_request *req)
117 {
118 unsigned long flags;
119
120 spin_lock_irqsave(&dev->request_lock, flags);
121 list_del(&req->list_ent);
122 spin_unlock_irqrestore(&dev->request_lock, flags);
123
124 kfree(req);
125 }
126
dump_rndis_message(struct hv_device * hv_dev,struct rndis_message * rndis_msg)127 static void dump_rndis_message(struct hv_device *hv_dev,
128 struct rndis_message *rndis_msg)
129 {
130 struct net_device *netdev;
131 struct netvsc_device *net_device;
132
133 net_device = hv_get_drvdata(hv_dev);
134 netdev = net_device->ndev;
135
136 switch (rndis_msg->ndis_msg_type) {
137 case RNDIS_MSG_PACKET:
138 netdev_dbg(netdev, "RNDIS_MSG_PACKET (len %u, "
139 "data offset %u data len %u, # oob %u, "
140 "oob offset %u, oob len %u, pkt offset %u, "
141 "pkt len %u\n",
142 rndis_msg->msg_len,
143 rndis_msg->msg.pkt.data_offset,
144 rndis_msg->msg.pkt.data_len,
145 rndis_msg->msg.pkt.num_oob_data_elements,
146 rndis_msg->msg.pkt.oob_data_offset,
147 rndis_msg->msg.pkt.oob_data_len,
148 rndis_msg->msg.pkt.per_pkt_info_offset,
149 rndis_msg->msg.pkt.per_pkt_info_len);
150 break;
151
152 case RNDIS_MSG_INIT_C:
153 netdev_dbg(netdev, "RNDIS_MSG_INIT_C "
154 "(len %u, id 0x%x, status 0x%x, major %d, minor %d, "
155 "device flags %d, max xfer size 0x%x, max pkts %u, "
156 "pkt aligned %u)\n",
157 rndis_msg->msg_len,
158 rndis_msg->msg.init_complete.req_id,
159 rndis_msg->msg.init_complete.status,
160 rndis_msg->msg.init_complete.major_ver,
161 rndis_msg->msg.init_complete.minor_ver,
162 rndis_msg->msg.init_complete.dev_flags,
163 rndis_msg->msg.init_complete.max_xfer_size,
164 rndis_msg->msg.init_complete.
165 max_pkt_per_msg,
166 rndis_msg->msg.init_complete.
167 pkt_alignment_factor);
168 break;
169
170 case RNDIS_MSG_QUERY_C:
171 netdev_dbg(netdev, "RNDIS_MSG_QUERY_C "
172 "(len %u, id 0x%x, status 0x%x, buf len %u, "
173 "buf offset %u)\n",
174 rndis_msg->msg_len,
175 rndis_msg->msg.query_complete.req_id,
176 rndis_msg->msg.query_complete.status,
177 rndis_msg->msg.query_complete.
178 info_buflen,
179 rndis_msg->msg.query_complete.
180 info_buf_offset);
181 break;
182
183 case RNDIS_MSG_SET_C:
184 netdev_dbg(netdev,
185 "RNDIS_MSG_SET_C (len %u, id 0x%x, status 0x%x)\n",
186 rndis_msg->msg_len,
187 rndis_msg->msg.set_complete.req_id,
188 rndis_msg->msg.set_complete.status);
189 break;
190
191 case RNDIS_MSG_INDICATE:
192 netdev_dbg(netdev, "RNDIS_MSG_INDICATE "
193 "(len %u, status 0x%x, buf len %u, buf offset %u)\n",
194 rndis_msg->msg_len,
195 rndis_msg->msg.indicate_status.status,
196 rndis_msg->msg.indicate_status.status_buflen,
197 rndis_msg->msg.indicate_status.status_buf_offset);
198 break;
199
200 default:
201 netdev_dbg(netdev, "0x%x (len %u)\n",
202 rndis_msg->ndis_msg_type,
203 rndis_msg->msg_len);
204 break;
205 }
206 }
207
rndis_filter_send_request(struct rndis_device * dev,struct rndis_request * req)208 static int rndis_filter_send_request(struct rndis_device *dev,
209 struct rndis_request *req)
210 {
211 int ret;
212 struct hv_netvsc_packet *packet;
213
214 /* Setup the packet to send it */
215 packet = &req->pkt;
216
217 packet->is_data_pkt = false;
218 packet->total_data_buflen = req->request_msg.msg_len;
219 packet->page_buf_cnt = 1;
220
221 packet->page_buf[0].pfn = virt_to_phys(&req->request_msg) >>
222 PAGE_SHIFT;
223 packet->page_buf[0].len = req->request_msg.msg_len;
224 packet->page_buf[0].offset =
225 (unsigned long)&req->request_msg & (PAGE_SIZE - 1);
226
227 /* Add one page_buf when request_msg crossing page boundary */
228 if (packet->page_buf[0].offset + packet->page_buf[0].len > PAGE_SIZE) {
229 packet->page_buf_cnt++;
230 packet->page_buf[0].len = PAGE_SIZE -
231 packet->page_buf[0].offset;
232 packet->page_buf[1].pfn = virt_to_phys((void *)&req->request_msg
233 + packet->page_buf[0].len) >> PAGE_SHIFT;
234 packet->page_buf[1].offset = 0;
235 packet->page_buf[1].len = req->request_msg.msg_len -
236 packet->page_buf[0].len;
237 }
238
239 packet->send_completion = NULL;
240
241 ret = netvsc_send(dev->net_dev->dev, packet);
242 return ret;
243 }
244
rndis_set_link_state(struct rndis_device * rdev,struct rndis_request * request)245 static void rndis_set_link_state(struct rndis_device *rdev,
246 struct rndis_request *request)
247 {
248 u32 link_status;
249 struct rndis_query_complete *query_complete;
250
251 query_complete = &request->response_msg.msg.query_complete;
252
253 if (query_complete->status == RNDIS_STATUS_SUCCESS &&
254 query_complete->info_buflen == sizeof(u32)) {
255 memcpy(&link_status, (void *)((unsigned long)query_complete +
256 query_complete->info_buf_offset), sizeof(u32));
257 rdev->link_state = link_status != 0;
258 }
259 }
260
rndis_filter_receive_response(struct rndis_device * dev,struct rndis_message * resp)261 static void rndis_filter_receive_response(struct rndis_device *dev,
262 struct rndis_message *resp)
263 {
264 struct rndis_request *request = NULL;
265 bool found = false;
266 unsigned long flags;
267 struct net_device *ndev;
268
269 ndev = dev->net_dev->ndev;
270
271 spin_lock_irqsave(&dev->request_lock, flags);
272 list_for_each_entry(request, &dev->req_list, list_ent) {
273 /*
274 * All request/response message contains RequestId as the 1st
275 * field
276 */
277 if (request->request_msg.msg.init_req.req_id
278 == resp->msg.init_complete.req_id) {
279 found = true;
280 break;
281 }
282 }
283 spin_unlock_irqrestore(&dev->request_lock, flags);
284
285 if (found) {
286 if (resp->msg_len <=
287 sizeof(struct rndis_message) + RNDIS_EXT_LEN) {
288 memcpy(&request->response_msg, resp,
289 resp->msg_len);
290 if (request->request_msg.ndis_msg_type ==
291 RNDIS_MSG_QUERY && request->request_msg.msg.
292 query_req.oid == RNDIS_OID_GEN_MEDIA_CONNECT_STATUS)
293 rndis_set_link_state(dev, request);
294 } else {
295 netdev_err(ndev,
296 "rndis response buffer overflow "
297 "detected (size %u max %zu)\n",
298 resp->msg_len,
299 sizeof(struct rndis_message));
300
301 if (resp->ndis_msg_type ==
302 RNDIS_MSG_RESET_C) {
303 /* does not have a request id field */
304 request->response_msg.msg.reset_complete.
305 status = RNDIS_STATUS_BUFFER_OVERFLOW;
306 } else {
307 request->response_msg.msg.
308 init_complete.status =
309 RNDIS_STATUS_BUFFER_OVERFLOW;
310 }
311 }
312
313 complete(&request->wait_event);
314 } else {
315 netdev_err(ndev,
316 "no rndis request found for this response "
317 "(id 0x%x res type 0x%x)\n",
318 resp->msg.init_complete.req_id,
319 resp->ndis_msg_type);
320 }
321 }
322
323 /*
324 * Get the Per-Packet-Info with the specified type
325 * return NULL if not found.
326 */
rndis_get_ppi(struct rndis_packet * rpkt,u32 type)327 static inline void *rndis_get_ppi(struct rndis_packet *rpkt, u32 type)
328 {
329 struct rndis_per_packet_info *ppi;
330 int len;
331
332 if (rpkt->per_pkt_info_offset == 0)
333 return NULL;
334
335 ppi = (struct rndis_per_packet_info *)((ulong)rpkt +
336 rpkt->per_pkt_info_offset);
337 len = rpkt->per_pkt_info_len;
338
339 while (len > 0) {
340 if (ppi->type == type)
341 return (void *)((ulong)ppi + ppi->ppi_offset);
342 len -= ppi->size;
343 ppi = (struct rndis_per_packet_info *)((ulong)ppi + ppi->size);
344 }
345
346 return NULL;
347 }
348
rndis_filter_receive_data(struct rndis_device * dev,struct rndis_message * msg,struct hv_netvsc_packet * pkt)349 static void rndis_filter_receive_data(struct rndis_device *dev,
350 struct rndis_message *msg,
351 struct hv_netvsc_packet *pkt)
352 {
353 struct rndis_packet *rndis_pkt;
354 u32 data_offset;
355 struct ndis_pkt_8021q_info *vlan;
356 struct ndis_tcp_ip_checksum_info *csum_info;
357
358 rndis_pkt = &msg->msg.pkt;
359
360 /* Remove the rndis header and pass it back up the stack */
361 data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
362
363 pkt->total_data_buflen -= data_offset;
364
365 /*
366 * Make sure we got a valid RNDIS message, now total_data_buflen
367 * should be the data packet size plus the trailer padding size
368 */
369 if (pkt->total_data_buflen < rndis_pkt->data_len) {
370 netdev_err(dev->net_dev->ndev, "rndis message buffer "
371 "overflow detected (got %u, min %u)"
372 "...dropping this message!\n",
373 pkt->total_data_buflen, rndis_pkt->data_len);
374 return;
375 }
376
377 /*
378 * Remove the rndis trailer padding from rndis packet message
379 * rndis_pkt->data_len tell us the real data length, we only copy
380 * the data packet to the stack, without the rndis trailer padding
381 */
382 pkt->total_data_buflen = rndis_pkt->data_len;
383 pkt->data = (void *)((unsigned long)pkt->data + data_offset);
384
385 vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);
386 if (vlan) {
387 pkt->vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid |
388 (vlan->pri << VLAN_PRIO_SHIFT);
389 } else {
390 pkt->vlan_tci = 0;
391 }
392
393 csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO);
394 netvsc_recv_callback(dev->net_dev->dev, pkt, csum_info);
395 }
396
rndis_filter_receive(struct hv_device * dev,struct hv_netvsc_packet * pkt)397 int rndis_filter_receive(struct hv_device *dev,
398 struct hv_netvsc_packet *pkt)
399 {
400 struct netvsc_device *net_dev = hv_get_drvdata(dev);
401 struct rndis_device *rndis_dev;
402 struct rndis_message *rndis_msg;
403 struct net_device *ndev;
404 int ret = 0;
405
406 if (!net_dev) {
407 ret = -EINVAL;
408 goto exit;
409 }
410
411 ndev = net_dev->ndev;
412
413 /* Make sure the rndis device state is initialized */
414 if (!net_dev->extension) {
415 netdev_err(ndev, "got rndis message but no rndis device - "
416 "dropping this message!\n");
417 ret = -ENODEV;
418 goto exit;
419 }
420
421 rndis_dev = (struct rndis_device *)net_dev->extension;
422 if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
423 netdev_err(ndev, "got rndis message but rndis device "
424 "uninitialized...dropping this message!\n");
425 ret = -ENODEV;
426 goto exit;
427 }
428
429 rndis_msg = pkt->data;
430
431 dump_rndis_message(dev, rndis_msg);
432
433 switch (rndis_msg->ndis_msg_type) {
434 case RNDIS_MSG_PACKET:
435 /* data msg */
436 rndis_filter_receive_data(rndis_dev, rndis_msg, pkt);
437 break;
438
439 case RNDIS_MSG_INIT_C:
440 case RNDIS_MSG_QUERY_C:
441 case RNDIS_MSG_SET_C:
442 /* completion msgs */
443 rndis_filter_receive_response(rndis_dev, rndis_msg);
444 break;
445
446 case RNDIS_MSG_INDICATE:
447 /* notification msgs */
448 netvsc_linkstatus_callback(dev, rndis_msg);
449 break;
450 default:
451 netdev_err(ndev,
452 "unhandled rndis message (type %u len %u)\n",
453 rndis_msg->ndis_msg_type,
454 rndis_msg->msg_len);
455 break;
456 }
457
458 exit:
459 if (ret != 0)
460 pkt->status = NVSP_STAT_FAIL;
461
462 return ret;
463 }
464
rndis_filter_query_device(struct rndis_device * dev,u32 oid,void * result,u32 * result_size)465 static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
466 void *result, u32 *result_size)
467 {
468 struct rndis_request *request;
469 u32 inresult_size = *result_size;
470 struct rndis_query_request *query;
471 struct rndis_query_complete *query_complete;
472 int ret = 0;
473 int t;
474
475 if (!result)
476 return -EINVAL;
477
478 *result_size = 0;
479 request = get_rndis_request(dev, RNDIS_MSG_QUERY,
480 RNDIS_MESSAGE_SIZE(struct rndis_query_request));
481 if (!request) {
482 ret = -ENOMEM;
483 goto cleanup;
484 }
485
486 /* Setup the rndis query */
487 query = &request->request_msg.msg.query_req;
488 query->oid = oid;
489 query->info_buf_offset = sizeof(struct rndis_query_request);
490 query->info_buflen = 0;
491 query->dev_vc_handle = 0;
492
493 if (oid == OID_GEN_RECEIVE_SCALE_CAPABILITIES) {
494 struct ndis_recv_scale_cap *cap;
495
496 request->request_msg.msg_len +=
497 sizeof(struct ndis_recv_scale_cap);
498 query->info_buflen = sizeof(struct ndis_recv_scale_cap);
499 cap = (struct ndis_recv_scale_cap *)((unsigned long)query +
500 query->info_buf_offset);
501 cap->hdr.type = NDIS_OBJECT_TYPE_RSS_CAPABILITIES;
502 cap->hdr.rev = NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2;
503 cap->hdr.size = sizeof(struct ndis_recv_scale_cap);
504 }
505
506 ret = rndis_filter_send_request(dev, request);
507 if (ret != 0)
508 goto cleanup;
509
510 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
511 if (t == 0) {
512 ret = -ETIMEDOUT;
513 goto cleanup;
514 }
515
516 /* Copy the response back */
517 query_complete = &request->response_msg.msg.query_complete;
518
519 if (query_complete->info_buflen > inresult_size) {
520 ret = -1;
521 goto cleanup;
522 }
523
524 memcpy(result,
525 (void *)((unsigned long)query_complete +
526 query_complete->info_buf_offset),
527 query_complete->info_buflen);
528
529 *result_size = query_complete->info_buflen;
530
531 cleanup:
532 if (request)
533 put_rndis_request(dev, request);
534
535 return ret;
536 }
537
rndis_filter_query_device_mac(struct rndis_device * dev)538 static int rndis_filter_query_device_mac(struct rndis_device *dev)
539 {
540 u32 size = ETH_ALEN;
541
542 return rndis_filter_query_device(dev,
543 RNDIS_OID_802_3_PERMANENT_ADDRESS,
544 dev->hw_mac_adr, &size);
545 }
546
547 #define NWADR_STR "NetworkAddress"
548 #define NWADR_STRLEN 14
549
rndis_filter_set_device_mac(struct hv_device * hdev,char * mac)550 int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac)
551 {
552 struct netvsc_device *nvdev = hv_get_drvdata(hdev);
553 struct rndis_device *rdev = nvdev->extension;
554 struct net_device *ndev = nvdev->ndev;
555 struct rndis_request *request;
556 struct rndis_set_request *set;
557 struct rndis_config_parameter_info *cpi;
558 wchar_t *cfg_nwadr, *cfg_mac;
559 struct rndis_set_complete *set_complete;
560 char macstr[2*ETH_ALEN+1];
561 u32 extlen = sizeof(struct rndis_config_parameter_info) +
562 2*NWADR_STRLEN + 4*ETH_ALEN;
563 int ret, t;
564
565 request = get_rndis_request(rdev, RNDIS_MSG_SET,
566 RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
567 if (!request)
568 return -ENOMEM;
569
570 set = &request->request_msg.msg.set_req;
571 set->oid = RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER;
572 set->info_buflen = extlen;
573 set->info_buf_offset = sizeof(struct rndis_set_request);
574 set->dev_vc_handle = 0;
575
576 cpi = (struct rndis_config_parameter_info *)((ulong)set +
577 set->info_buf_offset);
578 cpi->parameter_name_offset =
579 sizeof(struct rndis_config_parameter_info);
580 /* Multiply by 2 because host needs 2 bytes (utf16) for each char */
581 cpi->parameter_name_length = 2*NWADR_STRLEN;
582 cpi->parameter_type = RNDIS_CONFIG_PARAM_TYPE_STRING;
583 cpi->parameter_value_offset =
584 cpi->parameter_name_offset + cpi->parameter_name_length;
585 /* Multiply by 4 because each MAC byte displayed as 2 utf16 chars */
586 cpi->parameter_value_length = 4*ETH_ALEN;
587
588 cfg_nwadr = (wchar_t *)((ulong)cpi + cpi->parameter_name_offset);
589 cfg_mac = (wchar_t *)((ulong)cpi + cpi->parameter_value_offset);
590 ret = utf8s_to_utf16s(NWADR_STR, NWADR_STRLEN, UTF16_HOST_ENDIAN,
591 cfg_nwadr, NWADR_STRLEN);
592 if (ret < 0)
593 goto cleanup;
594 snprintf(macstr, 2*ETH_ALEN+1, "%pm", mac);
595 ret = utf8s_to_utf16s(macstr, 2*ETH_ALEN, UTF16_HOST_ENDIAN,
596 cfg_mac, 2*ETH_ALEN);
597 if (ret < 0)
598 goto cleanup;
599
600 ret = rndis_filter_send_request(rdev, request);
601 if (ret != 0)
602 goto cleanup;
603
604 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
605 if (t == 0) {
606 netdev_err(ndev, "timeout before we got a set response...\n");
607 /*
608 * can't put_rndis_request, since we may still receive a
609 * send-completion.
610 */
611 return -EBUSY;
612 } else {
613 set_complete = &request->response_msg.msg.set_complete;
614 if (set_complete->status != RNDIS_STATUS_SUCCESS) {
615 netdev_err(ndev, "Fail to set MAC on host side:0x%x\n",
616 set_complete->status);
617 ret = -EINVAL;
618 }
619 }
620
621 cleanup:
622 put_rndis_request(rdev, request);
623 return ret;
624 }
625
rndis_filter_set_offload_params(struct hv_device * hdev,struct ndis_offload_params * req_offloads)626 int rndis_filter_set_offload_params(struct hv_device *hdev,
627 struct ndis_offload_params *req_offloads)
628 {
629 struct netvsc_device *nvdev = hv_get_drvdata(hdev);
630 struct rndis_device *rdev = nvdev->extension;
631 struct net_device *ndev = nvdev->ndev;
632 struct rndis_request *request;
633 struct rndis_set_request *set;
634 struct ndis_offload_params *offload_params;
635 struct rndis_set_complete *set_complete;
636 u32 extlen = sizeof(struct ndis_offload_params);
637 int ret, t;
638 u32 vsp_version = nvdev->nvsp_version;
639
640 if (vsp_version <= NVSP_PROTOCOL_VERSION_4) {
641 extlen = VERSION_4_OFFLOAD_SIZE;
642 /* On NVSP_PROTOCOL_VERSION_4 and below, we do not support
643 * UDP checksum offload.
644 */
645 req_offloads->udp_ip_v4_csum = 0;
646 req_offloads->udp_ip_v6_csum = 0;
647 }
648
649 request = get_rndis_request(rdev, RNDIS_MSG_SET,
650 RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
651 if (!request)
652 return -ENOMEM;
653
654 set = &request->request_msg.msg.set_req;
655 set->oid = OID_TCP_OFFLOAD_PARAMETERS;
656 set->info_buflen = extlen;
657 set->info_buf_offset = sizeof(struct rndis_set_request);
658 set->dev_vc_handle = 0;
659
660 offload_params = (struct ndis_offload_params *)((ulong)set +
661 set->info_buf_offset);
662 *offload_params = *req_offloads;
663 offload_params->header.type = NDIS_OBJECT_TYPE_DEFAULT;
664 offload_params->header.revision = NDIS_OFFLOAD_PARAMETERS_REVISION_3;
665 offload_params->header.size = extlen;
666
667 ret = rndis_filter_send_request(rdev, request);
668 if (ret != 0)
669 goto cleanup;
670
671 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
672 if (t == 0) {
673 netdev_err(ndev, "timeout before we got aOFFLOAD set response...\n");
674 /* can't put_rndis_request, since we may still receive a
675 * send-completion.
676 */
677 return -EBUSY;
678 } else {
679 set_complete = &request->response_msg.msg.set_complete;
680 if (set_complete->status != RNDIS_STATUS_SUCCESS) {
681 netdev_err(ndev, "Fail to set offload on host side:0x%x\n",
682 set_complete->status);
683 ret = -EINVAL;
684 }
685 }
686
687 cleanup:
688 put_rndis_request(rdev, request);
689 return ret;
690 }
691
692 u8 netvsc_hash_key[HASH_KEYLEN] = {
693 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
694 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
695 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
696 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
697 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
698 };
699
rndis_filter_set_rss_param(struct rndis_device * rdev,int num_queue)700 int rndis_filter_set_rss_param(struct rndis_device *rdev, int num_queue)
701 {
702 struct net_device *ndev = rdev->net_dev->ndev;
703 struct rndis_request *request;
704 struct rndis_set_request *set;
705 struct rndis_set_complete *set_complete;
706 u32 extlen = sizeof(struct ndis_recv_scale_param) +
707 4*ITAB_NUM + HASH_KEYLEN;
708 struct ndis_recv_scale_param *rssp;
709 u32 *itab;
710 u8 *keyp;
711 int i, t, ret;
712
713 request = get_rndis_request(
714 rdev, RNDIS_MSG_SET,
715 RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
716 if (!request)
717 return -ENOMEM;
718
719 set = &request->request_msg.msg.set_req;
720 set->oid = OID_GEN_RECEIVE_SCALE_PARAMETERS;
721 set->info_buflen = extlen;
722 set->info_buf_offset = sizeof(struct rndis_set_request);
723 set->dev_vc_handle = 0;
724
725 rssp = (struct ndis_recv_scale_param *)(set + 1);
726 rssp->hdr.type = NDIS_OBJECT_TYPE_RSS_PARAMETERS;
727 rssp->hdr.rev = NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2;
728 rssp->hdr.size = sizeof(struct ndis_recv_scale_param);
729 rssp->flag = 0;
730 rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
731 NDIS_HASH_TCP_IPV4;
732 rssp->indirect_tabsize = 4*ITAB_NUM;
733 rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
734 rssp->hashkey_size = HASH_KEYLEN;
735 rssp->kashkey_offset = rssp->indirect_taboffset +
736 rssp->indirect_tabsize;
737
738 /* Set indirection table entries */
739 itab = (u32 *)(rssp + 1);
740 for (i = 0; i < ITAB_NUM; i++)
741 itab[i] = i % num_queue;
742
743 /* Set hask key values */
744 keyp = (u8 *)((unsigned long)rssp + rssp->kashkey_offset);
745 for (i = 0; i < HASH_KEYLEN; i++)
746 keyp[i] = netvsc_hash_key[i];
747
748
749 ret = rndis_filter_send_request(rdev, request);
750 if (ret != 0)
751 goto cleanup;
752
753 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
754 if (t == 0) {
755 netdev_err(ndev, "timeout before we got a set response...\n");
756 /* can't put_rndis_request, since we may still receive a
757 * send-completion.
758 */
759 return -ETIMEDOUT;
760 } else {
761 set_complete = &request->response_msg.msg.set_complete;
762 if (set_complete->status != RNDIS_STATUS_SUCCESS) {
763 netdev_err(ndev, "Fail to set RSS parameters:0x%x\n",
764 set_complete->status);
765 ret = -EINVAL;
766 }
767 }
768
769 cleanup:
770 put_rndis_request(rdev, request);
771 return ret;
772 }
773
774
rndis_filter_query_device_link_status(struct rndis_device * dev)775 static int rndis_filter_query_device_link_status(struct rndis_device *dev)
776 {
777 u32 size = sizeof(u32);
778 u32 link_status;
779 int ret;
780
781 ret = rndis_filter_query_device(dev,
782 RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
783 &link_status, &size);
784
785 return ret;
786 }
787
rndis_filter_set_packet_filter(struct rndis_device * dev,u32 new_filter)788 int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
789 {
790 struct rndis_request *request;
791 struct rndis_set_request *set;
792 struct rndis_set_complete *set_complete;
793 u32 status;
794 int ret, t;
795 struct net_device *ndev;
796
797 ndev = dev->net_dev->ndev;
798
799 request = get_rndis_request(dev, RNDIS_MSG_SET,
800 RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
801 sizeof(u32));
802 if (!request) {
803 ret = -ENOMEM;
804 goto cleanup;
805 }
806
807 /* Setup the rndis set */
808 set = &request->request_msg.msg.set_req;
809 set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
810 set->info_buflen = sizeof(u32);
811 set->info_buf_offset = sizeof(struct rndis_set_request);
812
813 memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
814 &new_filter, sizeof(u32));
815
816 ret = rndis_filter_send_request(dev, request);
817 if (ret != 0)
818 goto cleanup;
819
820 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
821
822 if (t == 0) {
823 netdev_err(ndev,
824 "timeout before we got a set response...\n");
825 ret = -ETIMEDOUT;
826 /*
827 * We can't deallocate the request since we may still receive a
828 * send completion for it.
829 */
830 goto exit;
831 } else {
832 set_complete = &request->response_msg.msg.set_complete;
833 status = set_complete->status;
834 }
835
836 cleanup:
837 if (request)
838 put_rndis_request(dev, request);
839 exit:
840 return ret;
841 }
842
843
rndis_filter_init_device(struct rndis_device * dev)844 static int rndis_filter_init_device(struct rndis_device *dev)
845 {
846 struct rndis_request *request;
847 struct rndis_initialize_request *init;
848 struct rndis_initialize_complete *init_complete;
849 u32 status;
850 int ret, t;
851
852 request = get_rndis_request(dev, RNDIS_MSG_INIT,
853 RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
854 if (!request) {
855 ret = -ENOMEM;
856 goto cleanup;
857 }
858
859 /* Setup the rndis set */
860 init = &request->request_msg.msg.init_req;
861 init->major_ver = RNDIS_MAJOR_VERSION;
862 init->minor_ver = RNDIS_MINOR_VERSION;
863 init->max_xfer_size = 0x4000;
864
865 dev->state = RNDIS_DEV_INITIALIZING;
866
867 ret = rndis_filter_send_request(dev, request);
868 if (ret != 0) {
869 dev->state = RNDIS_DEV_UNINITIALIZED;
870 goto cleanup;
871 }
872
873
874 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
875
876 if (t == 0) {
877 ret = -ETIMEDOUT;
878 goto cleanup;
879 }
880
881 init_complete = &request->response_msg.msg.init_complete;
882 status = init_complete->status;
883 if (status == RNDIS_STATUS_SUCCESS) {
884 dev->state = RNDIS_DEV_INITIALIZED;
885 ret = 0;
886 } else {
887 dev->state = RNDIS_DEV_UNINITIALIZED;
888 ret = -EINVAL;
889 }
890
891 cleanup:
892 if (request)
893 put_rndis_request(dev, request);
894
895 return ret;
896 }
897
rndis_filter_halt_device(struct rndis_device * dev)898 static void rndis_filter_halt_device(struct rndis_device *dev)
899 {
900 struct rndis_request *request;
901 struct rndis_halt_request *halt;
902 struct netvsc_device *nvdev = dev->net_dev;
903 struct hv_device *hdev = nvdev->dev;
904 ulong flags;
905
906 /* Attempt to do a rndis device halt */
907 request = get_rndis_request(dev, RNDIS_MSG_HALT,
908 RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
909 if (!request)
910 goto cleanup;
911
912 /* Setup the rndis set */
913 halt = &request->request_msg.msg.halt_req;
914 halt->req_id = atomic_inc_return(&dev->new_req_id);
915
916 /* Ignore return since this msg is optional. */
917 rndis_filter_send_request(dev, request);
918
919 dev->state = RNDIS_DEV_UNINITIALIZED;
920
921 cleanup:
922 spin_lock_irqsave(&hdev->channel->inbound_lock, flags);
923 nvdev->destroy = true;
924 spin_unlock_irqrestore(&hdev->channel->inbound_lock, flags);
925
926 /* Wait for all send completions */
927 wait_event(nvdev->wait_drain,
928 atomic_read(&nvdev->num_outstanding_sends) == 0);
929
930 if (request)
931 put_rndis_request(dev, request);
932 return;
933 }
934
rndis_filter_open_device(struct rndis_device * dev)935 static int rndis_filter_open_device(struct rndis_device *dev)
936 {
937 int ret;
938
939 if (dev->state != RNDIS_DEV_INITIALIZED)
940 return 0;
941
942 ret = rndis_filter_set_packet_filter(dev,
943 NDIS_PACKET_TYPE_BROADCAST |
944 NDIS_PACKET_TYPE_ALL_MULTICAST |
945 NDIS_PACKET_TYPE_DIRECTED);
946 if (ret == 0)
947 dev->state = RNDIS_DEV_DATAINITIALIZED;
948
949 return ret;
950 }
951
rndis_filter_close_device(struct rndis_device * dev)952 static int rndis_filter_close_device(struct rndis_device *dev)
953 {
954 int ret;
955
956 if (dev->state != RNDIS_DEV_DATAINITIALIZED)
957 return 0;
958
959 ret = rndis_filter_set_packet_filter(dev, 0);
960 if (ret == 0)
961 dev->state = RNDIS_DEV_INITIALIZED;
962
963 return ret;
964 }
965
netvsc_sc_open(struct vmbus_channel * new_sc)966 static void netvsc_sc_open(struct vmbus_channel *new_sc)
967 {
968 struct netvsc_device *nvscdev;
969 u16 chn_index = new_sc->offermsg.offer.sub_channel_index;
970 int ret;
971
972 nvscdev = hv_get_drvdata(new_sc->primary_channel->device_obj);
973
974 if (chn_index >= nvscdev->num_chn)
975 return;
976
977 set_per_channel_state(new_sc, nvscdev->sub_cb_buf + (chn_index - 1) *
978 NETVSC_PACKET_SIZE);
979
980 ret = vmbus_open(new_sc, nvscdev->ring_size * PAGE_SIZE,
981 nvscdev->ring_size * PAGE_SIZE, NULL, 0,
982 netvsc_channel_cb, new_sc);
983
984 if (ret == 0)
985 nvscdev->chn_table[chn_index] = new_sc;
986 }
987
rndis_filter_device_add(struct hv_device * dev,void * additional_info)988 int rndis_filter_device_add(struct hv_device *dev,
989 void *additional_info)
990 {
991 int ret;
992 struct netvsc_device *net_device;
993 struct rndis_device *rndis_device;
994 struct netvsc_device_info *device_info = additional_info;
995 struct ndis_offload_params offloads;
996 struct nvsp_message *init_packet;
997 int t;
998 struct ndis_recv_scale_cap rsscap;
999 u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
1000
1001 rndis_device = get_rndis_device();
1002 if (!rndis_device)
1003 return -ENODEV;
1004
1005 /*
1006 * Let the inner driver handle this first to create the netvsc channel
1007 * NOTE! Once the channel is created, we may get a receive callback
1008 * (RndisFilterOnReceive()) before this call is completed
1009 */
1010 ret = netvsc_device_add(dev, additional_info);
1011 if (ret != 0) {
1012 kfree(rndis_device);
1013 return ret;
1014 }
1015
1016
1017 /* Initialize the rndis device */
1018 net_device = hv_get_drvdata(dev);
1019 net_device->num_chn = 1;
1020
1021 net_device->extension = rndis_device;
1022 rndis_device->net_dev = net_device;
1023
1024 /* Send the rndis initialization message */
1025 ret = rndis_filter_init_device(rndis_device);
1026 if (ret != 0) {
1027 rndis_filter_device_remove(dev);
1028 return ret;
1029 }
1030
1031 /* Get the mac address */
1032 ret = rndis_filter_query_device_mac(rndis_device);
1033 if (ret != 0) {
1034 rndis_filter_device_remove(dev);
1035 return ret;
1036 }
1037
1038 memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
1039
1040 /* Turn on the offloads; the host supports all of the relevant
1041 * offloads.
1042 */
1043 memset(&offloads, 0, sizeof(struct ndis_offload_params));
1044 /* A value of zero means "no change"; now turn on what we
1045 * want.
1046 */
1047 offloads.ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1048 offloads.tcp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1049 offloads.udp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1050 offloads.tcp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1051 offloads.udp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1052 offloads.lso_v2_ipv4 = NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
1053
1054
1055 ret = rndis_filter_set_offload_params(dev, &offloads);
1056 if (ret)
1057 goto err_dev_remv;
1058
1059 rndis_filter_query_device_link_status(rndis_device);
1060
1061 device_info->link_state = rndis_device->link_state;
1062
1063 dev_info(&dev->device, "Device MAC %pM link state %s\n",
1064 rndis_device->hw_mac_adr,
1065 device_info->link_state ? "down" : "up");
1066
1067 if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5)
1068 return 0;
1069
1070 /* vRSS setup */
1071 memset(&rsscap, 0, rsscap_size);
1072 ret = rndis_filter_query_device(rndis_device,
1073 OID_GEN_RECEIVE_SCALE_CAPABILITIES,
1074 &rsscap, &rsscap_size);
1075 if (ret || rsscap.num_recv_que < 2)
1076 goto out;
1077
1078 net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ?
1079 num_online_cpus() : rsscap.num_recv_que;
1080 if (net_device->num_chn == 1)
1081 goto out;
1082
1083 net_device->sub_cb_buf = vzalloc((net_device->num_chn - 1) *
1084 NETVSC_PACKET_SIZE);
1085 if (!net_device->sub_cb_buf) {
1086 net_device->num_chn = 1;
1087 dev_info(&dev->device, "No memory for subchannels.\n");
1088 goto out;
1089 }
1090
1091 vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
1092
1093 init_packet = &net_device->channel_init_pkt;
1094 memset(init_packet, 0, sizeof(struct nvsp_message));
1095 init_packet->hdr.msg_type = NVSP_MSG5_TYPE_SUBCHANNEL;
1096 init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE;
1097 init_packet->msg.v5_msg.subchn_req.num_subchannels =
1098 net_device->num_chn - 1;
1099 ret = vmbus_sendpacket(dev->channel, init_packet,
1100 sizeof(struct nvsp_message),
1101 (unsigned long)init_packet,
1102 VM_PKT_DATA_INBAND,
1103 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
1104 if (ret)
1105 goto out;
1106 t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
1107 if (t == 0) {
1108 ret = -ETIMEDOUT;
1109 goto out;
1110 }
1111 if (init_packet->msg.v5_msg.subchn_comp.status !=
1112 NVSP_STAT_SUCCESS) {
1113 ret = -ENODEV;
1114 goto out;
1115 }
1116 net_device->num_chn = 1 +
1117 init_packet->msg.v5_msg.subchn_comp.num_subchannels;
1118
1119 vmbus_are_subchannels_present(dev->channel);
1120
1121 ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn);
1122
1123 out:
1124 if (ret)
1125 net_device->num_chn = 1;
1126 return 0; /* return 0 because primary channel can be used alone */
1127
1128 err_dev_remv:
1129 rndis_filter_device_remove(dev);
1130 return ret;
1131 }
1132
rndis_filter_device_remove(struct hv_device * dev)1133 void rndis_filter_device_remove(struct hv_device *dev)
1134 {
1135 struct netvsc_device *net_dev = hv_get_drvdata(dev);
1136 struct rndis_device *rndis_dev = net_dev->extension;
1137
1138 /* Halt and release the rndis device */
1139 rndis_filter_halt_device(rndis_dev);
1140
1141 kfree(rndis_dev);
1142 net_dev->extension = NULL;
1143
1144 netvsc_device_remove(dev);
1145 }
1146
1147
rndis_filter_open(struct hv_device * dev)1148 int rndis_filter_open(struct hv_device *dev)
1149 {
1150 struct netvsc_device *net_device = hv_get_drvdata(dev);
1151
1152 if (!net_device)
1153 return -EINVAL;
1154
1155 return rndis_filter_open_device(net_device->extension);
1156 }
1157
rndis_filter_close(struct hv_device * dev)1158 int rndis_filter_close(struct hv_device *dev)
1159 {
1160 struct netvsc_device *nvdev = hv_get_drvdata(dev);
1161
1162 if (!nvdev)
1163 return -EINVAL;
1164
1165 return rndis_filter_close_device(nvdev->extension);
1166 }
1167