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