iPXE
netfront.c
Go to the documentation of this file.
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
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdint.h>
28#include <stdlib.h>
29#include <errno.h>
30#include <ipxe/netdevice.h>
31#include <ipxe/ethernet.h>
32#include <ipxe/if_ether.h>
33#include <ipxe/malloc.h>
34#include <ipxe/base16.h>
35#include <ipxe/xen.h>
36#include <ipxe/xenstore.h>
37#include <ipxe/xenbus.h>
38#include <ipxe/xengrant.h>
39#include <ipxe/xenevent.h>
40#include "netfront.h"
41
42/** @file
43 *
44 * Xen netfront driver
45 *
46 */
47
48/* Disambiguate the various error causes */
49#define EIO_NETIF_RSP_ERROR \
50 __einfo_error ( EINFO_EIO_NETIF_RSP_ERROR )
51#define EINFO_EIO_NETIF_RSP_ERROR \
52 __einfo_uniqify ( EINFO_EIO, -NETIF_RSP_ERROR, \
53 "Unspecified network error" )
54#define EIO_NETIF_RSP_DROPPED \
55 __einfo_error ( EINFO_EIO_NETIF_RSP_DROPPED )
56#define EINFO_EIO_NETIF_RSP_DROPPED \
57 __einfo_uniqify ( EINFO_EIO, -NETIF_RSP_DROPPED, \
58 "Packet dropped" )
59#define EIO_NETIF_RSP( status ) \
60 EUNIQ ( EINFO_EIO, ( -(status) & 0x1f ), \
61 EIO_NETIF_RSP_ERROR, EIO_NETIF_RSP_DROPPED )
62
63/** List of netfront devices */
64static LIST_HEAD ( netfront_devices );
65
66/******************************************************************************
67 *
68 * XenStore interface
69 *
70 ******************************************************************************
71 */
72
73/**
74 * Reset device
75 *
76 * @v netfront Netfront device
77 * @ret rc Return status code
78 */
79static int netfront_reset ( struct netfront_nic *netfront ) {
80 struct xen_device *xendev = netfront->xendev;
81 int state;
82 int rc;
83
84 /* Get current backend state */
85 if ( ( state = xenbus_backend_state ( xendev ) ) < 0 ) {
86 rc = state;
87 DBGC ( netfront, "NETFRONT %s could not read backend state: "
88 "%s\n", xendev->key, strerror ( rc ) );
89 return rc;
90 }
91
92 /* If the backend is not already in InitWait, then mark
93 * frontend as Closed to shut down the backend.
94 */
95 if ( state != XenbusStateInitWait ) {
96
97 /* Set state to Closed */
99
100 /* Wait for backend to reach Closed */
101 if ( ( rc = xenbus_backend_wait ( xendev,
102 XenbusStateClosed ) ) != 0 ) {
103 DBGC ( netfront, "NETFRONT %s backend did not reach "
104 "Closed: %s\n", xendev->key, strerror ( rc ) );
105 return rc;
106 }
107 }
108
109 /* Reset state to Initialising */
111
112 /* Wait for backend to reach InitWait */
113 if ( ( rc = xenbus_backend_wait ( xendev, XenbusStateInitWait ) ) != 0){
114 DBGC ( netfront, "NETFRONT %s backend did not reach InitWait: "
115 "%s\n", xendev->key, strerror ( rc ) );
116 return rc;
117 }
118
119 return 0;
120}
121
122/**
123 * Fetch MAC address
124 *
125 * @v netfront Netfront device
126 * @v hw_addr Hardware address to fill in
127 * @ret rc Return status code
128 */
129static int netfront_read_mac ( struct netfront_nic *netfront, void *hw_addr ) {
130 struct xen_device *xendev = netfront->xendev;
131 struct xen_hypervisor *xen = xendev->xen;
132 char *mac;
133 int len;
134 int rc;
135
136 /* Fetch MAC address */
137 if ( ( rc = xenstore_read ( xen, &mac, xendev->key, "mac", NULL ) )!=0){
138 DBGC ( netfront, "NETFRONT %s could not read MAC address: %s\n",
139 xendev->key, strerror ( rc ) );
140 goto err_xenstore_read;
141 }
142 DBGC2 ( netfront, "NETFRONT %s has MAC address \"%s\"\n",
143 xendev->key, mac );
144
145 /* Decode MAC address */
146 len = hex_decode ( ':', mac, hw_addr, ETH_ALEN );
147 if ( len < 0 ) {
148 rc = len;
149 DBGC ( netfront, "NETFRONT %s could not decode MAC address "
150 "\"%s\": %s\n", xendev->key, mac, strerror ( rc ) );
151 goto err_decode;
152 }
153
154 /* Success */
155 rc = 0;
156
157 err_decode:
158 free ( mac );
159 err_xenstore_read:
160 return rc;
161}
162
163/**
164 * Write XenStore numeric value
165 *
166 * @v netfront Netfront device
167 * @v subkey Subkey
168 * @v num Numeric value
169 * @ret rc Return status code
170 */
171static int netfront_write_num ( struct netfront_nic *netfront,
172 const char *subkey, unsigned long num ) {
173 struct xen_device *xendev = netfront->xendev;
174 struct xen_hypervisor *xen = xendev->xen;
175 int rc;
176
177 /* Write value */
178 if ( ( rc = xenstore_write_num ( xen, num, xendev->key, subkey,
179 NULL ) ) != 0 ) {
180 DBGC ( netfront, "NETFRONT %s could not set %s=\"%ld\": %s\n",
181 xendev->key, subkey, num, strerror ( rc ) );
182 return rc;
183 }
184
185 return 0;
186}
187
188/**
189 * Write XenStore flag value
190 *
191 * @v netfront Netfront device
192 * @v subkey Subkey
193 * @v num Numeric value
194 * @ret rc Return status code
195 */
196static int netfront_write_flag ( struct netfront_nic *netfront,
197 const char *subkey ) {
198
199 return netfront_write_num ( netfront, subkey, 1 );
200}
201
202/**
203 * Delete XenStore value
204 *
205 * @v netfront Netfront device
206 * @v subkey Subkey
207 * @ret rc Return status code
208 */
209static int netfront_rm ( struct netfront_nic *netfront, const char *subkey ) {
210 struct xen_device *xendev = netfront->xendev;
211 struct xen_hypervisor *xen = xendev->xen;
212 int rc;
213
214 /* Remove value */
215 if ( ( rc = xenstore_rm ( xen, xendev->key, subkey, NULL ) ) != 0 ) {
216 DBGC ( netfront, "NETFRONT %s could not delete %s: %s\n",
217 xendev->key, subkey, strerror ( rc ) );
218 return rc;
219 }
220
221 return 0;
222}
223
224/******************************************************************************
225 *
226 * Events
227 *
228 ******************************************************************************
229 */
230
231/**
232 * Create event channel
233 *
234 * @v netfront Netfront device
235 * @ret rc Return status code
236 */
237static int netfront_create_event ( struct netfront_nic *netfront ) {
238 struct xen_device *xendev = netfront->xendev;
239 struct xen_hypervisor *xen = xendev->xen;
241 struct evtchn_close close;
242 int xenrc;
243 int rc;
244
245 /* Allocate event */
247 alloc_unbound.remote_dom = xendev->backend_id;
248 if ( ( xenrc = xenevent_alloc_unbound ( xen, &alloc_unbound ) ) != 0 ) {
249 rc = -EXEN ( xenrc );
250 DBGC ( netfront, "NETFRONT %s could not allocate event: %s\n",
251 xendev->key, strerror ( rc ) );
252 goto err_alloc_unbound;
253 }
254 netfront->event.port = alloc_unbound.port;
255
256 /* Publish event channel */
257 if ( ( rc = netfront_write_num ( netfront, "event-channel",
258 netfront->event.port ) ) != 0 )
259 goto err_write_num;
260
261 DBGC ( netfront, "NETFRONT %s event-channel=\"%d\"\n",
262 xendev->key, netfront->event.port );
263 return 0;
264
265 netfront_rm ( netfront, "event-channel" );
266 err_write_num:
267 close.port = netfront->event.port;
268 xenevent_close ( xen, &close );
269 err_alloc_unbound:
270 return rc;
271}
272
273/**
274 * Send event
275 *
276 * @v netfront Netfront device
277 * @ret rc Return status code
278 */
279static inline __attribute__ (( always_inline )) int
280netfront_send_event ( struct netfront_nic *netfront ) {
281 struct xen_device *xendev = netfront->xendev;
282 struct xen_hypervisor *xen = xendev->xen;
283 int xenrc;
284 int rc;
285
286 /* Send event */
287 if ( ( xenrc = xenevent_send ( xen, &netfront->event ) ) != 0 ) {
288 rc = -EXEN ( xenrc );
289 DBGC ( netfront, "NETFRONT %s could not send event: %s\n",
290 xendev->key, strerror ( rc ) );
291 return rc;
292 }
293
294 return 0;
295}
296
297/**
298 * Destroy event channel
299 *
300 * @v netfront Netfront device
301 */
302static void netfront_destroy_event ( struct netfront_nic *netfront ) {
303 struct xen_device *xendev = netfront->xendev;
304 struct xen_hypervisor *xen = xendev->xen;
305 struct evtchn_close close;
306
307 /* Unpublish event channel */
308 netfront_rm ( netfront, "event-channel" );
309
310 /* Close event channel */
311 close.port = netfront->event.port;
312 xenevent_close ( xen, &close );
313}
314
315/******************************************************************************
316 *
317 * Descriptor rings
318 *
319 ******************************************************************************
320 */
321
322/**
323 * Create descriptor ring
324 *
325 * @v netfront Netfront device
326 * @v ring Descriptor ring
327 * @ret rc Return status code
328 */
329static int netfront_create_ring ( struct netfront_nic *netfront,
330 struct netfront_ring *ring ) {
331 struct xen_device *xendev = netfront->xendev;
332 struct xen_hypervisor *xen = xendev->xen;
334 unsigned int i;
335 int rc;
336
337 /* Initialise buffer ID ring */
338 for ( i = 0 ; i < ring->count ; i++ ) {
339 ring->ids[i] = i;
340 assert ( ring->iobufs[i] == NULL );
341 }
342 ring->id_prod = 0;
343 ring->id_cons = 0;
344
345 /* Allocate and initialise shared ring */
347 if ( ! ring->sring.raw ) {
348 rc = -ENOMEM;
349 goto err_alloc;
350 }
351
352 /* Grant access to shared ring */
353 addr = virt_to_phys ( ring->sring.raw );
354 if ( ( rc = xengrant_permit_access ( xen, ring->ref, xendev->backend_id,
355 0, addr ) ) != 0 ) {
356 DBGC ( netfront, "NETFRONT %s could not permit access to "
357 "%#08lx: %s\n", xendev->key, addr, strerror ( rc ) );
358 goto err_permit_access;
359 }
360
361 /* Publish shared ring reference */
362 if ( ( rc = netfront_write_num ( netfront, ring->ref_key,
363 ring->ref ) ) != 0 )
364 goto err_write_num;
365
366 DBGC ( netfront, "NETFRONT %s %s=\"%d\" [%08lx,%08lx)\n", xendev->key,
367 ring->ref_key, ring->ref, addr, ( addr + PAGE_SIZE ) );
368 return 0;
369
370 netfront_rm ( netfront, ring->ref_key );
371 err_write_num:
372 xengrant_invalidate ( xen, ring->ref );
373 err_permit_access:
374 free_phys ( ring->sring.raw, PAGE_SIZE );
375 err_alloc:
376 return rc;
377}
378
379/**
380 * Add buffer to descriptor ring
381 *
382 * @v netfront Netfront device
383 * @v ring Descriptor ring
384 * @v addr Physical address
385 * @v iobuf Associated I/O buffer, or NULL
386 * @v id Buffer ID to fill in
387 * @v ref Grant reference to fill in
388 * @ret rc Return status code
389 *
390 * The caller is responsible for ensuring that there is space in the
391 * ring.
392 */
393static int netfront_push ( struct netfront_nic *netfront,
394 struct netfront_ring *ring, physaddr_t addr,
395 struct io_buffer *iobuf, uint16_t *id,
396 grant_ref_t *ref ) {
397 struct xen_device *xendev = netfront->xendev;
398 struct xen_hypervisor *xen = xendev->xen;
399 unsigned int next_id;
400 unsigned int next_ref;
401 int rc;
402
403 /* Sanity check */
404 assert ( ! netfront_ring_is_full ( ring ) );
405
406 /* Allocate buffer ID */
407 next_id = ring->ids[ ring->id_prod & ( ring->count - 1 ) ];
408 next_ref = ring->refs[next_id];
409
410 /* Grant access to page containing address */
411 if ( ( rc = xengrant_permit_access ( xen, next_ref, xendev->backend_id,
412 0, addr ) ) != 0 ) {
413 DBGC ( netfront, "NETFRONT %s could not permit access to "
414 "%#08lx: %s\n", xendev->key, addr, strerror ( rc ) );
415 return rc;
416 }
417
418 /* Store associated I/O buffer, if any */
419 assert ( ring->iobufs[next_id] == NULL );
420 ring->iobufs[next_id] = iobuf;
421
422 /* Consume buffer ID */
423 ring->id_prod++;
424
425 /* Return buffer ID and grant reference */
426 *id = next_id;
427 *ref = next_ref;
428
429 return 0;
430}
431
432/**
433 * Remove buffer from descriptor ring
434 *
435 * @v netfront Netfront device
436 * @v ring Descriptor ring
437 * @v id Buffer ID
438 * @ret iobuf Associated I/O buffer, if any
439 */
440static struct io_buffer * netfront_pull ( struct netfront_nic *netfront,
441 struct netfront_ring *ring,
442 unsigned int id ) {
443 struct xen_device *xendev = netfront->xendev;
444 struct xen_hypervisor *xen = xendev->xen;
445 struct io_buffer *iobuf;
446
447 /* Sanity check */
449
450 /* Revoke access from I/O buffer page */
451 xengrant_invalidate ( xen, ring->refs[id] );
452
453 /* Retrieve I/O buffer */
454 iobuf = ring->iobufs[id];
455 ring->iobufs[id] = NULL;
456
457 /* Free buffer ID */
458 ring->ids[ ( ring->id_cons++ ) & ( ring->count - 1 ) ] = id;
459
460 return iobuf;
461}
462
463/**
464 * Destroy descriptor ring
465 *
466 * @v netfront Netfront device
467 * @v ring Descriptor ring
468 * @v discard Method used to discard outstanding buffer, or NULL
469 */
470static void netfront_destroy_ring ( struct netfront_nic *netfront,
471 struct netfront_ring *ring,
472 void ( * discard ) ( struct io_buffer * ) ){
473 struct xen_device *xendev = netfront->xendev;
474 struct xen_hypervisor *xen = xendev->xen;
475 struct io_buffer *iobuf;
476 unsigned int id;
477
478 /* Flush any outstanding buffers */
479 while ( ! netfront_ring_is_empty ( ring ) ) {
480 id = ring->ids[ ring->id_cons & ( ring->count - 1 ) ];
481 iobuf = netfront_pull ( netfront, ring, id );
482 if ( discard )
483 discard ( iobuf );
484 }
485
486 /* Unpublish shared ring reference */
487 netfront_rm ( netfront, ring->ref_key );
488
489 /* Revoke access from shared ring */
490 xengrant_invalidate ( xen, ring->ref );
491
492 /* Free page */
493 free_phys ( ring->sring.raw, PAGE_SIZE );
494 ring->sring.raw = NULL;
495}
496
497/**
498 * Discard partially received I/O buffers
499 *
500 * @v netfront Netfront device
501 */
502static void netfront_discard ( struct netfront_nic *netfront ) {
503 struct io_buffer *iobuf;
504 struct io_buffer *tmp;
505
506 /* Discard all buffers in the list */
507 list_for_each_entry_safe ( iobuf, tmp, &netfront->rx_partial, list ) {
508 list_del ( &iobuf->list );
509 free_iob ( iobuf );
510 }
511}
512
513/******************************************************************************
514 *
515 * Network device interface
516 *
517 ******************************************************************************
518 */
519
520/**
521 * Refill receive descriptor ring
522 *
523 * @v netdev Network device
524 */
525static void netfront_refill_rx ( struct net_device *netdev ) {
526 struct netfront_nic *netfront = netdev->priv;
527 struct xen_device *xendev = netfront->xendev;
528 struct io_buffer *iobuf;
530 unsigned int refilled = 0;
532 int notify;
533 int rc;
534
535 /* Refill ring */
536 while ( netfront_ring_fill ( &netfront->rx ) < NETFRONT_RX_FILL ) {
537
538 /* Allocate I/O buffer */
539 iobuf = alloc_iob ( PAGE_SIZE );
540 if ( ! iobuf ) {
541 /* Wait for next refill */
542 break;
543 }
544 addr = virt_to_phys ( iobuf->data );
545
546 /* Add to descriptor ring */
547 request = RING_GET_REQUEST ( &netfront->rx_fring,
548 netfront->rx_fring.req_prod_pvt );
549 if ( ( rc = netfront_push ( netfront, &netfront->rx, addr,
550 iobuf, &request->id,
551 &request->gref ) ) != 0 ) {
552 netdev_rx_err ( netdev, iobuf, rc );
553 break;
554 }
555 DBGC2 ( netfront, "NETFRONT %s RX id %d ref %d is %#08lx+%zx\n",
556 xendev->key, request->id, request->gref, addr,
557 iob_tailroom ( iobuf ) );
558
559 /* Move to next descriptor */
560 netfront->rx_fring.req_prod_pvt++;
561 refilled++;
562 }
563
564 /* Push new descriptors and notify backend if applicable */
565 if ( refilled ) {
567 notify );
568 if ( notify )
569 netfront_send_event ( netfront );
570 }
571}
572
573/**
574 * Open network device
575 *
576 * @v netdev Network device
577 * @ret rc Return status code
578 */
579static int netfront_open ( struct net_device *netdev ) {
580 struct netfront_nic *netfront = netdev->priv;
581 struct xen_device *xendev = netfront->xendev;
582 int rc;
583
584 /* Ensure device is in a suitable initial state */
585 if ( ( rc = netfront_reset ( netfront ) ) != 0 )
586 goto err_reset;
587
588 /* Create transmit descriptor ring */
589 if ( ( rc = netfront_create_ring ( netfront, &netfront->tx ) ) != 0 )
590 goto err_create_tx;
591 SHARED_RING_INIT ( netfront->tx_sring );
592 FRONT_RING_INIT ( &netfront->tx_fring, netfront->tx_sring, PAGE_SIZE );
593 assert ( RING_SIZE ( &netfront->tx_fring ) >= netfront->tx.count );
594
595 /* Create receive descriptor ring */
596 if ( ( rc = netfront_create_ring ( netfront, &netfront->rx ) ) != 0 )
597 goto err_create_rx;
598 SHARED_RING_INIT ( netfront->rx_sring );
599 FRONT_RING_INIT ( &netfront->rx_fring, netfront->rx_sring, PAGE_SIZE );
600 assert ( RING_SIZE ( &netfront->rx_fring ) >= netfront->rx.count );
601
602 /* Create event channel */
603 if ( ( rc = netfront_create_event ( netfront ) ) != 0 )
604 goto err_create_event;
605
606 /* "Request" the rx-copy feature. Current versions of
607 * xen_netback.ko will fail silently if this parameter is not
608 * present.
609 */
610 if ( ( rc = netfront_write_flag ( netfront, "request-rx-copy" ) ) != 0 )
611 goto err_request_rx_copy;
612
613 /* Inform backend that we can support scatter-gather */
614 if ( ( rc = netfront_write_flag ( netfront, "feature-sg" ) ) != 0 )
615 goto err_feature_sg;
616
617 /* Disable checksum offload, since we will always do the work anyway */
618 if ( ( rc = netfront_write_flag ( netfront,
619 "feature-no-csum-offload" ) ) != 0 )
620 goto err_feature_no_csum_offload;
621
622 /* Inform backend that we will send notifications for RX requests */
623 if ( ( rc = netfront_write_flag ( netfront,
624 "feature-rx-notify" ) ) != 0 )
625 goto err_feature_rx_notify;
626
627 /* Set state to Connected */
628 if ( ( rc = xenbus_set_state ( xendev, XenbusStateConnected ) ) != 0 ) {
629 DBGC ( netfront, "NETFRONT %s could not set state=\"%d\": %s\n",
630 xendev->key, XenbusStateConnected, strerror ( rc ) );
631 goto err_set_state;
632 }
633
634 /* Wait for backend to connect */
635 if ( ( rc = xenbus_backend_wait ( xendev, XenbusStateConnected ) ) !=0){
636 DBGC ( netfront, "NETFRONT %s could not connect to backend: "
637 "%s\n", xendev->key, strerror ( rc ) );
638 goto err_backend_wait;
639 }
640
641 /* Refill receive descriptor ring */
643
644 /* Set link up */
646
647 return 0;
648
649 err_backend_wait:
650 netfront_reset ( netfront );
651 err_set_state:
652 netfront_rm ( netfront, "feature-rx-notify" );
653 err_feature_rx_notify:
654 netfront_rm ( netfront, "feature-no-csum-offload" );
655 err_feature_no_csum_offload:
656 netfront_rm ( netfront, "feature-sg" );
657 err_feature_sg:
658 netfront_rm ( netfront, "request-rx-copy" );
659 err_request_rx_copy:
660 netfront_destroy_event ( netfront );
661 err_create_event:
662 netfront_destroy_ring ( netfront, &netfront->rx, NULL );
663 err_create_rx:
664 netfront_destroy_ring ( netfront, &netfront->tx, NULL );
665 err_create_tx:
666 err_reset:
667 return rc;
668}
669
670/**
671 * Close network device
672 *
673 * @v netdev Network device
674 */
675static void netfront_close ( struct net_device *netdev ) {
676 struct netfront_nic *netfront = netdev->priv;
677 struct xen_device *xendev = netfront->xendev;
678 int rc;
679
680 /* Reset devic, thereby ensuring that grant references are no
681 * longer in use, etc.
682 */
683 if ( ( rc = netfront_reset ( netfront ) ) != 0 ) {
684 DBGC ( netfront, "NETFRONT %s could not disconnect from "
685 "backend: %s\n", xendev->key, strerror ( rc ) );
686 /* Things will probably go _very_ badly wrong if this
687 * happens, since it means the backend may still write
688 * to the outstanding RX buffers that we are about to
689 * free. The best we can do is report the error via
690 * the link status, but there's a good chance the
691 * machine will crash soon.
692 */
694 } else {
696 }
697
698 /* Delete flags */
699 netfront_rm ( netfront, "feature-rx-notify" );
700 netfront_rm ( netfront, "feature-no-csum-offload" );
701 netfront_rm ( netfront, "feature-sg" );
702 netfront_rm ( netfront, "request-rx-copy" );
703
704 /* Destroy event channel */
705 netfront_destroy_event ( netfront );
706
707 /* Discard any partially received I/O buffers */
708 netfront_discard ( netfront );
709
710 /* Destroy receive descriptor ring, freeing any outstanding
711 * I/O buffers.
712 */
713 netfront_destroy_ring ( netfront, &netfront->rx, free_iob );
714
715 /* Destroy transmit descriptor ring. Leave any outstanding
716 * I/O buffers to be freed by netdev_tx_flush().
717 */
718 netfront_destroy_ring ( netfront, &netfront->tx, NULL );
719}
720
721/**
722 * Transmit packet
723 *
724 * @v netdev Network device
725 * @v iobuf I/O buffer
726 * @ret rc Return status code
727 */
729 struct io_buffer *iobuf ) {
730 struct netfront_nic *netfront = netdev->priv;
731 struct xen_device *xendev = netfront->xendev;
734 size_t len;
735 size_t remaining;
736 size_t frag_len;
737 unsigned int offset;
738 unsigned int count;
739 unsigned int more;
740 int notify;
741 int rc;
742
743 /* Calculate number of page buffers required */
744 addr = virt_to_phys ( iobuf->data );
745 len = iob_len ( iobuf );
746 offset = ( addr & ( PAGE_SIZE - 1 ) );
747 count = ( ( offset + len + PAGE_SIZE - 1 ) / PAGE_SIZE );
748
749 /* Check that we have space in the ring */
750 if ( netfront_ring_space ( &netfront->tx ) < count ) {
751 DBGC ( netfront, "NETFRONT %s out of transmit descriptors\n",
752 xendev->key );
753 return -ENOBUFS;
754 }
755
756 /* Add to descriptor ring */
757 remaining = len;
758 while ( remaining ) {
759
760 /* Calculate length of this fragment */
761 frag_len = ( PAGE_SIZE - offset );
762 if ( frag_len >= remaining ) {
763 frag_len = remaining;
764 more = 0;
765 } else {
766 more = NETTXF_more_data;
767 }
768
769 /* Populate request */
770 request = RING_GET_REQUEST ( &netfront->tx_fring,
771 netfront->tx_fring.req_prod_pvt );
772 if ( ( rc = netfront_push ( netfront, &netfront->tx, addr,
773 ( more ? NULL : iobuf ),
774 &request->id,
775 &request->gref ) ) != 0 ) {
776 return rc;
777 }
778 request->flags = ( NETTXF_data_validated | more );
779 request->offset = offset;
780 request->size = ( ( remaining == len ) ? len : frag_len );
781 DBGC2 ( netfront, "NETFRONT %s TX id %d ref %d is "
782 "%#08lx+%zx%s\n", xendev->key, request->id,
783 request->gref, addr, frag_len, ( more ? "..." : "" ) );
784
785 /* Move to next descriptor */
786 netfront->tx_fring.req_prod_pvt++;
787 addr += frag_len;
788 remaining -= frag_len;
789 offset = 0;
790 }
791
792 /* Push new descriptors and notify backend if applicable */
793 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY ( &netfront->tx_fring, notify );
794 if ( notify )
795 netfront_send_event ( netfront );
796
797 return 0;
798}
799
800/**
801 * Poll for completed packets
802 *
803 * @v netdev Network device
804 */
805static void netfront_poll_tx ( struct net_device *netdev ) {
806 struct netfront_nic *netfront = netdev->priv;
807 struct xen_device *xendev = netfront->xendev;
808 struct netif_tx_response *response;
809 struct io_buffer *iobuf;
810 int status;
811 int rc;
812
813 /* Consume any unconsumed responses */
814 while ( RING_HAS_UNCONSUMED_RESPONSES ( &netfront->tx_fring ) ) {
815
816 /* Get next response */
817 response = RING_GET_RESPONSE ( &netfront->tx_fring,
818 netfront->tx_fring.rsp_cons++ );
819
820 /* Retrieve from descriptor ring */
821 iobuf = netfront_pull ( netfront, &netfront->tx, response->id );
822 status = response->status;
823 if ( status >= NETIF_RSP_OKAY ) {
824 DBGC2 ( netfront, "NETFRONT %s TX id %d complete\n",
825 xendev->key, response->id );
826 if ( iobuf )
827 netdev_tx_complete ( netdev, iobuf );
828 } else {
829 rc = -EIO_NETIF_RSP ( status );
830 DBGC2 ( netfront, "NETFRONT %s TX id %d error %d: %s\n",
831 xendev->key, response->id, status,
832 strerror ( rc ) );
833 netdev_tx_complete_err ( netdev, iobuf, rc );
834 }
835 }
836}
837
838/**
839 * Poll for received packets
840 *
841 * @v netdev Network device
842 */
843static void netfront_poll_rx ( struct net_device *netdev ) {
844 struct netfront_nic *netfront = netdev->priv;
845 struct xen_device *xendev = netfront->xendev;
846 struct netif_rx_response *response;
847 struct io_buffer *iobuf;
848 int status;
849 int more;
850 size_t len;
851 int rc;
852
853 /* Consume any unconsumed responses */
854 while ( RING_HAS_UNCONSUMED_RESPONSES ( &netfront->rx_fring ) ) {
855
856 /* Get next response */
857 response = RING_GET_RESPONSE ( &netfront->rx_fring,
858 netfront->rx_fring.rsp_cons++ );
859
860 /* Retrieve from descriptor ring */
861 iobuf = netfront_pull ( netfront, &netfront->rx, response->id );
862 status = response->status;
863 more = ( response->flags & NETRXF_more_data );
864
865 /* Report errors */
866 if ( status < 0 ) {
867 rc = -EIO_NETIF_RSP ( status );
868 DBGC2 ( netfront, "NETFRONT %s RX id %d error %d: %s\n",
869 xendev->key, response->id, status,
870 strerror ( rc ) );
871 netfront_discard ( netfront );
872 netdev_rx_err ( netdev, iobuf, rc );
873 continue;
874 }
875
876 /* Add to partial receive list */
877 len = status;
878 iob_reserve ( iobuf, response->offset );
879 iob_put ( iobuf, len );
880 DBGC2 ( netfront, "NETFRONT %s RX id %d complete "
881 "%#08lx+%zx%s\n", xendev->key, response->id,
882 virt_to_phys ( iobuf->data ), len,
883 ( more ? "..." : "" ) );
884 list_add_tail ( &iobuf->list, &netfront->rx_partial );
885
886 /* Wait until complete packet has been received */
887 if ( more )
888 continue;
889
890 /* Reassemble complete packet */
891 iobuf = iob_concatenate ( &netfront->rx_partial );
892 if ( ! iobuf ) {
893 DBGC2 ( netfront, "NETFRONT %s RX reassembly failed\n",
894 xendev->key );
895 netfront_discard ( netfront );
897 continue;
898 }
899
900 /* Hand off to network stack */
901 netdev_rx ( netdev, iobuf );
902 }
903}
904
905/**
906 * Poll for completed and received packets
907 *
908 * @v netdev Network device
909 */
910static void netfront_poll ( struct net_device *netdev ) {
911
912 /* Poll for TX completions */
914
915 /* Poll for RX completions */
917
918 /* Refill RX descriptor ring */
920}
921
922/** Network device operations */
924 .open = netfront_open,
925 .close = netfront_close,
926 .transmit = netfront_transmit,
927 .poll = netfront_poll,
928};
929
930/******************************************************************************
931 *
932 * Xen device bus interface
933 *
934 ******************************************************************************
935 */
936
937/**
938 * Probe Xen device
939 *
940 * @v xendev Xen device
941 * @ret rc Return status code
942 */
943static int netfront_probe ( struct xen_device *xendev ) {
944 struct xen_hypervisor *xen = xendev->xen;
945 struct net_device *netdev;
946 struct netfront_nic *netfront;
947 int rc;
948
949 /* Allocate and initialise structure */
950 netdev = alloc_etherdev ( sizeof ( *netfront ) );
951 if ( ! netdev ) {
952 rc = -ENOMEM;
953 goto err_alloc;
954 }
956 netdev->dev = &xendev->dev;
957 netfront = netdev->priv;
958 netfront->xendev = xendev;
959 netfront->netdev = netdev;
960 INIT_LIST_HEAD ( &netfront->rx_partial );
961 DBGC ( netfront, "NETFRONT %s backend=\"%s\" in domain %ld\n",
963
964 /* Allocate grant references and initialise descriptor rings */
965 if ( ( rc = xengrant_alloc ( xen, netfront->refs,
966 NETFRONT_REF_COUNT ) ) != 0 ) {
967 DBGC ( netfront, "NETFRONT %s could not allocate grant "
968 "references: %s\n", xendev->key, strerror ( rc ) );
969 goto err_grant_alloc;
970 }
971 netfront_init_ring ( &netfront->tx, "tx-ring-ref",
972 netfront->refs[NETFRONT_REF_TX_RING],
974 &netfront->refs[NETFRONT_REF_TX_BASE],
975 netfront->tx_ids );
976 netfront_init_ring ( &netfront->rx, "rx-ring-ref",
977 netfront->refs[NETFRONT_REF_RX_RING],
979 &netfront->refs[NETFRONT_REF_RX_BASE],
980 netfront->rx_ids );
981
982 /* Fetch MAC address */
983 if ( ( rc = netfront_read_mac ( netfront, netdev->hw_addr ) ) != 0 )
984 goto err_read_mac;
985
986 /* Reset device. Ignore failures; allow the device to be
987 * registered so that reset errors can be observed by the user
988 * when attempting to open the device.
989 */
990 netfront_reset ( netfront );
991
992 /* Register network device */
993 if ( ( rc = register_netdev ( netdev ) ) != 0 )
994 goto err_register_netdev;
995
996 /* Set initial link state */
998
999 /* Add to list of netfront devices */
1000 list_add_tail ( &netfront->list, &netfront_devices );
1001
1003 return 0;
1004
1005 list_del ( &netfront->list );
1007 err_register_netdev:
1008 err_read_mac:
1009 xengrant_free ( xen, netfront->refs, NETFRONT_REF_COUNT );
1010 err_grant_alloc:
1012 netdev_put ( netdev );
1013 err_alloc:
1014 return rc;
1015}
1016
1017/**
1018 * Remove Xen device
1019 *
1020 * @v xendev Xen device
1021 */
1022static void netfront_remove ( struct xen_device *xendev ) {
1023 struct net_device *netdev = xen_get_drvdata ( xendev );
1024 struct netfront_nic *netfront = netdev->priv;
1025 struct xen_hypervisor *xen = xendev->xen;
1026
1027 /* Remove from list of netfront devices */
1028 list_del ( &netfront->list );
1029
1030 /* Unregister network device */
1032
1033 /* Free resources */
1034 xengrant_free ( xen, netfront->refs, NETFRONT_REF_COUNT );
1035
1036 /* Free network device */
1038 netdev_put ( netdev );
1039}
1040
1041/** Xen netfront driver */
1042struct xen_driver netfront_driver __xen_driver = {
1043 .name = "netfront",
1044 .type = "vif",
1045 .probe = netfront_probe,
1046 .remove = netfront_remove,
1047};
1048
1049/* Generate build rules */
1050XEN_ROM ( "netfront", "Xen netfront virtual NIC" );
1051
1052/******************************************************************************
1053 *
1054 * Emulated PCI device inhibitor
1055 *
1056 ******************************************************************************
1057 */
1058
1059/**
1060 * Inhibit emulated PCI devices
1061 *
1062 * @v netdev Network device
1063 * @v priv Private data
1064 * @ret rc Return status code
1065 */
1067 void *priv __unused ) {
1068 struct netfront_nic *netfront;
1069
1070 /* Inhibit emulated PCI devices matching an existing netfront device */
1071 list_for_each_entry ( netfront, &netfront_devices, list ) {
1072 if ( ( netdev->dev != netfront->netdev->dev ) &&
1073 ( netdev->ll_protocol->ll_addr_len == ETH_ALEN ) &&
1074 ( memcmp ( netdev->hw_addr, netfront->netdev->hw_addr,
1075 ETH_ALEN ) == 0 ) ) {
1076 DBGC ( netfront, "NETFRONT %s inhibiting emulated %s "
1077 "%s\n", netfront->xendev->key,
1078 netdev->dev->driver_name, netdev->dev->name );
1079 return -EEXIST;
1080 }
1081 }
1082
1083 return 0;
1084}
1085
1086/** Emulated PCI device inhibitor driver */
1087struct net_driver netfront_net_driver __net_driver = {
1088 .name = "netfront",
1089 .probe = netfront_net_probe,
1090};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned short uint16_t
Definition stdint.h:11
unsigned long physaddr_t
Definition stdint.h:20
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
int hex_decode(char separator, const char *encoded, void *data, size_t len)
Decode hexadecimal string (with optional byte separator character)
Definition base16.c:77
Base16 encoding.
uint16_t offset
Offset to command line.
Definition bzimage.h:3
ring len
Length.
Definition dwmac.h:226
uint32_t addr
Buffer address.
Definition dwmac.h:9
uint8_t id
Request identifier.
Definition ena.h:1
uint8_t status
Status.
Definition ena.h:5
uint8_t mac[ETH_ALEN]
MAC address.
Definition ena.h:13
Error codes.
uint8_t state
State.
Definition eth_slow.h:36
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
Ethernet protocol.
static struct net_device * netdev
Definition gdbudp.c:53
uint32_t grant_ref_t
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBGC2(...)
Definition compiler.h:522
#define DBGC(...)
Definition compiler.h:505
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define EEXIST
File exists.
Definition errno.h:389
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOBUFS
No buffer space available.
Definition errno.h:499
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
u8 request[0]
List of IEs requested.
Definition ieee80211.h:2
#define ETH_ALEN
Definition if_ether.h:9
#define __attribute__(x)
Definition compiler.h:10
#define PAGE_SIZE
Page size.
Definition io.h:28
Xen interface.
#define EXEN(xenrc)
Convert a Xen status code to an iPXE status code.
Definition xen.h:87
#define DOMID_SELF
Definition xen.h:581
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
struct io_buffer * iob_concatenate(struct list_head *list)
Concatenate I/O buffers into a single buffer.
Definition iobuf.c:250
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_put(iobuf, len)
Definition iobuf.h:125
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_reserve(iobuf, len)
Definition iobuf.h:72
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition iobuf.h:180
Xen device bus.
static void * xen_get_drvdata(struct xen_device *xendev)
Get Xen device driver-private data.
Definition xenbus.h:80
#define XEN_ROM(_name, _desc)
Define build rules for a Xen device driver.
Definition xenbus.h:62
static void xen_set_drvdata(struct xen_device *xendev, void *priv)
Set Xen device driver-private data.
Definition xenbus.h:70
#define __xen_driver
Declare a Xen device driver.
Definition xenbus.h:59
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define LIST_HEAD(list)
Declare a static list head.
Definition list.h:38
void * malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
Definition malloc.c:707
void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition malloc.c:723
Dynamic memory allocation.
uint32_t num
Definition multiboot.h:0
void netdev_link_err(struct net_device *netdev, int rc)
Mark network device as having a specific link state.
Definition netdevice.c:208
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition netdevice.c:231
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
Definition netdevice.c:471
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition netdevice.c:587
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
Network device management.
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition netdevice.h:789
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
#define __net_driver
Declare a network driver.
Definition netdevice.h:507
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition netdevice.h:767
static int netfront_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition netfront.c:728
static void netfront_refill_rx(struct net_device *netdev)
Refill receive descriptor ring.
Definition netfront.c:525
static void netfront_destroy_event(struct netfront_nic *netfront)
Destroy event channel.
Definition netfront.c:302
static struct net_device_operations netfront_operations
Network device operations.
Definition netfront.c:923
static int netfront_net_probe(struct net_device *netdev, void *priv __unused)
Inhibit emulated PCI devices.
Definition netfront.c:1066
static int netfront_create_ring(struct netfront_nic *netfront, struct netfront_ring *ring)
Create descriptor ring.
Definition netfront.c:329
static int netfront_write_num(struct netfront_nic *netfront, const char *subkey, unsigned long num)
Write XenStore numeric value.
Definition netfront.c:171
static void netfront_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition netfront.c:910
static int netfront_reset(struct netfront_nic *netfront)
Reset device.
Definition netfront.c:79
static int netfront_rm(struct netfront_nic *netfront, const char *subkey)
Delete XenStore value.
Definition netfront.c:209
static void netfront_poll_rx(struct net_device *netdev)
Poll for received packets.
Definition netfront.c:843
static struct io_buffer * netfront_pull(struct netfront_nic *netfront, struct netfront_ring *ring, unsigned int id)
Remove buffer from descriptor ring.
Definition netfront.c:440
static int netfront_push(struct netfront_nic *netfront, struct netfront_ring *ring, physaddr_t addr, struct io_buffer *iobuf, uint16_t *id, grant_ref_t *ref)
Add buffer to descriptor ring.
Definition netfront.c:393
static int netfront_open(struct net_device *netdev)
Open network device.
Definition netfront.c:579
static void netfront_discard(struct netfront_nic *netfront)
Discard partially received I/O buffers.
Definition netfront.c:502
static int netfront_read_mac(struct netfront_nic *netfront, void *hw_addr)
Fetch MAC address.
Definition netfront.c:129
static int netfront_probe(struct xen_device *xendev)
Probe Xen device.
Definition netfront.c:943
static int netfront_send_event(struct netfront_nic *netfront)
Send event.
Definition netfront.c:280
static void netfront_destroy_ring(struct netfront_nic *netfront, struct netfront_ring *ring, void(*discard)(struct io_buffer *))
Destroy descriptor ring.
Definition netfront.c:470
static void netfront_remove(struct xen_device *xendev)
Remove Xen device.
Definition netfront.c:1022
static int netfront_write_flag(struct netfront_nic *netfront, const char *subkey)
Write XenStore flag value.
Definition netfront.c:196
static void netfront_poll_tx(struct net_device *netdev)
Poll for completed packets.
Definition netfront.c:805
static int netfront_create_event(struct netfront_nic *netfront)
Create event channel.
Definition netfront.c:237
#define EIO_NETIF_RSP(status)
Definition netfront.c:59
static void netfront_close(struct net_device *netdev)
Close network device.
Definition netfront.c:675
Xen netfront driver.
static const char grant_ref_t ref
Definition netfront.h:93
#define NETFRONT_RX_FILL
Receive ring fill level.
Definition netfront.h:33
#define NETFRONT_NUM_RX_DESC
Number of receive ring entries.
Definition netfront.h:20
@ NETFRONT_REF_TX_RING
Transmit ring grant reference index.
Definition netfront.h:38
@ NETFRONT_REF_COUNT
Total number of grant references required.
Definition netfront.h:46
@ NETFRONT_REF_TX_BASE
Transmit descriptor grant reference base index.
Definition netfront.h:40
@ NETFRONT_REF_RX_RING
Receive ring grant reference index.
Definition netfront.h:42
@ NETFRONT_REF_RX_BASE
Receive descriptor grant reference base index.
Definition netfront.h:44
#define NETFRONT_NUM_TX_DESC
Number of transmit ring entries.
Definition netfront.h:17
#define NETTXF_data_validated
Definition netif.h:966
#define NETIF_RSP_OKAY
Definition netif.h:1080
#define NETRXF_more_data
Definition netif.h:1053
#define NETTXF_more_data
Definition netif.h:970
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify)
Definition ring.h:318
#define SHARED_RING_INIT(_s)
Definition ring.h:164
#define RING_GET_REQUEST(_r, _idx)
Definition ring.h:243
#define RING_GET_RESPONSE(_r, _idx)
Definition ring.h:246
#define FRONT_RING_INIT(_r, _s, __size)
Definition ring.h:178
#define RING_HAS_UNCONSUMED_RESPONSES(_r)
Definition ring.h:238
#define RING_SIZE
Definition skge.h:32
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
evtchn_port_t port
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:45
Network device operations.
Definition netdevice.h:214
A network device.
Definition netdevice.h:353
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition netdevice.h:382
struct device * dev
Underlying hardware device.
Definition netdevice.h:365
A network upper-layer driver.
Definition netdevice.h:477
A netfront NIC.
Definition netfront.h:157
grant_ref_t refs[NETFRONT_REF_COUNT]
Grant references.
Definition netfront.h:161
uint8_t rx_ids[NETFRONT_NUM_RX_DESC]
Receive I/O buffer IDs.
Definition netfront.h:184
struct io_buffer * tx_iobufs[NETFRONT_NUM_TX_DESC]
Transmit I/O buffers.
Definition netfront.h:173
netif_tx_front_ring_t tx_fring
Transmit front ring.
Definition netfront.h:171
struct xen_device * xendev
Xen device.
Definition netfront.h:159
struct list_head rx_partial
Partial receive I/O buffer list.
Definition netfront.h:186
struct net_device * netdev
Network device.
Definition netfront.h:164
struct io_buffer * rx_iobufs[NETFRONT_NUM_RX_DESC]
Receive I/O buffers.
Definition netfront.h:182
struct evtchn_send event
Event channel.
Definition netfront.h:189
struct netfront_ring rx
Receive ring.
Definition netfront.h:178
netif_rx_front_ring_t rx_fring
Receive front ring.
Definition netfront.h:180
uint8_t tx_ids[NETFRONT_NUM_TX_DESC]
Transmit I/O buffer IDs.
Definition netfront.h:175
struct list_head list
List of netfront NICs.
Definition netfront.h:166
struct netfront_ring tx
Transmit ring.
Definition netfront.h:169
A netfront descriptor ring.
Definition netfront.h:50
grant_ref_t * refs
Grant references, indexed by buffer ID.
Definition netfront.h:70
size_t count
Maximum number of used descriptors.
Definition netfront.h:66
uint8_t * ids
Buffer ID ring.
Definition netfront.h:73
struct io_buffer ** iobufs
I/O buffers, indexed by buffer ID.
Definition netfront.h:68
unsigned int id_prod
Buffer ID ring producer counter.
Definition netfront.h:75
void * raw
Raw pointer.
Definition netfront.h:58
const char * ref_key
Shared ring grant reference key.
Definition netfront.h:61
unsigned int id_cons
Buffer ID ring consumer counter.
Definition netfront.h:77
grant_ref_t ref
Shared ring grant reference.
Definition netfront.h:63
union netfront_ring::@235351263275146342264217234007371176021305365026 sring
Shared ring.
int16_t status
Definition netif.h:1067
uint16_t offset
Definition netif.h:1065
uint16_t id
Definition netif.h:1064
uint16_t flags
Definition netif.h:1066
int16_t status
Definition netif.h:1032
uint16_t id
Definition netif.h:1031
A Xen device.
Definition xenbus.h:19
unsigned long backend_id
Backend domain ID.
Definition xenbus.h:29
struct device dev
Generic iPXE device.
Definition xenbus.h:21
char * key
XenStore key.
Definition xenbus.h:25
struct xen_hypervisor * xen
Xen hypervisor.
Definition xenbus.h:23
char * backend
Backend XenStore key.
Definition xenbus.h:27
A Xen device driver.
Definition xenbus.h:37
A Xen hypervisor.
Definition xen.h:51
static struct tlan_private * priv
Definition tlan.c:225
@ XenbusStateInitWait
Definition xenbus.h:31
@ XenbusStateInitialising
Definition xenbus.h:25
@ XenbusStateClosed
Definition xenbus.h:45
@ XenbusStateConnected
Definition xenbus.h:38
int xenbus_backend_state(struct xen_device *xendev)
Get backend state.
Definition xenbus.c:127
int xenbus_set_state(struct xen_device *xendev, int state)
Set device state.
Definition xenbus.c:107
int xenbus_backend_wait(struct xen_device *xendev, int state)
Wait for backend to reach a given state.
Definition xenbus.c:149
Xen events.
static struct evtchn_close * close
Definition xenevent.h:24
static struct evtchn_alloc_unbound * alloc_unbound
Definition xenevent.h:53
int xengrant_alloc(struct xen_hypervisor *xen, grant_ref_t *refs, unsigned int count)
Allocate grant references.
Definition xengrant.c:149
void xengrant_free(struct xen_hypervisor *xen, grant_ref_t *refs, unsigned int count)
Free grant references.
Definition xengrant.c:215
Xen grant tables.
int xenstore_rm(struct xen_hypervisor *xen,...)
Delete XenStore value.
Definition xenstore.c:484
int xenstore_read(struct xen_hypervisor *xen, char **value,...)
Read XenStore value.
Definition xenstore.c:372
int xenstore_write_num(struct xen_hypervisor *xen, unsigned long num,...)
Write XenStore numeric value.
Definition xenstore.c:461
XenStore interface.