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