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