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 ) 83 DBGC ( netfront,
"NETFRONT %s could not read backend state: " 99 DBGC ( netfront,
"NETFRONT %s backend did not reach " 110 DBGC ( netfront,
"NETFRONT %s backend did not reach InitWait: " 134 DBGC ( netfront,
"NETFRONT %s could not read MAC address: %s\n",
136 goto err_xenstore_read;
138 DBGC2 ( netfront,
"NETFRONT %s has MAC address \"%s\"\n",
145 DBGC ( netfront,
"NETFRONT %s could not decode MAC address " 168 const char *subkey,
unsigned long num ) {
176 DBGC ( netfront,
"NETFRONT %s could not set %s=\"%ld\": %s\n",
193 const char *subkey ) {
212 DBGC ( netfront,
"NETFRONT %s could not delete %s: %s\n",
244 if ( ( xenrc = xenevent_alloc_unbound ( xen, &
alloc_unbound ) ) != 0 ) {
246 DBGC ( netfront,
"NETFRONT %s could not allocate event: %s\n",
248 goto err_alloc_unbound;
257 DBGC ( netfront,
"NETFRONT %s event-channel=\"%d\"\n",
264 xenevent_close ( xen, &
close );
283 if ( ( xenrc = xenevent_send ( xen, &netfront->
event ) ) != 0 ) {
285 DBGC ( netfront,
"NETFRONT %s could not send event: %s\n",
308 xenevent_close ( xen, &
close );
334 for ( i = 0 ; i < ring->
count ; i++ ) {
350 if ( (
rc = xengrant_permit_access ( xen, ring->
ref, xendev->
backend_id,
352 DBGC ( netfront,
"NETFRONT %s could not permit access to " 354 goto err_permit_access;
362 DBGC ( netfront,
"NETFRONT %s %s=\"%d\" [%08lx,%08lx)\n", xendev->
key,
368 xengrant_invalidate ( xen, ring->
ref );
395 unsigned int next_id;
396 unsigned int next_ref;
400 assert ( ! netfront_ring_is_full ( ring ) );
404 next_ref = ring->
refs[next_id];
407 if ( (
rc = xengrant_permit_access ( xen, next_ref, xendev->
backend_id,
409 DBGC ( netfront,
"NETFRONT %s could not permit access to " 416 ring->
iobufs[next_id] = iobuf;
447 xengrant_invalidate ( xen, ring->
refs[
id] );
468 void ( * discard ) (
struct io_buffer * ) ){
475 while ( ! netfront_ring_is_empty ( ring ) ) {
486 xengrant_invalidate ( xen, ring->
ref );
526 unsigned int refilled = 0;
551 DBGC2 ( netfront,
"NETFRONT %s RX id %d ref %d is %#08lx+%zx\n",
600 goto err_create_event;
607 goto err_request_rx_copy;
615 "feature-no-csum-offload" ) ) != 0 )
616 goto err_feature_no_csum_offload;
620 "feature-rx-notify" ) ) != 0 )
621 goto err_feature_rx_notify;
625 DBGC ( netfront,
"NETFRONT %s could not set state=\"%d\": %s\n",
632 DBGC ( netfront,
"NETFRONT %s could not connect to backend: " 634 goto err_backend_wait;
649 err_feature_rx_notify:
650 netfront_rm ( netfront,
"feature-no-csum-offload" );
651 err_feature_no_csum_offload:
680 DBGC ( netfront,
"NETFRONT %s could not disconnect from " 696 netfront_rm ( netfront,
"feature-no-csum-offload" );
746 if ( netfront_ring_space ( &netfront->
tx ) <
count ) {
747 DBGC ( netfront,
"NETFRONT %s out of transmit descriptors\n",
754 while ( remaining ) {
758 if ( frag_len >= remaining ) {
759 frag_len = remaining;
769 ( more ?
NULL : iobuf ),
777 DBGC2 ( netfront,
"NETFRONT %s TX id %d ref %d is " 779 request->gref,
addr, frag_len, ( more ?
"..." :
"" ) );
784 remaining -= frag_len;
820 DBGC2 ( netfront,
"NETFRONT %s TX id %d complete\n",
821 xendev->
key, response->
id );
826 DBGC2 ( netfront,
"NETFRONT %s TX id %d error %d: %s\n",
864 DBGC2 ( netfront,
"NETFRONT %s RX id %d error %d: %s\n",
876 DBGC2 ( netfront,
"NETFRONT %s RX id %d complete " 877 "%#08lx+%zx%s\n", xendev->
key, response->
id,
879 ( more ?
"..." :
"" ) );
889 DBGC2 ( netfront,
"NETFRONT %s RX reassembly failed\n",
956 DBGC ( netfront,
"NETFRONT %s backend=\"%s\" in domain %ld\n",
962 DBGC ( netfront,
"NETFRONT %s could not allocate grant " 964 goto err_grant_alloc;
966 netfront_init_ring ( &netfront->
tx,
"tx-ring-ref",
971 netfront_init_ring ( &netfront->
rx,
"rx-ring-ref",
989 goto err_register_netdev;
static void netfront_refill_rx(struct net_device *netdev)
Refill receive descriptor ring.
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.
union netfront_ring::@79 sring
Shared ring.
#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.
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.
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.
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.
#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.
void * priv
Driver private data.
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 userptr_t size_t offset
Offset of the first segment within the content.
static struct net_device * netdev
static int netfront_write_flag(struct netfront_nic *netfront, const char *subkey)
Write XenStore flag value.
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)
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.
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.
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.
#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.
uint16_t count
Number of entries.
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.
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
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.
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 *)
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.