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