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