]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/staging/hv/netvsc.c
staging: hv: move netvsc_destroy_send_buf() to clean up forward declaration
[mirror_ubuntu-artful-kernel.git] / drivers / staging / hv / netvsc.c
CommitLineData
fceaf24a 1/*
fceaf24a
HJ
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:
d0e94d17 18 * Haiyang Zhang <haiyangz@microsoft.com>
fceaf24a 19 * Hank Janssen <hjanssen@microsoft.com>
fceaf24a 20 */
eb335bc4
HJ
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
5654e932 23#include <linux/kernel.h>
0c3b7b2f
S
24#include <linux/sched.h>
25#include <linux/wait.h>
0ffa63b0 26#include <linux/mm.h>
b4362c9c 27#include <linux/delay.h>
21a80820 28#include <linux/io.h>
5a0e3ad6 29#include <linux/slab.h>
e3fe0bb6 30#include "hv_api.h"
645954c5 31#include "logging.h"
af167ae9 32#include "netvsc.h"
043efcc3 33#include "rndis_filter.h"
314bf1d1 34#include "channel.h"
fceaf24a
HJ
35
36
454f18a9 37/* Globals */
85799a37 38static const char *driver_name = "netvsc";
fceaf24a 39
454f18a9 40/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
85799a37 41static const struct hv_guid netvsc_device_type = {
caf26a31
GKH
42 .data = {
43 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
44 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
45 }
fceaf24a
HJ
46};
47
5a71ae30 48static void netvsc_channel_cb(void *context);
21a80820 49
5a71ae30 50static int netvsc_init_send_buf(struct hv_device *device);
21a80820 51
5a71ae30 52static int netvsc_init_recv_buf(struct hv_device *device);
21a80820 53
5a71ae30 54static int netvsc_connect_vsp(struct hv_device *device);
21a80820 55
5a71ae30 56static void netvsc_send_completion(struct hv_device *device,
85799a37 57 struct vmpacket_descriptor *packet);
21a80820 58
5a71ae30 59static void netvsc_receive(struct hv_device *device,
85799a37 60 struct vmpacket_descriptor *packet);
21a80820 61
fceaf24a 62
5a71ae30 63static struct netvsc_device *alloc_net_device(struct hv_device *device)
fceaf24a 64{
85799a37 65 struct netvsc_device *net_device;
fceaf24a 66
85799a37
HZ
67 net_device = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL);
68 if (!net_device)
fceaf24a
HJ
69 return NULL;
70
454f18a9 71 /* Set to 2 to allow both inbound and outbound traffic */
53d21fdb 72 atomic_cmpxchg(&net_device->refcnt, 0, 2);
fceaf24a 73
53d21fdb 74 net_device->dev = device;
ca623ad3 75 device->ext = net_device;
fceaf24a 76
85799a37 77 return net_device;
fceaf24a
HJ
78}
79
5a71ae30 80static void free_net_device(struct netvsc_device *device)
fceaf24a 81{
31acaa50 82 WARN_ON(atomic_read(&device->refcnt) != 0);
ca623ad3 83 device->dev->ext = NULL;
85799a37 84 kfree(device);
fceaf24a
HJ
85}
86
87
454f18a9 88/* Get the net device object iff exists and its refcount > 1 */
5a71ae30 89static struct netvsc_device *get_outbound_net_device(struct hv_device *device)
fceaf24a 90{
85799a37 91 struct netvsc_device *net_device;
fceaf24a 92
ca623ad3 93 net_device = device->ext;
53d21fdb
HZ
94 if (net_device && atomic_read(&net_device->refcnt) > 1)
95 atomic_inc(&net_device->refcnt);
fceaf24a 96 else
85799a37 97 net_device = NULL;
fceaf24a 98
85799a37 99 return net_device;
fceaf24a
HJ
100}
101
454f18a9 102/* Get the net device object iff exists and its refcount > 0 */
5a71ae30 103static struct netvsc_device *get_inbound_net_device(struct hv_device *device)
fceaf24a 104{
85799a37 105 struct netvsc_device *net_device;
fceaf24a 106
ca623ad3 107 net_device = device->ext;
53d21fdb
HZ
108 if (net_device && atomic_read(&net_device->refcnt))
109 atomic_inc(&net_device->refcnt);
fceaf24a 110 else
85799a37 111 net_device = NULL;
fceaf24a 112
85799a37 113 return net_device;
fceaf24a
HJ
114}
115
5a71ae30 116static void put_net_device(struct hv_device *device)
fceaf24a 117{
85799a37 118 struct netvsc_device *net_device;
fceaf24a 119
ca623ad3 120 net_device = device->ext;
fceaf24a 121
53d21fdb 122 atomic_dec(&net_device->refcnt);
fceaf24a
HJ
123}
124
5a71ae30
HZ
125static struct netvsc_device *release_outbound_net_device(
126 struct hv_device *device)
fceaf24a 127{
85799a37 128 struct netvsc_device *net_device;
fceaf24a 129
ca623ad3 130 net_device = device->ext;
85799a37 131 if (net_device == NULL)
fceaf24a
HJ
132 return NULL;
133
454f18a9 134 /* Busy wait until the ref drop to 2, then set it to 1 */
53d21fdb 135 while (atomic_cmpxchg(&net_device->refcnt, 2, 1) != 2)
b4362c9c 136 udelay(100);
fceaf24a 137
85799a37 138 return net_device;
fceaf24a
HJ
139}
140
5a71ae30
HZ
141static struct netvsc_device *release_inbound_net_device(
142 struct hv_device *device)
fceaf24a 143{
85799a37 144 struct netvsc_device *net_device;
fceaf24a 145
ca623ad3 146 net_device = device->ext;
85799a37 147 if (net_device == NULL)
fceaf24a
HJ
148 return NULL;
149
454f18a9 150 /* Busy wait until the ref drop to 1, then set it to 0 */
53d21fdb 151 while (atomic_cmpxchg(&net_device->refcnt, 1, 0) != 1)
b4362c9c 152 udelay(100);
fceaf24a 153
ca623ad3 154 device->ext = NULL;
85799a37 155 return net_device;
fceaf24a
HJ
156}
157
ec91cd09
HZ
158static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
159{
160 struct nvsp_message *revoke_packet;
161 int ret = 0;
162
163 /*
164 * If we got a section count, it means we received a
165 * SendReceiveBufferComplete msg (ie sent
166 * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
167 * to send a revoke msg here
168 */
169 if (net_device->recv_section_cnt) {
170 /* Send the revoke receive buffer */
171 revoke_packet = &net_device->revoke_packet;
172 memset(revoke_packet, 0, sizeof(struct nvsp_message));
173
174 revoke_packet->hdr.msg_type =
175 NVSP_MSG1_TYPE_REVOKE_RECV_BUF;
176 revoke_packet->msg.v1_msg.
177 revoke_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
178
179 ret = vmbus_sendpacket(net_device->dev->channel,
180 revoke_packet,
181 sizeof(struct nvsp_message),
182 (unsigned long)revoke_packet,
183 VM_PKT_DATA_INBAND, 0);
184 /*
185 * If we failed here, we might as well return and
186 * have a leak rather than continue and a bugchk
187 */
188 if (ret != 0) {
189 dev_err(&net_device->dev->device, "unable to send "
190 "revoke receive buffer to netvsp");
191 return -1;
192 }
193 }
194
195 /* Teardown the gpadl on the vsp end */
196 if (net_device->recv_buf_gpadl_handle) {
197 ret = vmbus_teardown_gpadl(net_device->dev->channel,
198 net_device->recv_buf_gpadl_handle);
199
200 /* If we failed here, we might as well return and have a leak
201 * rather than continue and a bugchk
202 */
203 if (ret != 0) {
204 dev_err(&net_device->dev->device,
205 "unable to teardown receive buffer's gpadl");
206 return -1;
207 }
208 net_device->recv_buf_gpadl_handle = 0;
209 }
210
211 if (net_device->recv_buf) {
212 /* Free up the receive buffer */
213 free_pages((unsigned long)net_device->recv_buf,
214 get_order(net_device->recv_buf_size));
215 net_device->recv_buf = NULL;
216 }
217
218 if (net_device->recv_section) {
219 net_device->recv_section_cnt = 0;
220 kfree(net_device->recv_section);
221 net_device->recv_section = NULL;
222 }
223
224 return ret;
225}
226
5a71ae30 227static int netvsc_init_recv_buf(struct hv_device *device)
fceaf24a 228{
21a80820 229 int ret = 0;
85799a37
HZ
230 struct netvsc_device *net_device;
231 struct nvsp_message *init_packet;
fceaf24a 232
5a71ae30 233 net_device = get_outbound_net_device(device);
85799a37 234 if (!net_device) {
eb335bc4 235 dev_err(&device->device, "unable to get net device..."
21a80820 236 "device being destroyed?");
fceaf24a
HJ
237 return -1;
238 }
fceaf24a 239
53d21fdb 240 net_device->recv_buf =
df3493e0
S
241 (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
242 get_order(net_device->recv_buf_size));
53d21fdb 243 if (!net_device->recv_buf) {
eb335bc4
HJ
244 dev_err(&device->device, "unable to allocate receive "
245 "buffer of size %d", net_device->recv_buf_size);
fceaf24a 246 ret = -1;
0c3b7b2f 247 goto cleanup;
fceaf24a 248 }
fceaf24a 249
454f18a9
BP
250 /*
251 * Establish the gpadl handle for this buffer on this
252 * channel. Note: This call uses the vmbus connection rather
253 * than the channel to establish the gpadl handle.
254 */
53d21fdb
HZ
255 ret = vmbus_establish_gpadl(device->channel, net_device->recv_buf,
256 net_device->recv_buf_size,
257 &net_device->recv_buf_gpadl_handle);
21a80820 258 if (ret != 0) {
eb335bc4
HJ
259 dev_err(&device->device,
260 "unable to establish receive buffer's gpadl");
0c3b7b2f 261 goto cleanup;
fceaf24a
HJ
262 }
263
fceaf24a 264
454f18a9 265 /* Notify the NetVsp of the gpadl handle */
53d21fdb 266 init_packet = &net_device->channel_init_pkt;
fceaf24a 267
85799a37 268 memset(init_packet, 0, sizeof(struct nvsp_message));
fceaf24a 269
53d21fdb
HZ
270 init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_RECV_BUF;
271 init_packet->msg.v1_msg.send_recv_buf.
272 gpadl_handle = net_device->recv_buf_gpadl_handle;
273 init_packet->msg.v1_msg.
274 send_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
fceaf24a 275
454f18a9 276 /* Send the gpadl notification request */
0c3b7b2f 277 net_device->wait_condition = 0;
85799a37 278 ret = vmbus_sendpacket(device->channel, init_packet,
5a4df290 279 sizeof(struct nvsp_message),
85799a37 280 (unsigned long)init_packet,
415f2287 281 VM_PKT_DATA_INBAND,
5a4df290 282 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
21a80820 283 if (ret != 0) {
eb335bc4
HJ
284 dev_err(&device->device,
285 "unable to send receive buffer's gpadl to netvsp");
0c3b7b2f 286 goto cleanup;
fceaf24a
HJ
287 }
288
0c3b7b2f
S
289 wait_event_timeout(net_device->channel_init_wait,
290 net_device->wait_condition,
291 msecs_to_jiffies(1000));
292 BUG_ON(net_device->wait_condition == 0);
293
fceaf24a 294
454f18a9 295 /* Check the response */
53d21fdb
HZ
296 if (init_packet->msg.v1_msg.
297 send_recv_buf_complete.status != NVSP_STAT_SUCCESS) {
eb335bc4 298 dev_err(&device->device, "Unable to complete receive buffer "
21a80820 299 "initialzation with NetVsp - status %d",
53d21fdb
HZ
300 init_packet->msg.v1_msg.
301 send_recv_buf_complete.status);
fceaf24a 302 ret = -1;
0c3b7b2f 303 goto cleanup;
fceaf24a
HJ
304 }
305
454f18a9 306 /* Parse the response */
fceaf24a 307
53d21fdb
HZ
308 net_device->recv_section_cnt = init_packet->msg.
309 v1_msg.send_recv_buf_complete.num_sections;
fceaf24a 310
53d21fdb 311 net_device->recv_section = kmalloc(net_device->recv_section_cnt
85799a37 312 * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL);
53d21fdb 313 if (net_device->recv_section == NULL) {
fceaf24a 314 ret = -1;
0c3b7b2f 315 goto cleanup;
fceaf24a
HJ
316 }
317
53d21fdb
HZ
318 memcpy(net_device->recv_section,
319 init_packet->msg.v1_msg.
320 send_recv_buf_complete.sections,
321 net_device->recv_section_cnt *
85799a37 322 sizeof(struct nvsp_1_receive_buffer_section));
fceaf24a 323
21a80820
GKH
324 /*
325 * For 1st release, there should only be 1 section that represents the
326 * entire receive buffer
327 */
53d21fdb
HZ
328 if (net_device->recv_section_cnt != 1 ||
329 net_device->recv_section->offset != 0) {
fceaf24a 330 ret = -1;
0c3b7b2f 331 goto cleanup;
fceaf24a
HJ
332 }
333
0c3b7b2f 334 goto exit;
fceaf24a 335
0c3b7b2f 336cleanup:
5a71ae30 337 netvsc_destroy_recv_buf(net_device);
fceaf24a 338
0c3b7b2f 339exit:
5a71ae30 340 put_net_device(device);
fceaf24a
HJ
341 return ret;
342}
343
0021e71e
HZ
344static int netvsc_destroy_send_buf(struct netvsc_device *net_device)
345{
346 struct nvsp_message *revoke_packet;
347 int ret = 0;
348
349 /*
350 * If we got a section count, it means we received a
351 * SendReceiveBufferComplete msg (ie sent
352 * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
353 * to send a revoke msg here
354 */
355 if (net_device->send_section_size) {
356 /* Send the revoke send buffer */
357 revoke_packet = &net_device->revoke_packet;
358 memset(revoke_packet, 0, sizeof(struct nvsp_message));
359
360 revoke_packet->hdr.msg_type =
361 NVSP_MSG1_TYPE_REVOKE_SEND_BUF;
362 revoke_packet->msg.v1_msg.
363 revoke_send_buf.id = NETVSC_SEND_BUFFER_ID;
364
365 ret = vmbus_sendpacket(net_device->dev->channel,
366 revoke_packet,
367 sizeof(struct nvsp_message),
368 (unsigned long)revoke_packet,
369 VM_PKT_DATA_INBAND, 0);
370 /*
371 * If we failed here, we might as well return and have a leak
372 * rather than continue and a bugchk
373 */
374 if (ret != 0) {
375 dev_err(&net_device->dev->device, "unable to send "
376 "revoke send buffer to netvsp");
377 return -1;
378 }
379 }
380
381 /* Teardown the gpadl on the vsp end */
382 if (net_device->send_buf_gpadl_handle) {
383 ret = vmbus_teardown_gpadl(net_device->dev->channel,
384 net_device->send_buf_gpadl_handle);
385
386 /*
387 * If we failed here, we might as well return and have a leak
388 * rather than continue and a bugchk
389 */
390 if (ret != 0) {
391 dev_err(&net_device->dev->device,
392 "unable to teardown send buffer's gpadl");
393 return -1;
394 }
395 net_device->send_buf_gpadl_handle = 0;
396 }
397
398 if (net_device->send_buf) {
399 /* Free up the receive buffer */
400 free_pages((unsigned long)net_device->send_buf,
401 get_order(net_device->send_buf_size));
402 net_device->send_buf = NULL;
403 }
404
405 return ret;
406}
407
5a71ae30 408static int netvsc_init_send_buf(struct hv_device *device)
fceaf24a 409{
21a80820 410 int ret = 0;
85799a37
HZ
411 struct netvsc_device *net_device;
412 struct nvsp_message *init_packet;
fceaf24a 413
5a71ae30 414 net_device = get_outbound_net_device(device);
85799a37 415 if (!net_device) {
eb335bc4 416 dev_err(&device->device, "unable to get net device..."
21a80820 417 "device being destroyed?");
fceaf24a
HJ
418 return -1;
419 }
53d21fdb 420 if (net_device->send_buf_size <= 0) {
79069684 421 ret = -EINVAL;
0c3b7b2f 422 goto cleanup;
79069684
BP
423 }
424
53d21fdb 425 net_device->send_buf =
df3493e0
S
426 (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
427 get_order(net_device->send_buf_size));
53d21fdb 428 if (!net_device->send_buf) {
eb335bc4
HJ
429 dev_err(&device->device, "unable to allocate send "
430 "buffer of size %d", net_device->send_buf_size);
fceaf24a 431 ret = -1;
0c3b7b2f 432 goto cleanup;
fceaf24a 433 }
fceaf24a 434
454f18a9
BP
435 /*
436 * Establish the gpadl handle for this buffer on this
437 * channel. Note: This call uses the vmbus connection rather
438 * than the channel to establish the gpadl handle.
439 */
53d21fdb
HZ
440 ret = vmbus_establish_gpadl(device->channel, net_device->send_buf,
441 net_device->send_buf_size,
442 &net_device->send_buf_gpadl_handle);
21a80820 443 if (ret != 0) {
eb335bc4 444 dev_err(&device->device, "unable to establish send buffer's gpadl");
0c3b7b2f 445 goto cleanup;
fceaf24a
HJ
446 }
447
454f18a9 448 /* Notify the NetVsp of the gpadl handle */
53d21fdb 449 init_packet = &net_device->channel_init_pkt;
fceaf24a 450
85799a37 451 memset(init_packet, 0, sizeof(struct nvsp_message));
fceaf24a 452
53d21fdb
HZ
453 init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF;
454 init_packet->msg.v1_msg.send_recv_buf.
455 gpadl_handle = net_device->send_buf_gpadl_handle;
456 init_packet->msg.v1_msg.send_recv_buf.id =
85799a37 457 NETVSC_SEND_BUFFER_ID;
fceaf24a 458
454f18a9 459 /* Send the gpadl notification request */
0c3b7b2f 460 net_device->wait_condition = 0;
85799a37 461 ret = vmbus_sendpacket(device->channel, init_packet,
5a4df290 462 sizeof(struct nvsp_message),
85799a37 463 (unsigned long)init_packet,
415f2287 464 VM_PKT_DATA_INBAND,
5a4df290 465 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
21a80820 466 if (ret != 0) {
eb335bc4 467 dev_err(&device->device,
21a80820 468 "unable to send receive buffer's gpadl to netvsp");
0c3b7b2f 469 goto cleanup;
fceaf24a
HJ
470 }
471
0c3b7b2f
S
472 wait_event_timeout(net_device->channel_init_wait,
473 net_device->wait_condition,
474 msecs_to_jiffies(1000));
475 BUG_ON(net_device->wait_condition == 0);
fceaf24a 476
454f18a9 477 /* Check the response */
53d21fdb
HZ
478 if (init_packet->msg.v1_msg.
479 send_send_buf_complete.status != NVSP_STAT_SUCCESS) {
eb335bc4 480 dev_err(&device->device, "Unable to complete send buffer "
21a80820 481 "initialzation with NetVsp - status %d",
53d21fdb
HZ
482 init_packet->msg.v1_msg.
483 send_send_buf_complete.status);
fceaf24a 484 ret = -1;
0c3b7b2f 485 goto cleanup;
fceaf24a
HJ
486 }
487
53d21fdb
HZ
488 net_device->send_section_size = init_packet->
489 msg.v1_msg.send_send_buf_complete.section_size;
fceaf24a 490
0c3b7b2f 491 goto exit;
fceaf24a 492
0c3b7b2f 493cleanup:
5a71ae30 494 netvsc_destroy_send_buf(net_device);
fceaf24a 495
0c3b7b2f 496exit:
5a71ae30 497 put_net_device(device);
fceaf24a
HJ
498 return ret;
499}
500
fceaf24a 501
5a71ae30 502static int netvsc_connect_vsp(struct hv_device *device)
fceaf24a 503{
21a80820 504 int ret;
85799a37
HZ
505 struct netvsc_device *net_device;
506 struct nvsp_message *init_packet;
507 int ndis_version;
fceaf24a 508
5a71ae30 509 net_device = get_outbound_net_device(device);
85799a37 510 if (!net_device) {
eb335bc4 511 dev_err(&device->device, "unable to get net device..."
21a80820 512 "device being destroyed?");
fceaf24a
HJ
513 return -1;
514 }
515
53d21fdb 516 init_packet = &net_device->channel_init_pkt;
fceaf24a 517
85799a37 518 memset(init_packet, 0, sizeof(struct nvsp_message));
53d21fdb
HZ
519 init_packet->hdr.msg_type = NVSP_MSG_TYPE_INIT;
520 init_packet->msg.init_msg.init.min_protocol_ver =
85799a37 521 NVSP_MIN_PROTOCOL_VERSION;
53d21fdb 522 init_packet->msg.init_msg.init.max_protocol_ver =
85799a37 523 NVSP_MAX_PROTOCOL_VERSION;
fceaf24a 524
454f18a9 525 /* Send the init request */
0c3b7b2f 526 net_device->wait_condition = 0;
85799a37 527 ret = vmbus_sendpacket(device->channel, init_packet,
5a4df290 528 sizeof(struct nvsp_message),
85799a37 529 (unsigned long)init_packet,
415f2287 530 VM_PKT_DATA_INBAND,
5a4df290 531 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
21a80820 532
b8a3d52b 533 if (ret != 0)
0c3b7b2f 534 goto cleanup;
fceaf24a 535
0c3b7b2f
S
536 wait_event_timeout(net_device->channel_init_wait,
537 net_device->wait_condition,
538 msecs_to_jiffies(1000));
539 if (net_device->wait_condition == 0) {
540 ret = -ETIMEDOUT;
541 goto cleanup;
542 }
fceaf24a 543
53d21fdb
HZ
544 if (init_packet->msg.init_msg.init_complete.status !=
545 NVSP_STAT_SUCCESS) {
fceaf24a 546 ret = -1;
0c3b7b2f 547 goto cleanup;
fceaf24a
HJ
548 }
549
53d21fdb
HZ
550 if (init_packet->msg.init_msg.init_complete.
551 negotiated_protocol_ver != NVSP_PROTOCOL_VERSION_1) {
fceaf24a 552 ret = -1;
0c3b7b2f 553 goto cleanup;
fceaf24a 554 }
454f18a9 555 /* Send the ndis version */
85799a37 556 memset(init_packet, 0, sizeof(struct nvsp_message));
fceaf24a 557
85799a37 558 ndis_version = 0x00050000;
fceaf24a 559
53d21fdb
HZ
560 init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_NDIS_VER;
561 init_packet->msg.v1_msg.
562 send_ndis_ver.ndis_major_ver =
85799a37 563 (ndis_version & 0xFFFF0000) >> 16;
53d21fdb
HZ
564 init_packet->msg.v1_msg.
565 send_ndis_ver.ndis_minor_ver =
85799a37 566 ndis_version & 0xFFFF;
fceaf24a 567
454f18a9 568 /* Send the init request */
85799a37 569 ret = vmbus_sendpacket(device->channel, init_packet,
0c3b7b2f
S
570 sizeof(struct nvsp_message),
571 (unsigned long)init_packet,
572 VM_PKT_DATA_INBAND, 0);
21a80820 573 if (ret != 0) {
fceaf24a 574 ret = -1;
0c3b7b2f 575 goto cleanup;
fceaf24a 576 }
454f18a9
BP
577
578 /* Post the big receive buffer to NetVSP */
5a71ae30 579 ret = netvsc_init_recv_buf(device);
fceaf24a 580 if (ret == 0)
5a71ae30 581 ret = netvsc_init_send_buf(device);
fceaf24a 582
0c3b7b2f 583cleanup:
5a71ae30 584 put_net_device(device);
fceaf24a
HJ
585 return ret;
586}
587
85799a37 588static void NetVscDisconnectFromVsp(struct netvsc_device *net_device)
fceaf24a 589{
5a71ae30
HZ
590 netvsc_destroy_recv_buf(net_device);
591 netvsc_destroy_send_buf(net_device);
fceaf24a
HJ
592}
593
3e189519 594/*
5a71ae30
HZ
595 * netvsc_device_add - Callback when the device belonging to this
596 * driver is added
21a80820 597 */
5a71ae30 598static int netvsc_device_add(struct hv_device *device, void *additional_info)
fceaf24a 599{
21a80820 600 int ret = 0;
fceaf24a 601 int i;
85799a37 602 struct netvsc_device *net_device;
d29274ef 603 struct hv_netvsc_packet *packet, *pos;
85799a37 604 struct netvsc_driver *net_driver =
ca623ad3 605 (struct netvsc_driver *)device->drv;
fceaf24a 606
5a71ae30 607 net_device = alloc_net_device(device);
85799a37 608 if (!net_device) {
fceaf24a 609 ret = -1;
0c3b7b2f 610 goto cleanup;
fceaf24a
HJ
611 }
612
454f18a9 613 /* Initialize the NetVSC channel extension */
53d21fdb
HZ
614 net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
615 spin_lock_init(&net_device->recv_pkt_list_lock);
fceaf24a 616
53d21fdb 617 net_device->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
fceaf24a 618
53d21fdb 619 INIT_LIST_HEAD(&net_device->recv_pkt_list);
fceaf24a 620
21a80820
GKH
621 for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) {
622 packet = kzalloc(sizeof(struct hv_netvsc_packet) +
623 (NETVSC_RECEIVE_SG_COUNT *
624 sizeof(struct hv_page_buffer)), GFP_KERNEL);
b8a3d52b 625 if (!packet)
fceaf24a 626 break;
b8a3d52b 627
72a2f5bd 628 list_add_tail(&packet->list_ent,
53d21fdb 629 &net_device->recv_pkt_list);
fceaf24a 630 }
0c3b7b2f 631 init_waitqueue_head(&net_device->channel_init_wait);
fceaf24a 632
454f18a9 633 /* Open the channel */
72a2f5bd
HZ
634 ret = vmbus_open(device->channel, net_driver->ring_buf_size,
635 net_driver->ring_buf_size, NULL, 0,
5a71ae30 636 netvsc_channel_cb, device);
fceaf24a 637
21a80820 638 if (ret != 0) {
eb335bc4 639 dev_err(&device->device, "unable to open channel: %d", ret);
fceaf24a 640 ret = -1;
0c3b7b2f 641 goto cleanup;
fceaf24a
HJ
642 }
643
454f18a9 644 /* Channel is opened */
eb335bc4 645 pr_info("hv_netvsc channel opened successfully");
fceaf24a 646
454f18a9 647 /* Connect with the NetVsp */
5a71ae30 648 ret = netvsc_connect_vsp(device);
21a80820 649 if (ret != 0) {
eb335bc4
HJ
650 dev_err(&device->device,
651 "unable to connect to NetVSP - %d", ret);
fceaf24a 652 ret = -1;
1fb9dff0 653 goto close;
fceaf24a
HJ
654 }
655
fceaf24a
HJ
656 return ret;
657
1fb9dff0 658close:
454f18a9 659 /* Now, we can close the channel safely */
85799a37 660 vmbus_close(device->channel);
fceaf24a 661
0c3b7b2f 662cleanup:
fceaf24a 663
85799a37 664 if (net_device) {
d29274ef 665 list_for_each_entry_safe(packet, pos,
53d21fdb 666 &net_device->recv_pkt_list,
72a2f5bd
HZ
667 list_ent) {
668 list_del(&packet->list_ent);
8c69f52a 669 kfree(packet);
fceaf24a
HJ
670 }
671
5a71ae30
HZ
672 release_outbound_net_device(device);
673 release_inbound_net_device(device);
fceaf24a 674
5a71ae30 675 free_net_device(net_device);
fceaf24a
HJ
676 }
677
fceaf24a
HJ
678 return ret;
679}
680
3e189519 681/*
5a71ae30 682 * netvsc_device_remove - Callback when the root bus device is removed
21a80820 683 */
5a71ae30 684static int netvsc_device_remove(struct hv_device *device)
fceaf24a 685{
85799a37
HZ
686 struct netvsc_device *net_device;
687 struct hv_netvsc_packet *netvsc_packet, *pos;
fceaf24a 688
454f18a9 689 /* Stop outbound traffic ie sends and receives completions */
5a71ae30 690 net_device = release_outbound_net_device(device);
85799a37 691 if (!net_device) {
eb335bc4 692 dev_err(&device->device, "No net device present!!");
fceaf24a
HJ
693 return -1;
694 }
695
454f18a9 696 /* Wait for all send completions */
53d21fdb 697 while (atomic_read(&net_device->num_outstanding_sends)) {
eb335bc4
HJ
698 dev_err(&device->device,
699 "waiting for %d requests to complete...",
700 atomic_read(&net_device->num_outstanding_sends));
b4362c9c 701 udelay(100);
fceaf24a
HJ
702 }
703
85799a37 704 NetVscDisconnectFromVsp(net_device);
fceaf24a 705
454f18a9 706 /* Stop inbound traffic ie receives and sends completions */
5a71ae30 707 net_device = release_inbound_net_device(device);
fceaf24a 708
454f18a9 709 /* At this point, no one should be accessing netDevice except in here */
eb335bc4 710 dev_notice(&device->device, "net device safe to remove");
fceaf24a 711
454f18a9 712 /* Now, we can close the channel safely */
85799a37 713 vmbus_close(device->channel);
fceaf24a 714
454f18a9 715 /* Release all resources */
85799a37 716 list_for_each_entry_safe(netvsc_packet, pos,
53d21fdb 717 &net_device->recv_pkt_list, list_ent) {
72a2f5bd 718 list_del(&netvsc_packet->list_ent);
85799a37 719 kfree(netvsc_packet);
fceaf24a
HJ
720 }
721
5a71ae30 722 free_net_device(net_device);
21a80820 723 return 0;
fceaf24a
HJ
724}
725
3e189519 726/*
5a71ae30 727 * netvsc_cleanup - Perform any cleanup when the driver is removed
21a80820 728 */
5a71ae30 729static void netvsc_cleanup(struct hv_driver *drv)
fceaf24a 730{
fceaf24a
HJ
731}
732
5a71ae30 733static void netvsc_send_completion(struct hv_device *device,
85799a37 734 struct vmpacket_descriptor *packet)
fceaf24a 735{
85799a37
HZ
736 struct netvsc_device *net_device;
737 struct nvsp_message *nvsp_packet;
738 struct hv_netvsc_packet *nvsc_packet;
fceaf24a 739
5a71ae30 740 net_device = get_inbound_net_device(device);
85799a37 741 if (!net_device) {
eb335bc4 742 dev_err(&device->device, "unable to get net device..."
21a80820 743 "device being destroyed?");
fceaf24a
HJ
744 return;
745 }
746
85799a37 747 nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
415f2287 748 (packet->offset8 << 3));
fceaf24a 749
53d21fdb
HZ
750 if ((nvsp_packet->hdr.msg_type == NVSP_MSG_TYPE_INIT_COMPLETE) ||
751 (nvsp_packet->hdr.msg_type ==
752 NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE) ||
753 (nvsp_packet->hdr.msg_type ==
754 NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE)) {
454f18a9 755 /* Copy the response back */
53d21fdb 756 memcpy(&net_device->channel_init_pkt, nvsp_packet,
21a80820 757 sizeof(struct nvsp_message));
0c3b7b2f
S
758 net_device->wait_condition = 1;
759 wake_up(&net_device->channel_init_wait);
53d21fdb
HZ
760 } else if (nvsp_packet->hdr.msg_type ==
761 NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) {
454f18a9 762 /* Get the send context */
85799a37 763 nvsc_packet = (struct hv_netvsc_packet *)(unsigned long)
415f2287 764 packet->trans_id;
fceaf24a 765
454f18a9 766 /* Notify the layer above us */
72a2f5bd
HZ
767 nvsc_packet->completion.send.send_completion(
768 nvsc_packet->completion.send.send_completion_ctx);
fceaf24a 769
53d21fdb 770 atomic_dec(&net_device->num_outstanding_sends);
21a80820 771 } else {
eb335bc4 772 dev_err(&device->device, "Unknown send completion packet type- "
53d21fdb 773 "%d received!!", nvsp_packet->hdr.msg_type);
fceaf24a
HJ
774 }
775
5a71ae30 776 put_net_device(device);
fceaf24a
HJ
777}
778
5a71ae30 779static int netvsc_send(struct hv_device *device,
85799a37 780 struct hv_netvsc_packet *packet)
fceaf24a 781{
85799a37 782 struct netvsc_device *net_device;
21a80820 783 int ret = 0;
fceaf24a 784
223c1aa6 785 struct nvsp_message sendMessage;
fceaf24a 786
5a71ae30 787 net_device = get_outbound_net_device(device);
85799a37 788 if (!net_device) {
eb335bc4 789 dev_err(&device->device, "net device (%p) shutting down..."
85799a37 790 "ignoring outbound packets", net_device);
fceaf24a
HJ
791 return -2;
792 }
793
53d21fdb 794 sendMessage.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT;
72a2f5bd 795 if (packet->is_data_pkt) {
21a80820 796 /* 0 is RMC_DATA; */
53d21fdb 797 sendMessage.msg.v1_msg.send_rndis_pkt.channel_type = 0;
21a80820
GKH
798 } else {
799 /* 1 is RMC_CONTROL; */
53d21fdb 800 sendMessage.msg.v1_msg.send_rndis_pkt.channel_type = 1;
21a80820 801 }
fceaf24a 802
454f18a9 803 /* Not using send buffer section */
53d21fdb
HZ
804 sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_index =
805 0xFFFFFFFF;
806 sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_size = 0;
21a80820 807
72a2f5bd 808 if (packet->page_buf_cnt) {
85799a37 809 ret = vmbus_sendpacket_pagebuffer(device->channel,
72a2f5bd
HZ
810 packet->page_buf,
811 packet->page_buf_cnt,
ff3f8eec
GKH
812 &sendMessage,
813 sizeof(struct nvsp_message),
85799a37 814 (unsigned long)packet);
21a80820 815 } else {
85799a37 816 ret = vmbus_sendpacket(device->channel, &sendMessage,
5a4df290 817 sizeof(struct nvsp_message),
85799a37 818 (unsigned long)packet,
415f2287 819 VM_PKT_DATA_INBAND,
5a4df290 820 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
fceaf24a
HJ
821
822 }
823
824 if (ret != 0)
eb335bc4 825 dev_err(&device->device, "Unable to send packet %p ret %d",
85799a37 826 packet, ret);
fceaf24a 827
53d21fdb 828 atomic_inc(&net_device->num_outstanding_sends);
5a71ae30 829 put_net_device(device);
fceaf24a
HJ
830 return ret;
831}
832
5fa9d3c5
HZ
833static void netvsc_send_recv_completion(struct hv_device *device,
834 u64 transaction_id)
835{
836 struct nvsp_message recvcompMessage;
837 int retries = 0;
838 int ret;
839
840 recvcompMessage.hdr.msg_type =
841 NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE;
842
843 /* FIXME: Pass in the status */
844 recvcompMessage.msg.v1_msg.send_rndis_pkt_complete.status =
845 NVSP_STAT_SUCCESS;
846
847retry_send_cmplt:
848 /* Send the completion */
849 ret = vmbus_sendpacket(device->channel, &recvcompMessage,
850 sizeof(struct nvsp_message), transaction_id,
851 VM_PKT_COMP, 0);
852 if (ret == 0) {
853 /* success */
854 /* no-op */
855 } else if (ret == -1) {
856 /* no more room...wait a bit and attempt to retry 3 times */
857 retries++;
858 dev_err(&device->device, "unable to send receive completion pkt"
859 " (tid %llx)...retrying %d", transaction_id, retries);
860
861 if (retries < 4) {
862 udelay(100);
863 goto retry_send_cmplt;
864 } else {
865 dev_err(&device->device, "unable to send receive "
866 "completion pkt (tid %llx)...give up retrying",
867 transaction_id);
868 }
869 } else {
870 dev_err(&device->device, "unable to send receive "
871 "completion pkt - %llx", transaction_id);
872 }
873}
874
57991156
HZ
875/* Send a receive completion packet to RNDIS device (ie NetVsp) */
876static void netvsc_receive_completion(void *context)
877{
878 struct hv_netvsc_packet *packet = context;
879 struct hv_device *device = (struct hv_device *)packet->device;
880 struct netvsc_device *net_device;
881 u64 transaction_id = 0;
882 bool fsend_receive_comp = false;
883 unsigned long flags;
884
885 /*
886 * Even though it seems logical to do a GetOutboundNetDevice() here to
887 * send out receive completion, we are using GetInboundNetDevice()
888 * since we may have disable outbound traffic already.
889 */
890 net_device = get_inbound_net_device(device);
891 if (!net_device) {
892 dev_err(&device->device, "unable to get net device..."
893 "device being destroyed?");
894 return;
895 }
896
897 /* Overloading use of the lock. */
898 spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
899
900 packet->xfer_page_pkt->count--;
901
902 /*
903 * Last one in the line that represent 1 xfer page packet.
904 * Return the xfer page packet itself to the freelist
905 */
906 if (packet->xfer_page_pkt->count == 0) {
907 fsend_receive_comp = true;
908 transaction_id = packet->completion.recv.recv_completion_tid;
909 list_add_tail(&packet->xfer_page_pkt->list_ent,
910 &net_device->recv_pkt_list);
911
912 }
913
914 /* Put the packet back */
915 list_add_tail(&packet->list_ent, &net_device->recv_pkt_list);
916 spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags);
917
918 /* Send a receive completion for the xfer page packet */
919 if (fsend_receive_comp)
920 netvsc_send_recv_completion(device, transaction_id);
921
922 put_net_device(device);
923}
924
5a71ae30 925static void netvsc_receive(struct hv_device *device,
85799a37 926 struct vmpacket_descriptor *packet)
fceaf24a 927{
85799a37
HZ
928 struct netvsc_device *net_device;
929 struct vmtransfer_page_packet_header *vmxferpage_packet;
930 struct nvsp_message *nvsp_packet;
931 struct hv_netvsc_packet *netvsc_packet = NULL;
c4b0bc94 932 unsigned long start;
85799a37 933 unsigned long end, end_virtual;
7e23a6e9 934 /* struct netvsc_driver *netvscDriver; */
85799a37 935 struct xferpage_packet *xferpage_packet = NULL;
21a80820 936 int i, j;
85799a37 937 int count = 0, bytes_remain = 0;
6436873a 938 unsigned long flags;
d29274ef 939 LIST_HEAD(listHead);
fceaf24a 940
5a71ae30 941 net_device = get_inbound_net_device(device);
85799a37 942 if (!net_device) {
eb335bc4 943 dev_err(&device->device, "unable to get net device..."
21a80820 944 "device being destroyed?");
fceaf24a
HJ
945 return;
946 }
947
21a80820
GKH
948 /*
949 * All inbound packets other than send completion should be xfer page
950 * packet
951 */
415f2287 952 if (packet->type != VM_PKT_DATA_USING_XFER_PAGES) {
eb335bc4 953 dev_err(&device->device, "Unknown packet type received - %d",
415f2287 954 packet->type);
5a71ae30 955 put_net_device(device);
fceaf24a
HJ
956 return;
957 }
958
85799a37 959 nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
415f2287 960 (packet->offset8 << 3));
fceaf24a 961
454f18a9 962 /* Make sure this is a valid nvsp packet */
53d21fdb
HZ
963 if (nvsp_packet->hdr.msg_type !=
964 NVSP_MSG1_TYPE_SEND_RNDIS_PKT) {
eb335bc4
HJ
965 dev_err(&device->device, "Unknown nvsp packet type received-"
966 " %d", nvsp_packet->hdr.msg_type);
5a71ae30 967 put_net_device(device);
fceaf24a
HJ
968 return;
969 }
970
85799a37 971 vmxferpage_packet = (struct vmtransfer_page_packet_header *)packet;
fceaf24a 972
415f2287 973 if (vmxferpage_packet->xfer_pageset_id != NETVSC_RECEIVE_BUFFER_ID) {
eb335bc4 974 dev_err(&device->device, "Invalid xfer page set id - "
21a80820 975 "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID,
415f2287 976 vmxferpage_packet->xfer_pageset_id);
5a71ae30 977 put_net_device(device);
fceaf24a
HJ
978 return;
979 }
980
454f18a9
BP
981 /*
982 * Grab free packets (range count + 1) to represent this xfer
983 * page packet. +1 to represent the xfer page packet itself.
984 * We grab it here so that we know exactly how many we can
985 * fulfil
986 */
53d21fdb
HZ
987 spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
988 while (!list_empty(&net_device->recv_pkt_list)) {
989 list_move_tail(net_device->recv_pkt_list.next, &listHead);
415f2287 990 if (++count == vmxferpage_packet->range_cnt + 1)
fceaf24a
HJ
991 break;
992 }
53d21fdb 993 spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags);
fceaf24a 994
454f18a9
BP
995 /*
996 * We need at least 2 netvsc pkts (1 to represent the xfer
997 * page and at least 1 for the range) i.e. we can handled
998 * some of the xfer page packet ranges...
999 */
21a80820 1000 if (count < 2) {
eb335bc4
HJ
1001 dev_err(&device->device, "Got only %d netvsc pkt...needed "
1002 "%d pkts. Dropping this xfer page packet completely!",
1003 count, vmxferpage_packet->range_cnt + 1);
fceaf24a 1004
454f18a9 1005 /* Return it to the freelist */
53d21fdb 1006 spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
21a80820 1007 for (i = count; i != 0; i--) {
92ec0893 1008 list_move_tail(listHead.next,
53d21fdb 1009 &net_device->recv_pkt_list);
fceaf24a 1010 }
53d21fdb 1011 spin_unlock_irqrestore(&net_device->recv_pkt_list_lock,
21a80820 1012 flags);
fceaf24a 1013
5a71ae30 1014 netvsc_send_recv_completion(device,
415f2287 1015 vmxferpage_packet->d.trans_id);
fceaf24a 1016
5a71ae30 1017 put_net_device(device);
fceaf24a
HJ
1018 return;
1019 }
1020
454f18a9 1021 /* Remove the 1st packet to represent the xfer page packet itself */
85799a37 1022 xferpage_packet = (struct xferpage_packet *)listHead.next;
72a2f5bd 1023 list_del(&xferpage_packet->list_ent);
d29274ef 1024
21a80820 1025 /* This is how much we can satisfy */
72a2f5bd 1026 xferpage_packet->count = count - 1;
21a80820 1027
415f2287 1028 if (xferpage_packet->count != vmxferpage_packet->range_cnt) {
eb335bc4
HJ
1029 dev_err(&device->device, "Needed %d netvsc pkts to satisy "
1030 "this xfer page...got %d",
1031 vmxferpage_packet->range_cnt, xferpage_packet->count);
fceaf24a
HJ
1032 }
1033
454f18a9 1034 /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
21a80820 1035 for (i = 0; i < (count - 1); i++) {
85799a37 1036 netvsc_packet = (struct hv_netvsc_packet *)listHead.next;
72a2f5bd 1037 list_del(&netvsc_packet->list_ent);
fceaf24a 1038
454f18a9 1039 /* Initialize the netvsc packet */
72a2f5bd
HZ
1040 netvsc_packet->xfer_page_pkt = xferpage_packet;
1041 netvsc_packet->completion.recv.recv_completion =
5a71ae30 1042 netvsc_receive_completion;
72a2f5bd 1043 netvsc_packet->completion.recv.recv_completion_ctx =
85799a37 1044 netvsc_packet;
72a2f5bd 1045 netvsc_packet->device = device;
21a80820 1046 /* Save this so that we can send it back */
72a2f5bd 1047 netvsc_packet->completion.recv.recv_completion_tid =
415f2287 1048 vmxferpage_packet->d.trans_id;
fceaf24a 1049
72a2f5bd 1050 netvsc_packet->total_data_buflen =
415f2287 1051 vmxferpage_packet->ranges[i].byte_count;
72a2f5bd 1052 netvsc_packet->page_buf_cnt = 1;
fceaf24a 1053
ca623ad3 1054 netvsc_packet->page_buf[0].len =
415f2287 1055 vmxferpage_packet->ranges[i].byte_count;
fceaf24a 1056
85799a37 1057 start = virt_to_phys((void *)((unsigned long)net_device->
415f2287 1058 recv_buf + vmxferpage_packet->ranges[i].byte_offset));
fceaf24a 1059
ca623ad3 1060 netvsc_packet->page_buf[0].pfn = start >> PAGE_SHIFT;
53d21fdb 1061 end_virtual = (unsigned long)net_device->recv_buf
415f2287
HZ
1062 + vmxferpage_packet->ranges[i].byte_offset
1063 + vmxferpage_packet->ranges[i].byte_count - 1;
85799a37 1064 end = virt_to_phys((void *)end_virtual);
fceaf24a 1065
454f18a9 1066 /* Calculate the page relative offset */
ca623ad3 1067 netvsc_packet->page_buf[0].offset =
415f2287 1068 vmxferpage_packet->ranges[i].byte_offset &
85799a37 1069 (PAGE_SIZE - 1);
21a80820
GKH
1070 if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) {
1071 /* Handle frame across multiple pages: */
ca623ad3
HZ
1072 netvsc_packet->page_buf[0].len =
1073 (netvsc_packet->page_buf[0].pfn <<
85799a37 1074 PAGE_SHIFT)
21a80820 1075 + PAGE_SIZE - start;
72a2f5bd 1076 bytes_remain = netvsc_packet->total_data_buflen -
ca623ad3 1077 netvsc_packet->page_buf[0].len;
21a80820 1078 for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) {
ca623ad3 1079 netvsc_packet->page_buf[j].offset = 0;
85799a37 1080 if (bytes_remain <= PAGE_SIZE) {
ca623ad3 1081 netvsc_packet->page_buf[j].len =
85799a37
HZ
1082 bytes_remain;
1083 bytes_remain = 0;
21a80820 1084 } else {
ca623ad3 1085 netvsc_packet->page_buf[j].len =
85799a37
HZ
1086 PAGE_SIZE;
1087 bytes_remain -= PAGE_SIZE;
21a80820 1088 }
ca623ad3 1089 netvsc_packet->page_buf[j].pfn =
85799a37
HZ
1090 virt_to_phys((void *)(end_virtual -
1091 bytes_remain)) >> PAGE_SHIFT;
72a2f5bd 1092 netvsc_packet->page_buf_cnt++;
85799a37 1093 if (bytes_remain == 0)
21a80820 1094 break;
fceaf24a 1095 }
fceaf24a 1096 }
fceaf24a 1097
454f18a9 1098 /* Pass it to the upper layer */
ca623ad3 1099 ((struct netvsc_driver *)device->drv)->
72a2f5bd 1100 recv_cb(device, netvsc_packet);
fceaf24a 1101
5a71ae30 1102 netvsc_receive_completion(netvsc_packet->
72a2f5bd 1103 completion.recv.recv_completion_ctx);
fceaf24a
HJ
1104 }
1105
5a71ae30 1106 put_net_device(device);
fceaf24a
HJ
1107}
1108
5a71ae30 1109static void netvsc_channel_cb(void *context)
fceaf24a 1110{
21a80820 1111 int ret;
85799a37
HZ
1112 struct hv_device *device = context;
1113 struct netvsc_device *net_device;
1114 u32 bytes_recvd;
1115 u64 request_id;
c6fcf0ba 1116 unsigned char *packet;
8dc0a06a 1117 struct vmpacket_descriptor *desc;
c6fcf0ba
BP
1118 unsigned char *buffer;
1119 int bufferlen = NETVSC_PACKET_SIZE;
fceaf24a 1120
c6fcf0ba 1121 packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char),
d70c6731 1122 GFP_ATOMIC);
c6fcf0ba
BP
1123 if (!packet)
1124 return;
1125 buffer = packet;
1126
5a71ae30 1127 net_device = get_inbound_net_device(device);
85799a37 1128 if (!net_device) {
eb335bc4 1129 dev_err(&device->device, "net device (%p) shutting down..."
85799a37 1130 "ignoring inbound packets", net_device);
c6fcf0ba 1131 goto out;
fceaf24a
HJ
1132 }
1133
21a80820 1134 do {
9f630068 1135 ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen,
85799a37 1136 &bytes_recvd, &request_id);
21a80820 1137 if (ret == 0) {
85799a37 1138 if (bytes_recvd > 0) {
21a80820 1139 desc = (struct vmpacket_descriptor *)buffer;
415f2287
HZ
1140 switch (desc->type) {
1141 case VM_PKT_COMP:
5a71ae30 1142 netvsc_send_completion(device, desc);
21a80820
GKH
1143 break;
1144
415f2287 1145 case VM_PKT_DATA_USING_XFER_PAGES:
5a71ae30 1146 netvsc_receive(device, desc);
21a80820
GKH
1147 break;
1148
1149 default:
eb335bc4 1150 dev_err(&device->device,
21a80820
GKH
1151 "unhandled packet type %d, "
1152 "tid %llx len %d\n",
415f2287 1153 desc->type, request_id,
85799a37 1154 bytes_recvd);
21a80820 1155 break;
fceaf24a
HJ
1156 }
1157
454f18a9 1158 /* reset */
c6fcf0ba 1159 if (bufferlen > NETVSC_PACKET_SIZE) {
8c69f52a 1160 kfree(buffer);
fceaf24a 1161 buffer = packet;
c6fcf0ba 1162 bufferlen = NETVSC_PACKET_SIZE;
fceaf24a 1163 }
21a80820 1164 } else {
454f18a9 1165 /* reset */
c6fcf0ba 1166 if (bufferlen > NETVSC_PACKET_SIZE) {
8c69f52a 1167 kfree(buffer);
fceaf24a 1168 buffer = packet;
c6fcf0ba 1169 bufferlen = NETVSC_PACKET_SIZE;
fceaf24a
HJ
1170 }
1171
1172 break;
1173 }
21a80820
GKH
1174 } else if (ret == -2) {
1175 /* Handle large packet */
85799a37 1176 buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
21a80820 1177 if (buffer == NULL) {
454f18a9 1178 /* Try again next time around */
eb335bc4 1179 dev_err(&device->device,
21a80820 1180 "unable to allocate buffer of size "
85799a37 1181 "(%d)!!", bytes_recvd);
fceaf24a
HJ
1182 break;
1183 }
1184
85799a37 1185 bufferlen = bytes_recvd;
fceaf24a
HJ
1186 }
1187 } while (1);
1188
5a71ae30 1189 put_net_device(device);
c6fcf0ba
BP
1190out:
1191 kfree(buffer);
fceaf24a
HJ
1192 return;
1193}
af24ce42
HZ
1194
1195/*
1196 * netvsc_initialize - Main entry point
1197 */
1198int netvsc_initialize(struct hv_driver *drv)
1199{
1200 struct netvsc_driver *driver = (struct netvsc_driver *)drv;
1201
1202 drv->name = driver_name;
1203 memcpy(&drv->dev_type, &netvsc_device_type, sizeof(struct hv_guid));
1204
1205 /* Setup the dispatch table */
1206 driver->base.dev_add = netvsc_device_add;
1207 driver->base.dev_rm = netvsc_device_remove;
1208 driver->base.cleanup = netvsc_cleanup;
1209
1210 driver->send = netvsc_send;
1211
1212 rndis_filter_init(driver);
1213 return 0;
1214}