]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/hyperv/rndis_filter.c
x86/mm: Decouple <linux/vmalloc.h> from <asm/io.h>
[karo-tx-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
988         nvscdev = hv_get_drvdata(new_sc->primary_channel->device_obj);
989
990         if (chn_index >= nvscdev->num_chn)
991                 return;
992
993         set_per_channel_state(new_sc, nvscdev->sub_cb_buf + (chn_index - 1) *
994                               NETVSC_PACKET_SIZE);
995
996         ret = vmbus_open(new_sc, nvscdev->ring_size * PAGE_SIZE,
997                          nvscdev->ring_size * PAGE_SIZE, NULL, 0,
998                          netvsc_channel_cb, new_sc);
999
1000         if (ret == 0)
1001                 nvscdev->chn_table[chn_index] = new_sc;
1002 }
1003
1004 int rndis_filter_device_add(struct hv_device *dev,
1005                                   void *additional_info)
1006 {
1007         int ret;
1008         struct netvsc_device *net_device;
1009         struct rndis_device *rndis_device;
1010         struct netvsc_device_info *device_info = additional_info;
1011         struct ndis_offload_params offloads;
1012         struct nvsp_message *init_packet;
1013         unsigned long t;
1014         struct ndis_recv_scale_cap rsscap;
1015         u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
1016         u32 mtu, size;
1017
1018         rndis_device = get_rndis_device();
1019         if (!rndis_device)
1020                 return -ENODEV;
1021
1022         /*
1023          * Let the inner driver handle this first to create the netvsc channel
1024          * NOTE! Once the channel is created, we may get a receive callback
1025          * (RndisFilterOnReceive()) before this call is completed
1026          */
1027         ret = netvsc_device_add(dev, additional_info);
1028         if (ret != 0) {
1029                 kfree(rndis_device);
1030                 return ret;
1031         }
1032
1033
1034         /* Initialize the rndis device */
1035         net_device = hv_get_drvdata(dev);
1036         net_device->max_chn = 1;
1037         net_device->num_chn = 1;
1038
1039         net_device->extension = rndis_device;
1040         rndis_device->net_dev = net_device;
1041
1042         /* Send the rndis initialization message */
1043         ret = rndis_filter_init_device(rndis_device);
1044         if (ret != 0) {
1045                 rndis_filter_device_remove(dev);
1046                 return ret;
1047         }
1048
1049         /* Get the MTU from the host */
1050         size = sizeof(u32);
1051         ret = rndis_filter_query_device(rndis_device,
1052                                         RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE,
1053                                         &mtu, &size);
1054         if (ret == 0 && size == sizeof(u32))
1055                 net_device->ndev->mtu = mtu;
1056
1057         /* Get the mac address */
1058         ret = rndis_filter_query_device_mac(rndis_device);
1059         if (ret != 0) {
1060                 rndis_filter_device_remove(dev);
1061                 return ret;
1062         }
1063
1064         memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
1065
1066         /* Turn on the offloads; the host supports all of the relevant
1067          * offloads.
1068          */
1069         memset(&offloads, 0, sizeof(struct ndis_offload_params));
1070         /* A value of zero means "no change"; now turn on what we
1071          * want.
1072          */
1073         offloads.ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1074         offloads.tcp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1075         offloads.udp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1076         offloads.tcp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1077         offloads.udp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1078         offloads.lso_v2_ipv4 = NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
1079
1080
1081         ret = rndis_filter_set_offload_params(dev, &offloads);
1082         if (ret)
1083                 goto err_dev_remv;
1084
1085         rndis_filter_query_device_link_status(rndis_device);
1086
1087         device_info->link_state = rndis_device->link_state;
1088
1089         dev_info(&dev->device, "Device MAC %pM link state %s\n",
1090                  rndis_device->hw_mac_adr,
1091                  device_info->link_state ? "down" : "up");
1092
1093         if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5)
1094                 return 0;
1095
1096         /* vRSS setup */
1097         memset(&rsscap, 0, rsscap_size);
1098         ret = rndis_filter_query_device(rndis_device,
1099                                         OID_GEN_RECEIVE_SCALE_CAPABILITIES,
1100                                         &rsscap, &rsscap_size);
1101         if (ret || rsscap.num_recv_que < 2)
1102                 goto out;
1103
1104         net_device->max_chn = rsscap.num_recv_que;
1105         net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ?
1106                                num_online_cpus() : rsscap.num_recv_que;
1107         if (net_device->num_chn == 1)
1108                 goto out;
1109
1110         net_device->sub_cb_buf = vzalloc((net_device->num_chn - 1) *
1111                                          NETVSC_PACKET_SIZE);
1112         if (!net_device->sub_cb_buf) {
1113                 net_device->num_chn = 1;
1114                 dev_info(&dev->device, "No memory for subchannels.\n");
1115                 goto out;
1116         }
1117
1118         vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
1119
1120         init_packet = &net_device->channel_init_pkt;
1121         memset(init_packet, 0, sizeof(struct nvsp_message));
1122         init_packet->hdr.msg_type = NVSP_MSG5_TYPE_SUBCHANNEL;
1123         init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE;
1124         init_packet->msg.v5_msg.subchn_req.num_subchannels =
1125                                                 net_device->num_chn - 1;
1126         ret = vmbus_sendpacket(dev->channel, init_packet,
1127                                sizeof(struct nvsp_message),
1128                                (unsigned long)init_packet,
1129                                VM_PKT_DATA_INBAND,
1130                                VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
1131         if (ret)
1132                 goto out;
1133         t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
1134         if (t == 0) {
1135                 ret = -ETIMEDOUT;
1136                 goto out;
1137         }
1138         if (init_packet->msg.v5_msg.subchn_comp.status !=
1139             NVSP_STAT_SUCCESS) {
1140                 ret = -ENODEV;
1141                 goto out;
1142         }
1143         net_device->num_chn = 1 +
1144                 init_packet->msg.v5_msg.subchn_comp.num_subchannels;
1145
1146         ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn);
1147
1148 out:
1149         if (ret) {
1150                 net_device->max_chn = 1;
1151                 net_device->num_chn = 1;
1152         }
1153         return 0; /* return 0 because primary channel can be used alone */
1154
1155 err_dev_remv:
1156         rndis_filter_device_remove(dev);
1157         return ret;
1158 }
1159
1160 void rndis_filter_device_remove(struct hv_device *dev)
1161 {
1162         struct netvsc_device *net_dev = hv_get_drvdata(dev);
1163         struct rndis_device *rndis_dev = net_dev->extension;
1164
1165         /* Halt and release the rndis device */
1166         rndis_filter_halt_device(rndis_dev);
1167
1168         kfree(rndis_dev);
1169         net_dev->extension = NULL;
1170
1171         netvsc_device_remove(dev);
1172 }
1173
1174
1175 int rndis_filter_open(struct hv_device *dev)
1176 {
1177         struct netvsc_device *net_device = hv_get_drvdata(dev);
1178
1179         if (!net_device)
1180                 return -EINVAL;
1181
1182         return rndis_filter_open_device(net_device->extension);
1183 }
1184
1185 int rndis_filter_close(struct hv_device *dev)
1186 {
1187         struct netvsc_device *nvdev = hv_get_drvdata(dev);
1188
1189         if (!nvdev)
1190                 return -EINVAL;
1191
1192         return rndis_filter_close_device(nvdev->extension);
1193 }