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 struct hv_page_buffer *pb = page_buf;
214
215
216 packet = &req->pkt;
217
218 packet->total_data_buflen = req->request_msg.msg_len;
219 packet->page_buf_cnt = 1;
220
221 pb[0].pfn = virt_to_phys(&req->request_msg) >>
222 PAGE_SHIFT;
223 pb[0].len = req->request_msg.msg_len;
224 pb[0].offset =
225 (unsigned long)&req->request_msg & (PAGE_SIZE - 1);
226
227
228 if (pb[0].offset + pb[0].len > PAGE_SIZE) {
229 packet->page_buf_cnt++;
230 pb[0].len = PAGE_SIZE -
231 pb[0].offset;
232 pb[1].pfn = virt_to_phys((void *)&req->request_msg
233 + pb[0].len) >> PAGE_SHIFT;
234 pb[1].offset = 0;
235 pb[1].len = req->request_msg.msg_len -
236 pb[0].len;
237 }
238
239 ret = netvsc_send(dev->net_dev->dev, packet, NULL, &pb, NULL);
240 return ret;
241}
242
243static void rndis_set_link_state(struct rndis_device *rdev,
244 struct rndis_request *request)
245{
246 u32 link_status;
247 struct rndis_query_complete *query_complete;
248
249 query_complete = &request->response_msg.msg.query_complete;
250
251 if (query_complete->status == RNDIS_STATUS_SUCCESS &&
252 query_complete->info_buflen == sizeof(u32)) {
253 memcpy(&link_status, (void *)((unsigned long)query_complete +
254 query_complete->info_buf_offset), sizeof(u32));
255 rdev->link_state = link_status != 0;
256 }
257}
258
259static void rndis_filter_receive_response(struct rndis_device *dev,
260 struct rndis_message *resp)
261{
262 struct rndis_request *request = NULL;
263 bool found = false;
264 unsigned long flags;
265 struct net_device *ndev;
266
267 ndev = dev->net_dev->ndev;
268
269 spin_lock_irqsave(&dev->request_lock, flags);
270 list_for_each_entry(request, &dev->req_list, list_ent) {
271
272
273
274
275 if (request->request_msg.msg.init_req.req_id
276 == resp->msg.init_complete.req_id) {
277 found = true;
278 break;
279 }
280 }
281 spin_unlock_irqrestore(&dev->request_lock, flags);
282
283 if (found) {
284 if (resp->msg_len <=
285 sizeof(struct rndis_message) + RNDIS_EXT_LEN) {
286 memcpy(&request->response_msg, resp,
287 resp->msg_len);
288 if (request->request_msg.ndis_msg_type ==
289 RNDIS_MSG_QUERY && request->request_msg.msg.
290 query_req.oid == RNDIS_OID_GEN_MEDIA_CONNECT_STATUS)
291 rndis_set_link_state(dev, request);
292 } else {
293 netdev_err(ndev,
294 "rndis response buffer overflow "
295 "detected (size %u max %zu)\n",
296 resp->msg_len,
297 sizeof(struct rndis_message));
298
299 if (resp->ndis_msg_type ==
300 RNDIS_MSG_RESET_C) {
301
302 request->response_msg.msg.reset_complete.
303 status = RNDIS_STATUS_BUFFER_OVERFLOW;
304 } else {
305 request->response_msg.msg.
306 init_complete.status =
307 RNDIS_STATUS_BUFFER_OVERFLOW;
308 }
309 }
310
311 complete(&request->wait_event);
312 } else {
313 netdev_err(ndev,
314 "no rndis request found for this response "
315 "(id 0x%x res type 0x%x)\n",
316 resp->msg.init_complete.req_id,
317 resp->ndis_msg_type);
318 }
319}
320
321
322
323
324
325static inline void *rndis_get_ppi(struct rndis_packet *rpkt, u32 type)
326{
327 struct rndis_per_packet_info *ppi;
328 int len;
329
330 if (rpkt->per_pkt_info_offset == 0)
331 return NULL;
332
333 ppi = (struct rndis_per_packet_info *)((ulong)rpkt +
334 rpkt->per_pkt_info_offset);
335 len = rpkt->per_pkt_info_len;
336
337 while (len > 0) {
338 if (ppi->type == type)
339 return (void *)((ulong)ppi + ppi->ppi_offset);
340 len -= ppi->size;
341 ppi = (struct rndis_per_packet_info *)((ulong)ppi + ppi->size);
342 }
343
344 return NULL;
345}
346
347static int rndis_filter_receive_data(struct rndis_device *dev,
348 struct rndis_message *msg,
349 struct hv_netvsc_packet *pkt,
350 void **data,
351 struct vmbus_channel *channel)
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 u16 vlan_tci = 0;
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 NVSP_STAT_FAIL;
376 }
377
378
379
380
381
382
383 pkt->total_data_buflen = rndis_pkt->data_len;
384 *data = (void *)((unsigned long)(*data) + data_offset);
385
386 vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);
387 if (vlan) {
388 vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid |
389 (vlan->pri << VLAN_PRIO_SHIFT);
390 }
391
392 csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO);
393 return netvsc_recv_callback(dev->net_dev->dev, pkt, data,
394 csum_info, channel, vlan_tci);
395}
396
397int rndis_filter_receive(struct hv_device *dev,
398 struct hv_netvsc_packet *pkt,
399 void **data,
400 struct vmbus_channel *channel)
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 = NVSP_STAT_FAIL;
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 = NVSP_STAT_FAIL;
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 = NVSP_STAT_FAIL;
428 goto exit;
429 }
430
431 rndis_msg = *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 ret = rndis_filter_receive_data(rndis_dev, rndis_msg, pkt,
440 data, channel);
441 break;
442
443 case RNDIS_MSG_INIT_C:
444 case RNDIS_MSG_QUERY_C:
445 case RNDIS_MSG_SET_C:
446
447 rndis_filter_receive_response(rndis_dev, rndis_msg);
448 break;
449
450 case RNDIS_MSG_INDICATE:
451
452 netvsc_linkstatus_callback(dev, rndis_msg);
453 break;
454 default:
455 netdev_err(ndev,
456 "unhandled rndis message (type %u len %u)\n",
457 rndis_msg->ndis_msg_type,
458 rndis_msg->msg_len);
459 break;
460 }
461
462exit:
463 return ret;
464}
465
466static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
467 void *result, u32 *result_size)
468{
469 struct rndis_request *request;
470 u32 inresult_size = *result_size;
471 struct rndis_query_request *query;
472 struct rndis_query_complete *query_complete;
473 int ret = 0;
474 unsigned long t;
475
476 if (!result)
477 return -EINVAL;
478
479 *result_size = 0;
480 request = get_rndis_request(dev, RNDIS_MSG_QUERY,
481 RNDIS_MESSAGE_SIZE(struct rndis_query_request));
482 if (!request) {
483 ret = -ENOMEM;
484 goto cleanup;
485 }
486
487
488 query = &request->request_msg.msg.query_req;
489 query->oid = oid;
490 query->info_buf_offset = sizeof(struct rndis_query_request);
491 query->info_buflen = 0;
492 query->dev_vc_handle = 0;
493
494 if (oid == OID_GEN_RECEIVE_SCALE_CAPABILITIES) {
495 struct ndis_recv_scale_cap *cap;
496
497 request->request_msg.msg_len +=
498 sizeof(struct ndis_recv_scale_cap);
499 query->info_buflen = sizeof(struct ndis_recv_scale_cap);
500 cap = (struct ndis_recv_scale_cap *)((unsigned long)query +
501 query->info_buf_offset);
502 cap->hdr.type = NDIS_OBJECT_TYPE_RSS_CAPABILITIES;
503 cap->hdr.rev = NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2;
504 cap->hdr.size = sizeof(struct ndis_recv_scale_cap);
505 }
506
507 ret = rndis_filter_send_request(dev, request);
508 if (ret != 0)
509 goto cleanup;
510
511 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
512 if (t == 0) {
513 ret = -ETIMEDOUT;
514 goto cleanup;
515 }
516
517
518 query_complete = &request->response_msg.msg.query_complete;
519
520 if (query_complete->info_buflen > inresult_size) {
521 ret = -1;
522 goto cleanup;
523 }
524
525 memcpy(result,
526 (void *)((unsigned long)query_complete +
527 query_complete->info_buf_offset),
528 query_complete->info_buflen);
529
530 *result_size = query_complete->info_buflen;
531
532cleanup:
533 if (request)
534 put_rndis_request(dev, request);
535
536 return ret;
537}
538
539static int rndis_filter_query_device_mac(struct rndis_device *dev)
540{
541 u32 size = ETH_ALEN;
542
543 return rndis_filter_query_device(dev,
544 RNDIS_OID_802_3_PERMANENT_ADDRESS,
545 dev->hw_mac_adr, &size);
546}
547
548#define NWADR_STR "NetworkAddress"
549#define NWADR_STRLEN 14
550
551int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac)
552{
553 struct netvsc_device *nvdev = hv_get_drvdata(hdev);
554 struct rndis_device *rdev = nvdev->extension;
555 struct net_device *ndev = nvdev->ndev;
556 struct rndis_request *request;
557 struct rndis_set_request *set;
558 struct rndis_config_parameter_info *cpi;
559 wchar_t *cfg_nwadr, *cfg_mac;
560 struct rndis_set_complete *set_complete;
561 char macstr[2*ETH_ALEN+1];
562 u32 extlen = sizeof(struct rndis_config_parameter_info) +
563 2*NWADR_STRLEN + 4*ETH_ALEN;
564 int ret;
565 unsigned long t;
566
567 request = get_rndis_request(rdev, RNDIS_MSG_SET,
568 RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
569 if (!request)
570 return -ENOMEM;
571
572 set = &request->request_msg.msg.set_req;
573 set->oid = RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER;
574 set->info_buflen = extlen;
575 set->info_buf_offset = sizeof(struct rndis_set_request);
576 set->dev_vc_handle = 0;
577
578 cpi = (struct rndis_config_parameter_info *)((ulong)set +
579 set->info_buf_offset);
580 cpi->parameter_name_offset =
581 sizeof(struct rndis_config_parameter_info);
582
583 cpi->parameter_name_length = 2*NWADR_STRLEN;
584 cpi->parameter_type = RNDIS_CONFIG_PARAM_TYPE_STRING;
585 cpi->parameter_value_offset =
586 cpi->parameter_name_offset + cpi->parameter_name_length;
587
588 cpi->parameter_value_length = 4*ETH_ALEN;
589
590 cfg_nwadr = (wchar_t *)((ulong)cpi + cpi->parameter_name_offset);
591 cfg_mac = (wchar_t *)((ulong)cpi + cpi->parameter_value_offset);
592 ret = utf8s_to_utf16s(NWADR_STR, NWADR_STRLEN, UTF16_HOST_ENDIAN,
593 cfg_nwadr, NWADR_STRLEN);
594 if (ret < 0)
595 goto cleanup;
596 snprintf(macstr, 2*ETH_ALEN+1, "%pm", mac);
597 ret = utf8s_to_utf16s(macstr, 2*ETH_ALEN, UTF16_HOST_ENDIAN,
598 cfg_mac, 2*ETH_ALEN);
599 if (ret < 0)
600 goto cleanup;
601
602 ret = rndis_filter_send_request(rdev, request);
603 if (ret != 0)
604 goto cleanup;
605
606 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
607 if (t == 0) {
608 netdev_err(ndev, "timeout before we got a set response...\n");
609
610
611
612
613 return -EBUSY;
614 } else {
615 set_complete = &request->response_msg.msg.set_complete;
616 if (set_complete->status != RNDIS_STATUS_SUCCESS) {
617 netdev_err(ndev, "Fail to set MAC on host side:0x%x\n",
618 set_complete->status);
619 ret = -EINVAL;
620 }
621 }
622
623cleanup:
624 put_rndis_request(rdev, request);
625 return ret;
626}
627
628static int
629rndis_filter_set_offload_params(struct hv_device *hdev,
630 struct ndis_offload_params *req_offloads)
631{
632 struct netvsc_device *nvdev = hv_get_drvdata(hdev);
633 struct rndis_device *rdev = nvdev->extension;
634 struct net_device *ndev = nvdev->ndev;
635 struct rndis_request *request;
636 struct rndis_set_request *set;
637 struct ndis_offload_params *offload_params;
638 struct rndis_set_complete *set_complete;
639 u32 extlen = sizeof(struct ndis_offload_params);
640 int ret;
641 unsigned long t;
642 u32 vsp_version = nvdev->nvsp_version;
643
644 if (vsp_version <= NVSP_PROTOCOL_VERSION_4) {
645 extlen = VERSION_4_OFFLOAD_SIZE;
646
647
648
649 req_offloads->udp_ip_v4_csum = 0;
650 req_offloads->udp_ip_v6_csum = 0;
651 }
652
653 request = get_rndis_request(rdev, RNDIS_MSG_SET,
654 RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
655 if (!request)
656 return -ENOMEM;
657
658 set = &request->request_msg.msg.set_req;
659 set->oid = OID_TCP_OFFLOAD_PARAMETERS;
660 set->info_buflen = extlen;
661 set->info_buf_offset = sizeof(struct rndis_set_request);
662 set->dev_vc_handle = 0;
663
664 offload_params = (struct ndis_offload_params *)((ulong)set +
665 set->info_buf_offset);
666 *offload_params = *req_offloads;
667 offload_params->header.type = NDIS_OBJECT_TYPE_DEFAULT;
668 offload_params->header.revision = NDIS_OFFLOAD_PARAMETERS_REVISION_3;
669 offload_params->header.size = extlen;
670
671 ret = rndis_filter_send_request(rdev, request);
672 if (ret != 0)
673 goto cleanup;
674
675 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
676 if (t == 0) {
677 netdev_err(ndev, "timeout before we got aOFFLOAD set response...\n");
678
679
680
681 return -EBUSY;
682 } else {
683 set_complete = &request->response_msg.msg.set_complete;
684 if (set_complete->status != RNDIS_STATUS_SUCCESS) {
685 netdev_err(ndev, "Fail to set offload on host side:0x%x\n",
686 set_complete->status);
687 ret = -EINVAL;
688 }
689 }
690
691cleanup:
692 put_rndis_request(rdev, request);
693 return ret;
694}
695
696u8 netvsc_hash_key[HASH_KEYLEN] = {
697 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
698 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
699 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
700 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
701 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
702};
703
704static int rndis_filter_set_rss_param(struct rndis_device *rdev, int num_queue)
705{
706 struct net_device *ndev = rdev->net_dev->ndev;
707 struct rndis_request *request;
708 struct rndis_set_request *set;
709 struct rndis_set_complete *set_complete;
710 u32 extlen = sizeof(struct ndis_recv_scale_param) +
711 4*ITAB_NUM + HASH_KEYLEN;
712 struct ndis_recv_scale_param *rssp;
713 u32 *itab;
714 u8 *keyp;
715 int i, ret;
716 unsigned long t;
717
718 request = get_rndis_request(
719 rdev, RNDIS_MSG_SET,
720 RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
721 if (!request)
722 return -ENOMEM;
723
724 set = &request->request_msg.msg.set_req;
725 set->oid = OID_GEN_RECEIVE_SCALE_PARAMETERS;
726 set->info_buflen = extlen;
727 set->info_buf_offset = sizeof(struct rndis_set_request);
728 set->dev_vc_handle = 0;
729
730 rssp = (struct ndis_recv_scale_param *)(set + 1);
731 rssp->hdr.type = NDIS_OBJECT_TYPE_RSS_PARAMETERS;
732 rssp->hdr.rev = NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2;
733 rssp->hdr.size = sizeof(struct ndis_recv_scale_param);
734 rssp->flag = 0;
735 rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
736 NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 |
737 NDIS_HASH_TCP_IPV6;
738 rssp->indirect_tabsize = 4*ITAB_NUM;
739 rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
740 rssp->hashkey_size = HASH_KEYLEN;
741 rssp->kashkey_offset = rssp->indirect_taboffset +
742 rssp->indirect_tabsize;
743
744
745 itab = (u32 *)(rssp + 1);
746 for (i = 0; i < ITAB_NUM; i++)
747 itab[i] = i % num_queue;
748
749
750 keyp = (u8 *)((unsigned long)rssp + rssp->kashkey_offset);
751 for (i = 0; i < HASH_KEYLEN; i++)
752 keyp[i] = netvsc_hash_key[i];
753
754
755 ret = rndis_filter_send_request(rdev, request);
756 if (ret != 0)
757 goto cleanup;
758
759 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
760 if (t == 0) {
761 netdev_err(ndev, "timeout before we got a set response...\n");
762
763
764
765 return -ETIMEDOUT;
766 } else {
767 set_complete = &request->response_msg.msg.set_complete;
768 if (set_complete->status != RNDIS_STATUS_SUCCESS) {
769 netdev_err(ndev, "Fail to set RSS parameters:0x%x\n",
770 set_complete->status);
771 ret = -EINVAL;
772 }
773 }
774
775cleanup:
776 put_rndis_request(rdev, request);
777 return ret;
778}
779
780
781static int rndis_filter_query_device_link_status(struct rndis_device *dev)
782{
783 u32 size = sizeof(u32);
784 u32 link_status;
785 int ret;
786
787 ret = rndis_filter_query_device(dev,
788 RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
789 &link_status, &size);
790
791 return ret;
792}
793
794int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
795{
796 struct rndis_request *request;
797 struct rndis_set_request *set;
798 struct rndis_set_complete *set_complete;
799 u32 status;
800 int ret;
801 unsigned long t;
802 struct net_device *ndev;
803
804 ndev = dev->net_dev->ndev;
805
806 request = get_rndis_request(dev, RNDIS_MSG_SET,
807 RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
808 sizeof(u32));
809 if (!request) {
810 ret = -ENOMEM;
811 goto cleanup;
812 }
813
814
815 set = &request->request_msg.msg.set_req;
816 set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
817 set->info_buflen = sizeof(u32);
818 set->info_buf_offset = sizeof(struct rndis_set_request);
819
820 memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
821 &new_filter, sizeof(u32));
822
823 ret = rndis_filter_send_request(dev, request);
824 if (ret != 0)
825 goto cleanup;
826
827 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
828
829 if (t == 0) {
830 netdev_err(ndev,
831 "timeout before we got a set response...\n");
832 ret = -ETIMEDOUT;
833
834
835
836
837 goto exit;
838 } else {
839 set_complete = &request->response_msg.msg.set_complete;
840 status = set_complete->status;
841 }
842
843cleanup:
844 if (request)
845 put_rndis_request(dev, request);
846exit:
847 return ret;
848}
849
850
851static int rndis_filter_init_device(struct rndis_device *dev)
852{
853 struct rndis_request *request;
854 struct rndis_initialize_request *init;
855 struct rndis_initialize_complete *init_complete;
856 u32 status;
857 int ret;
858 unsigned long t;
859 struct netvsc_device *nvdev = dev->net_dev;
860
861 request = get_rndis_request(dev, RNDIS_MSG_INIT,
862 RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
863 if (!request) {
864 ret = -ENOMEM;
865 goto cleanup;
866 }
867
868
869 init = &request->request_msg.msg.init_req;
870 init->major_ver = RNDIS_MAJOR_VERSION;
871 init->minor_ver = RNDIS_MINOR_VERSION;
872 init->max_xfer_size = 0x4000;
873
874 dev->state = RNDIS_DEV_INITIALIZING;
875
876 ret = rndis_filter_send_request(dev, request);
877 if (ret != 0) {
878 dev->state = RNDIS_DEV_UNINITIALIZED;
879 goto cleanup;
880 }
881
882
883 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
884
885 if (t == 0) {
886 ret = -ETIMEDOUT;
887 goto cleanup;
888 }
889
890 init_complete = &request->response_msg.msg.init_complete;
891 status = init_complete->status;
892 if (status == RNDIS_STATUS_SUCCESS) {
893 dev->state = RNDIS_DEV_INITIALIZED;
894 nvdev->max_pkt = init_complete->max_pkt_per_msg;
895 nvdev->pkt_align = 1 << init_complete->pkt_alignment_factor;
896 ret = 0;
897 } else {
898 dev->state = RNDIS_DEV_UNINITIALIZED;
899 ret = -EINVAL;
900 }
901
902cleanup:
903 if (request)
904 put_rndis_request(dev, request);
905
906 return ret;
907}
908
909static void rndis_filter_halt_device(struct rndis_device *dev)
910{
911 struct rndis_request *request;
912 struct rndis_halt_request *halt;
913 struct netvsc_device *nvdev = dev->net_dev;
914 struct hv_device *hdev = nvdev->dev;
915 ulong flags;
916
917
918 request = get_rndis_request(dev, RNDIS_MSG_HALT,
919 RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
920 if (!request)
921 goto cleanup;
922
923
924 halt = &request->request_msg.msg.halt_req;
925 halt->req_id = atomic_inc_return(&dev->new_req_id);
926
927
928 rndis_filter_send_request(dev, request);
929
930 dev->state = RNDIS_DEV_UNINITIALIZED;
931
932cleanup:
933 spin_lock_irqsave(&hdev->channel->inbound_lock, flags);
934 nvdev->destroy = true;
935 spin_unlock_irqrestore(&hdev->channel->inbound_lock, flags);
936
937
938 wait_event(nvdev->wait_drain,
939 atomic_read(&nvdev->num_outstanding_sends) == 0);
940
941 if (request)
942 put_rndis_request(dev, request);
943 return;
944}
945
946static int rndis_filter_open_device(struct rndis_device *dev)
947{
948 int ret;
949
950 if (dev->state != RNDIS_DEV_INITIALIZED)
951 return 0;
952
953 ret = rndis_filter_set_packet_filter(dev,
954 NDIS_PACKET_TYPE_BROADCAST |
955 NDIS_PACKET_TYPE_ALL_MULTICAST |
956 NDIS_PACKET_TYPE_DIRECTED);
957 if (ret == 0)
958 dev->state = RNDIS_DEV_DATAINITIALIZED;
959
960 return ret;
961}
962
963static int rndis_filter_close_device(struct rndis_device *dev)
964{
965 int ret;
966
967 if (dev->state != RNDIS_DEV_DATAINITIALIZED)
968 return 0;
969
970 ret = rndis_filter_set_packet_filter(dev, 0);
971 if (ret == -ENODEV)
972 ret = 0;
973
974 if (ret == 0)
975 dev->state = RNDIS_DEV_INITIALIZED;
976
977 return ret;
978}
979
980static void netvsc_sc_open(struct vmbus_channel *new_sc)
981{
982 struct netvsc_device *nvscdev;
983 u16 chn_index = new_sc->offermsg.offer.sub_channel_index;
984 int ret;
985 unsigned long flags;
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 spin_lock_irqsave(&nvscdev->sc_lock, flags);
1003 nvscdev->num_sc_offered--;
1004 spin_unlock_irqrestore(&nvscdev->sc_lock, flags);
1005 if (nvscdev->num_sc_offered == 0)
1006 complete(&nvscdev->channel_init_wait);
1007}
1008
1009int rndis_filter_device_add(struct hv_device *dev,
1010 void *additional_info)
1011{
1012 int ret;
1013 struct netvsc_device *net_device;
1014 struct rndis_device *rndis_device;
1015 struct netvsc_device_info *device_info = additional_info;
1016 struct ndis_offload_params offloads;
1017 struct nvsp_message *init_packet;
1018 unsigned long t;
1019 struct ndis_recv_scale_cap rsscap;
1020 u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
1021 u32 mtu, size;
1022 u32 num_rss_qs;
1023 u32 sc_delta;
1024 const struct cpumask *node_cpu_mask;
1025 u32 num_possible_rss_qs;
1026 unsigned long flags;
1027
1028 rndis_device = get_rndis_device();
1029 if (!rndis_device)
1030 return -ENODEV;
1031
1032
1033
1034
1035
1036
1037 ret = netvsc_device_add(dev, additional_info);
1038 if (ret != 0) {
1039 kfree(rndis_device);
1040 return ret;
1041 }
1042
1043
1044
1045 net_device = hv_get_drvdata(dev);
1046 net_device->max_chn = 1;
1047 net_device->num_chn = 1;
1048
1049 spin_lock_init(&net_device->sc_lock);
1050
1051 net_device->extension = rndis_device;
1052 rndis_device->net_dev = net_device;
1053
1054
1055 ret = rndis_filter_init_device(rndis_device);
1056 if (ret != 0) {
1057 rndis_filter_device_remove(dev);
1058 return ret;
1059 }
1060
1061
1062 size = sizeof(u32);
1063 ret = rndis_filter_query_device(rndis_device,
1064 RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE,
1065 &mtu, &size);
1066 if (ret == 0 && size == sizeof(u32) && mtu < net_device->ndev->mtu)
1067 net_device->ndev->mtu = mtu;
1068
1069
1070 ret = rndis_filter_query_device_mac(rndis_device);
1071 if (ret != 0) {
1072 rndis_filter_device_remove(dev);
1073 return ret;
1074 }
1075
1076 memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
1077
1078
1079
1080
1081 memset(&offloads, 0, sizeof(struct ndis_offload_params));
1082
1083
1084
1085 offloads.ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1086 offloads.tcp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1087 offloads.udp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1088 offloads.tcp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1089 offloads.udp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1090 offloads.lso_v2_ipv4 = NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
1091
1092
1093 ret = rndis_filter_set_offload_params(dev, &offloads);
1094 if (ret)
1095 goto err_dev_remv;
1096
1097 rndis_filter_query_device_link_status(rndis_device);
1098
1099 device_info->link_state = rndis_device->link_state;
1100
1101 dev_info(&dev->device, "Device MAC %pM link state %s\n",
1102 rndis_device->hw_mac_adr,
1103 device_info->link_state ? "down" : "up");
1104
1105 if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5)
1106 return 0;
1107
1108
1109 memset(&rsscap, 0, rsscap_size);
1110 ret = rndis_filter_query_device(rndis_device,
1111 OID_GEN_RECEIVE_SCALE_CAPABILITIES,
1112 &rsscap, &rsscap_size);
1113 if (ret || rsscap.num_recv_que < 2)
1114 goto out;
1115
1116 net_device->max_chn = min_t(u32, VRSS_CHANNEL_MAX, rsscap.num_recv_que);
1117
1118 num_rss_qs = min(device_info->max_num_vrss_chns, net_device->max_chn);
1119
1120
1121
1122
1123
1124 node_cpu_mask = cpumask_of_node(cpu_to_node(dev->channel->target_cpu));
1125 num_possible_rss_qs = cpumask_weight(node_cpu_mask);
1126
1127
1128 if (device_info->num_chn && device_info->num_chn < net_device->max_chn)
1129 net_device->num_chn = device_info->num_chn;
1130 else
1131 net_device->num_chn = min(num_possible_rss_qs, num_rss_qs);
1132
1133 num_rss_qs = net_device->num_chn - 1;
1134 net_device->num_sc_offered = num_rss_qs;
1135
1136 if (net_device->num_chn == 1)
1137 goto out;
1138
1139 net_device->sub_cb_buf = vzalloc((net_device->num_chn - 1) *
1140 NETVSC_PACKET_SIZE);
1141 if (!net_device->sub_cb_buf) {
1142 net_device->num_chn = 1;
1143 dev_info(&dev->device, "No memory for subchannels.\n");
1144 goto out;
1145 }
1146
1147 vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
1148
1149 init_packet = &net_device->channel_init_pkt;
1150 memset(init_packet, 0, sizeof(struct nvsp_message));
1151 init_packet->hdr.msg_type = NVSP_MSG5_TYPE_SUBCHANNEL;
1152 init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE;
1153 init_packet->msg.v5_msg.subchn_req.num_subchannels =
1154 net_device->num_chn - 1;
1155 ret = vmbus_sendpacket(dev->channel, init_packet,
1156 sizeof(struct nvsp_message),
1157 (unsigned long)init_packet,
1158 VM_PKT_DATA_INBAND,
1159 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
1160 if (ret)
1161 goto out;
1162 t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
1163 if (t == 0) {
1164 ret = -ETIMEDOUT;
1165 goto out;
1166 }
1167 if (init_packet->msg.v5_msg.subchn_comp.status !=
1168 NVSP_STAT_SUCCESS) {
1169 ret = -ENODEV;
1170 goto out;
1171 }
1172 net_device->num_chn = 1 +
1173 init_packet->msg.v5_msg.subchn_comp.num_subchannels;
1174
1175 ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn);
1176
1177
1178
1179
1180 spin_lock_irqsave(&net_device->sc_lock, flags);
1181 sc_delta = num_rss_qs - (net_device->num_chn - 1);
1182 net_device->num_sc_offered -= sc_delta;
1183 spin_unlock_irqrestore(&net_device->sc_lock, flags);
1184
1185out:
1186 if (ret) {
1187 net_device->max_chn = 1;
1188 net_device->num_chn = 1;
1189 net_device->num_sc_offered = 0;
1190 }
1191
1192 return 0;
1193
1194err_dev_remv:
1195 rndis_filter_device_remove(dev);
1196 return ret;
1197}
1198
1199void rndis_filter_device_remove(struct hv_device *dev)
1200{
1201 struct netvsc_device *net_dev = hv_get_drvdata(dev);
1202 struct rndis_device *rndis_dev = net_dev->extension;
1203 unsigned long t;
1204
1205
1206
1207
1208 while (net_dev->num_sc_offered > 0) {
1209 t = wait_for_completion_timeout(&net_dev->channel_init_wait,
1210 10 * HZ);
1211 if (t == 0)
1212 WARN(1, "Netvsc: Waiting for sub-channel processing");
1213 }
1214
1215
1216 rndis_filter_halt_device(rndis_dev);
1217
1218 kfree(rndis_dev);
1219 net_dev->extension = NULL;
1220
1221 netvsc_device_remove(dev);
1222}
1223
1224
1225int rndis_filter_open(struct hv_device *dev)
1226{
1227 struct netvsc_device *net_device = hv_get_drvdata(dev);
1228
1229 if (!net_device)
1230 return -EINVAL;
1231
1232 return rndis_filter_open_device(net_device->extension);
1233}
1234
1235int rndis_filter_close(struct hv_device *dev)
1236{
1237 struct netvsc_device *nvdev = hv_get_drvdata(dev);
1238
1239 if (!nvdev)
1240 return -EINVAL;
1241
1242 return rndis_filter_close_device(nvdev->extension);
1243}
1244