1 /*
2 * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 /** @file
27 *
28 * Hyper-V network virtual service client
29 *
30 * The network virtual service client (NetVSC) connects to the network
31 * virtual service provider (NetVSP) via the Hyper-V virtual machine
32 * bus (VMBus). It provides a transport layer for RNDIS packets.
33 */
34
35 #include <errno.h>
36 #include <unistd.h>
37 #include <byteswap.h>
38 #include <ipxe/umalloc.h>
39 #include <ipxe/rndis.h>
40 #include <ipxe/vmbus.h>
41 #include "netvsc.h"
42
43 /**
44 * Send control message and wait for completion
45 *
46 * @v netvsc NetVSC device
47 * @v xrid Relative transaction ID
48 * @v data Data
49 * @v len Length of data
50 * @ret rc Return status code
51 */
netvsc_control(struct netvsc_device * netvsc,unsigned int xrid,const void * data,size_t len)52 static int netvsc_control ( struct netvsc_device *netvsc, unsigned int xrid,
53 const void *data, size_t len ) {
54 uint64_t xid = ( NETVSC_BASE_XID + xrid );
55 unsigned int i;
56 int rc;
57
58 /* Send control message */
59 if ( ( rc = vmbus_send_control ( netvsc->vmdev, xid, data, len ) ) !=0){
60 DBGC ( netvsc, "NETVSC %s could not send control message: %s\n",
61 netvsc->name, strerror ( rc ) );
62 return rc;
63 }
64
65 /* Record transaction ID */
66 netvsc->wait_xrid = xrid;
67
68 /* Wait for operation to complete */
69 for ( i = 0 ; i < NETVSC_MAX_WAIT_MS ; i++ ) {
70
71 /* Check for completion */
72 if ( ! netvsc->wait_xrid )
73 return netvsc->wait_rc;
74
75 /* Poll VMBus device */
76 vmbus_poll ( netvsc->vmdev );
77
78 /* Delay for 1ms */
79 mdelay ( 1 );
80 }
81
82 DBGC ( netvsc, "NETVSC %s timed out waiting for XRID %d\n",
83 netvsc->name, xrid );
84 vmbus_dump_channel ( netvsc->vmdev );
85 return -ETIMEDOUT;
86 }
87
88 /**
89 * Handle generic completion
90 *
91 * @v netvsc NetVSC device
92 * @v data Data
93 * @v len Length of data
94 * @ret rc Return status code
95 */
netvsc_completed(struct netvsc_device * netvsc __unused,const void * data __unused,size_t len __unused)96 static int netvsc_completed ( struct netvsc_device *netvsc __unused,
97 const void *data __unused, size_t len __unused ) {
98 return 0;
99 }
100
101 /**
102 * Initialise communication
103 *
104 * @v netvsc NetVSC device
105 * @ret rc Return status code
106 */
netvsc_initialise(struct netvsc_device * netvsc)107 static int netvsc_initialise ( struct netvsc_device *netvsc ) {
108 struct netvsc_init_message msg;
109 int rc;
110
111 /* Construct message */
112 memset ( &msg, 0, sizeof ( msg ) );
113 msg.header.type = cpu_to_le32 ( NETVSC_INIT_MSG );
114 msg.min = cpu_to_le32 ( NETVSC_VERSION_1 );
115 msg.max = cpu_to_le32 ( NETVSC_VERSION_1 );
116
117 /* Send message and wait for completion */
118 if ( ( rc = netvsc_control ( netvsc, NETVSC_INIT_XRID, &msg,
119 sizeof ( msg ) ) ) != 0 ) {
120 DBGC ( netvsc, "NETVSC %s could not initialise: %s\n",
121 netvsc->name, strerror ( rc ) );
122 return rc;
123 }
124
125 return 0;
126 }
127
128 /**
129 * Handle initialisation completion
130 *
131 * @v netvsc NetVSC device
132 * @v data Data
133 * @v len Length of data
134 * @ret rc Return status code
135 */
136 static int
netvsc_initialised(struct netvsc_device * netvsc,const void * data,size_t len)137 netvsc_initialised ( struct netvsc_device *netvsc, const void *data,
138 size_t len ) {
139 const struct netvsc_init_completion *cmplt = data;
140
141 /* Check completion */
142 if ( len < sizeof ( *cmplt ) ) {
143 DBGC ( netvsc, "NETVSC %s underlength initialisation "
144 "completion (%zd bytes)\n", netvsc->name, len );
145 return -EINVAL;
146 }
147 if ( cmplt->header.type != cpu_to_le32 ( NETVSC_INIT_CMPLT ) ) {
148 DBGC ( netvsc, "NETVSC %s unexpected initialisation completion "
149 "type %d\n", netvsc->name,
150 le32_to_cpu ( cmplt->header.type ) );
151 return -EPROTO;
152 }
153 if ( cmplt->status != cpu_to_le32 ( NETVSC_OK ) ) {
154 DBGC ( netvsc, "NETVSC %s initialisation failure status %d\n",
155 netvsc->name, le32_to_cpu ( cmplt->status ) );
156 return -EPROTO;
157 }
158
159 return 0;
160 }
161
162 /**
163 * Set NDIS version
164 *
165 * @v netvsc NetVSC device
166 * @ret rc Return status code
167 */
netvsc_ndis_version(struct netvsc_device * netvsc)168 static int netvsc_ndis_version ( struct netvsc_device *netvsc ) {
169 struct netvsc_ndis_version_message msg;
170 int rc;
171
172 /* Construct message */
173 memset ( &msg, 0, sizeof ( msg ) );
174 msg.header.type = cpu_to_le32 ( NETVSC_NDIS_VERSION_MSG );
175 msg.major = cpu_to_le32 ( NETVSC_NDIS_MAJOR );
176 msg.minor = cpu_to_le32 ( NETVSC_NDIS_MINOR );
177
178 /* Send message and wait for completion */
179 if ( ( rc = netvsc_control ( netvsc, NETVSC_NDIS_VERSION_XRID,
180 &msg, sizeof ( msg ) ) ) != 0 ) {
181 DBGC ( netvsc, "NETVSC %s could not set NDIS version: %s\n",
182 netvsc->name, strerror ( rc ) );
183 return rc;
184 }
185
186 return 0;
187 }
188
189 /**
190 * Establish data buffer
191 *
192 * @v netvsc NetVSC device
193 * @v buffer Data buffer
194 * @ret rc Return status code
195 */
netvsc_establish_buffer(struct netvsc_device * netvsc,struct netvsc_buffer * buffer)196 static int netvsc_establish_buffer ( struct netvsc_device *netvsc,
197 struct netvsc_buffer *buffer ) {
198 struct netvsc_establish_buffer_message msg;
199 int rc;
200
201 /* Construct message */
202 memset ( &msg, 0, sizeof ( msg ) );
203 msg.header.type = cpu_to_le32 ( buffer->establish_type );
204 msg.gpadl = cpu_to_le32 ( buffer->gpadl );
205 msg.pageset = buffer->pages.pageset; /* Already protocol-endian */
206
207 /* Send message and wait for completion */
208 if ( ( rc = netvsc_control ( netvsc, buffer->establish_xrid, &msg,
209 sizeof ( msg ) ) ) != 0 ) {
210 DBGC ( netvsc, "NETVSC %s could not establish buffer: %s\n",
211 netvsc->name, strerror ( rc ) );
212 return rc;
213 }
214
215 return 0;
216 }
217
218 /**
219 * Handle establish receive data buffer completion
220 *
221 * @v netvsc NetVSC device
222 * @v data Data
223 * @v len Length of data
224 * @ret rc Return status code
225 */
netvsc_rx_established_buffer(struct netvsc_device * netvsc,const void * data,size_t len)226 static int netvsc_rx_established_buffer ( struct netvsc_device *netvsc,
227 const void *data, size_t len ) {
228 const struct netvsc_rx_establish_buffer_completion *cmplt = data;
229
230 /* Check completion */
231 if ( len < sizeof ( *cmplt ) ) {
232 DBGC ( netvsc, "NETVSC %s underlength buffer completion (%zd "
233 "bytes)\n", netvsc->name, len );
234 return -EINVAL;
235 }
236 if ( cmplt->header.type != cpu_to_le32 ( NETVSC_RX_ESTABLISH_CMPLT ) ) {
237 DBGC ( netvsc, "NETVSC %s unexpected buffer completion type "
238 "%d\n", netvsc->name, le32_to_cpu ( cmplt->header.type));
239 return -EPROTO;
240 }
241 if ( cmplt->status != cpu_to_le32 ( NETVSC_OK ) ) {
242 DBGC ( netvsc, "NETVSC %s buffer failure status %d\n",
243 netvsc->name, le32_to_cpu ( cmplt->status ) );
244 return -EPROTO;
245 }
246
247 return 0;
248 }
249
250 /**
251 * Revoke data buffer
252 *
253 * @v netvsc NetVSC device
254 * @v buffer Data buffer
255 * @ret rc Return status code
256 */
netvsc_revoke_buffer(struct netvsc_device * netvsc,struct netvsc_buffer * buffer)257 static int netvsc_revoke_buffer ( struct netvsc_device *netvsc,
258 struct netvsc_buffer *buffer ) {
259 struct netvsc_revoke_buffer_message msg;
260 int rc;
261
262 /* If the buffer's GPADL is obsolete (i.e. was created before
263 * the most recent Hyper-V reset), then we will never receive
264 * a response to the revoke message. Since the GPADL is
265 * already destroyed as far as the hypervisor is concerned, no
266 * further action is required.
267 */
268 if ( netvsc_is_obsolete ( netvsc ) )
269 return 0;
270
271 /* Construct message */
272 memset ( &msg, 0, sizeof ( msg ) );
273 msg.header.type = cpu_to_le32 ( buffer->revoke_type );
274 msg.pageset = buffer->pages.pageset; /* Already protocol-endian */
275
276 /* Send message and wait for completion */
277 if ( ( rc = netvsc_control ( netvsc, buffer->revoke_xrid,
278 &msg, sizeof ( msg ) ) ) != 0 ) {
279 DBGC ( netvsc, "NETVSC %s could not revoke buffer: %s\n",
280 netvsc->name, strerror ( rc ) );
281 return rc;
282 }
283
284 return 0;
285 }
286
287 /**
288 * Handle received control packet
289 *
290 * @v vmdev VMBus device
291 * @v xid Transaction ID
292 * @v data Data
293 * @v len Length of data
294 * @ret rc Return status code
295 */
netvsc_recv_control(struct vmbus_device * vmdev,uint64_t xid,const void * data,size_t len)296 static int netvsc_recv_control ( struct vmbus_device *vmdev, uint64_t xid,
297 const void *data, size_t len ) {
298 struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
299 struct netvsc_device *netvsc = rndis->priv;
300
301 DBGC ( netvsc, "NETVSC %s received unsupported control packet "
302 "(%08llx):\n", netvsc->name, xid );
303 DBGC_HDA ( netvsc, 0, data, len );
304 return -ENOTSUP;
305 }
306
307 /**
308 * Handle received data packet
309 *
310 * @v vmdev VMBus device
311 * @v xid Transaction ID
312 * @v data Data
313 * @v len Length of data
314 * @v list List of I/O buffers
315 * @ret rc Return status code
316 */
netvsc_recv_data(struct vmbus_device * vmdev,uint64_t xid,const void * data,size_t len,struct list_head * list)317 static int netvsc_recv_data ( struct vmbus_device *vmdev, uint64_t xid,
318 const void *data, size_t len,
319 struct list_head *list ) {
320 struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
321 struct netvsc_device *netvsc = rndis->priv;
322 const struct netvsc_rndis_message *msg = data;
323 struct io_buffer *iobuf;
324 struct io_buffer *tmp;
325 int rc;
326
327 /* Sanity check */
328 if ( len < sizeof ( *msg ) ) {
329 DBGC ( netvsc, "NETVSC %s received underlength RNDIS packet "
330 "(%zd bytes)\n", netvsc->name, len );
331 rc = -EINVAL;
332 goto err_sanity;
333 }
334 if ( msg->header.type != cpu_to_le32 ( NETVSC_RNDIS_MSG ) ) {
335 DBGC ( netvsc, "NETVSC %s received unexpected RNDIS packet "
336 "type %d\n", netvsc->name,
337 le32_to_cpu ( msg->header.type ) );
338 rc = -EINVAL;
339 goto err_sanity;
340 }
341
342 /* Send completion back to host */
343 if ( ( rc = vmbus_send_completion ( vmdev, xid, NULL, 0 ) ) != 0 ) {
344 DBGC ( netvsc, "NETVSC %s could not send completion: %s\n",
345 netvsc->name, strerror ( rc ) );
346 goto err_completion;
347 }
348
349 /* Hand off to RNDIS */
350 list_for_each_entry_safe ( iobuf, tmp, list, list ) {
351 list_del ( &iobuf->list );
352 rndis_rx ( rndis, iob_disown ( iobuf ) );
353 }
354
355 return 0;
356
357 err_completion:
358 err_sanity:
359 list_for_each_entry_safe ( iobuf, tmp, list, list ) {
360 list_del ( &iobuf->list );
361 free_iob ( iobuf );
362 }
363 return rc;
364 }
365
366 /**
367 * Handle received completion packet
368 *
369 * @v vmdev VMBus device
370 * @v xid Transaction ID
371 * @v data Data
372 * @v len Length of data
373 * @ret rc Return status code
374 */
netvsc_recv_completion(struct vmbus_device * vmdev,uint64_t xid,const void * data,size_t len)375 static int netvsc_recv_completion ( struct vmbus_device *vmdev, uint64_t xid,
376 const void *data, size_t len ) {
377 struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
378 struct netvsc_device *netvsc = rndis->priv;
379 struct io_buffer *iobuf;
380 int ( * completion ) ( struct netvsc_device *netvsc,
381 const void *data, size_t len );
382 unsigned int xrid = ( xid - NETVSC_BASE_XID );
383 unsigned int tx_id;
384 int rc;
385
386 /* Handle transmit completion, if applicable */
387 tx_id = ( xrid - NETVSC_TX_BASE_XRID );
388 if ( ( tx_id < NETVSC_TX_NUM_DESC ) &&
389 ( ( iobuf = netvsc->tx.iobufs[tx_id] ) != NULL ) ) {
390
391 /* Free buffer ID */
392 netvsc->tx.iobufs[tx_id] = NULL;
393 netvsc->tx.ids[ ( netvsc->tx.id_cons++ ) &
394 ( netvsc->tx.count - 1 ) ] = tx_id;
395
396 /* Hand back to RNDIS */
397 rndis_tx_complete ( rndis, iobuf );
398 return 0;
399 }
400
401 /* Otherwise determine completion handler */
402 if ( xrid == NETVSC_INIT_XRID ) {
403 completion = netvsc_initialised;
404 } else if ( xrid == NETVSC_RX_ESTABLISH_XRID ) {
405 completion = netvsc_rx_established_buffer;
406 } else if ( ( netvsc->wait_xrid != 0 ) &&
407 ( xrid == netvsc->wait_xrid ) ) {
408 completion = netvsc_completed;
409 } else {
410 DBGC ( netvsc, "NETVSC %s received unexpected completion "
411 "(%08llx)\n", netvsc->name, xid );
412 return -EPIPE;
413 }
414
415 /* Hand off to completion handler */
416 rc = completion ( netvsc, data, len );
417
418 /* Record completion handler result if applicable */
419 if ( xrid == netvsc->wait_xrid ) {
420 netvsc->wait_xrid = 0;
421 netvsc->wait_rc = rc;
422 }
423
424 return rc;
425 }
426
427 /**
428 * Handle received cancellation packet
429 *
430 * @v vmdev VMBus device
431 * @v xid Transaction ID
432 * @ret rc Return status code
433 */
netvsc_recv_cancellation(struct vmbus_device * vmdev,uint64_t xid)434 static int netvsc_recv_cancellation ( struct vmbus_device *vmdev,
435 uint64_t xid ) {
436 struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
437 struct netvsc_device *netvsc = rndis->priv;
438
439 DBGC ( netvsc, "NETVSC %s received unsupported cancellation packet "
440 "(%08llx):\n", netvsc->name, xid );
441 return -ENOTSUP;
442 }
443
444 /** VMBus channel operations */
445 static struct vmbus_channel_operations netvsc_channel_operations = {
446 .recv_control = netvsc_recv_control,
447 .recv_data = netvsc_recv_data,
448 .recv_completion = netvsc_recv_completion,
449 .recv_cancellation = netvsc_recv_cancellation,
450 };
451
452 /**
453 * Poll for completed and received packets
454 *
455 * @v rndis RNDIS device
456 */
netvsc_poll(struct rndis_device * rndis)457 static void netvsc_poll ( struct rndis_device *rndis ) {
458 struct netvsc_device *netvsc = rndis->priv;
459 struct vmbus_device *vmdev = netvsc->vmdev;
460
461 /* Poll VMBus device */
462 while ( vmbus_has_data ( vmdev ) )
463 vmbus_poll ( vmdev );
464 }
465
466 /**
467 * Transmit packet
468 *
469 * @v rndis RNDIS device
470 * @v iobuf I/O buffer
471 * @ret rc Return status code
472 *
473 * If this method returns success then the RNDIS device must
474 * eventually report completion via rndis_tx_complete().
475 */
netvsc_transmit(struct rndis_device * rndis,struct io_buffer * iobuf)476 static int netvsc_transmit ( struct rndis_device *rndis,
477 struct io_buffer *iobuf ) {
478 struct netvsc_device *netvsc = rndis->priv;
479 struct rndis_header *header = iobuf->data;
480 struct netvsc_rndis_message msg;
481 unsigned int tx_id;
482 unsigned int xrid;
483 uint64_t xid;
484 int rc;
485
486 /* If the device is obsolete (i.e. was opened before the most
487 * recent Hyper-V reset), then we will never receive transmit
488 * completions. Fail transmissions immediately to minimise
489 * the delay in closing and reopening the device.
490 */
491 if ( netvsc_is_obsolete ( netvsc ) )
492 return -EPIPE;
493
494 /* Sanity check */
495 assert ( iob_len ( iobuf ) >= sizeof ( *header ) );
496 assert ( iob_len ( iobuf ) == le32_to_cpu ( header->len ) );
497
498 /* Check that we have space in the transmit ring */
499 if ( netvsc_ring_is_full ( &netvsc->tx ) )
500 return rndis_tx_defer ( rndis, iobuf );
501
502 /* Allocate buffer ID and calculate transaction ID */
503 tx_id = netvsc->tx.ids[ netvsc->tx.id_prod & ( netvsc->tx.count - 1 ) ];
504 assert ( netvsc->tx.iobufs[tx_id] == NULL );
505 xrid = ( NETVSC_TX_BASE_XRID + tx_id );
506 xid = ( NETVSC_BASE_XID + xrid );
507
508 /* Construct message */
509 memset ( &msg, 0, sizeof ( msg ) );
510 msg.header.type = cpu_to_le32 ( NETVSC_RNDIS_MSG );
511 msg.channel = ( ( header->type == cpu_to_le32 ( RNDIS_PACKET_MSG ) ) ?
512 NETVSC_RNDIS_DATA : NETVSC_RNDIS_CONTROL );
513 msg.buffer = cpu_to_le32 ( NETVSC_RNDIS_NO_BUFFER );
514
515 /* Send message */
516 if ( ( rc = vmbus_send_data ( netvsc->vmdev, xid, &msg, sizeof ( msg ),
517 iobuf ) ) != 0 ) {
518 DBGC ( netvsc, "NETVSC %s could not send RNDIS message: %s\n",
519 netvsc->name, strerror ( rc ) );
520 return rc;
521 }
522
523 /* Store I/O buffer and consume buffer ID */
524 netvsc->tx.iobufs[tx_id] = iobuf;
525 netvsc->tx.id_prod++;
526
527 return 0;
528 }
529
530 /**
531 * Cancel transmission
532 *
533 * @v netvsc NetVSC device
534 * @v iobuf I/O buffer
535 * @v tx_id Transmission ID
536 */
netvsc_cancel_transmit(struct netvsc_device * netvsc,struct io_buffer * iobuf,unsigned int tx_id)537 static void netvsc_cancel_transmit ( struct netvsc_device *netvsc,
538 struct io_buffer *iobuf,
539 unsigned int tx_id ) {
540 unsigned int xrid;
541 uint64_t xid;
542
543 /* Send cancellation */
544 xrid = ( NETVSC_TX_BASE_XRID + tx_id );
545 xid = ( NETVSC_BASE_XID + xrid );
546 DBGC ( netvsc, "NETVSC %s cancelling transmission %#x\n",
547 netvsc->name, tx_id );
548 vmbus_send_cancellation ( netvsc->vmdev, xid );
549
550 /* Report back to RNDIS */
551 rndis_tx_complete_err ( netvsc->rndis, iobuf, -ECANCELED );
552 }
553
554 /**
555 * Create descriptor ring
556 *
557 * @v netvsc NetVSC device
558 * @v ring Descriptor ring
559 * @ret rc Return status code
560 */
netvsc_create_ring(struct netvsc_device * netvsc __unused,struct netvsc_ring * ring)561 static int netvsc_create_ring ( struct netvsc_device *netvsc __unused,
562 struct netvsc_ring *ring ) {
563 unsigned int i;
564
565 /* Initialise buffer ID ring */
566 for ( i = 0 ; i < ring->count ; i++ ) {
567 ring->ids[i] = i;
568 assert ( ring->iobufs[i] == NULL );
569 }
570 ring->id_prod = 0;
571 ring->id_cons = 0;
572
573 return 0;
574 }
575
576 /**
577 * Destroy descriptor ring
578 *
579 * @v netvsc NetVSC device
580 * @v ring Descriptor ring
581 * @v discard Method used to discard outstanding buffer, or NULL
582 */
netvsc_destroy_ring(struct netvsc_device * netvsc,struct netvsc_ring * ring,void (* discard)(struct netvsc_device *,struct io_buffer *,unsigned int))583 static void netvsc_destroy_ring ( struct netvsc_device *netvsc,
584 struct netvsc_ring *ring,
585 void ( * discard ) ( struct netvsc_device *,
586 struct io_buffer *,
587 unsigned int ) ) {
588 struct io_buffer *iobuf;
589 unsigned int i;
590
591 /* Flush any outstanding buffers */
592 for ( i = 0 ; i < ring->count ; i++ ) {
593 iobuf = ring->iobufs[i];
594 if ( ! iobuf )
595 continue;
596 ring->iobufs[i] = NULL;
597 ring->ids[ ( ring->id_cons++ ) & ( ring->count - 1 ) ] = i;
598 if ( discard )
599 discard ( netvsc, iobuf, i );
600 }
601
602 /* Sanity check */
603 assert ( netvsc_ring_is_empty ( ring ) );
604 }
605
606 /**
607 * Copy data from data buffer
608 *
609 * @v pages Transfer page set
610 * @v data Data buffer
611 * @v offset Offset within page set
612 * @v len Length within page set
613 * @ret rc Return status code
614 */
netvsc_buffer_copy(struct vmbus_xfer_pages * pages,void * data,size_t offset,size_t len)615 static int netvsc_buffer_copy ( struct vmbus_xfer_pages *pages, void *data,
616 size_t offset, size_t len ) {
617 struct netvsc_buffer *buffer =
618 container_of ( pages, struct netvsc_buffer, pages );
619
620 /* Sanity check */
621 if ( ( offset > buffer->len ) || ( len > ( buffer->len - offset ) ) )
622 return -ERANGE;
623
624 /* Copy data from buffer */
625 copy_from_user ( data, buffer->data, offset, len );
626
627 return 0;
628 }
629
630 /** Transfer page set operations */
631 static struct vmbus_xfer_pages_operations netvsc_xfer_pages_operations = {
632 .copy = netvsc_buffer_copy,
633 };
634
635 /**
636 * Create data buffer
637 *
638 * @v netvsc NetVSC device
639 * @v buffer Data buffer
640 * @ret rc Return status code
641 */
netvsc_create_buffer(struct netvsc_device * netvsc,struct netvsc_buffer * buffer)642 static int netvsc_create_buffer ( struct netvsc_device *netvsc,
643 struct netvsc_buffer *buffer ) {
644 struct vmbus_device *vmdev = netvsc->vmdev;
645 int gpadl;
646 int rc;
647
648 /* Allocate receive buffer */
649 buffer->data = umalloc ( buffer->len );
650 if ( ! buffer->data ) {
651 DBGC ( netvsc, "NETVSC %s could not allocate %zd-byte buffer\n",
652 netvsc->name, buffer->len );
653 rc = -ENOMEM;
654 goto err_alloc;
655 }
656
657 /* Establish GPA descriptor list */
658 gpadl = vmbus_establish_gpadl ( vmdev, buffer->data, buffer->len );
659 if ( gpadl < 0 ) {
660 rc = gpadl;
661 DBGC ( netvsc, "NETVSC %s could not establish GPADL: %s\n",
662 netvsc->name, strerror ( rc ) );
663 goto err_establish_gpadl;
664 }
665 buffer->gpadl = gpadl;
666
667 /* Register transfer page set */
668 if ( ( rc = vmbus_register_pages ( vmdev, &buffer->pages ) ) != 0 ) {
669 DBGC ( netvsc, "NETVSC %s could not register transfer pages: "
670 "%s\n", netvsc->name, strerror ( rc ) );
671 goto err_register_pages;
672 }
673
674 return 0;
675
676 vmbus_unregister_pages ( vmdev, &buffer->pages );
677 err_register_pages:
678 vmbus_gpadl_teardown ( vmdev, gpadl );
679 err_establish_gpadl:
680 ufree ( buffer->data );
681 err_alloc:
682 return rc;
683 }
684
685 /**
686 * Destroy data buffer
687 *
688 * @v netvsc NetVSC device
689 * @v buffer Data buffer
690 */
netvsc_destroy_buffer(struct netvsc_device * netvsc,struct netvsc_buffer * buffer)691 static void netvsc_destroy_buffer ( struct netvsc_device *netvsc,
692 struct netvsc_buffer *buffer ) {
693 struct vmbus_device *vmdev = netvsc->vmdev;
694 int rc;
695
696 /* Unregister transfer pages */
697 vmbus_unregister_pages ( vmdev, &buffer->pages );
698
699 /* Tear down GPA descriptor list */
700 if ( ( rc = vmbus_gpadl_teardown ( vmdev, buffer->gpadl ) ) != 0 ) {
701 DBGC ( netvsc, "NETVSC %s could not tear down GPADL: %s\n",
702 netvsc->name, strerror ( rc ) );
703 /* Death is imminent. The host may well continue to
704 * write to the data buffer. The best we can do is
705 * leak memory for now and hope that the host doesn't
706 * write to this region after we load an OS.
707 */
708 return;
709 }
710
711 /* Free buffer */
712 ufree ( buffer->data );
713 }
714
715 /**
716 * Open device
717 *
718 * @v rndis RNDIS device
719 * @ret rc Return status code
720 */
netvsc_open(struct rndis_device * rndis)721 static int netvsc_open ( struct rndis_device *rndis ) {
722 struct netvsc_device *netvsc = rndis->priv;
723 int rc;
724
725 /* Initialise receive buffer */
726 if ( ( rc = netvsc_create_buffer ( netvsc, &netvsc->rx ) ) != 0 )
727 goto err_create_rx;
728
729 /* Open channel */
730 if ( ( rc = vmbus_open ( netvsc->vmdev, &netvsc_channel_operations,
731 PAGE_SIZE, PAGE_SIZE, NETVSC_MTU ) ) != 0 ) {
732 DBGC ( netvsc, "NETVSC %s could not open VMBus: %s\n",
733 netvsc->name, strerror ( rc ) );
734 goto err_vmbus_open;
735 }
736
737 /* Initialise communication with NetVSP */
738 if ( ( rc = netvsc_initialise ( netvsc ) ) != 0 )
739 goto err_initialise;
740 if ( ( rc = netvsc_ndis_version ( netvsc ) ) != 0 )
741 goto err_ndis_version;
742
743 /* Initialise transmit ring */
744 if ( ( rc = netvsc_create_ring ( netvsc, &netvsc->tx ) ) != 0 )
745 goto err_create_tx;
746
747 /* Establish receive buffer */
748 if ( ( rc = netvsc_establish_buffer ( netvsc, &netvsc->rx ) ) != 0 )
749 goto err_establish_rx;
750
751 return 0;
752
753 netvsc_revoke_buffer ( netvsc, &netvsc->rx );
754 err_establish_rx:
755 netvsc_destroy_ring ( netvsc, &netvsc->tx, NULL );
756 err_create_tx:
757 err_ndis_version:
758 err_initialise:
759 vmbus_close ( netvsc->vmdev );
760 err_vmbus_open:
761 netvsc_destroy_buffer ( netvsc, &netvsc->rx );
762 err_create_rx:
763 return rc;
764 }
765
766 /**
767 * Close device
768 *
769 * @v rndis RNDIS device
770 */
netvsc_close(struct rndis_device * rndis)771 static void netvsc_close ( struct rndis_device *rndis ) {
772 struct netvsc_device *netvsc = rndis->priv;
773
774 /* Revoke receive buffer */
775 netvsc_revoke_buffer ( netvsc, &netvsc->rx );
776
777 /* Destroy transmit ring */
778 netvsc_destroy_ring ( netvsc, &netvsc->tx, netvsc_cancel_transmit );
779
780 /* Close channel */
781 vmbus_close ( netvsc->vmdev );
782
783 /* Destroy receive buffer */
784 netvsc_destroy_buffer ( netvsc, &netvsc->rx );
785 }
786
787 /** RNDIS operations */
788 static struct rndis_operations netvsc_operations = {
789 .open = netvsc_open,
790 .close = netvsc_close,
791 .transmit = netvsc_transmit,
792 .poll = netvsc_poll,
793 };
794
795 /**
796 * Probe device
797 *
798 * @v vmdev VMBus device
799 * @ret rc Return status code
800 */
netvsc_probe(struct vmbus_device * vmdev)801 static int netvsc_probe ( struct vmbus_device *vmdev ) {
802 struct netvsc_device *netvsc;
803 struct rndis_device *rndis;
804 int rc;
805
806 /* Allocate and initialise structure */
807 rndis = alloc_rndis ( sizeof ( *netvsc ) );
808 if ( ! rndis ) {
809 rc = -ENOMEM;
810 goto err_alloc;
811 }
812 rndis_init ( rndis, &netvsc_operations );
813 rndis->netdev->dev = &vmdev->dev;
814 netvsc = rndis->priv;
815 netvsc->vmdev = vmdev;
816 netvsc->rndis = rndis;
817 netvsc->name = vmdev->dev.name;
818 netvsc_init_ring ( &netvsc->tx, NETVSC_TX_NUM_DESC,
819 netvsc->tx_iobufs, netvsc->tx_ids );
820 netvsc_init_buffer ( &netvsc->rx, NETVSC_RX_BUF_PAGESET,
821 &netvsc_xfer_pages_operations,
822 NETVSC_RX_ESTABLISH_MSG, NETVSC_RX_ESTABLISH_XRID,
823 NETVSC_RX_REVOKE_MSG, NETVSC_RX_REVOKE_XRID,
824 NETVSC_RX_BUF_LEN );
825 vmbus_set_drvdata ( vmdev, rndis );
826
827 /* Register RNDIS device */
828 if ( ( rc = register_rndis ( rndis ) ) != 0 ) {
829 DBGC ( netvsc, "NETVSC %s could not register: %s\n",
830 netvsc->name, strerror ( rc ) );
831 goto err_register;
832 }
833
834 return 0;
835
836 unregister_rndis ( rndis );
837 err_register:
838 free_rndis ( rndis );
839 err_alloc:
840 return rc;
841 }
842
843 /**
844 * Reset device
845 *
846 * @v vmdev VMBus device
847 * @ret rc Return status code
848 */
netvsc_reset(struct vmbus_device * vmdev)849 static int netvsc_reset ( struct vmbus_device *vmdev ) {
850 struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
851 struct netvsc_device *netvsc = rndis->priv;
852 struct net_device *netdev = rndis->netdev;
853 int rc;
854
855 /* A closed device holds no NetVSC (or RNDIS) state, so there
856 * is nothing to reset.
857 */
858 if ( ! netdev_is_open ( netdev ) )
859 return 0;
860
861 /* Close and reopen device to reset any stale state */
862 netdev_close ( netdev );
863 if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
864 DBGC ( netvsc, "NETVSC %s could not reopen: %s\n",
865 netvsc->name, strerror ( rc ) );
866 return rc;
867 }
868
869 return 0;
870 }
871
872 /**
873 * Remove device
874 *
875 * @v vmdev VMBus device
876 */
netvsc_remove(struct vmbus_device * vmdev)877 static void netvsc_remove ( struct vmbus_device *vmdev ) {
878 struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
879
880 /* Unregister RNDIS device */
881 unregister_rndis ( rndis );
882
883 /* Free RNDIS device */
884 free_rndis ( rndis );
885 }
886
887 /** NetVSC driver */
888 struct vmbus_driver netvsc_driver __vmbus_driver = {
889 .name = "netvsc",
890 .type = VMBUS_TYPE ( 0xf8615163, 0xdf3e, 0x46c5, 0x913f,
891 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e ),
892 .probe = netvsc_probe,
893 .reset = netvsc_reset,
894 .remove = netvsc_remove,
895 };
896