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