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