Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rndis_filter.c
Go to the documentation of this file.
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, write to the Free Software Foundation, Inc., 59 Temple
15  * Place - Suite 330, Boston, MA 02111-1307 USA.
16  *
17  * Authors:
18  * Haiyang Zhang <[email protected]>
19  * Hank Janssen <[email protected]>
20  */
21 #include <linux/kernel.h>
22 #include <linux/sched.h>
23 #include <linux/wait.h>
24 #include <linux/highmem.h>
25 #include <linux/slab.h>
26 #include <linux/io.h>
27 #include <linux/if_ether.h>
28 #include <linux/netdevice.h>
29 #include <linux/if_vlan.h>
30 #include <linux/nls.h>
31 
32 #include "hyperv_net.h"
33 
34 
35 #define RNDIS_EXT_LEN 100
36 struct rndis_request {
39 
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  */
48 
49  /* Simplify allocation by having a netvsc packet inline */
51  /* Set 2 pages for rndis requests crossing page boundary */
52  struct hv_page_buffer buf[2];
53 
55  /*
56  * The buffer for the extended info after the RNDIS request message.
57  * It is referenced and sized in a similar way as response_ext.
58  */
60 };
61 
62 static void rndis_filter_send_completion(void *ctx);
63 
64 static void rndis_filter_send_request_completion(void *ctx);
65 
66 
67 
68 static struct rndis_device *get_rndis_device(void)
69 {
70  struct rndis_device *device;
71 
72  device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL);
73  if (!device)
74  return NULL;
75 
76  spin_lock_init(&device->request_lock);
77 
78  INIT_LIST_HEAD(&device->req_list);
79 
81 
82  return device;
83 }
84 
85 static struct rndis_request *get_rndis_request(struct rndis_device *dev,
86  u32 msg_type,
87  u32 msg_len)
88 {
89  struct rndis_request *request;
90  struct rndis_message *rndis_msg;
91  struct rndis_set_request *set;
92  unsigned long flags;
93 
94  request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL);
95  if (!request)
96  return NULL;
97 
98  init_completion(&request->wait_event);
99 
100  rndis_msg = &request->request_msg;
101  rndis_msg->ndis_msg_type = msg_type;
102  rndis_msg->msg_len = msg_len;
103 
104  /*
105  * Set the request id. This field is always after the rndis header for
106  * request/response packet types so we just used the SetRequest as a
107  * template
108  */
109  set = &rndis_msg->msg.set_req;
110  set->req_id = atomic_inc_return(&dev->new_req_id);
111 
112  /* Add to the request list */
113  spin_lock_irqsave(&dev->request_lock, flags);
114  list_add_tail(&request->list_ent, &dev->req_list);
115  spin_unlock_irqrestore(&dev->request_lock, flags);
116 
117  return request;
118 }
119 
120 static void put_rndis_request(struct rndis_device *dev,
121  struct rndis_request *req)
122 {
123  unsigned long flags;
124 
125  spin_lock_irqsave(&dev->request_lock, flags);
126  list_del(&req->list_ent);
127  spin_unlock_irqrestore(&dev->request_lock, flags);
128 
129  kfree(req);
130 }
131 
132 static void dump_rndis_message(struct hv_device *hv_dev,
133  struct rndis_message *rndis_msg)
134 {
135  struct net_device *netdev;
136  struct netvsc_device *net_device;
137 
138  net_device = hv_get_drvdata(hv_dev);
139  netdev = net_device->ndev;
140 
141  switch (rndis_msg->ndis_msg_type) {
142  case RNDIS_MSG_PACKET:
143  netdev_dbg(netdev, "RNDIS_MSG_PACKET (len %u, "
144  "data offset %u data len %u, # oob %u, "
145  "oob offset %u, oob len %u, pkt offset %u, "
146  "pkt len %u\n",
147  rndis_msg->msg_len,
148  rndis_msg->msg.pkt.data_offset,
149  rndis_msg->msg.pkt.data_len,
150  rndis_msg->msg.pkt.num_oob_data_elements,
151  rndis_msg->msg.pkt.oob_data_offset,
152  rndis_msg->msg.pkt.oob_data_len,
153  rndis_msg->msg.pkt.per_pkt_info_offset,
154  rndis_msg->msg.pkt.per_pkt_info_len);
155  break;
156 
157  case RNDIS_MSG_INIT_C:
158  netdev_dbg(netdev, "RNDIS_MSG_INIT_C "
159  "(len %u, id 0x%x, status 0x%x, major %d, minor %d, "
160  "device flags %d, max xfer size 0x%x, max pkts %u, "
161  "pkt aligned %u)\n",
162  rndis_msg->msg_len,
163  rndis_msg->msg.init_complete.req_id,
164  rndis_msg->msg.init_complete.status,
165  rndis_msg->msg.init_complete.major_ver,
166  rndis_msg->msg.init_complete.minor_ver,
167  rndis_msg->msg.init_complete.dev_flags,
168  rndis_msg->msg.init_complete.max_xfer_size,
169  rndis_msg->msg.init_complete.
170  max_pkt_per_msg,
171  rndis_msg->msg.init_complete.
172  pkt_alignment_factor);
173  break;
174 
175  case RNDIS_MSG_QUERY_C:
176  netdev_dbg(netdev, "RNDIS_MSG_QUERY_C "
177  "(len %u, id 0x%x, status 0x%x, buf len %u, "
178  "buf offset %u)\n",
179  rndis_msg->msg_len,
180  rndis_msg->msg.query_complete.req_id,
181  rndis_msg->msg.query_complete.status,
182  rndis_msg->msg.query_complete.
183  info_buflen,
184  rndis_msg->msg.query_complete.
185  info_buf_offset);
186  break;
187 
188  case RNDIS_MSG_SET_C:
189  netdev_dbg(netdev,
190  "RNDIS_MSG_SET_C (len %u, id 0x%x, status 0x%x)\n",
191  rndis_msg->msg_len,
192  rndis_msg->msg.set_complete.req_id,
193  rndis_msg->msg.set_complete.status);
194  break;
195 
196  case RNDIS_MSG_INDICATE:
197  netdev_dbg(netdev, "RNDIS_MSG_INDICATE "
198  "(len %u, status 0x%x, buf len %u, buf offset %u)\n",
199  rndis_msg->msg_len,
200  rndis_msg->msg.indicate_status.status,
201  rndis_msg->msg.indicate_status.status_buflen,
202  rndis_msg->msg.indicate_status.status_buf_offset);
203  break;
204 
205  default:
206  netdev_dbg(netdev, "0x%x (len %u)\n",
207  rndis_msg->ndis_msg_type,
208  rndis_msg->msg_len);
209  break;
210  }
211 }
212 
213 static int rndis_filter_send_request(struct rndis_device *dev,
214  struct rndis_request *req)
215 {
216  int ret;
217  struct hv_netvsc_packet *packet;
218 
219  /* Setup the packet to send it */
220  packet = &req->pkt;
221 
222  packet->is_data_pkt = false;
223  packet->total_data_buflen = req->request_msg.msg_len;
224  packet->page_buf_cnt = 1;
225 
226  packet->page_buf[0].pfn = virt_to_phys(&req->request_msg) >>
227  PAGE_SHIFT;
228  packet->page_buf[0].len = req->request_msg.msg_len;
229  packet->page_buf[0].offset =
230  (unsigned long)&req->request_msg & (PAGE_SIZE - 1);
231 
232  /* Add one page_buf when request_msg crossing page boundary */
233  if (packet->page_buf[0].offset + packet->page_buf[0].len > PAGE_SIZE) {
234  packet->page_buf_cnt++;
235  packet->page_buf[0].len = PAGE_SIZE -
236  packet->page_buf[0].offset;
237  packet->page_buf[1].pfn = virt_to_phys((void *)&req->request_msg
238  + packet->page_buf[0].len) >> PAGE_SHIFT;
239  packet->page_buf[1].offset = 0;
240  packet->page_buf[1].len = req->request_msg.msg_len -
241  packet->page_buf[0].len;
242  }
243 
244  packet->completion.send.send_completion_ctx = req;/* packet; */
245  packet->completion.send.send_completion =
246  rndis_filter_send_request_completion;
247  packet->completion.send.send_completion_tid = (unsigned long)dev;
248 
249  ret = netvsc_send(dev->net_dev->dev, packet);
250  return ret;
251 }
252 
253 static void rndis_filter_receive_response(struct rndis_device *dev,
254  struct rndis_message *resp)
255 {
256  struct rndis_request *request = NULL;
257  bool found = false;
258  unsigned long flags;
259  struct net_device *ndev;
260 
261  ndev = dev->net_dev->ndev;
262 
263  spin_lock_irqsave(&dev->request_lock, flags);
264  list_for_each_entry(request, &dev->req_list, list_ent) {
265  /*
266  * All request/response message contains RequestId as the 1st
267  * field
268  */
269  if (request->request_msg.msg.init_req.req_id
270  == resp->msg.init_complete.req_id) {
271  found = true;
272  break;
273  }
274  }
275  spin_unlock_irqrestore(&dev->request_lock, flags);
276 
277  if (found) {
278  if (resp->msg_len <=
279  sizeof(struct rndis_message) + RNDIS_EXT_LEN) {
280  memcpy(&request->response_msg, resp,
281  resp->msg_len);
282  } else {
283  netdev_err(ndev,
284  "rndis response buffer overflow "
285  "detected (size %u max %zu)\n",
286  resp->msg_len,
287  sizeof(struct rndis_filter_packet));
288 
289  if (resp->ndis_msg_type ==
291  /* does not have a request id field */
292  request->response_msg.msg.reset_complete.
294  } else {
295  request->response_msg.msg.
296  init_complete.status =
298  }
299  }
300 
301  complete(&request->wait_event);
302  } else {
303  netdev_err(ndev,
304  "no rndis request found for this response "
305  "(id 0x%x res type 0x%x)\n",
306  resp->msg.init_complete.req_id,
307  resp->ndis_msg_type);
308  }
309 }
310 
311 static void rndis_filter_receive_indicate_status(struct rndis_device *dev,
312  struct rndis_message *resp)
313 {
314  struct rndis_indicate_status *indicate =
315  &resp->msg.indicate_status;
316 
317  if (indicate->status == RNDIS_STATUS_MEDIA_CONNECT) {
319  dev->net_dev->dev, 1);
320  } else if (indicate->status == RNDIS_STATUS_MEDIA_DISCONNECT) {
322  dev->net_dev->dev, 0);
323  } else {
324  /*
325  * TODO:
326  */
327  }
328 }
329 
330 /*
331  * Get the Per-Packet-Info with the specified type
332  * return NULL if not found.
333  */
334 static inline void *rndis_get_ppi(struct rndis_packet *rpkt, u32 type)
335 {
336  struct rndis_per_packet_info *ppi;
337  int len;
338 
339  if (rpkt->per_pkt_info_offset == 0)
340  return NULL;
341 
342  ppi = (struct rndis_per_packet_info *)((ulong)rpkt +
343  rpkt->per_pkt_info_offset);
344  len = rpkt->per_pkt_info_len;
345 
346  while (len > 0) {
347  if (ppi->type == type)
348  return (void *)((ulong)ppi + ppi->ppi_offset);
349  len -= ppi->size;
350  ppi = (struct rndis_per_packet_info *)((ulong)ppi + ppi->size);
351  }
352 
353  return NULL;
354 }
355 
356 static void rndis_filter_receive_data(struct rndis_device *dev,
357  struct rndis_message *msg,
358  struct hv_netvsc_packet *pkt)
359 {
360  struct rndis_packet *rndis_pkt;
362  struct ndis_pkt_8021q_info *vlan;
363 
364  rndis_pkt = &msg->msg.pkt;
365 
366  /*
367  * FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this
368  * netvsc packet (ie TotalDataBufferLength != MessageLength)
369  */
370 
371  /* Remove the rndis header and pass it back up the stack */
372  data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
373 
375 
376  /*
377  * Make sure we got a valid RNDIS message, now total_data_buflen
378  * should be the data packet size plus the trailer padding size
379  */
380  if (pkt->total_data_buflen < rndis_pkt->data_len) {
381  netdev_err(dev->net_dev->ndev, "rndis message buffer "
382  "overflow detected (got %u, min %u)"
383  "...dropping this message!\n",
384  pkt->total_data_buflen, rndis_pkt->data_len);
385  return;
386  }
387 
388  /*
389  * Remove the rndis trailer padding from rndis packet message
390  * rndis_pkt->data_len tell us the real data length, we only copy
391  * the data packet to the stack, without the rndis trailer padding
392  */
393  pkt->total_data_buflen = rndis_pkt->data_len;
394  pkt->data = (void *)((unsigned long)pkt->data + data_offset);
395 
396  pkt->is_data_pkt = true;
397 
398  vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);
399  if (vlan) {
400  pkt->vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid |
401  (vlan->pri << VLAN_PRIO_SHIFT);
402  } else {
403  pkt->vlan_tci = 0;
404  }
405 
406  netvsc_recv_callback(dev->net_dev->dev, pkt);
407 }
408 
409 int rndis_filter_receive(struct hv_device *dev,
410  struct hv_netvsc_packet *pkt)
411 {
412  struct netvsc_device *net_dev = hv_get_drvdata(dev);
413  struct rndis_device *rndis_dev;
414  struct rndis_message *rndis_msg;
415  struct net_device *ndev;
416  int ret = 0;
417 
418  if (!net_dev) {
419  ret = -EINVAL;
420  goto exit;
421  }
422 
423  ndev = net_dev->ndev;
424 
425  /* Make sure the rndis device state is initialized */
426  if (!net_dev->extension) {
427  netdev_err(ndev, "got rndis message but no rndis device - "
428  "dropping this message!\n");
429  ret = -ENODEV;
430  goto exit;
431  }
432 
433  rndis_dev = (struct rndis_device *)net_dev->extension;
434  if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
435  netdev_err(ndev, "got rndis message but rndis device "
436  "uninitialized...dropping this message!\n");
437  ret = -ENODEV;
438  goto exit;
439  }
440 
441  rndis_msg = pkt->data;
442 
443  dump_rndis_message(dev, rndis_msg);
444 
445  switch (rndis_msg->ndis_msg_type) {
446  case RNDIS_MSG_PACKET:
447  /* data msg */
448  rndis_filter_receive_data(rndis_dev, rndis_msg, pkt);
449  break;
450 
451  case RNDIS_MSG_INIT_C:
452  case RNDIS_MSG_QUERY_C:
453  case RNDIS_MSG_SET_C:
454  /* completion msgs */
455  rndis_filter_receive_response(rndis_dev, rndis_msg);
456  break;
457 
458  case RNDIS_MSG_INDICATE:
459  /* notification msgs */
460  rndis_filter_receive_indicate_status(rndis_dev, rndis_msg);
461  break;
462  default:
463  netdev_err(ndev,
464  "unhandled rndis message (type %u len %u)\n",
465  rndis_msg->ndis_msg_type,
466  rndis_msg->msg_len);
467  break;
468  }
469 
470 exit:
471  if (ret != 0)
472  pkt->status = NVSP_STAT_FAIL;
473 
474  return ret;
475 }
476 
477 static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
478  void *result, u32 *result_size)
479 {
480  struct rndis_request *request;
481  u32 inresult_size = *result_size;
482  struct rndis_query_request *query;
483  struct rndis_query_complete *query_complete;
484  int ret = 0;
485  int t;
486 
487  if (!result)
488  return -EINVAL;
489 
490  *result_size = 0;
491  request = get_rndis_request(dev, RNDIS_MSG_QUERY,
493  if (!request) {
494  ret = -ENOMEM;
495  goto cleanup;
496  }
497 
498  /* Setup the rndis query */
499  query = &request->request_msg.msg.query_req;
500  query->oid = oid;
501  query->info_buf_offset = sizeof(struct rndis_query_request);
502  query->info_buflen = 0;
503  query->dev_vc_handle = 0;
504 
505  ret = rndis_filter_send_request(dev, request);
506  if (ret != 0)
507  goto cleanup;
508 
509  t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
510  if (t == 0) {
511  ret = -ETIMEDOUT;
512  goto cleanup;
513  }
514 
515  /* Copy the response back */
516  query_complete = &request->response_msg.msg.query_complete;
517 
518  if (query_complete->info_buflen > inresult_size) {
519  ret = -1;
520  goto cleanup;
521  }
522 
523  memcpy(result,
524  (void *)((unsigned long)query_complete +
525  query_complete->info_buf_offset),
526  query_complete->info_buflen);
527 
528  *result_size = query_complete->info_buflen;
529 
530 cleanup:
531  if (request)
532  put_rndis_request(dev, request);
533 
534  return ret;
535 }
536 
537 static int rndis_filter_query_device_mac(struct rndis_device *dev)
538 {
539  u32 size = ETH_ALEN;
540 
541  return rndis_filter_query_device(dev,
543  dev->hw_mac_adr, &size);
544 }
545 
546 #define NWADR_STR "NetworkAddress"
547 #define NWADR_STRLEN 14
548 
549 int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac)
550 {
551  struct netvsc_device *nvdev = hv_get_drvdata(hdev);
552  struct rndis_device *rdev = nvdev->extension;
553  struct net_device *ndev = nvdev->ndev;
554  struct rndis_request *request;
555  struct rndis_set_request *set;
557  wchar_t *cfg_nwadr, *cfg_mac;
558  struct rndis_set_complete *set_complete;
559  char macstr[2*ETH_ALEN+1];
560  u32 extlen = sizeof(struct rndis_config_parameter_info) +
561  2*NWADR_STRLEN + 4*ETH_ALEN;
562  int ret, t;
563 
564  request = get_rndis_request(rdev, RNDIS_MSG_SET,
565  RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
566  if (!request)
567  return -ENOMEM;
568 
569  set = &request->request_msg.msg.set_req;
571  set->info_buflen = extlen;
572  set->info_buf_offset = sizeof(struct rndis_set_request);
573  set->dev_vc_handle = 0;
574 
575  cpi = (struct rndis_config_parameter_info *)((ulong)set +
576  set->info_buf_offset);
577  cpi->parameter_name_offset =
578  sizeof(struct rndis_config_parameter_info);
579  /* Multiply by 2 because host needs 2 bytes (utf16) for each char */
584  /* Multiply by 4 because each MAC byte displayed as 2 utf16 chars */
586 
587  cfg_nwadr = (wchar_t *)((ulong)cpi + cpi->parameter_name_offset);
588  cfg_mac = (wchar_t *)((ulong)cpi + cpi->parameter_value_offset);
590  cfg_nwadr, NWADR_STRLEN);
591  if (ret < 0)
592  goto cleanup;
593  snprintf(macstr, 2*ETH_ALEN+1, "%pm", mac);
594  ret = utf8s_to_utf16s(macstr, 2*ETH_ALEN, UTF16_HOST_ENDIAN,
595  cfg_mac, 2*ETH_ALEN);
596  if (ret < 0)
597  goto cleanup;
598 
599  ret = rndis_filter_send_request(rdev, request);
600  if (ret != 0)
601  goto cleanup;
602 
603  t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
604  if (t == 0) {
605  netdev_err(ndev, "timeout before we got a set response...\n");
606  /*
607  * can't put_rndis_request, since we may still receive a
608  * send-completion.
609  */
610  return -EBUSY;
611  } else {
612  set_complete = &request->response_msg.msg.set_complete;
613  if (set_complete->status != RNDIS_STATUS_SUCCESS)
614  ret = -EINVAL;
615  }
616 
617 cleanup:
618  put_rndis_request(rdev, request);
619  return ret;
620 }
621 
622 
623 static int rndis_filter_query_device_link_status(struct rndis_device *dev)
624 {
625  u32 size = sizeof(u32);
627  int ret;
628 
629  ret = rndis_filter_query_device(dev,
631  &link_status, &size);
632  dev->link_state = (link_status != 0) ? true : false;
633 
634  return ret;
635 }
636 
637 int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
638 {
639  struct rndis_request *request;
640  struct rndis_set_request *set;
641  struct rndis_set_complete *set_complete;
642  u32 status;
643  int ret, t;
644  struct net_device *ndev;
645 
646  ndev = dev->net_dev->ndev;
647 
648  request = get_rndis_request(dev, RNDIS_MSG_SET,
650  sizeof(u32));
651  if (!request) {
652  ret = -ENOMEM;
653  goto cleanup;
654  }
655 
656  /* Setup the rndis set */
657  set = &request->request_msg.msg.set_req;
659  set->info_buflen = sizeof(u32);
660  set->info_buf_offset = sizeof(struct rndis_set_request);
661 
662  memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
663  &new_filter, sizeof(u32));
664 
665  ret = rndis_filter_send_request(dev, request);
666  if (ret != 0)
667  goto cleanup;
668 
669  t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
670 
671  if (t == 0) {
672  netdev_err(ndev,
673  "timeout before we got a set response...\n");
674  ret = -ETIMEDOUT;
675  /*
676  * We can't deallocate the request since we may still receive a
677  * send completion for it.
678  */
679  goto exit;
680  } else {
681  set_complete = &request->response_msg.msg.set_complete;
682  status = set_complete->status;
683  }
684 
685 cleanup:
686  if (request)
687  put_rndis_request(dev, request);
688 exit:
689  return ret;
690 }
691 
692 
693 static int rndis_filter_init_device(struct rndis_device *dev)
694 {
695  struct rndis_request *request;
697  struct rndis_initialize_complete *init_complete;
698  u32 status;
699  int ret, t;
700 
701  request = get_rndis_request(dev, RNDIS_MSG_INIT,
703  if (!request) {
704  ret = -ENOMEM;
705  goto cleanup;
706  }
707 
708  /* Setup the rndis set */
709  init = &request->request_msg.msg.init_req;
712  init->max_xfer_size = 0x4000;
713 
715 
716  ret = rndis_filter_send_request(dev, request);
717  if (ret != 0) {
719  goto cleanup;
720  }
721 
722 
723  t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
724 
725  if (t == 0) {
726  ret = -ETIMEDOUT;
727  goto cleanup;
728  }
729 
730  init_complete = &request->response_msg.msg.init_complete;
731  status = init_complete->status;
732  if (status == RNDIS_STATUS_SUCCESS) {
734  ret = 0;
735  } else {
737  ret = -EINVAL;
738  }
739 
740 cleanup:
741  if (request)
742  put_rndis_request(dev, request);
743 
744  return ret;
745 }
746 
747 static void rndis_filter_halt_device(struct rndis_device *dev)
748 {
749  struct rndis_request *request;
750  struct rndis_halt_request *halt;
751  struct netvsc_device *nvdev = dev->net_dev;
752  struct hv_device *hdev = nvdev->dev;
753  ulong flags;
754 
755  /* Attempt to do a rndis device halt */
756  request = get_rndis_request(dev, RNDIS_MSG_HALT,
758  if (!request)
759  goto cleanup;
760 
761  /* Setup the rndis set */
762  halt = &request->request_msg.msg.halt_req;
763  halt->req_id = atomic_inc_return(&dev->new_req_id);
764 
765  /* Ignore return since this msg is optional. */
766  rndis_filter_send_request(dev, request);
767 
769 
770 cleanup:
771  spin_lock_irqsave(&hdev->channel->inbound_lock, flags);
772  nvdev->destroy = true;
773  spin_unlock_irqrestore(&hdev->channel->inbound_lock, flags);
774 
775  /* Wait for all send completions */
776  wait_event(nvdev->wait_drain,
777  atomic_read(&nvdev->num_outstanding_sends) == 0);
778 
779  if (request)
780  put_rndis_request(dev, request);
781  return;
782 }
783 
784 static int rndis_filter_open_device(struct rndis_device *dev)
785 {
786  int ret;
787 
788  if (dev->state != RNDIS_DEV_INITIALIZED)
789  return 0;
790 
795  if (ret == 0)
797 
798  return ret;
799 }
800 
801 static int rndis_filter_close_device(struct rndis_device *dev)
802 {
803  int ret;
804 
805  if (dev->state != RNDIS_DEV_DATAINITIALIZED)
806  return 0;
807 
808  ret = rndis_filter_set_packet_filter(dev, 0);
809  if (ret == 0)
811 
812  return ret;
813 }
814 
815 int rndis_filter_device_add(struct hv_device *dev,
816  void *additional_info)
817 {
818  int ret;
819  struct netvsc_device *net_device;
820  struct rndis_device *rndis_device;
821  struct netvsc_device_info *device_info = additional_info;
822 
823  rndis_device = get_rndis_device();
824  if (!rndis_device)
825  return -ENODEV;
826 
827  /*
828  * Let the inner driver handle this first to create the netvsc channel
829  * NOTE! Once the channel is created, we may get a receive callback
830  * (RndisFilterOnReceive()) before this call is completed
831  */
832  ret = netvsc_device_add(dev, additional_info);
833  if (ret != 0) {
834  kfree(rndis_device);
835  return ret;
836  }
837 
838 
839  /* Initialize the rndis device */
840  net_device = hv_get_drvdata(dev);
841 
842  net_device->extension = rndis_device;
843  rndis_device->net_dev = net_device;
844 
845  /* Send the rndis initialization message */
846  ret = rndis_filter_init_device(rndis_device);
847  if (ret != 0) {
849  return ret;
850  }
851 
852  /* Get the mac address */
853  ret = rndis_filter_query_device_mac(rndis_device);
854  if (ret != 0) {
856  return ret;
857  }
858 
859  memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
860 
861  rndis_filter_query_device_link_status(rndis_device);
862 
863  device_info->link_state = rndis_device->link_state;
864 
865  dev_info(&dev->device, "Device MAC %pM link state %s\n",
866  rndis_device->hw_mac_adr,
867  device_info->link_state ? "down" : "up");
868 
869  return ret;
870 }
871 
872 void rndis_filter_device_remove(struct hv_device *dev)
873 {
874  struct netvsc_device *net_dev = hv_get_drvdata(dev);
875  struct rndis_device *rndis_dev = net_dev->extension;
876 
877  /* Halt and release the rndis device */
878  rndis_filter_halt_device(rndis_dev);
879 
880  kfree(rndis_dev);
881  net_dev->extension = NULL;
882 
884 }
885 
886 
887 int rndis_filter_open(struct hv_device *dev)
888 {
889  struct netvsc_device *net_device = hv_get_drvdata(dev);
890 
891  if (!net_device)
892  return -EINVAL;
893 
894  return rndis_filter_open_device(net_device->extension);
895 }
896 
897 int rndis_filter_close(struct hv_device *dev)
898 {
899  struct netvsc_device *nvdev = hv_get_drvdata(dev);
900 
901  if (!nvdev)
902  return -EINVAL;
903 
904  return rndis_filter_close_device(nvdev->extension);
905 }
906 
907 int rndis_filter_send(struct hv_device *dev,
908  struct hv_netvsc_packet *pkt)
909 {
910  int ret;
911  struct rndis_filter_packet *filter_pkt;
912  struct rndis_message *rndis_msg;
913  struct rndis_packet *rndis_pkt;
914  u32 rndis_msg_size;
915  bool isvlan = pkt->vlan_tci & VLAN_TAG_PRESENT;
916 
917  /* Add the rndis header */
918  filter_pkt = (struct rndis_filter_packet *)pkt->extension;
919 
920  rndis_msg = &filter_pkt->msg;
921  rndis_msg_size = RNDIS_MESSAGE_SIZE(struct rndis_packet);
922  if (isvlan)
923  rndis_msg_size += NDIS_VLAN_PPI_SIZE;
924 
925  rndis_msg->ndis_msg_type = RNDIS_MSG_PACKET;
926  rndis_msg->msg_len = pkt->total_data_buflen +
927  rndis_msg_size;
928 
929  rndis_pkt = &rndis_msg->msg.pkt;
930  rndis_pkt->data_offset = sizeof(struct rndis_packet);
931  if (isvlan)
932  rndis_pkt->data_offset += NDIS_VLAN_PPI_SIZE;
933  rndis_pkt->data_len = pkt->total_data_buflen;
934 
935  if (isvlan) {
936  struct rndis_per_packet_info *ppi;
937  struct ndis_pkt_8021q_info *vlan;
938 
939  rndis_pkt->per_pkt_info_offset = sizeof(struct rndis_packet);
941 
942  ppi = (struct rndis_per_packet_info *)((ulong)rndis_pkt +
943  rndis_pkt->per_pkt_info_offset);
944  ppi->size = NDIS_VLAN_PPI_SIZE;
945  ppi->type = IEEE_8021Q_INFO;
946  ppi->ppi_offset = sizeof(struct rndis_per_packet_info);
947 
948  vlan = (struct ndis_pkt_8021q_info *)((ulong)ppi +
949  ppi->ppi_offset);
950  vlan->vlanid = pkt->vlan_tci & VLAN_VID_MASK;
951  vlan->pri = (pkt->vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
952  }
953 
954  pkt->is_data_pkt = true;
955  pkt->page_buf[0].pfn = virt_to_phys(rndis_msg) >> PAGE_SHIFT;
956  pkt->page_buf[0].offset =
957  (unsigned long)rndis_msg & (PAGE_SIZE-1);
958  pkt->page_buf[0].len = rndis_msg_size;
959 
960  /* Add one page_buf if the rndis msg goes beyond page boundary */
961  if (pkt->page_buf[0].offset + rndis_msg_size > PAGE_SIZE) {
962  int i;
963  for (i = pkt->page_buf_cnt; i > 1; i--)
964  pkt->page_buf[i] = pkt->page_buf[i-1];
965  pkt->page_buf_cnt++;
966  pkt->page_buf[0].len = PAGE_SIZE - pkt->page_buf[0].offset;
967  pkt->page_buf[1].pfn = virt_to_phys((void *)((ulong)
968  rndis_msg + pkt->page_buf[0].len)) >> PAGE_SHIFT;
969  pkt->page_buf[1].offset = 0;
970  pkt->page_buf[1].len = rndis_msg_size - pkt->page_buf[0].len;
971  }
972 
973  /* Save the packet send completion and context */
974  filter_pkt->completion = pkt->completion.send.send_completion;
975  filter_pkt->completion_ctx =
976  pkt->completion.send.send_completion_ctx;
977 
978  /* Use ours */
979  pkt->completion.send.send_completion = rndis_filter_send_completion;
980  pkt->completion.send.send_completion_ctx = filter_pkt;
981 
982  ret = netvsc_send(dev, pkt);
983  if (ret != 0) {
984  /*
985  * Reset the completion to originals to allow retries from
986  * above
987  */
988  pkt->completion.send.send_completion =
989  filter_pkt->completion;
990  pkt->completion.send.send_completion_ctx =
991  filter_pkt->completion_ctx;
992  }
993 
994  return ret;
995 }
996 
997 static void rndis_filter_send_completion(void *ctx)
998 {
999  struct rndis_filter_packet *filter_pkt = ctx;
1000 
1001  /* Pass it back to the original handler */
1002  filter_pkt->completion(filter_pkt->completion_ctx);
1003 }
1004 
1005 
1006 static void rndis_filter_send_request_completion(void *ctx)
1007 {
1008  /* Noop */
1009 }