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