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 <haiyangz@microsoft.com>
19  *   Hank Janssen  <hjanssen@microsoft.com>
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 
29 #include "logging.h"
30 #include "hv_api.h"
31 #include "netvsc_api.h"
32 #include "rndis_filter.h"
33 
34 /* Data types */
35 struct rndis_filter_driver_object {
36 	/* The original driver */
37 	struct netvsc_driver inner_drv;
38 };
39 
40 enum rndis_device_state {
41 	RNDIS_DEV_UNINITIALIZED = 0,
42 	RNDIS_DEV_INITIALIZING,
43 	RNDIS_DEV_INITIALIZED,
44 	RNDIS_DEV_DATAINITIALIZED,
45 };
46 
47 struct rndis_device {
48 	struct netvsc_device *net_dev;
49 
50 	enum rndis_device_state state;
51 	u32 link_stat;
52 	atomic_t new_req_id;
53 
54 	spinlock_t request_lock;
55 	struct list_head req_list;
56 
57 	unsigned char hw_mac_adr[ETH_ALEN];
58 };
59 
60 struct rndis_request {
61 	struct list_head list_ent;
62 	int wait_condition;
63 	wait_queue_head_t wait_event;
64 
65 	/*
66 	 * FIXME: We assumed a fixed size response here. If we do ever need to
67 	 * handle a bigger response, we can either define a max response
68 	 * message or add a response buffer variable above this field
69 	 */
70 	struct rndis_message response_msg;
71 
72 	/* Simplify allocation by having a netvsc packet inline */
73 	struct hv_netvsc_packet	pkt;
74 	struct hv_page_buffer buf;
75 	/* FIXME: We assumed a fixed size request here. */
76 	struct rndis_message request_msg;
77 };
78 
79 
80 struct rndis_filter_packet {
81 	void *completion_ctx;
82 	void (*completion)(void *context);
83 	struct rndis_message msg;
84 };
85 
86 
87 static int rndis_filte_device_add(struct hv_device *dev,
88 				  void *additional_info);
89 
90 static int rndis_filter_device_remove(struct hv_device *dev);
91 
92 static void rndis_filter_cleanup(struct hv_driver *drv);
93 
94 static int rndis_filter_send(struct hv_device *dev,
95 			     struct hv_netvsc_packet *pkt);
96 
97 static void rndis_filter_send_completion(void *ctx);
98 
99 static void rndis_filter_send_request_completion(void *ctx);
100 
101 
102 /* The one and only */
103 static struct rndis_filter_driver_object rndis_filter;
104 
get_rndis_device(void)105 static struct rndis_device *get_rndis_device(void)
106 {
107 	struct rndis_device *device;
108 
109 	device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL);
110 	if (!device)
111 		return NULL;
112 
113 	spin_lock_init(&device->request_lock);
114 
115 	INIT_LIST_HEAD(&device->req_list);
116 
117 	device->state = RNDIS_DEV_UNINITIALIZED;
118 
119 	return device;
120 }
121 
get_rndis_request(struct rndis_device * dev,u32 msg_type,u32 msg_len)122 static struct rndis_request *get_rndis_request(struct rndis_device *dev,
123 					     u32 msg_type,
124 					     u32 msg_len)
125 {
126 	struct rndis_request *request;
127 	struct rndis_message *rndis_msg;
128 	struct rndis_set_request *set;
129 	unsigned long flags;
130 
131 	request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL);
132 	if (!request)
133 		return NULL;
134 
135 	init_waitqueue_head(&request->wait_event);
136 
137 	rndis_msg = &request->request_msg;
138 	rndis_msg->ndis_msg_type = msg_type;
139 	rndis_msg->msg_len = msg_len;
140 
141 	/*
142 	 * Set the request id. This field is always after the rndis header for
143 	 * request/response packet types so we just used the SetRequest as a
144 	 * template
145 	 */
146 	set = &rndis_msg->msg.set_req;
147 	set->req_id = atomic_inc_return(&dev->new_req_id);
148 
149 	/* Add to the request list */
150 	spin_lock_irqsave(&dev->request_lock, flags);
151 	list_add_tail(&request->list_ent, &dev->req_list);
152 	spin_unlock_irqrestore(&dev->request_lock, flags);
153 
154 	return request;
155 }
156 
put_rndis_request(struct rndis_device * dev,struct rndis_request * req)157 static void put_rndis_request(struct rndis_device *dev,
158 			    struct rndis_request *req)
159 {
160 	unsigned long flags;
161 
162 	spin_lock_irqsave(&dev->request_lock, flags);
163 	list_del(&req->list_ent);
164 	spin_unlock_irqrestore(&dev->request_lock, flags);
165 
166 	kfree(req);
167 }
168 
dump_rndis_message(struct rndis_message * rndis_msg)169 static void dump_rndis_message(struct rndis_message *rndis_msg)
170 {
171 	switch (rndis_msg->ndis_msg_type) {
172 	case REMOTE_NDIS_PACKET_MSG:
173 		DPRINT_DBG(NETVSC, "REMOTE_NDIS_PACKET_MSG (len %u, "
174 			   "data offset %u data len %u, # oob %u, "
175 			   "oob offset %u, oob len %u, pkt offset %u, "
176 			   "pkt len %u",
177 			   rndis_msg->msg_len,
178 			   rndis_msg->msg.pkt.data_offset,
179 			   rndis_msg->msg.pkt.data_len,
180 			   rndis_msg->msg.pkt.num_oob_data_elements,
181 			   rndis_msg->msg.pkt.oob_data_offset,
182 			   rndis_msg->msg.pkt.oob_data_len,
183 			   rndis_msg->msg.pkt.per_pkt_info_offset,
184 			   rndis_msg->msg.pkt.per_pkt_info_len);
185 		break;
186 
187 	case REMOTE_NDIS_INITIALIZE_CMPLT:
188 		DPRINT_DBG(NETVSC, "REMOTE_NDIS_INITIALIZE_CMPLT "
189 			"(len %u, id 0x%x, status 0x%x, major %d, minor %d, "
190 			"device flags %d, max xfer size 0x%x, max pkts %u, "
191 			"pkt aligned %u)",
192 			rndis_msg->msg_len,
193 			rndis_msg->msg.init_complete.req_id,
194 			rndis_msg->msg.init_complete.status,
195 			rndis_msg->msg.init_complete.major_ver,
196 			rndis_msg->msg.init_complete.minor_ver,
197 			rndis_msg->msg.init_complete.dev_flags,
198 			rndis_msg->msg.init_complete.max_xfer_size,
199 			rndis_msg->msg.init_complete.
200 			   max_pkt_per_msg,
201 			rndis_msg->msg.init_complete.
202 			   pkt_alignment_factor);
203 		break;
204 
205 	case REMOTE_NDIS_QUERY_CMPLT:
206 		DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT "
207 			"(len %u, id 0x%x, status 0x%x, buf len %u, "
208 			"buf offset %u)",
209 			rndis_msg->msg_len,
210 			rndis_msg->msg.query_complete.req_id,
211 			rndis_msg->msg.query_complete.status,
212 			rndis_msg->msg.query_complete.
213 			   info_buflen,
214 			rndis_msg->msg.query_complete.
215 			   info_buf_offset);
216 		break;
217 
218 	case REMOTE_NDIS_SET_CMPLT:
219 		DPRINT_DBG(NETVSC,
220 			"REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)",
221 			rndis_msg->msg_len,
222 			rndis_msg->msg.set_complete.req_id,
223 			rndis_msg->msg.set_complete.status);
224 		break;
225 
226 	case REMOTE_NDIS_INDICATE_STATUS_MSG:
227 		DPRINT_DBG(NETVSC, "REMOTE_NDIS_INDICATE_STATUS_MSG "
228 			"(len %u, status 0x%x, buf len %u, buf offset %u)",
229 			rndis_msg->msg_len,
230 			rndis_msg->msg.indicate_status.status,
231 			rndis_msg->msg.indicate_status.status_buflen,
232 			rndis_msg->msg.indicate_status.status_buf_offset);
233 		break;
234 
235 	default:
236 		DPRINT_DBG(NETVSC, "0x%x (len %u)",
237 			rndis_msg->ndis_msg_type,
238 			rndis_msg->msg_len);
239 		break;
240 	}
241 }
242 
rndis_filter_send_request(struct rndis_device * dev,struct rndis_request * req)243 static int rndis_filter_send_request(struct rndis_device *dev,
244 				  struct rndis_request *req)
245 {
246 	int ret;
247 	struct hv_netvsc_packet *packet;
248 
249 	/* Setup the packet to send it */
250 	packet = &req->pkt;
251 
252 	packet->is_data_pkt = false;
253 	packet->total_data_buflen = req->request_msg.msg_len;
254 	packet->page_buf_cnt = 1;
255 
256 	packet->page_buf[0].pfn = virt_to_phys(&req->request_msg) >>
257 					PAGE_SHIFT;
258 	packet->page_buf[0].len = req->request_msg.msg_len;
259 	packet->page_buf[0].offset =
260 		(unsigned long)&req->request_msg & (PAGE_SIZE - 1);
261 
262 	packet->completion.send.send_completion_ctx = req;/* packet; */
263 	packet->completion.send.send_completion =
264 		rndis_filter_send_request_completion;
265 	packet->completion.send.send_completion_tid = (unsigned long)dev;
266 
267 	ret = rndis_filter.inner_drv.send(dev->net_dev->dev, packet);
268 	return ret;
269 }
270 
rndis_filter_receive_response(struct rndis_device * dev,struct rndis_message * resp)271 static void rndis_filter_receive_response(struct rndis_device *dev,
272 				       struct rndis_message *resp)
273 {
274 	struct rndis_request *request = NULL;
275 	bool found = false;
276 	unsigned long flags;
277 
278 	spin_lock_irqsave(&dev->request_lock, flags);
279 	list_for_each_entry(request, &dev->req_list, list_ent) {
280 		/*
281 		 * All request/response message contains RequestId as the 1st
282 		 * field
283 		 */
284 		if (request->request_msg.msg.init_req.req_id
285 		    == resp->msg.init_complete.req_id) {
286 			DPRINT_DBG(NETVSC, "found rndis request for "
287 				"this response (id 0x%x req type 0x%x res "
288 				"type 0x%x)",
289 				request->request_msg.msg.
290 				   init_req.req_id,
291 				request->request_msg.ndis_msg_type,
292 				resp->ndis_msg_type);
293 
294 			found = true;
295 			break;
296 		}
297 	}
298 	spin_unlock_irqrestore(&dev->request_lock, flags);
299 
300 	if (found) {
301 		if (resp->msg_len <= sizeof(struct rndis_message)) {
302 			memcpy(&request->response_msg, resp,
303 			       resp->msg_len);
304 		} else {
305 			DPRINT_ERR(NETVSC, "rndis response buffer overflow "
306 				  "detected (size %u max %zu)",
307 				  resp->msg_len,
308 				  sizeof(struct rndis_filter_packet));
309 
310 			if (resp->ndis_msg_type ==
311 			    REMOTE_NDIS_RESET_CMPLT) {
312 				/* does not have a request id field */
313 				request->response_msg.msg.reset_complete.
314 					status = STATUS_BUFFER_OVERFLOW;
315 			} else {
316 				request->response_msg.msg.
317 				init_complete.status =
318 					STATUS_BUFFER_OVERFLOW;
319 			}
320 		}
321 
322 		request->wait_condition = 1;
323 		wake_up(&request->wait_event);
324 	} else {
325 		DPRINT_ERR(NETVSC, "no rndis request found for this response "
326 			   "(id 0x%x res type 0x%x)",
327 			   resp->msg.init_complete.req_id,
328 			   resp->ndis_msg_type);
329 	}
330 }
331 
rndis_filter_receive_indicate_status(struct rndis_device * dev,struct rndis_message * resp)332 static void rndis_filter_receive_indicate_status(struct rndis_device *dev,
333 					     struct rndis_message *resp)
334 {
335 	struct rndis_indicate_status *indicate =
336 			&resp->msg.indicate_status;
337 
338 	if (indicate->status == RNDIS_STATUS_MEDIA_CONNECT) {
339 		rndis_filter.inner_drv.link_status_change(
340 			dev->net_dev->dev, 1);
341 	} else if (indicate->status == RNDIS_STATUS_MEDIA_DISCONNECT) {
342 		rndis_filter.inner_drv.link_status_change(
343 			dev->net_dev->dev, 0);
344 	} else {
345 		/*
346 		 * TODO:
347 		 */
348 	}
349 }
350 
rndis_filter_receive_data(struct rndis_device * dev,struct rndis_message * msg,struct hv_netvsc_packet * pkt)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 
358 	rndis_pkt = &msg->msg.pkt;
359 
360 	/*
361 	 * FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this
362 	 * netvsc packet (ie TotalDataBufferLength != MessageLength)
363 	 */
364 
365 	/* Remove the rndis header and pass it back up the stack */
366 	data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
367 
368 	pkt->total_data_buflen -= data_offset;
369 	pkt->page_buf[0].offset += data_offset;
370 	pkt->page_buf[0].len -= data_offset;
371 
372 	pkt->is_data_pkt = true;
373 
374 	rndis_filter.inner_drv.recv_cb(dev->net_dev->dev,
375 						   pkt);
376 }
377 
rndis_filter_receive(struct hv_device * dev,struct hv_netvsc_packet * pkt)378 static int rndis_filter_receive(struct hv_device *dev,
379 				struct hv_netvsc_packet	*pkt)
380 {
381 	struct netvsc_device *net_dev = dev->ext;
382 	struct rndis_device *rndis_dev;
383 	struct rndis_message rndis_msg;
384 	struct rndis_message *rndis_hdr;
385 
386 	if (!net_dev)
387 		return -EINVAL;
388 
389 	/* Make sure the rndis device state is initialized */
390 	if (!net_dev->extension) {
391 		DPRINT_ERR(NETVSC, "got rndis message but no rndis device..."
392 			  "dropping this message!");
393 		return -1;
394 	}
395 
396 	rndis_dev = (struct rndis_device *)net_dev->extension;
397 	if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
398 		DPRINT_ERR(NETVSC, "got rndis message but rndis device "
399 			   "uninitialized...dropping this message!");
400 		return -1;
401 	}
402 
403 	rndis_hdr = (struct rndis_message *)kmap_atomic(
404 			pfn_to_page(pkt->page_buf[0].pfn), KM_IRQ0);
405 
406 	rndis_hdr = (void *)((unsigned long)rndis_hdr +
407 			pkt->page_buf[0].offset);
408 
409 	/* Make sure we got a valid rndis message */
410 	/*
411 	 * FIXME: There seems to be a bug in set completion msg where its
412 	 * MessageLength is 16 bytes but the ByteCount field in the xfer page
413 	 * range shows 52 bytes
414 	 * */
415 #if 0
416 	if (pkt->total_data_buflen != rndis_hdr->msg_len) {
417 		kunmap_atomic(rndis_hdr - pkt->page_buf[0].offset,
418 			      KM_IRQ0);
419 
420 		DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u "
421 			   "bytes got %u)...dropping this message!",
422 			   rndis_hdr->msg_len,
423 			   pkt->total_data_buflen);
424 		return -1;
425 	}
426 #endif
427 
428 	if ((rndis_hdr->ndis_msg_type != REMOTE_NDIS_PACKET_MSG) &&
429 	    (rndis_hdr->msg_len > sizeof(struct rndis_message))) {
430 		DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow "
431 			   "detected (got %u, max %zu)...marking it an error!",
432 			   rndis_hdr->msg_len,
433 			   sizeof(struct rndis_message));
434 	}
435 
436 	memcpy(&rndis_msg, rndis_hdr,
437 		(rndis_hdr->msg_len > sizeof(struct rndis_message)) ?
438 			sizeof(struct rndis_message) :
439 			rndis_hdr->msg_len);
440 
441 	kunmap_atomic(rndis_hdr - pkt->page_buf[0].offset, KM_IRQ0);
442 
443 	dump_rndis_message(&rndis_msg);
444 
445 	switch (rndis_msg.ndis_msg_type) {
446 	case REMOTE_NDIS_PACKET_MSG:
447 		/* data msg */
448 		rndis_filter_receive_data(rndis_dev, &rndis_msg, pkt);
449 		break;
450 
451 	case REMOTE_NDIS_INITIALIZE_CMPLT:
452 	case REMOTE_NDIS_QUERY_CMPLT:
453 	case REMOTE_NDIS_SET_CMPLT:
454 		/* completion msgs */
455 		rndis_filter_receive_response(rndis_dev, &rndis_msg);
456 		break;
457 
458 	case REMOTE_NDIS_INDICATE_STATUS_MSG:
459 		/* notification msgs */
460 		rndis_filter_receive_indicate_status(rndis_dev, &rndis_msg);
461 		break;
462 	default:
463 		DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)",
464 			   rndis_msg.ndis_msg_type,
465 			   rndis_msg.msg_len);
466 		break;
467 	}
468 
469 	return 0;
470 }
471 
rndis_filter_query_device(struct rndis_device * dev,u32 oid,void * result,u32 * result_size)472 static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
473 				  void *result, u32 *result_size)
474 {
475 	struct rndis_request *request;
476 	u32 inresult_size = *result_size;
477 	struct rndis_query_request *query;
478 	struct rndis_query_complete *query_complete;
479 	int ret = 0;
480 
481 	if (!result)
482 		return -EINVAL;
483 
484 	*result_size = 0;
485 	request = get_rndis_request(dev, REMOTE_NDIS_QUERY_MSG,
486 			RNDIS_MESSAGE_SIZE(struct rndis_query_request));
487 	if (!request) {
488 		ret = -1;
489 		goto Cleanup;
490 	}
491 
492 	/* Setup the rndis query */
493 	query = &request->request_msg.msg.query_req;
494 	query->oid = oid;
495 	query->info_buf_offset = sizeof(struct rndis_query_request);
496 	query->info_buflen = 0;
497 	query->dev_vc_handle = 0;
498 
499 	request->wait_condition = 0;
500 	ret = rndis_filter_send_request(dev, request);
501 	if (ret != 0)
502 		goto Cleanup;
503 
504 	wait_event_timeout(request->wait_event, request->wait_condition,
505 				msecs_to_jiffies(1000));
506 	if (request->wait_condition == 0) {
507 		ret = -ETIMEDOUT;
508 		goto Cleanup;
509 	}
510 
511 	/* Copy the response back */
512 	query_complete = &request->response_msg.msg.query_complete;
513 
514 	if (query_complete->info_buflen > inresult_size) {
515 		ret = -1;
516 		goto Cleanup;
517 	}
518 
519 	memcpy(result,
520 	       (void *)((unsigned long)query_complete +
521 			 query_complete->info_buf_offset),
522 	       query_complete->info_buflen);
523 
524 	*result_size = query_complete->info_buflen;
525 
526 Cleanup:
527 	if (request)
528 		put_rndis_request(dev, request);
529 
530 	return ret;
531 }
532 
rndis_filter_query_device_mac(struct rndis_device * dev)533 static int rndis_filter_query_device_mac(struct rndis_device *dev)
534 {
535 	u32 size = ETH_ALEN;
536 
537 	return rndis_filter_query_device(dev,
538 				      RNDIS_OID_802_3_PERMANENT_ADDRESS,
539 				      dev->hw_mac_adr, &size);
540 }
541 
rndis_filter_query_device_link_status(struct rndis_device * dev)542 static int rndis_filter_query_device_link_status(struct rndis_device *dev)
543 {
544 	u32 size = sizeof(u32);
545 
546 	return rndis_filter_query_device(dev,
547 				      RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
548 				      &dev->link_stat, &size);
549 }
550 
rndis_filter_set_packet_filter(struct rndis_device * dev,u32 new_filter)551 static int rndis_filter_set_packet_filter(struct rndis_device *dev,
552 				      u32 new_filter)
553 {
554 	struct rndis_request *request;
555 	struct rndis_set_request *set;
556 	struct rndis_set_complete *set_complete;
557 	u32 status;
558 	int ret;
559 
560 	request = get_rndis_request(dev, REMOTE_NDIS_SET_MSG,
561 			RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
562 			sizeof(u32));
563 	if (!request) {
564 		ret = -1;
565 		goto Cleanup;
566 	}
567 
568 	/* Setup the rndis set */
569 	set = &request->request_msg.msg.set_req;
570 	set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
571 	set->info_buflen = sizeof(u32);
572 	set->info_buf_offset = sizeof(struct rndis_set_request);
573 
574 	memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
575 	       &new_filter, sizeof(u32));
576 
577 	request->wait_condition = 0;
578 	ret = rndis_filter_send_request(dev, request);
579 	if (ret != 0)
580 		goto Cleanup;
581 
582 	wait_event_timeout(request->wait_event, request->wait_condition,
583 		msecs_to_jiffies(2000));
584 	if (request->wait_condition == 0) {
585 		ret = -1;
586 		DPRINT_ERR(NETVSC, "timeout before we got a set response...");
587 		/*
588 		 * We can't deallocate the request since we may still receive a
589 		 * send completion for it.
590 		 */
591 		goto Exit;
592 	} else {
593 		if (ret > 0)
594 			ret = 0;
595 		set_complete = &request->response_msg.msg.set_complete;
596 		status = set_complete->status;
597 	}
598 
599 Cleanup:
600 	if (request)
601 		put_rndis_request(dev, request);
602 Exit:
603 	return ret;
604 }
605 
rndis_filter_init(struct netvsc_driver * drv)606 int rndis_filter_init(struct netvsc_driver *drv)
607 {
608 	DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd",
609 		   sizeof(struct rndis_filter_packet));
610 
611 	drv->req_ext_size = sizeof(struct rndis_filter_packet);
612 
613 	/* Driver->Context = rndisDriver; */
614 
615 	memset(&rndis_filter, 0, sizeof(struct rndis_filter_driver_object));
616 
617 	/*rndisDriver->Driver = Driver;
618 
619 	ASSERT(Driver->OnLinkStatusChanged);
620 	rndisDriver->OnLinkStatusChanged = Driver->OnLinkStatusChanged;*/
621 
622 	/* Save the original dispatch handlers before we override it */
623 	rndis_filter.inner_drv.base.dev_add = drv->base.dev_add;
624 	rndis_filter.inner_drv.base.dev_rm =
625 					drv->base.dev_rm;
626 	rndis_filter.inner_drv.base.cleanup = drv->base.cleanup;
627 
628 	rndis_filter.inner_drv.send = drv->send;
629 	rndis_filter.inner_drv.recv_cb = drv->recv_cb;
630 	rndis_filter.inner_drv.link_status_change =
631 					drv->link_status_change;
632 
633 	/* Override */
634 	drv->base.dev_add = rndis_filte_device_add;
635 	drv->base.dev_rm = rndis_filter_device_remove;
636 	drv->base.cleanup = rndis_filter_cleanup;
637 	drv->send = rndis_filter_send;
638 	drv->recv_cb = rndis_filter_receive;
639 
640 	return 0;
641 }
642 
rndis_filter_init_device(struct rndis_device * dev)643 static int rndis_filter_init_device(struct rndis_device *dev)
644 {
645 	struct rndis_request *request;
646 	struct rndis_initialize_request *init;
647 	struct rndis_initialize_complete *init_complete;
648 	u32 status;
649 	int ret;
650 
651 	request = get_rndis_request(dev, REMOTE_NDIS_INITIALIZE_MSG,
652 			RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
653 	if (!request) {
654 		ret = -1;
655 		goto Cleanup;
656 	}
657 
658 	/* Setup the rndis set */
659 	init = &request->request_msg.msg.init_req;
660 	init->major_ver = RNDIS_MAJOR_VERSION;
661 	init->minor_ver = RNDIS_MINOR_VERSION;
662 	/* FIXME: Use 1536 - rounded ethernet frame size */
663 	init->max_xfer_size = 2048;
664 
665 	dev->state = RNDIS_DEV_INITIALIZING;
666 
667 	request->wait_condition = 0;
668 	ret = rndis_filter_send_request(dev, request);
669 	if (ret != 0) {
670 		dev->state = RNDIS_DEV_UNINITIALIZED;
671 		goto Cleanup;
672 	}
673 
674 
675 	wait_event_timeout(request->wait_event, request->wait_condition,
676 		msecs_to_jiffies(1000));
677 	if (request->wait_condition == 0) {
678 		ret = -ETIMEDOUT;
679 		goto Cleanup;
680 	}
681 
682 	init_complete = &request->response_msg.msg.init_complete;
683 	status = init_complete->status;
684 	if (status == RNDIS_STATUS_SUCCESS) {
685 		dev->state = RNDIS_DEV_INITIALIZED;
686 		ret = 0;
687 	} else {
688 		dev->state = RNDIS_DEV_UNINITIALIZED;
689 		ret = -1;
690 	}
691 
692 Cleanup:
693 	if (request)
694 		put_rndis_request(dev, request);
695 
696 	return ret;
697 }
698 
rndis_filter_halt_device(struct rndis_device * dev)699 static void rndis_filter_halt_device(struct rndis_device *dev)
700 {
701 	struct rndis_request *request;
702 	struct rndis_halt_request *halt;
703 
704 	/* Attempt to do a rndis device halt */
705 	request = get_rndis_request(dev, REMOTE_NDIS_HALT_MSG,
706 				RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
707 	if (!request)
708 		goto Cleanup;
709 
710 	/* Setup the rndis set */
711 	halt = &request->request_msg.msg.halt_req;
712 	halt->req_id = atomic_inc_return(&dev->new_req_id);
713 
714 	/* Ignore return since this msg is optional. */
715 	rndis_filter_send_request(dev, request);
716 
717 	dev->state = RNDIS_DEV_UNINITIALIZED;
718 
719 Cleanup:
720 	if (request)
721 		put_rndis_request(dev, request);
722 	return;
723 }
724 
rndis_filter_open_device(struct rndis_device * dev)725 static int rndis_filter_open_device(struct rndis_device *dev)
726 {
727 	int ret;
728 
729 	if (dev->state != RNDIS_DEV_INITIALIZED)
730 		return 0;
731 
732 	ret = rndis_filter_set_packet_filter(dev,
733 					 NDIS_PACKET_TYPE_BROADCAST |
734 					 NDIS_PACKET_TYPE_ALL_MULTICAST |
735 					 NDIS_PACKET_TYPE_DIRECTED);
736 	if (ret == 0)
737 		dev->state = RNDIS_DEV_DATAINITIALIZED;
738 
739 	return ret;
740 }
741 
rndis_filter_close_device(struct rndis_device * dev)742 static int rndis_filter_close_device(struct rndis_device *dev)
743 {
744 	int ret;
745 
746 	if (dev->state != RNDIS_DEV_DATAINITIALIZED)
747 		return 0;
748 
749 	ret = rndis_filter_set_packet_filter(dev, 0);
750 	if (ret == 0)
751 		dev->state = RNDIS_DEV_INITIALIZED;
752 
753 	return ret;
754 }
755 
rndis_filte_device_add(struct hv_device * dev,void * additional_info)756 static int rndis_filte_device_add(struct hv_device *dev,
757 				  void *additional_info)
758 {
759 	int ret;
760 	struct netvsc_device *netDevice;
761 	struct rndis_device *rndisDevice;
762 	struct netvsc_device_info *deviceInfo = additional_info;
763 
764 	rndisDevice = get_rndis_device();
765 	if (!rndisDevice)
766 		return -1;
767 
768 	DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice);
769 
770 	/*
771 	 * Let the inner driver handle this first to create the netvsc channel
772 	 * NOTE! Once the channel is created, we may get a receive callback
773 	 * (RndisFilterOnReceive()) before this call is completed
774 	 */
775 	ret = rndis_filter.inner_drv.base.dev_add(dev, additional_info);
776 	if (ret != 0) {
777 		kfree(rndisDevice);
778 		return ret;
779 	}
780 
781 
782 	/* Initialize the rndis device */
783 	netDevice = dev->ext;
784 
785 	netDevice->extension = rndisDevice;
786 	rndisDevice->net_dev = netDevice;
787 
788 	/* Send the rndis initialization message */
789 	ret = rndis_filter_init_device(rndisDevice);
790 	if (ret != 0) {
791 		/*
792 		 * TODO: If rndis init failed, we will need to shut down the
793 		 * channel
794 		 */
795 	}
796 
797 	/* Get the mac address */
798 	ret = rndis_filter_query_device_mac(rndisDevice);
799 	if (ret != 0) {
800 		/*
801 		 * TODO: shutdown rndis device and the channel
802 		 */
803 	}
804 
805 	DPRINT_INFO(NETVSC, "Device 0x%p mac addr %pM",
806 		    rndisDevice, rndisDevice->hw_mac_adr);
807 
808 	memcpy(deviceInfo->mac_adr, rndisDevice->hw_mac_adr, ETH_ALEN);
809 
810 	rndis_filter_query_device_link_status(rndisDevice);
811 
812 	deviceInfo->link_state = rndisDevice->link_stat;
813 	DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice,
814 		    ((deviceInfo->link_state) ? ("down") : ("up")));
815 
816 	return ret;
817 }
818 
rndis_filter_device_remove(struct hv_device * dev)819 static int rndis_filter_device_remove(struct hv_device *dev)
820 {
821 	struct netvsc_device *net_dev = dev->ext;
822 	struct rndis_device *rndis_dev = net_dev->extension;
823 
824 	/* Halt and release the rndis device */
825 	rndis_filter_halt_device(rndis_dev);
826 
827 	kfree(rndis_dev);
828 	net_dev->extension = NULL;
829 
830 	/* Pass control to inner driver to remove the device */
831 	rndis_filter.inner_drv.base.dev_rm(dev);
832 
833 	return 0;
834 }
835 
rndis_filter_cleanup(struct hv_driver * drv)836 static void rndis_filter_cleanup(struct hv_driver *drv)
837 {
838 }
839 
rndis_filter_open(struct hv_device * dev)840 int rndis_filter_open(struct hv_device *dev)
841 {
842 	struct netvsc_device *netDevice = dev->ext;
843 
844 	if (!netDevice)
845 		return -EINVAL;
846 
847 	return rndis_filter_open_device(netDevice->extension);
848 }
849 
rndis_filter_close(struct hv_device * dev)850 int rndis_filter_close(struct hv_device *dev)
851 {
852 	struct netvsc_device *netDevice = dev->ext;
853 
854 	if (!netDevice)
855 		return -EINVAL;
856 
857 	return rndis_filter_close_device(netDevice->extension);
858 }
859 
rndis_filter_send(struct hv_device * dev,struct hv_netvsc_packet * pkt)860 static int rndis_filter_send(struct hv_device *dev,
861 			     struct hv_netvsc_packet *pkt)
862 {
863 	int ret;
864 	struct rndis_filter_packet *filterPacket;
865 	struct rndis_message *rndisMessage;
866 	struct rndis_packet *rndisPacket;
867 	u32 rndisMessageSize;
868 
869 	/* Add the rndis header */
870 	filterPacket = (struct rndis_filter_packet *)pkt->extension;
871 
872 	memset(filterPacket, 0, sizeof(struct rndis_filter_packet));
873 
874 	rndisMessage = &filterPacket->msg;
875 	rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet);
876 
877 	rndisMessage->ndis_msg_type = REMOTE_NDIS_PACKET_MSG;
878 	rndisMessage->msg_len = pkt->total_data_buflen +
879 				      rndisMessageSize;
880 
881 	rndisPacket = &rndisMessage->msg.pkt;
882 	rndisPacket->data_offset = sizeof(struct rndis_packet);
883 	rndisPacket->data_len = pkt->total_data_buflen;
884 
885 	pkt->is_data_pkt = true;
886 	pkt->page_buf[0].pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT;
887 	pkt->page_buf[0].offset =
888 			(unsigned long)rndisMessage & (PAGE_SIZE-1);
889 	pkt->page_buf[0].len = rndisMessageSize;
890 
891 	/* Save the packet send completion and context */
892 	filterPacket->completion = pkt->completion.send.send_completion;
893 	filterPacket->completion_ctx =
894 				pkt->completion.send.send_completion_ctx;
895 
896 	/* Use ours */
897 	pkt->completion.send.send_completion = rndis_filter_send_completion;
898 	pkt->completion.send.send_completion_ctx = filterPacket;
899 
900 	ret = rndis_filter.inner_drv.send(dev, pkt);
901 	if (ret != 0) {
902 		/*
903 		 * Reset the completion to originals to allow retries from
904 		 * above
905 		 */
906 		pkt->completion.send.send_completion =
907 				filterPacket->completion;
908 		pkt->completion.send.send_completion_ctx =
909 				filterPacket->completion_ctx;
910 	}
911 
912 	return ret;
913 }
914 
rndis_filter_send_completion(void * ctx)915 static void rndis_filter_send_completion(void *ctx)
916 {
917 	struct rndis_filter_packet *filterPacket = ctx;
918 
919 	/* Pass it back to the original handler */
920 	filterPacket->completion(filterPacket->completion_ctx);
921 }
922 
923 
rndis_filter_send_request_completion(void * ctx)924 static void rndis_filter_send_request_completion(void *ctx)
925 {
926 	/* Noop */
927 }
928