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
31#include "hyperv_net.h"
32
33
34#define RNDIS_EXT_LEN PAGE_SIZE
35struct rndis_request {
36 struct list_head list_ent;
37 struct completion wait_event;
38
39 struct rndis_message response_msg;
40
41
42
43
44
45
46 u8 response_ext[RNDIS_EXT_LEN];
47
48
49 struct hv_netvsc_packet pkt;
50
51 struct hv_page_buffer buf[2];
52
53 struct rndis_message request_msg;
54
55
56
57
58 u8 request_ext[RNDIS_EXT_LEN];
59};
60
61static 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
78static 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
101
102
103
104 set = &rndis_msg->msg.set_req;
105 set->req_id = atomic_inc_return(&dev->new_req_id);
106
107
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
115static 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
127static 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
208static 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
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
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
245static 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
261static 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
275
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
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
325
326
327static 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
349static 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
361 data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
362
363 pkt->total_data_buflen -= data_offset;
364
365
366
367
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
379
380
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
397int 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
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
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
443 rndis_filter_receive_response(rndis_dev, rndis_msg);
444 break;
445
446 case RNDIS_MSG_INDICATE:
447
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
458exit:
459 if (ret != 0)
460 pkt->status = NVSP_STAT_FAIL;
461
462 return ret;
463}
464
465static 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 unsigned long 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
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
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
531cleanup:
532 if (request)
533 put_rndis_request(dev, request);
534
535 return ret;
536}
537
538static 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
550int 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;
564 unsigned long t;
565
566 request = get_rndis_request(rdev, RNDIS_MSG_SET,
567 RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
568 if (!request)
569 return -ENOMEM;
570
571 set = &request->request_msg.msg.set_req;
572 set->oid = RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER;
573 set->info_buflen = extlen;
574 set->info_buf_offset = sizeof(struct rndis_set_request);
575 set->dev_vc_handle = 0;
576
577 cpi = (struct rndis_config_parameter_info *)((ulong)set +
578 set->info_buf_offset);
579 cpi->parameter_name_offset =
580 sizeof(struct rndis_config_parameter_info);
581
582 cpi->parameter_name_length = 2*NWADR_STRLEN;
583 cpi->parameter_type = RNDIS_CONFIG_PARAM_TYPE_STRING;
584 cpi->parameter_value_offset =
585 cpi->parameter_name_offset + cpi->parameter_name_length;
586
587 cpi->parameter_value_length = 4*ETH_ALEN;
588
589 cfg_nwadr = (wchar_t *)((ulong)cpi + cpi->parameter_name_offset);
590 cfg_mac = (wchar_t *)((ulong)cpi + cpi->parameter_value_offset);
591 ret = utf8s_to_utf16s(NWADR_STR, NWADR_STRLEN, UTF16_HOST_ENDIAN,
592 cfg_nwadr, NWADR_STRLEN);
593 if (ret < 0)
594 goto cleanup;
595 snprintf(macstr, 2*ETH_ALEN+1, "%pm", mac);
596 ret = utf8s_to_utf16s(macstr, 2*ETH_ALEN, UTF16_HOST_ENDIAN,
597 cfg_mac, 2*ETH_ALEN);
598 if (ret < 0)
599 goto cleanup;
600
601 ret = rndis_filter_send_request(rdev, request);
602 if (ret != 0)
603 goto cleanup;
604
605 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
606 if (t == 0) {
607 netdev_err(ndev, "timeout before we got a set response...\n");
608
609
610
611
612 return -EBUSY;
613 } else {
614 set_complete = &request->response_msg.msg.set_complete;
615 if (set_complete->status != RNDIS_STATUS_SUCCESS) {
616 netdev_err(ndev, "Fail to set MAC on host side:0x%x\n",
617 set_complete->status);
618 ret = -EINVAL;
619 }
620 }
621
622cleanup:
623 put_rndis_request(rdev, request);
624 return ret;
625}
626
627static int
628rndis_filter_set_offload_params(struct hv_device *hdev,
629 struct ndis_offload_params *req_offloads)
630{
631 struct netvsc_device *nvdev = hv_get_drvdata(hdev);
632 struct rndis_device *rdev = nvdev->extension;
633 struct net_device *ndev = nvdev->ndev;
634 struct rndis_request *request;
635 struct rndis_set_request *set;
636 struct ndis_offload_params *offload_params;
637 struct rndis_set_complete *set_complete;
638 u32 extlen = sizeof(struct ndis_offload_params);
639 int ret;
640 unsigned long t;
641 u32 vsp_version = nvdev->nvsp_version;
642
643 if (vsp_version <= NVSP_PROTOCOL_VERSION_4) {
644 extlen = VERSION_4_OFFLOAD_SIZE;
645
646
647
648 req_offloads->udp_ip_v4_csum = 0;
649 req_offloads->udp_ip_v6_csum = 0;
650 }
651
652 request = get_rndis_request(rdev, RNDIS_MSG_SET,
653 RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
654 if (!request)
655 return -ENOMEM;
656
657 set = &request->request_msg.msg.set_req;
658 set->oid = OID_TCP_OFFLOAD_PARAMETERS;
659 set->info_buflen = extlen;
660 set->info_buf_offset = sizeof(struct rndis_set_request);
661 set->dev_vc_handle = 0;
662
663 offload_params = (struct ndis_offload_params *)((ulong)set +
664 set->info_buf_offset);
665 *offload_params = *req_offloads;
666 offload_params->header.type = NDIS_OBJECT_TYPE_DEFAULT;
667 offload_params->header.revision = NDIS_OFFLOAD_PARAMETERS_REVISION_3;
668 offload_params->header.size = extlen;
669
670 ret = rndis_filter_send_request(rdev, request);
671 if (ret != 0)
672 goto cleanup;
673
674 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
675 if (t == 0) {
676 netdev_err(ndev, "timeout before we got aOFFLOAD set response...\n");
677
678
679
680 return -EBUSY;
681 } else {
682 set_complete = &request->response_msg.msg.set_complete;
683 if (set_complete->status != RNDIS_STATUS_SUCCESS) {
684 netdev_err(ndev, "Fail to set offload on host side:0x%x\n",
685 set_complete->status);
686 ret = -EINVAL;
687 }
688 }
689
690cleanup:
691 put_rndis_request(rdev, request);
692 return ret;
693}
694
695u8 netvsc_hash_key[HASH_KEYLEN] = {
696 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
697 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
698 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
699 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
700 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
701};
702
703static int rndis_filter_set_rss_param(struct rndis_device *rdev, int num_queue)
704{
705 struct net_device *ndev = rdev->net_dev->ndev;
706 struct rndis_request *request;
707 struct rndis_set_request *set;
708 struct rndis_set_complete *set_complete;
709 u32 extlen = sizeof(struct ndis_recv_scale_param) +
710 4*ITAB_NUM + HASH_KEYLEN;
711 struct ndis_recv_scale_param *rssp;
712 u32 *itab;
713 u8 *keyp;
714 int i, ret;
715 unsigned long t;
716
717 request = get_rndis_request(
718 rdev, RNDIS_MSG_SET,
719 RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
720 if (!request)
721 return -ENOMEM;
722
723 set = &request->request_msg.msg.set_req;
724 set->oid = OID_GEN_RECEIVE_SCALE_PARAMETERS;
725 set->info_buflen = extlen;
726 set->info_buf_offset = sizeof(struct rndis_set_request);
727 set->dev_vc_handle = 0;
728
729 rssp = (struct ndis_recv_scale_param *)(set + 1);
730 rssp->hdr.type = NDIS_OBJECT_TYPE_RSS_PARAMETERS;
731 rssp->hdr.rev = NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2;
732 rssp->hdr.size = sizeof(struct ndis_recv_scale_param);
733 rssp->flag = 0;
734 rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
735 NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 |
736 NDIS_HASH_TCP_IPV6;
737 rssp->indirect_tabsize = 4*ITAB_NUM;
738 rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
739 rssp->hashkey_size = HASH_KEYLEN;
740 rssp->kashkey_offset = rssp->indirect_taboffset +
741 rssp->indirect_tabsize;
742
743
744 itab = (u32 *)(rssp + 1);
745 for (i = 0; i < ITAB_NUM; i++)
746 itab[i] = i % num_queue;
747
748
749 keyp = (u8 *)((unsigned long)rssp + rssp->kashkey_offset);
750 for (i = 0; i < HASH_KEYLEN; i++)
751 keyp[i] = netvsc_hash_key[i];
752
753
754 ret = rndis_filter_send_request(rdev, request);
755 if (ret != 0)
756 goto cleanup;
757
758 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
759 if (t == 0) {
760 netdev_err(ndev, "timeout before we got a set response...\n");
761
762
763
764 return -ETIMEDOUT;
765 } else {
766 set_complete = &request->response_msg.msg.set_complete;
767 if (set_complete->status != RNDIS_STATUS_SUCCESS) {
768 netdev_err(ndev, "Fail to set RSS parameters:0x%x\n",
769 set_complete->status);
770 ret = -EINVAL;
771 }
772 }
773
774cleanup:
775 put_rndis_request(rdev, request);
776 return ret;
777}
778
779
780static int rndis_filter_query_device_link_status(struct rndis_device *dev)
781{
782 u32 size = sizeof(u32);
783 u32 link_status;
784 int ret;
785
786 ret = rndis_filter_query_device(dev,
787 RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
788 &link_status, &size);
789
790 return ret;
791}
792
793int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
794{
795 struct rndis_request *request;
796 struct rndis_set_request *set;
797 struct rndis_set_complete *set_complete;
798 u32 status;
799 int ret;
800 unsigned long t;
801 struct net_device *ndev;
802
803 ndev = dev->net_dev->ndev;
804
805 request = get_rndis_request(dev, RNDIS_MSG_SET,
806 RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
807 sizeof(u32));
808 if (!request) {
809 ret = -ENOMEM;
810 goto cleanup;
811 }
812
813
814 set = &request->request_msg.msg.set_req;
815 set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
816 set->info_buflen = sizeof(u32);
817 set->info_buf_offset = sizeof(struct rndis_set_request);
818
819 memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
820 &new_filter, sizeof(u32));
821
822 ret = rndis_filter_send_request(dev, request);
823 if (ret != 0)
824 goto cleanup;
825
826 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
827
828 if (t == 0) {
829 netdev_err(ndev,
830 "timeout before we got a set response...\n");
831 ret = -ETIMEDOUT;
832
833
834
835
836 goto exit;
837 } else {
838 set_complete = &request->response_msg.msg.set_complete;
839 status = set_complete->status;
840 }
841
842cleanup:
843 if (request)
844 put_rndis_request(dev, request);
845exit:
846 return ret;
847}
848
849
850static int rndis_filter_init_device(struct rndis_device *dev)
851{
852 struct rndis_request *request;
853 struct rndis_initialize_request *init;
854 struct rndis_initialize_complete *init_complete;
855 u32 status;
856 int ret;
857 unsigned long t;
858
859 request = get_rndis_request(dev, RNDIS_MSG_INIT,
860 RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
861 if (!request) {
862 ret = -ENOMEM;
863 goto cleanup;
864 }
865
866
867 init = &request->request_msg.msg.init_req;
868 init->major_ver = RNDIS_MAJOR_VERSION;
869 init->minor_ver = RNDIS_MINOR_VERSION;
870 init->max_xfer_size = 0x4000;
871
872 dev->state = RNDIS_DEV_INITIALIZING;
873
874 ret = rndis_filter_send_request(dev, request);
875 if (ret != 0) {
876 dev->state = RNDIS_DEV_UNINITIALIZED;
877 goto cleanup;
878 }
879
880
881 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
882
883 if (t == 0) {
884 ret = -ETIMEDOUT;
885 goto cleanup;
886 }
887
888 init_complete = &request->response_msg.msg.init_complete;
889 status = init_complete->status;
890 if (status == RNDIS_STATUS_SUCCESS) {
891 dev->state = RNDIS_DEV_INITIALIZED;
892 ret = 0;
893 } else {
894 dev->state = RNDIS_DEV_UNINITIALIZED;
895 ret = -EINVAL;
896 }
897
898cleanup:
899 if (request)
900 put_rndis_request(dev, request);
901
902 return ret;
903}
904
905static void rndis_filter_halt_device(struct rndis_device *dev)
906{
907 struct rndis_request *request;
908 struct rndis_halt_request *halt;
909 struct netvsc_device *nvdev = dev->net_dev;
910 struct hv_device *hdev = nvdev->dev;
911 ulong flags;
912
913
914 request = get_rndis_request(dev, RNDIS_MSG_HALT,
915 RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
916 if (!request)
917 goto cleanup;
918
919
920 halt = &request->request_msg.msg.halt_req;
921 halt->req_id = atomic_inc_return(&dev->new_req_id);
922
923
924 rndis_filter_send_request(dev, request);
925
926 dev->state = RNDIS_DEV_UNINITIALIZED;
927
928cleanup:
929 spin_lock_irqsave(&hdev->channel->inbound_lock, flags);
930 nvdev->destroy = true;
931 spin_unlock_irqrestore(&hdev->channel->inbound_lock, flags);
932
933
934 wait_event(nvdev->wait_drain,
935 atomic_read(&nvdev->num_outstanding_sends) == 0);
936
937 if (request)
938 put_rndis_request(dev, request);
939 return;
940}
941
942static int rndis_filter_open_device(struct rndis_device *dev)
943{
944 int ret;
945
946 if (dev->state != RNDIS_DEV_INITIALIZED)
947 return 0;
948
949 ret = rndis_filter_set_packet_filter(dev,
950 NDIS_PACKET_TYPE_BROADCAST |
951 NDIS_PACKET_TYPE_ALL_MULTICAST |
952 NDIS_PACKET_TYPE_DIRECTED);
953 if (ret == 0)
954 dev->state = RNDIS_DEV_DATAINITIALIZED;
955
956 return ret;
957}
958
959static int rndis_filter_close_device(struct rndis_device *dev)
960{
961 int ret;
962
963 if (dev->state != RNDIS_DEV_DATAINITIALIZED)
964 return 0;
965
966 ret = rndis_filter_set_packet_filter(dev, 0);
967 if (ret == -ENODEV)
968 ret = 0;
969
970 if (ret == 0)
971 dev->state = RNDIS_DEV_INITIALIZED;
972
973 return ret;
974}
975
976static void netvsc_sc_open(struct vmbus_channel *new_sc)
977{
978 struct netvsc_device *nvscdev;
979 u16 chn_index = new_sc->offermsg.offer.sub_channel_index;
980 int ret;
981
982 nvscdev = hv_get_drvdata(new_sc->primary_channel->device_obj);
983
984 if (chn_index >= nvscdev->num_chn)
985 return;
986
987 set_per_channel_state(new_sc, nvscdev->sub_cb_buf + (chn_index - 1) *
988 NETVSC_PACKET_SIZE);
989
990 ret = vmbus_open(new_sc, nvscdev->ring_size * PAGE_SIZE,
991 nvscdev->ring_size * PAGE_SIZE, NULL, 0,
992 netvsc_channel_cb, new_sc);
993
994 if (ret == 0)
995 nvscdev->chn_table[chn_index] = new_sc;
996}
997
998int rndis_filter_device_add(struct hv_device *dev,
999 void *additional_info)
1000{
1001 int ret;
1002 struct netvsc_device *net_device;
1003 struct rndis_device *rndis_device;
1004 struct netvsc_device_info *device_info = additional_info;
1005 struct ndis_offload_params offloads;
1006 struct nvsp_message *init_packet;
1007 unsigned long t;
1008 struct ndis_recv_scale_cap rsscap;
1009 u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
1010 u32 mtu, size;
1011
1012 rndis_device = get_rndis_device();
1013 if (!rndis_device)
1014 return -ENODEV;
1015
1016
1017
1018
1019
1020
1021 ret = netvsc_device_add(dev, additional_info);
1022 if (ret != 0) {
1023 kfree(rndis_device);
1024 return ret;
1025 }
1026
1027
1028
1029 net_device = hv_get_drvdata(dev);
1030 net_device->num_chn = 1;
1031
1032 net_device->extension = rndis_device;
1033 rndis_device->net_dev = net_device;
1034
1035
1036 ret = rndis_filter_init_device(rndis_device);
1037 if (ret != 0) {
1038 rndis_filter_device_remove(dev);
1039 return ret;
1040 }
1041
1042
1043 size = sizeof(u32);
1044 ret = rndis_filter_query_device(rndis_device,
1045 RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE,
1046 &mtu, &size);
1047 if (ret == 0 && size == sizeof(u32))
1048 net_device->ndev->mtu = mtu;
1049
1050
1051 ret = rndis_filter_query_device_mac(rndis_device);
1052 if (ret != 0) {
1053 rndis_filter_device_remove(dev);
1054 return ret;
1055 }
1056
1057 memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
1058
1059
1060
1061
1062 memset(&offloads, 0, sizeof(struct ndis_offload_params));
1063
1064
1065
1066 offloads.ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1067 offloads.tcp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1068 offloads.udp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1069 offloads.tcp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1070 offloads.udp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1071 offloads.lso_v2_ipv4 = NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
1072
1073
1074 ret = rndis_filter_set_offload_params(dev, &offloads);
1075 if (ret)
1076 goto err_dev_remv;
1077
1078 rndis_filter_query_device_link_status(rndis_device);
1079
1080 device_info->link_state = rndis_device->link_state;
1081
1082 dev_info(&dev->device, "Device MAC %pM link state %s\n",
1083 rndis_device->hw_mac_adr,
1084 device_info->link_state ? "down" : "up");
1085
1086 if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5)
1087 return 0;
1088
1089
1090 memset(&rsscap, 0, rsscap_size);
1091 ret = rndis_filter_query_device(rndis_device,
1092 OID_GEN_RECEIVE_SCALE_CAPABILITIES,
1093 &rsscap, &rsscap_size);
1094 if (ret || rsscap.num_recv_que < 2)
1095 goto out;
1096
1097 net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ?
1098 num_online_cpus() : rsscap.num_recv_que;
1099 if (net_device->num_chn == 1)
1100 goto out;
1101
1102 net_device->sub_cb_buf = vzalloc((net_device->num_chn - 1) *
1103 NETVSC_PACKET_SIZE);
1104 if (!net_device->sub_cb_buf) {
1105 net_device->num_chn = 1;
1106 dev_info(&dev->device, "No memory for subchannels.\n");
1107 goto out;
1108 }
1109
1110 vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
1111
1112 init_packet = &net_device->channel_init_pkt;
1113 memset(init_packet, 0, sizeof(struct nvsp_message));
1114 init_packet->hdr.msg_type = NVSP_MSG5_TYPE_SUBCHANNEL;
1115 init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE;
1116 init_packet->msg.v5_msg.subchn_req.num_subchannels =
1117 net_device->num_chn - 1;
1118 ret = vmbus_sendpacket(dev->channel, init_packet,
1119 sizeof(struct nvsp_message),
1120 (unsigned long)init_packet,
1121 VM_PKT_DATA_INBAND,
1122 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
1123 if (ret)
1124 goto out;
1125 t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
1126 if (t == 0) {
1127 ret = -ETIMEDOUT;
1128 goto out;
1129 }
1130 if (init_packet->msg.v5_msg.subchn_comp.status !=
1131 NVSP_STAT_SUCCESS) {
1132 ret = -ENODEV;
1133 goto out;
1134 }
1135 net_device->num_chn = 1 +
1136 init_packet->msg.v5_msg.subchn_comp.num_subchannels;
1137
1138 vmbus_are_subchannels_present(dev->channel);
1139
1140 ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn);
1141
1142out:
1143 if (ret)
1144 net_device->num_chn = 1;
1145 return 0;
1146
1147err_dev_remv:
1148 rndis_filter_device_remove(dev);
1149 return ret;
1150}
1151
1152void rndis_filter_device_remove(struct hv_device *dev)
1153{
1154 struct netvsc_device *net_dev = hv_get_drvdata(dev);
1155 struct rndis_device *rndis_dev = net_dev->extension;
1156
1157
1158 rndis_filter_halt_device(rndis_dev);
1159
1160 kfree(rndis_dev);
1161 net_dev->extension = NULL;
1162
1163 netvsc_device_remove(dev);
1164}
1165
1166
1167int rndis_filter_open(struct hv_device *dev)
1168{
1169 struct netvsc_device *net_device = hv_get_drvdata(dev);
1170
1171 if (!net_device)
1172 return -EINVAL;
1173
1174 return rndis_filter_open_device(net_device->extension);
1175}
1176
1177int rndis_filter_close(struct hv_device *dev)
1178{
1179 struct netvsc_device *nvdev = hv_get_drvdata(dev);
1180
1181 if (!nvdev)
1182 return -EINVAL;
1183
1184 return rndis_filter_close_device(nvdev->extension);
1185}
1186