rndis_filter.c 35.5 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>
31

32
#include "hyperv_net.h"
33

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

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

41
	struct rndis_message response_msg;
42
	/*
43 44 45 46
	 * 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.
47
	 */
48
	u8 response_ext[RNDIS_EXT_LEN];
49

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

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

61 62 63 64 65 66 67 68
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
};

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

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

77
	spin_lock_init(&device->request_lock);
78

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

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

	return device;
}

87
static struct rndis_request *get_rndis_request(struct rndis_device *dev,
88 89
					     u32 msg_type,
					     u32 msg_len)
90
{
91
	struct rndis_request *request;
92
	struct rndis_message *rndis_msg;
93
	struct rndis_set_request *set;
94
	unsigned long flags;
95

96
	request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL);
97 98 99
	if (!request)
		return NULL;

100
	init_completion(&request->wait_event);
101

102
	rndis_msg = &request->request_msg;
103 104
	rndis_msg->ndis_msg_type = msg_type;
	rndis_msg->msg_len = msg_len;
105

106 107
	request->pkt.q_idx = 0;

108 109 110 111 112
	/*
	 * 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
	 */
113 114
	set = &rndis_msg->msg.set_req;
	set->req_id = atomic_inc_return(&dev->new_req_id);
115

116
	/* Add to the request list */
117 118 119
	spin_lock_irqsave(&dev->request_lock, flags);
	list_add_tail(&request->list_ent, &dev->req_list);
	spin_unlock_irqrestore(&dev->request_lock, flags);
120 121 122 123

	return request;
}

124
static void put_rndis_request(struct rndis_device *dev,
125
			    struct rndis_request *req)
126
{
127 128
	unsigned long flags;

129 130 131
	spin_lock_irqsave(&dev->request_lock, flags);
	list_del(&req->list_ent);
	spin_unlock_irqrestore(&dev->request_lock, flags);
132

133
	kfree(req);
134 135
}

136
static void dump_rndis_message(struct hv_device *hv_dev,
137
			       const struct rndis_message *rndis_msg)
138
{
139
	struct net_device *netdev = hv_get_drvdata(hv_dev);
140

141
	switch (rndis_msg->ndis_msg_type) {
142 143
	case RNDIS_MSG_PACKET:
		netdev_dbg(netdev, "RNDIS_MSG_PACKET (len %u, "
144 145
			   "data offset %u data len %u, # oob %u, "
			   "oob offset %u, oob len %u, pkt offset %u, "
146
			   "pkt len %u\n",
147 148 149 150 151 152 153 154
			   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);
155 156
		break;

157 158
	case RNDIS_MSG_INIT_C:
		netdev_dbg(netdev, "RNDIS_MSG_INIT_C "
159 160
			"(len %u, id 0x%x, status 0x%x, major %d, minor %d, "
			"device flags %d, max xfer size 0x%x, max pkts %u, "
161
			"pkt aligned %u)\n",
162 163 164 165 166 167 168 169 170 171 172
			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);
173 174
		break;

175 176
	case RNDIS_MSG_QUERY_C:
		netdev_dbg(netdev, "RNDIS_MSG_QUERY_C "
177
			"(len %u, id 0x%x, status 0x%x, buf len %u, "
178
			"buf offset %u)\n",
179 180 181 182 183 184 185
			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);
186 187
		break;

188
	case RNDIS_MSG_SET_C:
189
		netdev_dbg(netdev,
190
			"RNDIS_MSG_SET_C (len %u, id 0x%x, status 0x%x)\n",
191 192 193
			rndis_msg->msg_len,
			rndis_msg->msg.set_complete.req_id,
			rndis_msg->msg.set_complete.status);
194 195
		break;

196 197
	case RNDIS_MSG_INDICATE:
		netdev_dbg(netdev, "RNDIS_MSG_INDICATE "
198
			"(len %u, status 0x%x, buf len %u, buf offset %u)\n",
199 200 201 202
			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);
203 204 205
		break;

	default:
206
		netdev_dbg(netdev, "0x%x (len %u)\n",
207 208
			rndis_msg->ndis_msg_type,
			rndis_msg->msg_len);
209 210 211 212
		break;
	}
}

213
static int rndis_filter_send_request(struct rndis_device *dev,
214
				  struct rndis_request *req)
215
{
216
	int ret;
217
	struct hv_netvsc_packet *packet;
218
	struct hv_page_buffer page_buf[2];
219
	struct hv_page_buffer *pb = page_buf;
220
	struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
221

222
	/* Setup the packet to send it */
223
	packet = &req->pkt;
224

225
	packet->total_data_buflen = req->request_msg.msg_len;
226
	packet->page_buf_cnt = 1;
227

228
	pb[0].pfn = virt_to_phys(&req->request_msg) >>
229
					PAGE_SHIFT;
230 231
	pb[0].len = req->request_msg.msg_len;
	pb[0].offset =
232
		(unsigned long)&req->request_msg & (PAGE_SIZE - 1);
233

234
	/* Add one page_buf when request_msg crossing page boundary */
235
	if (pb[0].offset + pb[0].len > PAGE_SIZE) {
236
		packet->page_buf_cnt++;
237 238 239 240 241 242 243
		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;
244 245
	}

246
	ret = netvsc_send(net_device_ctx->device_ctx, packet, NULL, &pb, NULL);
247 248 249
	return ret;
}

250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
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;
	}
}

266
static void rndis_filter_receive_response(struct rndis_device *dev,
267
				       struct rndis_message *resp)
268
{
269
	struct rndis_request *request = NULL;
270
	bool found = false;
271
	unsigned long flags;
272
	struct net_device *ndev = dev->ndev;
273

274 275
	spin_lock_irqsave(&dev->request_lock, flags);
	list_for_each_entry(request, &dev->req_list, list_ent) {
276 277 278 279
		/*
		 * All request/response message contains RequestId as the 1st
		 * field
		 */
280 281
		if (request->request_msg.msg.init_req.req_id
		    == resp->msg.init_complete.req_id) {
282
			found = true;
283 284 285
			break;
		}
	}
286
	spin_unlock_irqrestore(&dev->request_lock, flags);
287

288
	if (found) {
289 290
		if (resp->msg_len <=
		    sizeof(struct rndis_message) + RNDIS_EXT_LEN) {
291
			memcpy(&request->response_msg, resp,
292
			       resp->msg_len);
293 294 295 296
			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);
297
		} else {
298
			netdev_err(ndev,
299 300 301
				"rndis response buffer overflow "
				"detected (size %u max %zu)\n",
				resp->msg_len,
302
				sizeof(struct rndis_message));
303

304
			if (resp->ndis_msg_type ==
305
			    RNDIS_MSG_RESET_C) {
306
				/* does not have a request id field */
307
				request->response_msg.msg.reset_complete.
308
					status = RNDIS_STATUS_BUFFER_OVERFLOW;
309
			} else {
310 311
				request->response_msg.msg.
				init_complete.status =
312
					RNDIS_STATUS_BUFFER_OVERFLOW;
313 314 315
			}
		}

316
		complete(&request->wait_event);
317
	} else {
318
		netdev_err(ndev,
319 320 321 322
			"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);
323 324 325
	}
}

326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
/*
 * 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;
}

352 353 354 355 356
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)
357
{
358 359 360
	struct rndis_packet *rndis_pkt = &msg->msg.pkt;
	const struct ndis_tcp_ip_checksum_info *csum_info;
	const struct ndis_pkt_8021q_info *vlan;
361
	u32 data_offset;
362

363
	/* Remove the rndis header and pass it back up the stack */
364
	data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
365

366
	data_buflen -= data_offset;
367 368 369 370 371

	/*
	 * Make sure we got a valid RNDIS message, now total_data_buflen
	 * should be the data packet size plus the trailer padding size
	 */
372
	if (unlikely(data_buflen < rndis_pkt->data_len)) {
373
		netdev_err(dev->ndev, "rndis message buffer "
374 375
			   "overflow detected (got %u, min %u)"
			   "...dropping this message!\n",
376
			   data_buflen, rndis_pkt->data_len);
377
		return NVSP_STAT_FAIL;
378 379
	}

380 381
	vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);

382 383 384 385 386
	/*
	 * 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
	 */
387
	data = (void *)((unsigned long)data + data_offset);
388
	csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO);
389 390 391
	return netvsc_recv_callback(ndev, channel,
				    data, rndis_pkt->data_len,
				    csum_info, vlan);
392 393
}

394 395 396 397 398
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)
399
{
400
	struct net_device_context *net_device_ctx = netdev_priv(ndev);
401 402
	struct rndis_device *rndis_dev = net_dev->extension;
	struct rndis_message *rndis_msg = data;
403

404
	/* Make sure the rndis device state is initialized */
405 406 407 408
	if (unlikely(!rndis_dev)) {
		netif_err(net_device_ctx, rx_err, ndev,
			  "got rndis message but no rndis device!\n");
		return NVSP_STAT_FAIL;
409 410
	}

411 412 413 414
	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;
415 416
	}

417
	if (netif_msg_rx_status(net_device_ctx))
418
		dump_rndis_message(dev, rndis_msg);
419

420
	switch (rndis_msg->ndis_msg_type) {
421
	case RNDIS_MSG_PACKET:
422 423
		return rndis_filter_receive_data(ndev, rndis_dev, rndis_msg,
						 channel, data, buflen);
424 425 426
	case RNDIS_MSG_INIT_C:
	case RNDIS_MSG_QUERY_C:
	case RNDIS_MSG_SET_C:
427
		/* completion msgs */
428
		rndis_filter_receive_response(rndis_dev, rndis_msg);
429 430
		break;

431
	case RNDIS_MSG_INDICATE:
432
		/* notification msgs */
433
		netvsc_linkstatus_callback(dev, rndis_msg);
434 435
		break;
	default:
436
		netdev_err(ndev,
437
			"unhandled rndis message (type %u len %u)\n",
438 439
			   rndis_msg->ndis_msg_type,
			   rndis_msg->msg_len);
440 441 442
		break;
	}

443
	return 0;
444 445
}

446
static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
447
				  void *result, u32 *result_size)
448
{
449
	struct rndis_request *request;
450
	u32 inresult_size = *result_size;
451
	struct rndis_query_request *query;
452
	struct rndis_query_complete *query_complete;
453
	int ret = 0;
454

455
	if (!result)
456
		return -EINVAL;
457

458
	*result_size = 0;
459
	request = get_rndis_request(dev, RNDIS_MSG_QUERY,
460 461
			RNDIS_MESSAGE_SIZE(struct rndis_query_request));
	if (!request) {
462
		ret = -ENOMEM;
463
		goto cleanup;
464 465
	}

466
	/* Setup the rndis query */
467 468 469 470 471
	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;
472

473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501
	if (oid == OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES) {
		struct net_device_context *ndevctx = netdev_priv(dev->ndev);
		struct netvsc_device *nvdev = ndevctx->nvdev;
		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) {
502 503 504 505 506 507 508 509 510 511 512 513
		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);
	}

514
	ret = rndis_filter_send_request(dev, request);
515
	if (ret != 0)
516
		goto cleanup;
517

518
	wait_for_completion(&request->wait_event);
519

520
	/* Copy the response back */
521
	query_complete = &request->response_msg.msg.query_complete;
522

523
	if (query_complete->info_buflen > inresult_size) {
524
		ret = -1;
525
		goto cleanup;
526 527
	}

528 529
	memcpy(result,
	       (void *)((unsigned long)query_complete +
530 531
			 query_complete->info_buf_offset),
	       query_complete->info_buflen);
532

533
	*result_size = query_complete->info_buflen;
534

535
cleanup:
536
	if (request)
537
		put_rndis_request(dev, request);
538 539 540 541

	return ret;
}

542 543 544 545 546 547 548 549 550 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
/* 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;
}

580
static int rndis_filter_query_device_mac(struct rndis_device *dev)
581
{
582
	u32 size = ETH_ALEN;
583

584
	return rndis_filter_query_device(dev,
585
				      RNDIS_OID_802_3_PERMANENT_ADDRESS,
586
				      dev->hw_mac_adr, &size);
587 588
}

589 590 591
#define NWADR_STR "NetworkAddress"
#define NWADR_STRLEN 14

592
int rndis_filter_set_device_mac(struct net_device *ndev, char *mac)
593
{
594
	struct netvsc_device *nvdev = net_device_to_netvsc_device(ndev);
595 596 597 598 599 600 601 602 603
	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;
604
	int ret;
605 606 607 608 609 610 611 612 613 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

	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;

645 646 647 648 649 650 651
	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;
652 653 654 655 656 657 658
	}

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

L
Lad, Prabhakar 已提交
659
static int
660
rndis_filter_set_offload_params(struct net_device *ndev,
661 662
				struct ndis_offload_params *req_offloads)
{
663
	struct netvsc_device *nvdev = net_device_to_netvsc_device(ndev);
664 665 666 667 668 669
	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);
670
	int ret;
671 672 673 674 675 676 677 678 679 680
	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;
	}
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703

	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;

704 705 706 707 708 709
	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;
710 711 712 713 714 715
	}

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

717 718
int rndis_filter_set_rss_param(struct rndis_device *rdev,
			       const u8 *rss_key, int num_queue)
719
{
720
	struct net_device *ndev = rdev->ndev;
721 722 723 724
	struct rndis_request *request;
	struct rndis_set_request *set;
	struct rndis_set_complete *set_complete;
	u32 extlen = sizeof(struct ndis_recv_scale_param) +
725
		     4 * ITAB_NUM + NETVSC_HASH_KEYLEN;
726 727 728
	struct ndis_recv_scale_param *rssp;
	u32 *itab;
	u8 *keyp;
729
	int i, ret;
730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748

	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 |
749 750
			 NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 |
			 NDIS_HASH_TCP_IPV6;
751 752
	rssp->indirect_tabsize = 4*ITAB_NUM;
	rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
753
	rssp->hashkey_size = NETVSC_HASH_KEYLEN;
754 755 756 757 758 759
	rssp->kashkey_offset = rssp->indirect_taboffset +
			       rssp->indirect_tabsize;

	/* Set indirection table entries */
	itab = (u32 *)(rssp + 1);
	for (i = 0; i < ITAB_NUM; i++)
760
		itab[i] = rdev->ind_table[i];
761 762 763

	/* Set hask key values */
	keyp = (u8 *)((unsigned long)rssp + rssp->kashkey_offset);
764
	memcpy(keyp, rss_key, NETVSC_HASH_KEYLEN);
765 766 767 768 769

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

770 771
	wait_for_completion(&request->wait_event);
	set_complete = &request->response_msg.msg.set_complete;
772 773 774
	if (set_complete->status == RNDIS_STATUS_SUCCESS)
		memcpy(rdev->rss_key, rss_key, NETVSC_HASH_KEYLEN);
	else {
775 776 777
		netdev_err(ndev, "Fail to set RSS parameters:0x%x\n",
			   set_complete->status);
		ret = -EINVAL;
778 779 780 781 782 783 784
	}

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

785
static int rndis_filter_query_device_link_status(struct rndis_device *dev)
786
{
787
	u32 size = sizeof(u32);
788 789
	u32 link_status;
	int ret;
790

791
	ret = rndis_filter_query_device(dev,
792
				      RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
793 794 795
				      &link_status, &size);

	return ret;
796 797
}

798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819
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;
}

820 821
static int rndis_filter_set_packet_filter(struct rndis_device *dev,
					  u32 new_filter)
822
{
823
	struct rndis_request *request;
824
	struct rndis_set_request *set;
825
	int ret;
826

827
	request = get_rndis_request(dev, RNDIS_MSG_SET,
828 829
			RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
			sizeof(u32));
830 831 832
	if (!request)
		return -ENOMEM;

833

834
	/* Setup the rndis set */
835 836 837 838
	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);
839

840
	memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
841
	       &new_filter, sizeof(u32));
842

843
	ret = rndis_filter_send_request(dev, request);
844 845
	if (ret == 0)
		wait_for_completion(&request->wait_event);
846

847
	put_rndis_request(dev, request);
848

849 850 851
	return ret;
}

852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873
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);
}

874
static int rndis_filter_init_device(struct rndis_device *dev)
875
{
876
	struct rndis_request *request;
877
	struct rndis_initialize_request *init;
878
	struct rndis_initialize_complete *init_complete;
879
	u32 status;
880
	int ret;
881
	struct netvsc_device *nvdev = net_device_to_netvsc_device(dev->ndev);
882

883
	request = get_rndis_request(dev, RNDIS_MSG_INIT,
884 885
			RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
	if (!request) {
886
		ret = -ENOMEM;
887
		goto cleanup;
888 889
	}

890
	/* Setup the rndis set */
891 892 893
	init = &request->request_msg.msg.init_req;
	init->major_ver = RNDIS_MAJOR_VERSION;
	init->minor_ver = RNDIS_MINOR_VERSION;
894
	init->max_xfer_size = 0x4000;
895

896
	dev->state = RNDIS_DEV_INITIALIZING;
897

898
	ret = rndis_filter_send_request(dev, request);
899
	if (ret != 0) {
900
		dev->state = RNDIS_DEV_UNINITIALIZED;
901
		goto cleanup;
902 903
	}

904
	wait_for_completion(&request->wait_event);
905

906 907
	init_complete = &request->response_msg.msg.init_complete;
	status = init_complete->status;
908
	if (status == RNDIS_STATUS_SUCCESS) {
909
		dev->state = RNDIS_DEV_INITIALIZED;
910 911
		nvdev->max_pkt = init_complete->max_pkt_per_msg;
		nvdev->pkt_align = 1 << init_complete->pkt_alignment_factor;
912
		ret = 0;
913
	} else {
914
		dev->state = RNDIS_DEV_UNINITIALIZED;
915
		ret = -EINVAL;
916 917
	}

918
cleanup:
919
	if (request)
920
		put_rndis_request(dev, request);
921 922 923 924

	return ret;
}

925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941
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;
}

942
static void rndis_filter_halt_device(struct rndis_device *dev)
943
{
944
	struct rndis_request *request;
945
	struct rndis_halt_request *halt;
946 947
	struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
	struct netvsc_device *nvdev = net_device_ctx->nvdev;
948

949
	/* Attempt to do a rndis device halt */
950
	request = get_rndis_request(dev, RNDIS_MSG_HALT,
951
				RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
952
	if (!request)
953
		goto cleanup;
954

955
	/* Setup the rndis set */
956 957
	halt = &request->request_msg.msg.halt_req;
	halt->req_id = atomic_inc_return(&dev->new_req_id);
958

959
	/* Ignore return since this msg is optional. */
960
	rndis_filter_send_request(dev, request);
961

962
	dev->state = RNDIS_DEV_UNINITIALIZED;
963

964
cleanup:
965
	nvdev->destroy = true;
966 967 968

	/* Force flag to be ordered before waiting */
	wmb();
969 970

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

973
	if (request)
974
		put_rndis_request(dev, request);
975 976
}

977
static int rndis_filter_open_device(struct rndis_device *dev)
978
{
979
	int ret;
980

981
	if (dev->state != RNDIS_DEV_INITIALIZED)
982 983
		return 0;

984
	ret = rndis_filter_set_packet_filter(dev,
985
					 NDIS_PACKET_TYPE_BROADCAST |
986
					 NDIS_PACKET_TYPE_ALL_MULTICAST |
987
					 NDIS_PACKET_TYPE_DIRECTED);
988
	if (ret == 0)
989
		dev->state = RNDIS_DEV_DATAINITIALIZED;
990 991 992 993

	return ret;
}

994
static int rndis_filter_close_device(struct rndis_device *dev)
995 996 997
{
	int ret;

998
	if (dev->state != RNDIS_DEV_DATAINITIALIZED)
999 1000
		return 0;

1001 1002 1003
	/* Make sure rndis_set_multicast doesn't re-enable filter! */
	cancel_work_sync(&dev->mcast_work);

1004
	ret = rndis_filter_set_packet_filter(dev, 0);
1005 1006 1007
	if (ret == -ENODEV)
		ret = 0;

1008
	if (ret == 0)
1009
		dev->state = RNDIS_DEV_INITIALIZED;
1010 1011 1012 1013

	return ret;
}

1014 1015
static void netvsc_sc_open(struct vmbus_channel *new_sc)
{
1016 1017
	struct net_device *ndev =
		hv_get_drvdata(new_sc->primary_channel->device_obj);
1018
	struct netvsc_device *nvscdev = net_device_to_netvsc_device(ndev);
1019
	u16 chn_index = new_sc->offermsg.offer.sub_channel_index;
1020 1021
	struct netvsc_channel *nvchan;
	int ret;
1022 1023 1024 1025

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

1026 1027
	nvchan = nvscdev->chan_table + chn_index;
	nvchan->mrc.buf
1028
		= vzalloc(NETVSC_RECVSLOT_MAX * sizeof(struct recv_comp_data));
1029

1030 1031 1032
	if (!nvchan->mrc.buf)
		return;

1033 1034 1035 1036 1037
	/* 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);

1038 1039
	/* Set the channel before opening.*/
	nvchan->channel = new_sc;
1040 1041
	netif_napi_add(ndev, &nvchan->napi,
		       netvsc_poll, NAPI_POLL_WEIGHT);
1042

1043 1044
	ret = vmbus_open(new_sc, nvscdev->ring_size * PAGE_SIZE,
			 nvscdev->ring_size * PAGE_SIZE, NULL, 0,
1045
			 netvsc_channel_cb, nvchan);
1046 1047 1048
	if (ret == 0)
		napi_enable(&nvchan->napi);
	else
1049
		netif_napi_del(&nvchan->napi);
S
stephen hemminger 已提交
1050

1051
	if (refcount_dec_and_test(&nvscdev->sc_offered))
1052
		complete(&nvscdev->channel_init_wait);
1053 1054
}

1055
int rndis_filter_device_add(struct hv_device *dev,
1056
			    struct netvsc_device_info *device_info)
1057
{
1058 1059
	struct net_device *net = hv_get_drvdata(dev);
	struct net_device_context *net_device_ctx = netdev_priv(net);
1060
	struct netvsc_device *net_device;
1061
	struct rndis_device *rndis_device;
1062
	struct ndis_offload hwcaps;
1063
	struct ndis_offload_params offloads;
1064 1065 1066
	struct nvsp_message *init_packet;
	struct ndis_recv_scale_cap rsscap;
	u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
1067
	unsigned int gso_max_size = GSO_MAX_SIZE;
1068
	u32 mtu, size, num_rss_qs;
1069 1070
	const struct cpumask *node_cpu_mask;
	u32 num_possible_rss_qs;
1071
	int i, ret;
1072

1073 1074
	rndis_device = get_rndis_device();
	if (!rndis_device)
1075
		return -ENODEV;
1076

1077 1078 1079 1080 1081
	/*
	 * 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
	 */
1082
	ret = netvsc_device_add(dev, device_info);
1083
	if (ret != 0) {
1084
		kfree(rndis_device);
1085 1086 1087
		return ret;
	}

1088
	/* Initialize the rndis device */
1089
	net_device = net_device_ctx->nvdev;
1090
	net_device->max_chn = 1;
1091
	net_device->num_chn = 1;
1092

1093
	refcount_set(&net_device->sc_offered, 0);
1094

1095
	net_device->extension = rndis_device;
1096
	rndis_device->ndev = net;
1097

1098
	/* Send the rndis initialization message */
1099
	ret = rndis_filter_init_device(rndis_device);
1100
	if (ret != 0) {
1101
		rndis_filter_device_remove(dev, net_device);
1102
		return ret;
1103 1104
	}

1105 1106 1107 1108 1109
	/* Get the MTU from the host */
	size = sizeof(u32);
	ret = rndis_filter_query_device(rndis_device,
					RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE,
					&mtu, &size);
1110 1111
	if (ret == 0 && size == sizeof(u32) && mtu < net->mtu)
		net->mtu = mtu;
1112

1113
	/* Get the mac address */
1114
	ret = rndis_filter_query_device_mac(rndis_device);
1115
	if (ret != 0) {
1116
		rndis_filter_device_remove(dev, net_device);
1117
		return ret;
1118 1119
	}

1120
	memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
1121

1122 1123 1124
	/* Find HW offload capabilities */
	ret = rndis_query_hwcaps(rndis_device, &hwcaps);
	if (ret != 0) {
1125
		rndis_filter_device_remove(dev, net_device);
1126 1127 1128 1129
		return ret;
	}

	/* A value of zero means "no change"; now turn on what we want. */
1130
	memset(&offloads, 0, sizeof(struct ndis_offload_params));
1131 1132 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

	/* 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);
1181

1182
	ret = rndis_filter_set_offload_params(net, &offloads);
1183 1184 1185
	if (ret)
		goto err_dev_remv;

1186
	rndis_filter_query_device_link_status(rndis_device);
1187

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

1192 1193 1194
	if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5)
		return 0;

1195 1196
	rndis_filter_query_link_speed(rndis_device);

1197 1198 1199 1200 1201 1202 1203 1204
	/* 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;

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

1215
	net_device->max_chn = min_t(u32, VRSS_CHANNEL_MAX, num_possible_rss_qs);
1216

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

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

1224 1225 1226
	num_rss_qs = net_device->num_chn - 1;
	if (num_rss_qs == 0)
		return 0;
1227

1228
	refcount_set(&net_device->sc_offered, num_rss_qs);
1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243
	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;
1244

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

1251 1252 1253
	net_device->num_chn = 1 +
		init_packet->msg.v5_msg.subchn_comp.num_subchannels;

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

1263
	return 0; /* return 0 because primary channel can be used alone */
1264 1265

err_dev_remv:
1266
	rndis_filter_device_remove(dev, net_device);
1267
	return ret;
1268 1269
}

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

1275
	/* Halt and release the rndis device */
1276
	rndis_filter_halt_device(rndis_dev);
1277

1278
	kfree(rndis_dev);
1279
	net_dev->extension = NULL;
1280

1281
	netvsc_device_remove(dev);
1282 1283
}

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

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

1292
	return rndis_filter_open_device(nvdev->extension);
1293 1294
}

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

1300 1301 1302
	if (atomic_dec_return(&nvdev->open_cnt) != 0)
		return 0;

1303
	return rndis_filter_close_device(nvdev->extension);
1304
}