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, \ 58 #define EIO_NETIF_RSP( status ) \ 59 EUNIQ ( EINFO_EIO, ( -(status) & 0x1f ), \ 60 EIO_NETIF_RSP_ERROR, EIO_NETIF_RSP_DROPPED ) 86 DBGC ( netfront,
"NETFRONT %s could not read backend state: " 102 DBGC ( netfront,
"NETFRONT %s backend did not reach " 113 DBGC ( netfront,
"NETFRONT %s backend did not reach InitWait: " 137 DBGC ( netfront,
"NETFRONT %s could not read MAC address: %s\n",
139 goto err_xenstore_read;
141 DBGC2 ( netfront,
"NETFRONT %s has MAC address \"%s\"\n",
148 DBGC ( netfront,
"NETFRONT %s could not decode MAC address " 171 const char *subkey,
unsigned long num ) {
179 DBGC ( netfront,
"NETFRONT %s could not set %s=\"%ld\": %s\n",
196 const char *subkey ) {
215 DBGC ( netfront,
"NETFRONT %s could not delete %s: %s\n",
247 if ( ( xenrc = xenevent_alloc_unbound ( xen, &
alloc_unbound ) ) != 0 ) {
249 DBGC ( netfront,
"NETFRONT %s could not allocate event: %s\n",
251 goto err_alloc_unbound;
260 DBGC ( netfront,
"NETFRONT %s event-channel=\"%d\"\n",
267 xenevent_close ( xen, &
close );
286 if ( ( xenrc = xenevent_send ( xen, &netfront->
event ) ) != 0 ) {
288 DBGC ( netfront,
"NETFRONT %s could not send event: %s\n",
311 xenevent_close ( xen, &
close );
337 for ( i = 0 ; i < ring->
count ; i++ ) {
353 if ( (
rc = xengrant_permit_access ( xen, ring->
ref, xendev->
backend_id,
355 DBGC ( netfront,
"NETFRONT %s could not permit access to " 357 goto err_permit_access;
365 DBGC ( netfront,
"NETFRONT %s %s=\"%d\" [%08lx,%08lx)\n", xendev->
key,
371 xengrant_invalidate ( xen, ring->
ref );
398 unsigned int next_id;
399 unsigned int next_ref;
403 assert ( ! netfront_ring_is_full ( ring ) );
407 next_ref = ring->
refs[next_id];
410 if ( (
rc = xengrant_permit_access ( xen, next_ref, xendev->
backend_id,
412 DBGC ( netfront,
"NETFRONT %s could not permit access to " 419 ring->
iobufs[next_id] = iobuf;
450 xengrant_invalidate ( xen, ring->
refs[
id] );
471 void ( * discard ) (
struct io_buffer * ) ){
478 while ( ! netfront_ring_is_empty ( ring ) ) {
489 xengrant_invalidate ( xen, ring->
ref );
529 unsigned int refilled = 0;
554 DBGC2 ( netfront,
"NETFRONT %s RX id %d ref %d is %#08lx+%zx\n",
603 goto err_create_event;
610 goto err_request_rx_copy;
618 "feature-no-csum-offload" ) ) != 0 )
619 goto err_feature_no_csum_offload;
623 "feature-rx-notify" ) ) != 0 )
624 goto err_feature_rx_notify;
628 DBGC ( netfront,
"NETFRONT %s could not set state=\"%d\": %s\n",
635 DBGC ( netfront,
"NETFRONT %s could not connect to backend: " 637 goto err_backend_wait;
652 err_feature_rx_notify:
653 netfront_rm ( netfront,
"feature-no-csum-offload" );
654 err_feature_no_csum_offload:
683 DBGC ( netfront,
"NETFRONT %s could not disconnect from " 699 netfront_rm ( netfront,
"feature-no-csum-offload" );
749 if ( netfront_ring_space ( &netfront->
tx ) <
count ) {
750 DBGC ( netfront,
"NETFRONT %s out of transmit descriptors\n",
757 while ( remaining ) {
761 if ( frag_len >= remaining ) {
762 frag_len = remaining;
772 ( more ?
NULL : iobuf ),
780 DBGC2 ( netfront,
"NETFRONT %s TX id %d ref %d is " 782 request->gref,
addr, frag_len, ( more ?
"..." :
"" ) );
787 remaining -= frag_len;
823 DBGC2 ( netfront,
"NETFRONT %s TX id %d complete\n",
824 xendev->
key, response->
id );
829 DBGC2 ( netfront,
"NETFRONT %s TX id %d error %d: %s\n",
867 DBGC2 ( netfront,
"NETFRONT %s RX id %d error %d: %s\n",
879 DBGC2 ( netfront,
"NETFRONT %s RX id %d complete " 880 "%#08lx+%zx%s\n", xendev->
key, response->
id,
882 ( more ?
"..." :
"" ) );
892 DBGC2 ( netfront,
"NETFRONT %s RX reassembly failed\n",
960 DBGC ( netfront,
"NETFRONT %s backend=\"%s\" in domain %ld\n",
966 DBGC ( netfront,
"NETFRONT %s could not allocate grant " 968 goto err_grant_alloc;
970 netfront_init_ring ( &netfront->
tx,
"tx-ring-ref",
975 netfront_init_ring ( &netfront->
rx,
"rx-ring-ref",
993 goto err_register_netdev;
1006 err_register_netdev:
1072 DBGC ( netfront,
"NETFRONT %s inhibiting emulated %s "
static void netfront_refill_rx(struct net_device *netdev)
Refill receive descriptor ring.
struct net_device * netdev
Network device.
char * backend
Backend XenStore key.
struct arbelprm_rc_send_wqe rc
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
#define iob_put(iobuf, len)
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
const char * ref_key
Shared ring grant reference key.
unsigned int id_cons
Buffer ID ring consumer counter.
uint8_t ll_addr_len
Link-layer address length.
struct list_head rx_partial
Partial receive I/O buffer list.
int(* open)(struct net_device *netdev)
Open network device.
static int netfront_rm(struct netfront_nic *netfront, const char *subkey)
Delete XenStore value.
int xenbus_backend_wait(struct xen_device *xendev, int state)
Wait for backend to reach a given state.
static int netfront_open(struct net_device *netdev)
Open network device.
static int netfront_create_event(struct netfront_nic *netfront)
Create event channel.
grant_ref_t ref
Shared ring grant reference.
#define EEXIST
File exists.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
static void *__malloc malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
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.
#define RING_GET_REQUEST(_r, _idx)
static int netfront_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
static struct net_device_operations netfront_operations
Network device operations.
int xenstore_read(struct xen_hypervisor *xen, char **value,...)
Read XenStore value.
uint8_t mac[ETH_ALEN]
MAC address.
#define PAGE_SIZE
Page size.
struct io_buffer * rx_iobufs[NETFRONT_NUM_RX_DESC]
Receive I/O buffers.
#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify)
static int netfront_send_event(struct netfront_nic *netfront)
Send event.
static void netfront_destroy_event(struct netfront_nic *netfront)
Destroy event channel.
int xenstore_write_num(struct xen_hypervisor *xen, unsigned long num,...)
Write XenStore numeric value.
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
static void netfront_remove(struct xen_device *xendev)
Remove Xen device.
Total number of grant references required.
A network upper-layer driver.
uint8_t rx_ids[NETFRONT_NUM_RX_DESC]
Receive I/O buffer IDs.
#define EXEN(xenrc)
Convert a Xen status code to an iPXE status code.
Dynamic memory allocation.
#define EIO_NETIF_RSP(status)
#define NETFRONT_NUM_TX_DESC
Number of transmit ring entries.
struct evtchn_send event
Event channel.
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
#define list_del(list)
Delete an entry from a list.
static int netfront_reset(struct netfront_nic *netfront)
Reset device.
#define SHARED_RING_INIT(_s)
grant_ref_t * refs
Grant references, indexed by buffer ID.
#define ENOMEM
Not enough space.
union netfront_ring::@86 sring
Shared ring.
#define NETFRONT_NUM_RX_DESC
Number of receive ring entries.
static void netfront_poll_tx(struct net_device *netdev)
Poll for completed packets.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
static void netfront_poll(struct net_device *netdev)
Poll for completed and received packets.
static int netfront_read_mac(struct netfront_nic *netfront, void *hw_addr)
Fetch MAC address.
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
void * priv
Driver private data.
#define __unused
Declare a variable or data structure as unused.
static void xen_set_drvdata(struct xen_device *xendev, void *priv)
Set Xen device driver-private data.
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
#define NETFRONT_RX_FILL
Receive ring fill level.
Receive ring grant reference index.
static struct net_device * netdev
static int netfront_write_flag(struct netfront_nic *netfront, const char *subkey)
Write XenStore flag value.
uint16_t count
Number of entries.
Receive descriptor grant reference base index.
int hex_decode(char separator, const char *encoded, void *data, size_t len)
Decode hexadecimal string (with optional byte separator character)
const char * driver_name
Driver name.
void unregister_netdev(struct net_device *netdev)
Unregister network device.
uint8_t * ids
Buffer ID ring.
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
uint8_t id
Request identifier.
size_t count
Maximum number of used descriptors.
struct io_buffer * iob_concatenate(struct list_head *list)
Concatenate I/O buffers into a single buffer.
static int netfront_create_ring(struct netfront_nic *netfront, struct netfront_ring *ring)
Create descriptor ring.
char * strerror(int errno)
Retrieve string representation of error number.
static void(* free)(struct refcnt *refcnt))
int register_netdev(struct net_device *netdev)
Register network device.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
unsigned long backend_id
Backend domain ID.
struct io_buffer * tx_iobufs[NETFRONT_NUM_TX_DESC]
Transmit I/O buffers.
void netdev_link_err(struct net_device *netdev, int rc)
Mark network device as having a specific link state.
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
struct net_driver netfront_net_driver __net_driver
Emulated PCI device inhibitor driver.
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
static int netfront_write_num(struct netfront_nic *netfront, const char *subkey, unsigned long num)
Write XenStore numeric value.
static void netfront_discard(struct netfront_nic *netfront)
Discard partially received I/O buffers.
Transmit descriptor grant reference base index.
grant_ref_t refs[NETFRONT_REF_COUNT]
Grant references.
void xengrant_free(struct xen_hypervisor *xen, grant_ref_t *refs, unsigned int count)
Free grant references.
Network device operations.
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
struct device * dev
Underlying hardware device.
Network device management.
uint8_t tx_ids[NETFRONT_NUM_TX_DESC]
Transmit I/O buffer IDs.
static int netfront_net_probe(struct net_device *netdev, void *priv __unused)
Inhibit emulated PCI devices.
A netfront descriptor ring.
struct io_buffer ** iobufs
I/O buffers, indexed by buffer ID.
#define iob_reserve(iobuf, len)
struct netfront_ring rx
Receive ring.
#define INIT_LIST_HEAD(list)
Initialise a list head.
#define RING_HAS_UNCONSUMED_RESPONSES(_r)
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
struct list_head list
List of which this buffer is a member.
#define ENOBUFS
No buffer space available.
static int netfront_probe(struct xen_device *xendev)
Probe Xen device.
static struct tlan_private * priv
#define RING_GET_RESPONSE(_r, _idx)
static void netfront_destroy_ring(struct netfront_nic *netfront, struct netfront_ring *ring, void(*discard)(struct io_buffer *))
Destroy descriptor ring.
void * data
Start of data.
netif_tx_front_ring_t tx_fring
Transmit front ring.
unsigned int id_prod
Buffer ID ring producer counter.
static void netfront_close(struct net_device *netdev)
Close network device.
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
u8 request[0]
List of IEs requested.
struct list_head list
List of netfront NICs.
netif_rx_front_ring_t rx_fring
Receive front ring.
static void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
struct device dev
Generic iPXE device.
#define FRONT_RING_INIT(_r, _s, __size)
static struct evtchn_alloc_unbound * alloc_unbound
uint16_t offset
Offset to command line.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define NETTXF_data_validated
static void netfront_poll_rx(struct net_device *netdev)
Poll for received packets.
static struct evtchn_close * close
static const char grant_ref_t ref
int xenbus_backend_state(struct xen_device *xendev)
Get backend state.
struct xen_device * xendev
Xen device.
struct netfront_ring tx
Transmit ring.
int xengrant_alloc(struct xen_hypervisor *xen, grant_ref_t *refs, unsigned int count)
Allocate grant references.
int xenbus_set_state(struct xen_device *xendev, int state)
Set device state.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
int xenstore_rm(struct xen_hypervisor *xen,...)
Delete XenStore value.
#define NULL
NULL pointer (VOID *)
struct ll_protocol * ll_protocol
Link-layer protocol.
static struct io_buffer * netfront_pull(struct netfront_nic *netfront, struct netfront_ring *ring, unsigned int id)
Remove buffer from descriptor ring.
static void * xen_get_drvdata(struct xen_device *xendev)
Get Xen device driver-private data.
struct xen_driver netfront_driver __xen_driver
Xen netfront driver.
Transmit ring grant reference index.
struct xen_hypervisor * xen
Xen hypervisor.
static LIST_HEAD(netfront_devices)
List of netfront devices.