rndis_filter.c 35.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * Copyright (c) 2009, Microsoft Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * 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 17 18 19
 *
 * Authors:
 *   Haiyang Zhang <haiyangz@microsoft.com>
 *   Hank Janssen  <hjanssen@microsoft.com>
 */
20
#include <linux/kernel.h>
21 22
#include <linux/sched.h>
#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>
S
stephen hemminger 已提交
31
#include <linux/rtnetlink.h>
32

33
#include "hyperv_net.h"
34

35
static void rndis_set_multicast(struct work_struct *w);
36

37
#define RNDIS_EXT_LEN PAGE_SIZE
38
struct rndis_request {
39
	struct list_head list_ent;
40
	struct completion  wait_event;
41

42
	struct rndis_message response_msg;
43
	/*
44 45 46 47
	 * The buffer for extended info after the RNDIS response message. It's
	 * referenced based on the data offset in the RNDIS message. Its size
	 * is enough for current needs, and should be sufficient for the near
	 * future.
48
	 */
49
	u8 response_ext[RNDIS_EXT_LEN];
50

51
	/* Simplify allocation by having a netvsc packet inline */
52
	struct hv_netvsc_packet	pkt;
53

54
	struct rndis_message request_msg;
55
	/*
56 57
	 * The buffer for the extended info after the RNDIS request message.
	 * It is referenced and sized in a similar way as response_ext.
58
	 */
59
	u8 request_ext[RNDIS_EXT_LEN];
60
};
61

62 63 64 65 66 67 68 69
static const u8 netvsc_hash_key[NETVSC_HASH_KEYLEN] = {
	0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
	0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
	0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
	0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
	0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
};

70
static struct rndis_device *get_rndis_device(void)
71
{
72
	struct rndis_device *device;
73

74
	device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL);
75 76 77
	if (!device)
		return NULL;

78
	spin_lock_init(&device->request_lock);
79

80
	INIT_LIST_HEAD(&device->req_list);
81
	INIT_WORK(&device->mcast_work, rndis_set_multicast);
82

83
	device->state = RNDIS_DEV_UNINITIALIZED;
84 85 86 87

	return device;
}

88 89 90 91 92 93 94 95
static struct netvsc_device *
net_device_to_netvsc_device(struct net_device *ndev)
{
	struct net_device_context *net_device_ctx = netdev_priv(ndev);

	return rtnl_dereference(net_device_ctx->nvdev);
}

96
static struct rndis_request *get_rndis_request(struct rndis_device *dev,
97 98
					     u32 msg_type,
					     u32 msg_len)
99
{
100
	struct rndis_request *request;
101
	struct rndis_message *rndis_msg;
102
	struct rndis_set_request *set;
103
	unsigned long flags;
104

105
	request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL);
106 107 108
	if (!request)
		return NULL;

109
	init_completion(&request->wait_event);
110

111
	rndis_msg = &request->request_msg;
112 113
	rndis_msg->ndis_msg_type = msg_type;
	rndis_msg->msg_len = msg_len;
114

115 116
	request->pkt.q_idx = 0;

117 118 119 120 121
	/*
	 * Set the request id. This field is always after the rndis header for
	 * request/response packet types so we just used the SetRequest as a
	 * template
	 */
122 123
	set = &rndis_msg->msg.set_req;
	set->req_id = atomic_inc_return(&dev->new_req_id);
124

125
	/* Add to the request list */
126 127 128
	spin_lock_irqsave(&dev->request_lock, flags);
	list_add_tail(&request->list_ent, &dev->req_list);
	spin_unlock_irqrestore(&dev->request_lock, flags);
129 130 131 132

	return request;
}

133
static void put_rndis_request(struct rndis_device *dev,
134
			    struct rndis_request *req)
135
{
136 137
	unsigned long flags;

138 139 140
	spin_lock_irqsave(&dev->request_lock, flags);
	list_del(&req->list_ent);
	spin_unlock_irqrestore(&dev->request_lock, flags);
141

142
	kfree(req);
143 144
}

145
static void dump_rndis_message(struct hv_device *hv_dev,
146
			       const struct rndis_message *rndis_msg)
147
{
148
	struct net_device *netdev = hv_get_drvdata(hv_dev);
149

150
	switch (rndis_msg->ndis_msg_type) {
151 152
	case RNDIS_MSG_PACKET:
		netdev_dbg(netdev, "RNDIS_MSG_PACKET (len %u, "
153 154
			   "data offset %u data len %u, # oob %u, "
			   "oob offset %u, oob len %u, pkt offset %u, "
155
			   "pkt len %u\n",
156 157 158 159 160 161 162 163
			   rndis_msg->msg_len,
			   rndis_msg->msg.pkt.data_offset,
			   rndis_msg->msg.pkt.data_len,
			   rndis_msg->msg.pkt.num_oob_data_elements,
			   rndis_msg->msg.pkt.oob_data_offset,
			   rndis_msg->msg.pkt.oob_data_len,
			   rndis_msg->msg.pkt.per_pkt_info_offset,
			   rndis_msg->msg.pkt.per_pkt_info_len);
164 165
		break;

166 167
	case RNDIS_MSG_INIT_C:
		netdev_dbg(netdev, "RNDIS_MSG_INIT_C "
168 169
			"(len %u, id 0x%x, status 0x%x, major %d, minor %d, "
			"device flags %d, max xfer size 0x%x, max pkts %u, "
170
			"pkt aligned %u)\n",
171 172 173 174 175 176 177 178 179 180 181
			rndis_msg->msg_len,
			rndis_msg->msg.init_complete.req_id,
			rndis_msg->msg.init_complete.status,
			rndis_msg->msg.init_complete.major_ver,
			rndis_msg->msg.init_complete.minor_ver,
			rndis_msg->msg.init_complete.dev_flags,
			rndis_msg->msg.init_complete.max_xfer_size,
			rndis_msg->msg.init_complete.
			   max_pkt_per_msg,
			rndis_msg->msg.init_complete.
			   pkt_alignment_factor);
182 183
		break;

184 185
	case RNDIS_MSG_QUERY_C:
		netdev_dbg(netdev, "RNDIS_MSG_QUERY_C "
186
			"(len %u, id 0x%x, status 0x%x, buf len %u, "
187
			"buf offset %u)\n",
188 189 190 191 192 193 194
			rndis_msg->msg_len,
			rndis_msg->msg.query_complete.req_id,
			rndis_msg->msg.query_complete.status,
			rndis_msg->msg.query_complete.
			   info_buflen,
			rndis_msg->msg.query_complete.
			   info_buf_offset);
195 196
		break;

197
	case RNDIS_MSG_SET_C:
198
		netdev_dbg(netdev,
199
			"RNDIS_MSG_SET_C (len %u, id 0x%x, status 0x%x)\n",
200 201 202
			rndis_msg->msg_len,
			rndis_msg->msg.set_complete.req_id,
			rndis_msg->msg.set_complete.status);
203 204
		break;

205 206
	case RNDIS_MSG_INDICATE:
		netdev_dbg(netdev, "RNDIS_MSG_INDICATE "
207
			"(len %u, status 0x%x, buf len %u, buf offset %u)\n",
208 209 210 211
			rndis_msg->msg_len,
			rndis_msg->msg.indicate_status.status,
			rndis_msg->msg.indicate_status.status_buflen,
			rndis_msg->msg.indicate_status.status_buf_offset);
212 213 214
		break;

	default:
215
		netdev_dbg(netdev, "0x%x (len %u)\n",
216 217
			rndis_msg->ndis_msg_type,
			rndis_msg->msg_len);
218 219 220 221
		break;
	}
}

222
static int rndis_filter_send_request(struct rndis_device *dev,
223
				  struct rndis_request *req)
224
{
225
	int ret;
226
	struct hv_netvsc_packet *packet;
227
	struct hv_page_buffer page_buf[2];
228
	struct hv_page_buffer *pb = page_buf;
229
	struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
230

231
	/* Setup the packet to send it */
232
	packet = &req->pkt;
233

234
	packet->total_data_buflen = req->request_msg.msg_len;
235
	packet->page_buf_cnt = 1;
236

237
	pb[0].pfn = virt_to_phys(&req->request_msg) >>
238
					PAGE_SHIFT;
239 240
	pb[0].len = req->request_msg.msg_len;
	pb[0].offset =
241
		(unsigned long)&req->request_msg & (PAGE_SIZE - 1);
242

243
	/* Add one page_buf when request_msg crossing page boundary */
244
	if (pb[0].offset + pb[0].len > PAGE_SIZE) {
245
		packet->page_buf_cnt++;
246 247 248 249 250 251 252
		pb[0].len = PAGE_SIZE -
			pb[0].offset;
		pb[1].pfn = virt_to_phys((void *)&req->request_msg
			+ pb[0].len) >> PAGE_SHIFT;
		pb[1].offset = 0;
		pb[1].len = req->request_msg.msg_len -
			pb[0].len;
253 254
	}

255
	ret = netvsc_send(net_device_ctx, packet, NULL, &pb, NULL);
256 257 258
	return ret;
}

259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
static void rndis_set_link_state(struct rndis_device *rdev,
				 struct rndis_request *request)
{
	u32 link_status;
	struct rndis_query_complete *query_complete;

	query_complete = &request->response_msg.msg.query_complete;

	if (query_complete->status == RNDIS_STATUS_SUCCESS &&
	    query_complete->info_buflen == sizeof(u32)) {
		memcpy(&link_status, (void *)((unsigned long)query_complete +
		       query_complete->info_buf_offset), sizeof(u32));
		rdev->link_state = link_status != 0;
	}
}

275
static void rndis_filter_receive_response(struct rndis_device *dev,
276
				       struct rndis_message *resp)
277
{
278
	struct rndis_request *request = NULL;
279
	bool found = false;
280
	unsigned long flags;
281
	struct net_device *ndev = dev->ndev;
282

283 284
	spin_lock_irqsave(&dev->request_lock, flags);
	list_for_each_entry(request, &dev->req_list, list_ent) {
285 286 287 288
		/*
		 * All request/response message contains RequestId as the 1st
		 * field
		 */
289 290
		if (request->request_msg.msg.init_req.req_id
		    == resp->msg.init_complete.req_id) {
291
			found = true;
292 293 294
			break;
		}
	}
295
	spin_unlock_irqrestore(&dev->request_lock, flags);
296

297
	if (found) {
298 299
		if (resp->msg_len <=
		    sizeof(struct rndis_message) + RNDIS_EXT_LEN) {
300
			memcpy(&request->response_msg, resp,
301
			       resp->msg_len);
302 303 304 305
			if (request->request_msg.ndis_msg_type ==
			    RNDIS_MSG_QUERY && request->request_msg.msg.
			    query_req.oid == RNDIS_OID_GEN_MEDIA_CONNECT_STATUS)
				rndis_set_link_state(dev, request);
306
		} else {
307
			netdev_err(ndev,
308 309 310
				"rndis response buffer overflow "
				"detected (size %u max %zu)\n",
				resp->msg_len,
311
				sizeof(struct rndis_message));
312

313
			if (resp->ndis_msg_type ==
314
			    RNDIS_MSG_RESET_C) {
315
				/* does not have a request id field */
316
				request->response_msg.msg.reset_complete.
317
					status = RNDIS_STATUS_BUFFER_OVERFLOW;
318
			} else {
319 320
				request->response_msg.msg.
				init_complete.status =
321
					RNDIS_STATUS_BUFFER_OVERFLOW;
322 323 324
			}
		}

325
		complete(&request->wait_event);
326
	} else {
327
		netdev_err(ndev,
328 329 330 331
			"no rndis request found for this response "
			"(id 0x%x res type 0x%x)\n",
			resp->msg.init_complete.req_id,
			resp->ndis_msg_type);
332 333 334
	}
}

335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
/*
 * Get the Per-Packet-Info with the specified type
 * return NULL if not found.
 */
static inline void *rndis_get_ppi(struct rndis_packet *rpkt, u32 type)
{
	struct rndis_per_packet_info *ppi;
	int len;

	if (rpkt->per_pkt_info_offset == 0)
		return NULL;

	ppi = (struct rndis_per_packet_info *)((ulong)rpkt +
		rpkt->per_pkt_info_offset);
	len = rpkt->per_pkt_info_len;

	while (len > 0) {
		if (ppi->type == type)
			return (void *)((ulong)ppi + ppi->ppi_offset);
		len -= ppi->size;
		ppi = (struct rndis_per_packet_info *)((ulong)ppi + ppi->size);
	}

	return NULL;
}

361 362 363 364 365
static int rndis_filter_receive_data(struct net_device *ndev,
				     struct rndis_device *dev,
				     struct rndis_message *msg,
				     struct vmbus_channel *channel,
				     void *data, u32 data_buflen)
366
{
367 368 369
	struct rndis_packet *rndis_pkt = &msg->msg.pkt;
	const struct ndis_tcp_ip_checksum_info *csum_info;
	const struct ndis_pkt_8021q_info *vlan;
370
	u32 data_offset;
371

372
	/* Remove the rndis header and pass it back up the stack */
373
	data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
374

375
	data_buflen -= data_offset;
376 377 378 379 380

	/*
	 * Make sure we got a valid RNDIS message, now total_data_buflen
	 * should be the data packet size plus the trailer padding size
	 */
381
	if (unlikely(data_buflen < rndis_pkt->data_len)) {
382
		netdev_err(dev->ndev, "rndis message buffer "
383 384
			   "overflow detected (got %u, min %u)"
			   "...dropping this message!\n",
385
			   data_buflen, rndis_pkt->data_len);
386
		return NVSP_STAT_FAIL;
387 388
	}

389 390
	vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);

391 392 393 394 395
	/*
	 * Remove the rndis trailer padding from rndis packet message
	 * rndis_pkt->data_len tell us the real data length, we only copy
	 * the data packet to the stack, without the rndis trailer padding
	 */
396
	data = (void *)((unsigned long)data + data_offset);
397
	csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO);
398 399 400
	return netvsc_recv_callback(ndev, channel,
				    data, rndis_pkt->data_len,
				    csum_info, vlan);
401 402
}

403 404 405 406 407
int rndis_filter_receive(struct net_device *ndev,
			 struct netvsc_device *net_dev,
			 struct hv_device *dev,
			 struct vmbus_channel *channel,
			 void *data, u32 buflen)
408
{
409
	struct net_device_context *net_device_ctx = netdev_priv(ndev);
410 411
	struct rndis_device *rndis_dev = net_dev->extension;
	struct rndis_message *rndis_msg = data;
412

413
	/* Make sure the rndis device state is initialized */
414 415 416 417
	if (unlikely(!rndis_dev)) {
		netif_err(net_device_ctx, rx_err, ndev,
			  "got rndis message but no rndis device!\n");
		return NVSP_STAT_FAIL;
418 419
	}

420 421 422 423
	if (unlikely(rndis_dev->state == RNDIS_DEV_UNINITIALIZED)) {
		netif_err(net_device_ctx, rx_err, ndev,
			  "got rndis message uninitialized\n");
		return NVSP_STAT_FAIL;
424 425
	}

426
	if (netif_msg_rx_status(net_device_ctx))
427
		dump_rndis_message(dev, rndis_msg);
428

429
	switch (rndis_msg->ndis_msg_type) {
430
	case RNDIS_MSG_PACKET:
431 432
		return rndis_filter_receive_data(ndev, rndis_dev, rndis_msg,
						 channel, data, buflen);
433 434 435
	case RNDIS_MSG_INIT_C:
	case RNDIS_MSG_QUERY_C:
	case RNDIS_MSG_SET_C:
436
		/* completion msgs */
437
		rndis_filter_receive_response(rndis_dev, rndis_msg);
438 439
		break;

440
	case RNDIS_MSG_INDICATE:
441
		/* notification msgs */
442
		netvsc_linkstatus_callback(dev, rndis_msg);
443 444
		break;
	default:
445
		netdev_err(ndev,
446
			"unhandled rndis message (type %u len %u)\n",
447 448
			   rndis_msg->ndis_msg_type,
			   rndis_msg->msg_len);
449 450 451
		break;
	}

452
	return 0;
453 454
}

455
static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
456
				  void *result, u32 *result_size)
457
{
458
	struct rndis_request *request;
459
	u32 inresult_size = *result_size;
460
	struct rndis_query_request *query;
461
	struct rndis_query_complete *query_complete;
462
	int ret = 0;
463

464
	if (!result)
465
		return -EINVAL;
466

467
	*result_size = 0;
468
	request = get_rndis_request(dev, RNDIS_MSG_QUERY,
469 470
			RNDIS_MESSAGE_SIZE(struct rndis_query_request));
	if (!request) {
471
		ret = -ENOMEM;
472
		goto cleanup;
473 474
	}

475
	/* Setup the rndis query */
476 477 478 479 480
	query = &request->request_msg.msg.query_req;
	query->oid = oid;
	query->info_buf_offset = sizeof(struct rndis_query_request);
	query->info_buflen = 0;
	query->dev_vc_handle = 0;
481

482 483
	if (oid == OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES) {
		struct net_device_context *ndevctx = netdev_priv(dev->ndev);
484
		struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
		struct ndis_offload *hwcaps;
		u32 nvsp_version = nvdev->nvsp_version;
		u8 ndis_rev;
		size_t size;

		if (nvsp_version >= NVSP_PROTOCOL_VERSION_5) {
			ndis_rev = NDIS_OFFLOAD_PARAMETERS_REVISION_3;
			size = NDIS_OFFLOAD_SIZE;
		} else if (nvsp_version >= NVSP_PROTOCOL_VERSION_4) {
			ndis_rev = NDIS_OFFLOAD_PARAMETERS_REVISION_2;
			size = NDIS_OFFLOAD_SIZE_6_1;
		} else {
			ndis_rev = NDIS_OFFLOAD_PARAMETERS_REVISION_1;
			size = NDIS_OFFLOAD_SIZE_6_0;
		}

		request->request_msg.msg_len += size;
		query->info_buflen = size;
		hwcaps = (struct ndis_offload *)
			((unsigned long)query + query->info_buf_offset);

		hwcaps->header.type = NDIS_OBJECT_TYPE_OFFLOAD;
		hwcaps->header.revision = ndis_rev;
		hwcaps->header.size = size;

	} else if (oid == OID_GEN_RECEIVE_SCALE_CAPABILITIES) {
511 512 513 514 515 516 517 518 519 520 521 522
		struct ndis_recv_scale_cap *cap;

		request->request_msg.msg_len +=
			sizeof(struct ndis_recv_scale_cap);
		query->info_buflen = sizeof(struct ndis_recv_scale_cap);
		cap = (struct ndis_recv_scale_cap *)((unsigned long)query +
						     query->info_buf_offset);
		cap->hdr.type = NDIS_OBJECT_TYPE_RSS_CAPABILITIES;
		cap->hdr.rev = NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2;
		cap->hdr.size = sizeof(struct ndis_recv_scale_cap);
	}

523
	ret = rndis_filter_send_request(dev, request);
524
	if (ret != 0)
525
		goto cleanup;
526

527
	wait_for_completion(&request->wait_event);
528

529
	/* Copy the response back */
530
	query_complete = &request->response_msg.msg.query_complete;
531

532
	if (query_complete->info_buflen > inresult_size) {
533
		ret = -1;
534
		goto cleanup;
535 536
	}

537 538
	memcpy(result,
	       (void *)((unsigned long)query_complete +
539 540
			 query_complete->info_buf_offset),
	       query_complete->info_buflen);
541

542
	*result_size = query_complete->info_buflen;
543

544
cleanup:
545
	if (request)
546
		put_rndis_request(dev, request);
547 548 549 550

	return ret;
}

551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
/* Get the hardware offload capabilities */
static int
rndis_query_hwcaps(struct rndis_device *dev, struct ndis_offload *caps)
{
	u32 caps_len = sizeof(*caps);
	int ret;

	memset(caps, 0, sizeof(*caps));

	ret = rndis_filter_query_device(dev,
					OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES,
					caps, &caps_len);
	if (ret)
		return ret;

	if (caps->header.type != NDIS_OBJECT_TYPE_OFFLOAD) {
		netdev_warn(dev->ndev, "invalid NDIS objtype %#x\n",
			    caps->header.type);
		return -EINVAL;
	}

	if (caps->header.revision < NDIS_OFFLOAD_PARAMETERS_REVISION_1) {
		netdev_warn(dev->ndev, "invalid NDIS objrev %x\n",
			    caps->header.revision);
		return -EINVAL;
	}

	if (caps->header.size > caps_len ||
	    caps->header.size < NDIS_OFFLOAD_SIZE_6_0) {
		netdev_warn(dev->ndev,
			    "invalid NDIS objsize %u, data size %u\n",
			    caps->header.size, caps_len);
		return -EINVAL;
	}

	return 0;
}

589
static int rndis_filter_query_device_mac(struct rndis_device *dev)
590
{
591
	u32 size = ETH_ALEN;
592

593
	return rndis_filter_query_device(dev,
594
				      RNDIS_OID_802_3_PERMANENT_ADDRESS,
595
				      dev->hw_mac_adr, &size);
596 597
}

598 599 600
#define NWADR_STR "NetworkAddress"
#define NWADR_STRLEN 14

601
int rndis_filter_set_device_mac(struct net_device *ndev, char *mac)
602
{
603
	struct netvsc_device *nvdev = net_device_to_netvsc_device(ndev);
604 605 606 607 608 609 610 611 612
	struct rndis_device *rdev = nvdev->extension;
	struct rndis_request *request;
	struct rndis_set_request *set;
	struct rndis_config_parameter_info *cpi;
	wchar_t *cfg_nwadr, *cfg_mac;
	struct rndis_set_complete *set_complete;
	char macstr[2*ETH_ALEN+1];
	u32 extlen = sizeof(struct rndis_config_parameter_info) +
		2*NWADR_STRLEN + 4*ETH_ALEN;
613
	int ret;
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653

	request = get_rndis_request(rdev, RNDIS_MSG_SET,
		RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
	if (!request)
		return -ENOMEM;

	set = &request->request_msg.msg.set_req;
	set->oid = RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER;
	set->info_buflen = extlen;
	set->info_buf_offset = sizeof(struct rndis_set_request);
	set->dev_vc_handle = 0;

	cpi = (struct rndis_config_parameter_info *)((ulong)set +
		set->info_buf_offset);
	cpi->parameter_name_offset =
		sizeof(struct rndis_config_parameter_info);
	/* Multiply by 2 because host needs 2 bytes (utf16) for each char */
	cpi->parameter_name_length = 2*NWADR_STRLEN;
	cpi->parameter_type = RNDIS_CONFIG_PARAM_TYPE_STRING;
	cpi->parameter_value_offset =
		cpi->parameter_name_offset + cpi->parameter_name_length;
	/* Multiply by 4 because each MAC byte displayed as 2 utf16 chars */
	cpi->parameter_value_length = 4*ETH_ALEN;

	cfg_nwadr = (wchar_t *)((ulong)cpi + cpi->parameter_name_offset);
	cfg_mac = (wchar_t *)((ulong)cpi + cpi->parameter_value_offset);
	ret = utf8s_to_utf16s(NWADR_STR, NWADR_STRLEN, UTF16_HOST_ENDIAN,
			      cfg_nwadr, NWADR_STRLEN);
	if (ret < 0)
		goto cleanup;
	snprintf(macstr, 2*ETH_ALEN+1, "%pm", mac);
	ret = utf8s_to_utf16s(macstr, 2*ETH_ALEN, UTF16_HOST_ENDIAN,
			      cfg_mac, 2*ETH_ALEN);
	if (ret < 0)
		goto cleanup;

	ret = rndis_filter_send_request(rdev, request);
	if (ret != 0)
		goto cleanup;

654 655 656 657 658 659 660
	wait_for_completion(&request->wait_event);

	set_complete = &request->response_msg.msg.set_complete;
	if (set_complete->status != RNDIS_STATUS_SUCCESS) {
		netdev_err(ndev, "Fail to set MAC on host side:0x%x\n",
			   set_complete->status);
		ret = -EINVAL;
661 662 663 664 665 666 667
	}

cleanup:
	put_rndis_request(rdev, request);
	return ret;
}

L
Lad, Prabhakar 已提交
668
static int
669
rndis_filter_set_offload_params(struct net_device *ndev,
670
				struct netvsc_device *nvdev,
671 672 673 674 675 676 677 678
				struct ndis_offload_params *req_offloads)
{
	struct rndis_device *rdev = nvdev->extension;
	struct rndis_request *request;
	struct rndis_set_request *set;
	struct ndis_offload_params *offload_params;
	struct rndis_set_complete *set_complete;
	u32 extlen = sizeof(struct ndis_offload_params);
679
	int ret;
680 681 682 683 684 685 686 687 688 689
	u32 vsp_version = nvdev->nvsp_version;

	if (vsp_version <= NVSP_PROTOCOL_VERSION_4) {
		extlen = VERSION_4_OFFLOAD_SIZE;
		/* On NVSP_PROTOCOL_VERSION_4 and below, we do not support
		 * UDP checksum offload.
		 */
		req_offloads->udp_ip_v4_csum = 0;
		req_offloads->udp_ip_v6_csum = 0;
	}
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712

	request = get_rndis_request(rdev, RNDIS_MSG_SET,
		RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
	if (!request)
		return -ENOMEM;

	set = &request->request_msg.msg.set_req;
	set->oid = OID_TCP_OFFLOAD_PARAMETERS;
	set->info_buflen = extlen;
	set->info_buf_offset = sizeof(struct rndis_set_request);
	set->dev_vc_handle = 0;

	offload_params = (struct ndis_offload_params *)((ulong)set +
				set->info_buf_offset);
	*offload_params = *req_offloads;
	offload_params->header.type = NDIS_OBJECT_TYPE_DEFAULT;
	offload_params->header.revision = NDIS_OFFLOAD_PARAMETERS_REVISION_3;
	offload_params->header.size = extlen;

	ret = rndis_filter_send_request(rdev, request);
	if (ret != 0)
		goto cleanup;

713 714 715 716 717 718
	wait_for_completion(&request->wait_event);
	set_complete = &request->response_msg.msg.set_complete;
	if (set_complete->status != RNDIS_STATUS_SUCCESS) {
		netdev_err(ndev, "Fail to set offload on host side:0x%x\n",
			   set_complete->status);
		ret = -EINVAL;
719 720 721 722 723 724
	}

cleanup:
	put_rndis_request(rdev, request);
	return ret;
}
725

726 727
int rndis_filter_set_rss_param(struct rndis_device *rdev,
			       const u8 *rss_key, int num_queue)
728
{
729
	struct net_device *ndev = rdev->ndev;
730 731 732 733
	struct rndis_request *request;
	struct rndis_set_request *set;
	struct rndis_set_complete *set_complete;
	u32 extlen = sizeof(struct ndis_recv_scale_param) +
734
		     4 * ITAB_NUM + NETVSC_HASH_KEYLEN;
735 736 737
	struct ndis_recv_scale_param *rssp;
	u32 *itab;
	u8 *keyp;
738
	int i, ret;
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757

	request = get_rndis_request(
			rdev, RNDIS_MSG_SET,
			RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
	if (!request)
		return -ENOMEM;

	set = &request->request_msg.msg.set_req;
	set->oid = OID_GEN_RECEIVE_SCALE_PARAMETERS;
	set->info_buflen = extlen;
	set->info_buf_offset = sizeof(struct rndis_set_request);
	set->dev_vc_handle = 0;

	rssp = (struct ndis_recv_scale_param *)(set + 1);
	rssp->hdr.type = NDIS_OBJECT_TYPE_RSS_PARAMETERS;
	rssp->hdr.rev = NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2;
	rssp->hdr.size = sizeof(struct ndis_recv_scale_param);
	rssp->flag = 0;
	rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
758 759
			 NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 |
			 NDIS_HASH_TCP_IPV6;
760 761
	rssp->indirect_tabsize = 4*ITAB_NUM;
	rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
762
	rssp->hashkey_size = NETVSC_HASH_KEYLEN;
763 764 765 766 767 768
	rssp->kashkey_offset = rssp->indirect_taboffset +
			       rssp->indirect_tabsize;

	/* Set indirection table entries */
	itab = (u32 *)(rssp + 1);
	for (i = 0; i < ITAB_NUM; i++)
769
		itab[i] = rdev->ind_table[i];
770 771 772

	/* Set hask key values */
	keyp = (u8 *)((unsigned long)rssp + rssp->kashkey_offset);
773
	memcpy(keyp, rss_key, NETVSC_HASH_KEYLEN);
774 775 776 777 778

	ret = rndis_filter_send_request(rdev, request);
	if (ret != 0)
		goto cleanup;

779 780
	wait_for_completion(&request->wait_event);
	set_complete = &request->response_msg.msg.set_complete;
781 782 783
	if (set_complete->status == RNDIS_STATUS_SUCCESS)
		memcpy(rdev->rss_key, rss_key, NETVSC_HASH_KEYLEN);
	else {
784 785 786
		netdev_err(ndev, "Fail to set RSS parameters:0x%x\n",
			   set_complete->status);
		ret = -EINVAL;
787 788 789 790 791 792 793
	}

cleanup:
	put_rndis_request(rdev, request);
	return ret;
}

794
static int rndis_filter_query_device_link_status(struct rndis_device *dev)
795
{
796
	u32 size = sizeof(u32);
797 798
	u32 link_status;
	int ret;
799

800
	ret = rndis_filter_query_device(dev,
801
				      RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
802 803 804
				      &link_status, &size);

	return ret;
805 806
}

807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
static int rndis_filter_query_link_speed(struct rndis_device *dev)
{
	u32 size = sizeof(u32);
	u32 link_speed;
	struct net_device_context *ndc;
	int ret;

	ret = rndis_filter_query_device(dev, RNDIS_OID_GEN_LINK_SPEED,
					&link_speed, &size);

	if (!ret) {
		ndc = netdev_priv(dev->ndev);

		/* The link speed reported from host is in 100bps unit, so
		 * we convert it to Mbps here.
		 */
		ndc->speed = link_speed / 10000;
	}

	return ret;
}

829 830
static int rndis_filter_set_packet_filter(struct rndis_device *dev,
					  u32 new_filter)
831
{
832
	struct rndis_request *request;
833
	struct rndis_set_request *set;
834
	int ret;
835

836
	request = get_rndis_request(dev, RNDIS_MSG_SET,
837 838
			RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
			sizeof(u32));
839 840 841
	if (!request)
		return -ENOMEM;

842

843
	/* Setup the rndis set */
844 845 846 847
	set = &request->request_msg.msg.set_req;
	set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
	set->info_buflen = sizeof(u32);
	set->info_buf_offset = sizeof(struct rndis_set_request);
848

849
	memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
850
	       &new_filter, sizeof(u32));
851

852
	ret = rndis_filter_send_request(dev, request);
853 854
	if (ret == 0)
		wait_for_completion(&request->wait_event);
855

856
	put_rndis_request(dev, request);
857

858 859 860
	return ret;
}

861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882
static void rndis_set_multicast(struct work_struct *w)
{
	struct rndis_device *rdev
		= container_of(w, struct rndis_device, mcast_work);

	if (rdev->ndev->flags & IFF_PROMISC)
		rndis_filter_set_packet_filter(rdev,
					       NDIS_PACKET_TYPE_PROMISCUOUS);
	else
		rndis_filter_set_packet_filter(rdev,
					       NDIS_PACKET_TYPE_BROADCAST |
					       NDIS_PACKET_TYPE_ALL_MULTICAST |
					       NDIS_PACKET_TYPE_DIRECTED);
}

void rndis_filter_update(struct netvsc_device *nvdev)
{
	struct rndis_device *rdev = nvdev->extension;

	schedule_work(&rdev->mcast_work);
}

883
static int rndis_filter_init_device(struct rndis_device *dev)
884
{
885
	struct rndis_request *request;
886
	struct rndis_initialize_request *init;
887
	struct rndis_initialize_complete *init_complete;
888
	u32 status;
889
	int ret;
890
	struct netvsc_device *nvdev = net_device_to_netvsc_device(dev->ndev);
891

892
	request = get_rndis_request(dev, RNDIS_MSG_INIT,
893 894
			RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
	if (!request) {
895
		ret = -ENOMEM;
896
		goto cleanup;
897 898
	}

899
	/* Setup the rndis set */
900 901 902
	init = &request->request_msg.msg.init_req;
	init->major_ver = RNDIS_MAJOR_VERSION;
	init->minor_ver = RNDIS_MINOR_VERSION;
903
	init->max_xfer_size = 0x4000;
904

905
	dev->state = RNDIS_DEV_INITIALIZING;
906

907
	ret = rndis_filter_send_request(dev, request);
908
	if (ret != 0) {
909
		dev->state = RNDIS_DEV_UNINITIALIZED;
910
		goto cleanup;
911 912
	}

913
	wait_for_completion(&request->wait_event);
914

915 916
	init_complete = &request->response_msg.msg.init_complete;
	status = init_complete->status;
917
	if (status == RNDIS_STATUS_SUCCESS) {
918
		dev->state = RNDIS_DEV_INITIALIZED;
919 920
		nvdev->max_pkt = init_complete->max_pkt_per_msg;
		nvdev->pkt_align = 1 << init_complete->pkt_alignment_factor;
921
		ret = 0;
922
	} else {
923
		dev->state = RNDIS_DEV_UNINITIALIZED;
924
		ret = -EINVAL;
925 926
	}

927
cleanup:
928
	if (request)
929
		put_rndis_request(dev, request);
930 931 932 933

	return ret;
}

934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950
static bool netvsc_device_idle(const struct netvsc_device *nvdev)
{
	int i;

	if (atomic_read(&nvdev->num_outstanding_recvs) > 0)
		return false;

	for (i = 0; i < nvdev->num_chn; i++) {
		const struct netvsc_channel *nvchan = &nvdev->chan_table[i];

		if (atomic_read(&nvchan->queue_sends) > 0)
			return false;
	}

	return true;
}

951
static void rndis_filter_halt_device(struct rndis_device *dev)
952
{
953
	struct rndis_request *request;
954
	struct rndis_halt_request *halt;
955
	struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
956
	struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
957

958
	/* Attempt to do a rndis device halt */
959
	request = get_rndis_request(dev, RNDIS_MSG_HALT,
960
				RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
961
	if (!request)
962
		goto cleanup;
963

964
	/* Setup the rndis set */
965 966
	halt = &request->request_msg.msg.halt_req;
	halt->req_id = atomic_inc_return(&dev->new_req_id);
967

968
	/* Ignore return since this msg is optional. */
969
	rndis_filter_send_request(dev, request);
970

971
	dev->state = RNDIS_DEV_UNINITIALIZED;
972

973
cleanup:
974
	nvdev->destroy = true;
975 976 977

	/* Force flag to be ordered before waiting */
	wmb();
978 979

	/* Wait for all send completions */
980
	wait_event(nvdev->wait_drain, netvsc_device_idle(nvdev));
981

982
	if (request)
983
		put_rndis_request(dev, request);
984 985
}

986
static int rndis_filter_open_device(struct rndis_device *dev)
987
{
988
	int ret;
989

990
	if (dev->state != RNDIS_DEV_INITIALIZED)
991 992
		return 0;

993
	ret = rndis_filter_set_packet_filter(dev,
994
					 NDIS_PACKET_TYPE_BROADCAST |
995
					 NDIS_PACKET_TYPE_ALL_MULTICAST |
996
					 NDIS_PACKET_TYPE_DIRECTED);
997
	if (ret == 0)
998
		dev->state = RNDIS_DEV_DATAINITIALIZED;
999 1000 1001 1002

	return ret;
}

1003
static int rndis_filter_close_device(struct rndis_device *dev)
1004 1005 1006
{
	int ret;

1007
	if (dev->state != RNDIS_DEV_DATAINITIALIZED)
1008 1009
		return 0;

1010 1011 1012
	/* Make sure rndis_set_multicast doesn't re-enable filter! */
	cancel_work_sync(&dev->mcast_work);

1013
	ret = rndis_filter_set_packet_filter(dev, 0);
1014 1015 1016
	if (ret == -ENODEV)
		ret = 0;

1017
	if (ret == 0)
1018
		dev->state = RNDIS_DEV_INITIALIZED;
1019 1020 1021 1022

	return ret;
}

1023 1024
static void netvsc_sc_open(struct vmbus_channel *new_sc)
{
1025 1026
	struct net_device *ndev =
		hv_get_drvdata(new_sc->primary_channel->device_obj);
1027
	struct netvsc_device *nvscdev = net_device_to_netvsc_device(ndev);
1028
	u16 chn_index = new_sc->offermsg.offer.sub_channel_index;
1029 1030
	struct netvsc_channel *nvchan;
	int ret;
1031 1032 1033 1034

	if (chn_index >= nvscdev->num_chn)
		return;

1035 1036
	nvchan = nvscdev->chan_table + chn_index;
	nvchan->mrc.buf
1037
		= vzalloc(NETVSC_RECVSLOT_MAX * sizeof(struct recv_comp_data));
1038

1039 1040 1041
	if (!nvchan->mrc.buf)
		return;

1042 1043 1044 1045 1046
	/* Because the device uses NAPI, all the interrupt batching and
	 * control is done via Net softirq, not the channel handling
	 */
	set_channel_read_mode(new_sc, HV_CALL_ISR);

1047 1048
	/* Set the channel before opening.*/
	nvchan->channel = new_sc;
1049 1050
	netif_napi_add(ndev, &nvchan->napi,
		       netvsc_poll, NAPI_POLL_WEIGHT);
1051

1052 1053
	ret = vmbus_open(new_sc, nvscdev->ring_size * PAGE_SIZE,
			 nvscdev->ring_size * PAGE_SIZE, NULL, 0,
1054
			 netvsc_channel_cb, nvchan);
1055 1056 1057
	if (ret == 0)
		napi_enable(&nvchan->napi);
	else
1058
		netif_napi_del(&nvchan->napi);
S
stephen hemminger 已提交
1059

1060
	if (refcount_dec_and_test(&nvscdev->sc_offered))
1061
		complete(&nvscdev->channel_init_wait);
1062 1063
}

1064 1065
struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
				      struct netvsc_device_info *device_info)
1066
{
1067 1068
	struct net_device *net = hv_get_drvdata(dev);
	struct net_device_context *net_device_ctx = netdev_priv(net);
1069
	struct netvsc_device *net_device;
1070
	struct rndis_device *rndis_device;
1071
	struct ndis_offload hwcaps;
1072
	struct ndis_offload_params offloads;
1073 1074 1075
	struct nvsp_message *init_packet;
	struct ndis_recv_scale_cap rsscap;
	u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
1076
	unsigned int gso_max_size = GSO_MAX_SIZE;
1077
	u32 mtu, size, num_rss_qs;
1078 1079
	const struct cpumask *node_cpu_mask;
	u32 num_possible_rss_qs;
1080
	int i, ret;
1081

1082 1083
	rndis_device = get_rndis_device();
	if (!rndis_device)
1084
		return ERR_PTR(-ENODEV);
1085

1086 1087 1088 1089 1090
	/*
	 * Let the inner driver handle this first to create the netvsc channel
	 * NOTE! Once the channel is created, we may get a receive callback
	 * (RndisFilterOnReceive()) before this call is completed
	 */
1091 1092
	net_device = netvsc_device_add(dev, device_info);
	if (IS_ERR(net_device)) {
1093
		kfree(rndis_device);
1094
		return net_device;
1095 1096
	}

1097
	/* Initialize the rndis device */
1098
	net_device->max_chn = 1;
1099
	net_device->num_chn = 1;
1100

1101
	refcount_set(&net_device->sc_offered, 0);
1102

1103
	net_device->extension = rndis_device;
1104
	rndis_device->ndev = net;
1105

1106
	/* Send the rndis initialization message */
1107
	ret = rndis_filter_init_device(rndis_device);
1108 1109
	if (ret != 0)
		goto err_dev_remv;
1110

1111 1112 1113 1114 1115
	/* Get the MTU from the host */
	size = sizeof(u32);
	ret = rndis_filter_query_device(rndis_device,
					RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE,
					&mtu, &size);
1116 1117
	if (ret == 0 && size == sizeof(u32) && mtu < net->mtu)
		net->mtu = mtu;
1118

1119
	/* Get the mac address */
1120
	ret = rndis_filter_query_device_mac(rndis_device);
1121 1122
	if (ret != 0)
		goto err_dev_remv;
1123

1124
	memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
1125

1126 1127
	/* Find HW offload capabilities */
	ret = rndis_query_hwcaps(rndis_device, &hwcaps);
1128 1129
	if (ret != 0)
		goto err_dev_remv;
1130 1131

	/* A value of zero means "no change"; now turn on what we want. */
1132
	memset(&offloads, 0, sizeof(struct ndis_offload_params));
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182

	/* Linux does not care about IP checksum, always does in kernel */
	offloads.ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED;

	/* Compute tx offload settings based on hw capabilities */
	net->hw_features = NETIF_F_RXCSUM;

	if ((hwcaps.csum.ip4_txcsum & NDIS_TXCSUM_ALL_TCP4) == NDIS_TXCSUM_ALL_TCP4) {
		/* Can checksum TCP */
		net->hw_features |= NETIF_F_IP_CSUM;
		net_device_ctx->tx_checksum_mask |= TRANSPORT_INFO_IPV4_TCP;

		offloads.tcp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;

		if (hwcaps.lsov2.ip4_encap & NDIS_OFFLOAD_ENCAP_8023) {
			offloads.lso_v2_ipv4 = NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
			net->hw_features |= NETIF_F_TSO;

			if (hwcaps.lsov2.ip4_maxsz < gso_max_size)
				gso_max_size = hwcaps.lsov2.ip4_maxsz;
		}

		if (hwcaps.csum.ip4_txcsum & NDIS_TXCSUM_CAP_UDP4) {
			offloads.udp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
			net_device_ctx->tx_checksum_mask |= TRANSPORT_INFO_IPV4_UDP;
		}
	}

	if ((hwcaps.csum.ip6_txcsum & NDIS_TXCSUM_ALL_TCP6) == NDIS_TXCSUM_ALL_TCP6) {
		net->hw_features |= NETIF_F_IPV6_CSUM;

		offloads.tcp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
		net_device_ctx->tx_checksum_mask |= TRANSPORT_INFO_IPV6_TCP;

		if ((hwcaps.lsov2.ip6_encap & NDIS_OFFLOAD_ENCAP_8023) &&
		    (hwcaps.lsov2.ip6_opts & NDIS_LSOV2_CAP_IP6) == NDIS_LSOV2_CAP_IP6) {
			offloads.lso_v2_ipv6 = NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
			net->hw_features |= NETIF_F_TSO6;

			if (hwcaps.lsov2.ip6_maxsz < gso_max_size)
				gso_max_size = hwcaps.lsov2.ip6_maxsz;
		}

		if (hwcaps.csum.ip6_txcsum & NDIS_TXCSUM_CAP_UDP6) {
			offloads.udp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
			net_device_ctx->tx_checksum_mask |= TRANSPORT_INFO_IPV6_UDP;
		}
	}

	netif_set_gso_max_size(net, gso_max_size);
1183

1184
	ret = rndis_filter_set_offload_params(net, net_device, &offloads);
1185 1186 1187
	if (ret)
		goto err_dev_remv;

1188
	rndis_filter_query_device_link_status(rndis_device);
1189

1190 1191
	netdev_dbg(net, "Device MAC %pM link state %s\n",
		   rndis_device->hw_mac_adr,
1192
		   rndis_device->link_state ? "down" : "up");
1193

1194
	if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5)
1195
		return net_device;
1196

1197 1198
	rndis_filter_query_link_speed(rndis_device);

1199 1200 1201 1202 1203 1204 1205 1206
	/* vRSS setup */
	memset(&rsscap, 0, rsscap_size);
	ret = rndis_filter_query_device(rndis_device,
					OID_GEN_RECEIVE_SCALE_CAPABILITIES,
					&rsscap, &rsscap_size);
	if (ret || rsscap.num_recv_que < 2)
		goto out;

1207 1208 1209
	/*
	 * We will limit the VRSS channels to the number CPUs in the NUMA node
	 * the primary channel is currently bound to.
1210 1211
	 *
	 * This also guarantees that num_possible_rss_qs <= num_online_cpus
1212 1213
	 */
	node_cpu_mask = cpumask_of_node(cpu_to_node(dev->channel->target_cpu));
1214 1215
	num_possible_rss_qs = min_t(u32, cpumask_weight(node_cpu_mask),
				    rsscap.num_recv_que);
1216

1217
	net_device->max_chn = min_t(u32, VRSS_CHANNEL_MAX, num_possible_rss_qs);
1218

1219 1220
	/* We will use the given number of channels if available. */
	net_device->num_chn = min(net_device->max_chn, device_info->num_chn);
1221 1222 1223 1224 1225

	for (i = 0; i < ITAB_NUM; i++)
		rndis_device->ind_table[i] = ethtool_rxfh_indir_default(i,
							net_device->num_chn);

1226 1227
	num_rss_qs = net_device->num_chn - 1;
	if (num_rss_qs == 0)
1228
		return net_device;
1229

1230
	refcount_set(&net_device->sc_offered, num_rss_qs);
1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245
	vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);

	init_packet = &net_device->channel_init_pkt;
	memset(init_packet, 0, sizeof(struct nvsp_message));
	init_packet->hdr.msg_type = NVSP_MSG5_TYPE_SUBCHANNEL;
	init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE;
	init_packet->msg.v5_msg.subchn_req.num_subchannels =
						net_device->num_chn - 1;
	ret = vmbus_sendpacket(dev->channel, init_packet,
			       sizeof(struct nvsp_message),
			       (unsigned long)init_packet,
			       VM_PKT_DATA_INBAND,
			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
	if (ret)
		goto out;
1246

1247
	if (init_packet->msg.v5_msg.subchn_comp.status != NVSP_STAT_SUCCESS) {
1248 1249 1250
		ret = -ENODEV;
		goto out;
	}
1251 1252
	wait_for_completion(&net_device->channel_init_wait);

1253 1254 1255
	net_device->num_chn = 1 +
		init_packet->msg.v5_msg.subchn_comp.num_subchannels;

1256 1257 1258
	/* ignore failues from setting rss parameters, still have channels */
	rndis_filter_set_rss_param(rndis_device, netvsc_hash_key,
				   net_device->num_chn);
1259
out:
1260 1261
	if (ret) {
		net_device->max_chn = 1;
1262
		net_device->num_chn = 1;
1263
	}
1264

1265
	return net_device;
1266 1267

err_dev_remv:
1268
	rndis_filter_device_remove(dev, net_device);
1269
	return ERR_PTR(ret);
1270 1271
}

1272 1273
void rndis_filter_device_remove(struct hv_device *dev,
				struct netvsc_device *net_dev)
1274
{
1275
	struct rndis_device *rndis_dev = net_dev->extension;
1276

1277
	/* Halt and release the rndis device */
1278
	rndis_filter_halt_device(rndis_dev);
1279

1280
	kfree(rndis_dev);
1281
	net_dev->extension = NULL;
1282

1283
	netvsc_device_remove(dev);
1284 1285
}

1286
int rndis_filter_open(struct netvsc_device *nvdev)
1287
{
1288
	if (!nvdev)
1289 1290
		return -EINVAL;

1291
	if (atomic_inc_return(&nvdev->open_cnt) != 1)
1292 1293
		return 0;

1294
	return rndis_filter_open_device(nvdev->extension);
1295 1296
}

1297
int rndis_filter_close(struct netvsc_device *nvdev)
1298
{
1299
	if (!nvdev)
1300 1301
		return -EINVAL;

1302 1303 1304
	if (atomic_dec_return(&nvdev->open_cnt) != 0)
		return 0;

1305
	return rndis_filter_close_device(nvdev->extension);
1306
}
1307 1308 1309 1310 1311

bool rndis_filter_opened(const struct netvsc_device *nvdev)
{
	return atomic_read(&nvdev->open_cnt) > 0;
}