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