iPXE
netfront.c File Reference

Xen netfront driver. More...

#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <ipxe/netdevice.h>
#include <ipxe/ethernet.h>
#include <ipxe/if_ether.h>
#include <ipxe/malloc.h>
#include <ipxe/base16.h>
#include <ipxe/xen.h>
#include <ipxe/xenstore.h>
#include <ipxe/xenbus.h>
#include <ipxe/xengrant.h>
#include <ipxe/xenevent.h>
#include "netfront.h"

Go to the source code of this file.

Macros

#define EIO_NETIF_RSP_ERROR    __einfo_error ( EINFO_EIO_NETIF_RSP_ERROR )
#define EINFO_EIO_NETIF_RSP_ERROR
#define EIO_NETIF_RSP_DROPPED    __einfo_error ( EINFO_EIO_NETIF_RSP_DROPPED )
#define EINFO_EIO_NETIF_RSP_DROPPED
#define EIO_NETIF_RSP(status)

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static LIST_HEAD (netfront_devices)
 List of netfront devices.
static int netfront_reset (struct netfront_nic *netfront)
 Reset device.
static int netfront_read_mac (struct netfront_nic *netfront, void *hw_addr)
 Fetch MAC address.
static int netfront_write_num (struct netfront_nic *netfront, const char *subkey, unsigned long num)
 Write XenStore numeric value.
static int netfront_write_flag (struct netfront_nic *netfront, const char *subkey)
 Write XenStore flag value.
static int netfront_rm (struct netfront_nic *netfront, const char *subkey)
 Delete XenStore value.
static int netfront_create_event (struct netfront_nic *netfront)
 Create event channel.
static int netfront_send_event (struct netfront_nic *netfront)
 Send event.
static void netfront_destroy_event (struct netfront_nic *netfront)
 Destroy event channel.
static int netfront_create_ring (struct netfront_nic *netfront, struct netfront_ring *ring)
 Create descriptor ring.
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.
static struct io_buffernetfront_pull (struct netfront_nic *netfront, struct netfront_ring *ring, unsigned int id)
 Remove buffer from descriptor ring.
static void netfront_destroy_ring (struct netfront_nic *netfront, struct netfront_ring *ring, void(*discard)(struct io_buffer *))
 Destroy descriptor ring.
static void netfront_discard (struct netfront_nic *netfront)
 Discard partially received I/O buffers.
static void netfront_refill_rx (struct net_device *netdev)
 Refill receive descriptor ring.
static int netfront_open (struct net_device *netdev)
 Open network device.
static void netfront_close (struct net_device *netdev)
 Close network device.
static int netfront_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet.
static void netfront_poll_tx (struct net_device *netdev)
 Poll for completed packets.
static void netfront_poll_rx (struct net_device *netdev)
 Poll for received packets.
static void netfront_poll (struct net_device *netdev)
 Poll for completed and received packets.
static int netfront_probe (struct xen_device *xendev)
 Probe Xen device.
static void netfront_remove (struct xen_device *xendev)
 Remove Xen device.
 XEN_ROM ("netfront", "Xen netfront virtual NIC")
static int netfront_net_probe (struct net_device *netdev, void *priv __unused)
 Inhibit emulated PCI devices.

Variables

static struct net_device_operations netfront_operations
 Network device operations.
struct xen_driver netfront_driver __xen_driver
 Xen netfront driver.
struct net_driver netfront_net_driver __net_driver
 Emulated PCI device inhibitor driver.

Detailed Description

Xen netfront driver.

Definition in file netfront.c.

Macro Definition Documentation

◆ EIO_NETIF_RSP_ERROR

#define EIO_NETIF_RSP_ERROR    __einfo_error ( EINFO_EIO_NETIF_RSP_ERROR )

Definition at line 49 of file netfront.c.

49#define EIO_NETIF_RSP_ERROR \
50 __einfo_error ( EINFO_EIO_NETIF_RSP_ERROR )

◆ EINFO_EIO_NETIF_RSP_ERROR

#define EINFO_EIO_NETIF_RSP_ERROR
Value:
"Unspecified network error" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition errno.h:181
#define EINFO_EIO
Definition errno.h:435
#define NETIF_RSP_ERROR
Definition netif.h:1079

Definition at line 51 of file netfront.c.

51#define EINFO_EIO_NETIF_RSP_ERROR \
52 __einfo_uniqify ( EINFO_EIO, -NETIF_RSP_ERROR, \
53 "Unspecified network error" )

◆ EIO_NETIF_RSP_DROPPED

#define EIO_NETIF_RSP_DROPPED    __einfo_error ( EINFO_EIO_NETIF_RSP_DROPPED )

Definition at line 54 of file netfront.c.

54#define EIO_NETIF_RSP_DROPPED \
55 __einfo_error ( EINFO_EIO_NETIF_RSP_DROPPED )

◆ EINFO_EIO_NETIF_RSP_DROPPED

#define EINFO_EIO_NETIF_RSP_DROPPED
Value:
"Packet dropped" )
#define NETIF_RSP_DROPPED
Definition netif.h:1078

Definition at line 56 of file netfront.c.

56#define EINFO_EIO_NETIF_RSP_DROPPED \
57 __einfo_uniqify ( EINFO_EIO, -NETIF_RSP_DROPPED, \
58 "Packet dropped" )

◆ EIO_NETIF_RSP

#define EIO_NETIF_RSP ( status)
Value:
EUNIQ ( EINFO_EIO, ( -(status) & 0x1f ), \
uint8_t status
Status.
Definition ena.h:5
#define EUNIQ(einfo_base, uniq,...)
Disambiguate a base error based on non-constant information.
Definition errno.h:226
#define EIO_NETIF_RSP_ERROR
Definition netfront.c:49
#define EIO_NETIF_RSP_DROPPED
Definition netfront.c:54

Definition at line 59 of file netfront.c.

59#define EIO_NETIF_RSP( status ) \
60 EUNIQ ( EINFO_EIO, ( -(status) & 0x1f ), \
61 EIO_NETIF_RSP_ERROR, EIO_NETIF_RSP_DROPPED )

Referenced by netfront_poll_rx(), and netfront_poll_tx().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ LIST_HEAD()

LIST_HEAD ( netfront_devices )
static

List of netfront devices.

◆ netfront_reset()

int netfront_reset ( struct netfront_nic * netfront)
static

Reset device.

Parameters
netfrontNetfront device
Return values
rcReturn status code

Definition at line 79 of file netfront.c.

79 {
80 struct xen_device *xendev = netfront->xendev;
81 int state;
82 int rc;
83
84 /* Get current backend state */
85 if ( ( state = xenbus_backend_state ( xendev ) ) < 0 ) {
86 rc = state;
87 DBGC ( netfront, "NETFRONT %s could not read backend state: "
88 "%s\n", xendev->key, strerror ( rc ) );
89 return rc;
90 }
91
92 /* If the backend is not already in InitWait, then mark
93 * frontend as Closed to shut down the backend.
94 */
95 if ( state != XenbusStateInitWait ) {
96
97 /* Set state to Closed */
99
100 /* Wait for backend to reach Closed */
101 if ( ( rc = xenbus_backend_wait ( xendev,
102 XenbusStateClosed ) ) != 0 ) {
103 DBGC ( netfront, "NETFRONT %s backend did not reach "
104 "Closed: %s\n", xendev->key, strerror ( rc ) );
105 return rc;
106 }
107 }
108
109 /* Reset state to Initialising */
111
112 /* Wait for backend to reach InitWait */
113 if ( ( rc = xenbus_backend_wait ( xendev, XenbusStateInitWait ) ) != 0){
114 DBGC ( netfront, "NETFRONT %s backend did not reach InitWait: "
115 "%s\n", xendev->key, strerror ( rc ) );
116 return rc;
117 }
118
119 return 0;
120}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
uint8_t state
State.
Definition eth_slow.h:36
#define DBGC(...)
Definition compiler.h:505
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
struct xen_device * xendev
Xen device.
Definition netfront.h:159
A Xen device.
Definition xenbus.h:19
char * key
XenStore key.
Definition xenbus.h:25
@ XenbusStateInitWait
Definition xenbus.h:31
@ XenbusStateInitialising
Definition xenbus.h:25
@ XenbusStateClosed
Definition xenbus.h:45
int xenbus_backend_state(struct xen_device *xendev)
Get backend state.
Definition xenbus.c:127
int xenbus_set_state(struct xen_device *xendev, int state)
Set device state.
Definition xenbus.c:107
int xenbus_backend_wait(struct xen_device *xendev, int state)
Wait for backend to reach a given state.
Definition xenbus.c:149

References DBGC, xen_device::key, rc, state, strerror(), xenbus_backend_state(), xenbus_backend_wait(), xenbus_set_state(), XenbusStateClosed, XenbusStateInitialising, XenbusStateInitWait, and netfront_nic::xendev.

Referenced by netfront_close(), netfront_open(), and netfront_probe().

◆ netfront_read_mac()

int netfront_read_mac ( struct netfront_nic * netfront,
void * hw_addr )
static

Fetch MAC address.

Parameters
netfrontNetfront device
hw_addrHardware address to fill in
Return values
rcReturn status code

Definition at line 129 of file netfront.c.

129 {
130 struct xen_device *xendev = netfront->xendev;
131 struct xen_hypervisor *xen = xendev->xen;
132 char *mac;
133 int len;
134 int rc;
135
136 /* Fetch MAC address */
137 if ( ( rc = xenstore_read ( xen, &mac, xendev->key, "mac", NULL ) )!=0){
138 DBGC ( netfront, "NETFRONT %s could not read MAC address: %s\n",
139 xendev->key, strerror ( rc ) );
140 goto err_xenstore_read;
141 }
142 DBGC2 ( netfront, "NETFRONT %s has MAC address \"%s\"\n",
143 xendev->key, mac );
144
145 /* Decode MAC address */
146 len = hex_decode ( ':', mac, hw_addr, ETH_ALEN );
147 if ( len < 0 ) {
148 rc = len;
149 DBGC ( netfront, "NETFRONT %s could not decode MAC address "
150 "\"%s\": %s\n", xendev->key, mac, strerror ( rc ) );
151 goto err_decode;
152 }
153
154 /* Success */
155 rc = 0;
156
157 err_decode:
158 free ( mac );
159 err_xenstore_read:
160 return rc;
161}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
int hex_decode(char separator, const char *encoded, void *data, size_t len)
Decode hexadecimal string (with optional byte separator character)
Definition base16.c:77
ring len
Length.
Definition dwmac.h:226
uint8_t mac[ETH_ALEN]
MAC address.
Definition ena.h:13
#define DBGC2(...)
Definition compiler.h:522
#define ETH_ALEN
Definition if_ether.h:9
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
struct xen_hypervisor * xen
Xen hypervisor.
Definition xenbus.h:23
A Xen hypervisor.
Definition xen.h:51
int xenstore_read(struct xen_hypervisor *xen, char **value,...)
Read XenStore value.
Definition xenstore.c:372

References DBGC, DBGC2, ETH_ALEN, free, hex_decode(), xen_device::key, len, mac, NULL, rc, strerror(), xen_device::xen, netfront_nic::xendev, and xenstore_read().

Referenced by netfront_probe().

◆ netfront_write_num()

int netfront_write_num ( struct netfront_nic * netfront,
const char * subkey,
unsigned long num )
static

Write XenStore numeric value.

Parameters
netfrontNetfront device
subkeySubkey
numNumeric value
Return values
rcReturn status code

Definition at line 171 of file netfront.c.

172 {
173 struct xen_device *xendev = netfront->xendev;
174 struct xen_hypervisor *xen = xendev->xen;
175 int rc;
176
177 /* Write value */
178 if ( ( rc = xenstore_write_num ( xen, num, xendev->key, subkey,
179 NULL ) ) != 0 ) {
180 DBGC ( netfront, "NETFRONT %s could not set %s=\"%ld\": %s\n",
181 xendev->key, subkey, num, strerror ( rc ) );
182 return rc;
183 }
184
185 return 0;
186}
uint32_t num
Definition multiboot.h:0
int xenstore_write_num(struct xen_hypervisor *xen, unsigned long num,...)
Write XenStore numeric value.
Definition xenstore.c:461

References DBGC, xen_device::key, NULL, num, rc, strerror(), xen_device::xen, netfront_nic::xendev, and xenstore_write_num().

Referenced by netfront_create_event(), netfront_create_ring(), and netfront_write_flag().

◆ netfront_write_flag()

int netfront_write_flag ( struct netfront_nic * netfront,
const char * subkey )
static

Write XenStore flag value.

Parameters
netfrontNetfront device
subkeySubkey
numNumeric value
Return values
rcReturn status code

Definition at line 196 of file netfront.c.

197 {
198
199 return netfront_write_num ( netfront, subkey, 1 );
200}
static int netfront_write_num(struct netfront_nic *netfront, const char *subkey, unsigned long num)
Write XenStore numeric value.
Definition netfront.c:171

References netfront_write_num().

Referenced by netfront_open().

◆ netfront_rm()

int netfront_rm ( struct netfront_nic * netfront,
const char * subkey )
static

Delete XenStore value.

Parameters
netfrontNetfront device
subkeySubkey
Return values
rcReturn status code

Definition at line 209 of file netfront.c.

209 {
210 struct xen_device *xendev = netfront->xendev;
211 struct xen_hypervisor *xen = xendev->xen;
212 int rc;
213
214 /* Remove value */
215 if ( ( rc = xenstore_rm ( xen, xendev->key, subkey, NULL ) ) != 0 ) {
216 DBGC ( netfront, "NETFRONT %s could not delete %s: %s\n",
217 xendev->key, subkey, strerror ( rc ) );
218 return rc;
219 }
220
221 return 0;
222}
int xenstore_rm(struct xen_hypervisor *xen,...)
Delete XenStore value.
Definition xenstore.c:484

References DBGC, xen_device::key, NULL, rc, strerror(), xen_device::xen, netfront_nic::xendev, and xenstore_rm().

Referenced by netfront_close(), netfront_create_event(), netfront_create_ring(), netfront_destroy_event(), netfront_destroy_ring(), and netfront_open().

◆ netfront_create_event()

int netfront_create_event ( struct netfront_nic * netfront)
static

Create event channel.

Parameters
netfrontNetfront device
Return values
rcReturn status code

Definition at line 237 of file netfront.c.

237 {
238 struct xen_device *xendev = netfront->xendev;
239 struct xen_hypervisor *xen = xendev->xen;
241 struct evtchn_close close;
242 int xenrc;
243 int rc;
244
245 /* Allocate event */
247 alloc_unbound.remote_dom = xendev->backend_id;
248 if ( ( xenrc = xenevent_alloc_unbound ( xen, &alloc_unbound ) ) != 0 ) {
249 rc = -EXEN ( xenrc );
250 DBGC ( netfront, "NETFRONT %s could not allocate event: %s\n",
251 xendev->key, strerror ( rc ) );
252 goto err_alloc_unbound;
253 }
254 netfront->event.port = alloc_unbound.port;
255
256 /* Publish event channel */
257 if ( ( rc = netfront_write_num ( netfront, "event-channel",
258 netfront->event.port ) ) != 0 )
259 goto err_write_num;
260
261 DBGC ( netfront, "NETFRONT %s event-channel=\"%d\"\n",
262 xendev->key, netfront->event.port );
263 return 0;
264
265 netfront_rm ( netfront, "event-channel" );
266 err_write_num:
267 close.port = netfront->event.port;
268 xenevent_close ( xen, &close );
269 err_alloc_unbound:
270 return rc;
271}
#define EXEN(xenrc)
Convert a Xen status code to an iPXE status code.
Definition xen.h:87
#define DOMID_SELF
Definition xen.h:581
static int netfront_rm(struct netfront_nic *netfront, const char *subkey)
Delete XenStore value.
Definition netfront.c:209
evtchn_port_t port
struct evtchn_send event
Event channel.
Definition netfront.h:189
unsigned long backend_id
Backend domain ID.
Definition xenbus.h:29
static struct evtchn_close * close
Definition xenevent.h:24
static struct evtchn_alloc_unbound * alloc_unbound
Definition xenevent.h:53

References alloc_unbound, xen_device::backend_id, close, DBGC, DOMID_SELF, netfront_nic::event, EXEN, xen_device::key, netfront_rm(), netfront_write_num(), evtchn_send::port, rc, strerror(), xen_device::xen, and netfront_nic::xendev.

Referenced by netfront_open().

◆ netfront_send_event()

int netfront_send_event ( struct netfront_nic * netfront)
inlinestatic

Send event.

Parameters
netfrontNetfront device
Return values
rcReturn status code

Definition at line 280 of file netfront.c.

280 {
281 struct xen_device *xendev = netfront->xendev;
282 struct xen_hypervisor *xen = xendev->xen;
283 int xenrc;
284 int rc;
285
286 /* Send event */
287 if ( ( xenrc = xenevent_send ( xen, &netfront->event ) ) != 0 ) {
288 rc = -EXEN ( xenrc );
289 DBGC ( netfront, "NETFRONT %s could not send event: %s\n",
290 xendev->key, strerror ( rc ) );
291 return rc;
292 }
293
294 return 0;
295}

References DBGC, netfront_nic::event, EXEN, xen_device::key, rc, strerror(), xen_device::xen, and netfront_nic::xendev.

Referenced by netfront_refill_rx(), and netfront_transmit().

◆ netfront_destroy_event()

void netfront_destroy_event ( struct netfront_nic * netfront)
static

Destroy event channel.

Parameters
netfrontNetfront device

Definition at line 302 of file netfront.c.

302 {
303 struct xen_device *xendev = netfront->xendev;
304 struct xen_hypervisor *xen = xendev->xen;
305 struct evtchn_close close;
306
307 /* Unpublish event channel */
308 netfront_rm ( netfront, "event-channel" );
309
310 /* Close event channel */
311 close.port = netfront->event.port;
312 xenevent_close ( xen, &close );
313}

References close, netfront_nic::event, netfront_rm(), evtchn_send::port, xen_device::xen, and netfront_nic::xendev.

Referenced by netfront_close(), and netfront_open().

◆ netfront_create_ring()

int netfront_create_ring ( struct netfront_nic * netfront,
struct netfront_ring * ring )
static

Create descriptor ring.

Parameters
netfrontNetfront device
ringDescriptor ring
Return values
rcReturn status code

Definition at line 329 of file netfront.c.

330 {
331 struct xen_device *xendev = netfront->xendev;
332 struct xen_hypervisor *xen = xendev->xen;
334 unsigned int i;
335 int rc;
336
337 /* Initialise buffer ID ring */
338 for ( i = 0 ; i < ring->count ; i++ ) {
339 ring->ids[i] = i;
340 assert ( ring->iobufs[i] == NULL );
341 }
342 ring->id_prod = 0;
343 ring->id_cons = 0;
344
345 /* Allocate and initialise shared ring */
347 if ( ! ring->sring.raw ) {
348 rc = -ENOMEM;
349 goto err_alloc;
350 }
351
352 /* Grant access to shared ring */
353 addr = virt_to_phys ( ring->sring.raw );
354 if ( ( rc = xengrant_permit_access ( xen, ring->ref, xendev->backend_id,
355 0, addr ) ) != 0 ) {
356 DBGC ( netfront, "NETFRONT %s could not permit access to "
357 "%#08lx: %s\n", xendev->key, addr, strerror ( rc ) );
358 goto err_permit_access;
359 }
360
361 /* Publish shared ring reference */
362 if ( ( rc = netfront_write_num ( netfront, ring->ref_key,
363 ring->ref ) ) != 0 )
364 goto err_write_num;
365
366 DBGC ( netfront, "NETFRONT %s %s=\"%d\" [%08lx,%08lx)\n", xendev->key,
367 ring->ref_key, ring->ref, addr, ( addr + PAGE_SIZE ) );
368 return 0;
369
370 netfront_rm ( netfront, ring->ref_key );
371 err_write_num:
372 xengrant_invalidate ( xen, ring->ref );
373 err_permit_access:
374 free_phys ( ring->sring.raw, PAGE_SIZE );
375 err_alloc:
376 return rc;
377}
unsigned long physaddr_t
Definition stdint.h:20
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
uint32_t addr
Buffer address.
Definition dwmac.h:9
#define ENOMEM
Not enough space.
Definition errno.h:535
#define PAGE_SIZE
Page size.
Definition io.h:28
void * malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
Definition malloc.c:707
void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition malloc.c:723
size_t count
Maximum number of used descriptors.
Definition netfront.h:66
uint8_t * ids
Buffer ID ring.
Definition netfront.h:73
struct io_buffer ** iobufs
I/O buffers, indexed by buffer ID.
Definition netfront.h:68
unsigned int id_prod
Buffer ID ring producer counter.
Definition netfront.h:75
void * raw
Raw pointer.
Definition netfront.h:58
const char * ref_key
Shared ring grant reference key.
Definition netfront.h:61
unsigned int id_cons
Buffer ID ring consumer counter.
Definition netfront.h:77
grant_ref_t ref
Shared ring grant reference.
Definition netfront.h:63
union netfront_ring::@235351263275146342264217234007371176021305365026 sring
Shared ring.

References addr, assert, xen_device::backend_id, netfront_ring::count, DBGC, ENOMEM, free_phys(), netfront_ring::id_cons, netfront_ring::id_prod, netfront_ring::ids, netfront_ring::iobufs, xen_device::key, malloc_phys(), netfront_rm(), netfront_write_num(), NULL, PAGE_SIZE, netfront_ring::raw, rc, netfront_ring::ref, netfront_ring::ref_key, netfront_ring::sring, strerror(), xen_device::xen, and netfront_nic::xendev.

Referenced by netfront_open().

◆ netfront_push()

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 )
static

Add buffer to descriptor ring.

Parameters
netfrontNetfront device
ringDescriptor ring
addrPhysical address
iobufAssociated I/O buffer, or NULL
idBuffer ID to fill in
refGrant reference to fill in
Return values
rcReturn status code

The caller is responsible for ensuring that there is space in the ring.

Definition at line 393 of file netfront.c.

396 {
397 struct xen_device *xendev = netfront->xendev;
398 struct xen_hypervisor *xen = xendev->xen;
399 unsigned int next_id;
400 unsigned int next_ref;
401 int rc;
402
403 /* Sanity check */
404 assert ( ! netfront_ring_is_full ( ring ) );
405
406 /* Allocate buffer ID */
407 next_id = ring->ids[ ring->id_prod & ( ring->count - 1 ) ];
408 next_ref = ring->refs[next_id];
409
410 /* Grant access to page containing address */
411 if ( ( rc = xengrant_permit_access ( xen, next_ref, xendev->backend_id,
412 0, addr ) ) != 0 ) {
413 DBGC ( netfront, "NETFRONT %s could not permit access to "
414 "%#08lx: %s\n", xendev->key, addr, strerror ( rc ) );
415 return rc;
416 }
417
418 /* Store associated I/O buffer, if any */
419 assert ( ring->iobufs[next_id] == NULL );
420 ring->iobufs[next_id] = iobuf;
421
422 /* Consume buffer ID */
423 ring->id_prod++;
424
425 /* Return buffer ID and grant reference */
426 *id = next_id;
427 *ref = next_ref;
428
429 return 0;
430}
static const char grant_ref_t ref
Definition netfront.h:93
grant_ref_t * refs
Grant references, indexed by buffer ID.
Definition netfront.h:70

References addr, assert, xen_device::backend_id, netfront_ring::count, DBGC, netfront_ring::id_prod, netfront_ring::ids, netfront_ring::iobufs, xen_device::key, NULL, rc, ref, netfront_ring::refs, strerror(), xen_device::xen, and netfront_nic::xendev.

Referenced by netfront_refill_rx(), and netfront_transmit().

◆ netfront_pull()

struct io_buffer * netfront_pull ( struct netfront_nic * netfront,
struct netfront_ring * ring,
unsigned int id )
static

Remove buffer from descriptor ring.

Parameters
netfrontNetfront device
ringDescriptor ring
idBuffer ID
Return values
iobufAssociated I/O buffer, if any

Definition at line 440 of file netfront.c.

442 {
443 struct xen_device *xendev = netfront->xendev;
444 struct xen_hypervisor *xen = xendev->xen;
445 struct io_buffer *iobuf;
446
447 /* Sanity check */
449
450 /* Revoke access from I/O buffer page */
451 xengrant_invalidate ( xen, ring->refs[id] );
452
453 /* Retrieve I/O buffer */
454 iobuf = ring->iobufs[id];
455 ring->iobufs[id] = NULL;
456
457 /* Free buffer ID */
458 ring->ids[ ( ring->id_cons++ ) & ( ring->count - 1 ) ] = id;
459
460 return iobuf;
461}
uint8_t id
Request identifier.
Definition ena.h:1
static unsigned int count
Number of entries.
Definition dwmac.h:220
A persistent I/O buffer.
Definition iobuf.h:38

References assert, count, netfront_ring::count, id, netfront_ring::id_cons, netfront_ring::ids, netfront_ring::iobufs, NULL, netfront_ring::refs, xen_device::xen, and netfront_nic::xendev.

Referenced by netfront_destroy_ring(), netfront_poll_rx(), and netfront_poll_tx().

◆ netfront_destroy_ring()

void netfront_destroy_ring ( struct netfront_nic * netfront,
struct netfront_ring * ring,
void(* discard )(struct io_buffer *) )
static

Destroy descriptor ring.

Parameters
netfrontNetfront device
ringDescriptor ring
discardMethod used to discard outstanding buffer, or NULL

Definition at line 470 of file netfront.c.

472 {
473 struct xen_device *xendev = netfront->xendev;
474 struct xen_hypervisor *xen = xendev->xen;
475 struct io_buffer *iobuf;
476 unsigned int id;
477
478 /* Flush any outstanding buffers */
479 while ( ! netfront_ring_is_empty ( ring ) ) {
480 id = ring->ids[ ring->id_cons & ( ring->count - 1 ) ];
481 iobuf = netfront_pull ( netfront, ring, id );
482 if ( discard )
483 discard ( iobuf );
484 }
485
486 /* Unpublish shared ring reference */
487 netfront_rm ( netfront, ring->ref_key );
488
489 /* Revoke access from shared ring */
490 xengrant_invalidate ( xen, ring->ref );
491
492 /* Free page */
493 free_phys ( ring->sring.raw, PAGE_SIZE );
494 ring->sring.raw = NULL;
495}
static struct io_buffer * netfront_pull(struct netfront_nic *netfront, struct netfront_ring *ring, unsigned int id)
Remove buffer from descriptor ring.
Definition netfront.c:440

References netfront_ring::count, free_phys(), id, netfront_ring::id_cons, netfront_ring::ids, netfront_pull(), netfront_rm(), NULL, PAGE_SIZE, netfront_ring::raw, netfront_ring::ref, netfront_ring::ref_key, netfront_ring::sring, xen_device::xen, and netfront_nic::xendev.

Referenced by netfront_close(), and netfront_open().

◆ netfront_discard()

void netfront_discard ( struct netfront_nic * netfront)
static

Discard partially received I/O buffers.

Parameters
netfrontNetfront device

Definition at line 502 of file netfront.c.

502 {
503 struct io_buffer *iobuf;
504 struct io_buffer *tmp;
505
506 /* Discard all buffers in the list */
507 list_for_each_entry_safe ( iobuf, tmp, &netfront->rx_partial, list ) {
508 list_del ( &iobuf->list );
509 free_iob ( iobuf );
510 }
511}
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:45
struct list_head rx_partial
Partial receive I/O buffer list.
Definition netfront.h:186

References free_iob(), io_buffer::list, list_del, list_for_each_entry_safe, netfront_nic::rx_partial, and tmp.

Referenced by netfront_close(), and netfront_poll_rx().

◆ netfront_refill_rx()

void netfront_refill_rx ( struct net_device * netdev)
static

Refill receive descriptor ring.

Parameters
netdevNetwork device

Definition at line 525 of file netfront.c.

525 {
526 struct netfront_nic *netfront = netdev->priv;
527 struct xen_device *xendev = netfront->xendev;
528 struct io_buffer *iobuf;
530 unsigned int refilled = 0;
532 int notify;
533 int rc;
534
535 /* Refill ring */
536 while ( netfront_ring_fill ( &netfront->rx ) < NETFRONT_RX_FILL ) {
537
538 /* Allocate I/O buffer */
539 iobuf = alloc_iob ( PAGE_SIZE );
540 if ( ! iobuf ) {
541 /* Wait for next refill */
542 break;
543 }
544 addr = virt_to_phys ( iobuf->data );
545
546 /* Add to descriptor ring */
547 request = RING_GET_REQUEST ( &netfront->rx_fring,
548 netfront->rx_fring.req_prod_pvt );
549 if ( ( rc = netfront_push ( netfront, &netfront->rx, addr,
550 iobuf, &request->id,
551 &request->gref ) ) != 0 ) {
552 netdev_rx_err ( netdev, iobuf, rc );
553 break;
554 }
555 DBGC2 ( netfront, "NETFRONT %s RX id %d ref %d is %#08lx+%zx\n",
556 xendev->key, request->id, request->gref, addr,
557 iob_tailroom ( iobuf ) );
558
559 /* Move to next descriptor */
560 netfront->rx_fring.req_prod_pvt++;
561 refilled++;
562 }
563
564 /* Push new descriptors and notify backend if applicable */
565 if ( refilled ) {
567 notify );
568 if ( notify )
569 netfront_send_event ( netfront );
570 }
571}
static struct net_device * netdev
Definition gdbudp.c:53
u8 request[0]
List of IEs requested.
Definition ieee80211.h:2
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition iobuf.h:180
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition netdevice.c:587
static int netfront_push(struct netfront_nic *netfront, struct netfront_ring *ring, physaddr_t addr, struct io_buffer *iobuf, uint16_t *id, grant_ref_t *ref)
Add buffer to descriptor ring.
Definition netfront.c:393
static int netfront_send_event(struct netfront_nic *netfront)
Send event.
Definition netfront.c:280
#define NETFRONT_RX_FILL
Receive ring fill level.
Definition netfront.h:33
#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify)
Definition ring.h:318
#define RING_GET_REQUEST(_r, _idx)
Definition ring.h:243
void * data
Start of data.
Definition iobuf.h:53
A netfront NIC.
Definition netfront.h:157
struct netfront_ring rx
Receive ring.
Definition netfront.h:178
netif_rx_front_ring_t rx_fring
Receive front ring.
Definition netfront.h:180

References addr, alloc_iob(), io_buffer::data, DBGC2, iob_tailroom(), xen_device::key, netdev, netdev_rx_err(), netfront_push(), NETFRONT_RX_FILL, netfront_send_event(), PAGE_SIZE, rc, request, RING_GET_REQUEST, RING_PUSH_REQUESTS_AND_CHECK_NOTIFY, netfront_nic::rx, netfront_nic::rx_fring, and netfront_nic::xendev.

Referenced by netfront_open(), and netfront_poll().

◆ netfront_open()

int netfront_open ( struct net_device * netdev)
static

Open network device.

Parameters
netdevNetwork device
Return values
rcReturn status code

Definition at line 579 of file netfront.c.

579 {
580 struct netfront_nic *netfront = netdev->priv;
581 struct xen_device *xendev = netfront->xendev;
582 int rc;
583
584 /* Ensure device is in a suitable initial state */
585 if ( ( rc = netfront_reset ( netfront ) ) != 0 )
586 goto err_reset;
587
588 /* Create transmit descriptor ring */
589 if ( ( rc = netfront_create_ring ( netfront, &netfront->tx ) ) != 0 )
590 goto err_create_tx;
591 SHARED_RING_INIT ( netfront->tx_sring );
592 FRONT_RING_INIT ( &netfront->tx_fring, netfront->tx_sring, PAGE_SIZE );
593 assert ( RING_SIZE ( &netfront->tx_fring ) >= netfront->tx.count );
594
595 /* Create receive descriptor ring */
596 if ( ( rc = netfront_create_ring ( netfront, &netfront->rx ) ) != 0 )
597 goto err_create_rx;
598 SHARED_RING_INIT ( netfront->rx_sring );
599 FRONT_RING_INIT ( &netfront->rx_fring, netfront->rx_sring, PAGE_SIZE );
600 assert ( RING_SIZE ( &netfront->rx_fring ) >= netfront->rx.count );
601
602 /* Create event channel */
603 if ( ( rc = netfront_create_event ( netfront ) ) != 0 )
604 goto err_create_event;
605
606 /* "Request" the rx-copy feature. Current versions of
607 * xen_netback.ko will fail silently if this parameter is not
608 * present.
609 */
610 if ( ( rc = netfront_write_flag ( netfront, "request-rx-copy" ) ) != 0 )
611 goto err_request_rx_copy;
612
613 /* Inform backend that we can support scatter-gather */
614 if ( ( rc = netfront_write_flag ( netfront, "feature-sg" ) ) != 0 )
615 goto err_feature_sg;
616
617 /* Disable checksum offload, since we will always do the work anyway */
618 if ( ( rc = netfront_write_flag ( netfront,
619 "feature-no-csum-offload" ) ) != 0 )
620 goto err_feature_no_csum_offload;
621
622 /* Inform backend that we will send notifications for RX requests */
623 if ( ( rc = netfront_write_flag ( netfront,
624 "feature-rx-notify" ) ) != 0 )
625 goto err_feature_rx_notify;
626
627 /* Set state to Connected */
628 if ( ( rc = xenbus_set_state ( xendev, XenbusStateConnected ) ) != 0 ) {
629 DBGC ( netfront, "NETFRONT %s could not set state=\"%d\": %s\n",
630 xendev->key, XenbusStateConnected, strerror ( rc ) );
631 goto err_set_state;
632 }
633
634 /* Wait for backend to connect */
635 if ( ( rc = xenbus_backend_wait ( xendev, XenbusStateConnected ) ) !=0){
636 DBGC ( netfront, "NETFRONT %s could not connect to backend: "
637 "%s\n", xendev->key, strerror ( rc ) );
638 goto err_backend_wait;
639 }
640
641 /* Refill receive descriptor ring */
643
644 /* Set link up */
646
647 return 0;
648
649 err_backend_wait:
650 netfront_reset ( netfront );
651 err_set_state:
652 netfront_rm ( netfront, "feature-rx-notify" );
653 err_feature_rx_notify:
654 netfront_rm ( netfront, "feature-no-csum-offload" );
655 err_feature_no_csum_offload:
656 netfront_rm ( netfront, "feature-sg" );
657 err_feature_sg:
658 netfront_rm ( netfront, "request-rx-copy" );
659 err_request_rx_copy:
660 netfront_destroy_event ( netfront );
661 err_create_event:
662 netfront_destroy_ring ( netfront, &netfront->rx, NULL );
663 err_create_rx:
664 netfront_destroy_ring ( netfront, &netfront->tx, NULL );
665 err_create_tx:
666 err_reset:
667 return rc;
668}
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition netdevice.h:789
static void netfront_refill_rx(struct net_device *netdev)
Refill receive descriptor ring.
Definition netfront.c:525
static void netfront_destroy_event(struct netfront_nic *netfront)
Destroy event channel.
Definition netfront.c:302
static int netfront_create_ring(struct netfront_nic *netfront, struct netfront_ring *ring)
Create descriptor ring.
Definition netfront.c:329
static int netfront_reset(struct netfront_nic *netfront)
Reset device.
Definition netfront.c:79
static void netfront_destroy_ring(struct netfront_nic *netfront, struct netfront_ring *ring, void(*discard)(struct io_buffer *))
Destroy descriptor ring.
Definition netfront.c:470
static int netfront_write_flag(struct netfront_nic *netfront, const char *subkey)
Write XenStore flag value.
Definition netfront.c:196
static int netfront_create_event(struct netfront_nic *netfront)
Create event channel.
Definition netfront.c:237
#define SHARED_RING_INIT(_s)
Definition ring.h:164
#define FRONT_RING_INIT(_r, _s, __size)
Definition ring.h:178
#define RING_SIZE
Definition skge.h:32
netif_tx_front_ring_t tx_fring
Transmit front ring.
Definition netfront.h:171
struct netfront_ring tx
Transmit ring.
Definition netfront.h:169
@ XenbusStateConnected
Definition xenbus.h:38

References assert, netfront_ring::count, DBGC, FRONT_RING_INIT, xen_device::key, netdev, netdev_link_up(), netfront_create_event(), netfront_create_ring(), netfront_destroy_event(), netfront_destroy_ring(), netfront_refill_rx(), netfront_reset(), netfront_rm(), netfront_write_flag(), NULL, PAGE_SIZE, rc, RING_SIZE, netfront_nic::rx, netfront_nic::rx_fring, SHARED_RING_INIT, strerror(), netfront_nic::tx, netfront_nic::tx_fring, xenbus_backend_wait(), xenbus_set_state(), XenbusStateConnected, and netfront_nic::xendev.

◆ netfront_close()

void netfront_close ( struct net_device * netdev)
static

Close network device.

Parameters
netdevNetwork device

Definition at line 675 of file netfront.c.

675 {
676 struct netfront_nic *netfront = netdev->priv;
677 struct xen_device *xendev = netfront->xendev;
678 int rc;
679
680 /* Reset devic, thereby ensuring that grant references are no
681 * longer in use, etc.
682 */
683 if ( ( rc = netfront_reset ( netfront ) ) != 0 ) {
684 DBGC ( netfront, "NETFRONT %s could not disconnect from "
685 "backend: %s\n", xendev->key, strerror ( rc ) );
686 /* Things will probably go _very_ badly wrong if this
687 * happens, since it means the backend may still write
688 * to the outstanding RX buffers that we are about to
689 * free. The best we can do is report the error via
690 * the link status, but there's a good chance the
691 * machine will crash soon.
692 */
694 } else {
696 }
697
698 /* Delete flags */
699 netfront_rm ( netfront, "feature-rx-notify" );
700 netfront_rm ( netfront, "feature-no-csum-offload" );
701 netfront_rm ( netfront, "feature-sg" );
702 netfront_rm ( netfront, "request-rx-copy" );
703
704 /* Destroy event channel */
705 netfront_destroy_event ( netfront );
706
707 /* Discard any partially received I/O buffers */
708 netfront_discard ( netfront );
709
710 /* Destroy receive descriptor ring, freeing any outstanding
711 * I/O buffers.
712 */
713 netfront_destroy_ring ( netfront, &netfront->rx, free_iob );
714
715 /* Destroy transmit descriptor ring. Leave any outstanding
716 * I/O buffers to be freed by netdev_tx_flush().
717 */
718 netfront_destroy_ring ( netfront, &netfront->tx, NULL );
719}
void netdev_link_err(struct net_device *netdev, int rc)
Mark network device as having a specific link state.
Definition netdevice.c:208
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition netdevice.c:231
static void netfront_discard(struct netfront_nic *netfront)
Discard partially received I/O buffers.
Definition netfront.c:502

References DBGC, free_iob(), xen_device::key, netdev, netdev_link_down(), netdev_link_err(), netfront_destroy_event(), netfront_destroy_ring(), netfront_discard(), netfront_reset(), netfront_rm(), NULL, rc, netfront_nic::rx, strerror(), netfront_nic::tx, and netfront_nic::xendev.

◆ netfront_transmit()

int netfront_transmit ( struct net_device * netdev,
struct io_buffer * iobuf )
static

Transmit packet.

Parameters
netdevNetwork device
iobufI/O buffer
Return values
rcReturn status code

Definition at line 728 of file netfront.c.

729 {
730 struct netfront_nic *netfront = netdev->priv;
731 struct xen_device *xendev = netfront->xendev;
734 size_t len;
735 size_t remaining;
736 size_t frag_len;
737 unsigned int offset;
738 unsigned int count;
739 unsigned int more;
740 int notify;
741 int rc;
742
743 /* Calculate number of page buffers required */
744 addr = virt_to_phys ( iobuf->data );
745 len = iob_len ( iobuf );
746 offset = ( addr & ( PAGE_SIZE - 1 ) );
747 count = ( ( offset + len + PAGE_SIZE - 1 ) / PAGE_SIZE );
748
749 /* Check that we have space in the ring */
750 if ( netfront_ring_space ( &netfront->tx ) < count ) {
751 DBGC ( netfront, "NETFRONT %s out of transmit descriptors\n",
752 xendev->key );
753 return -ENOBUFS;
754 }
755
756 /* Add to descriptor ring */
757 remaining = len;
758 while ( remaining ) {
759
760 /* Calculate length of this fragment */
761 frag_len = ( PAGE_SIZE - offset );
762 if ( frag_len >= remaining ) {
763 frag_len = remaining;
764 more = 0;
765 } else {
766 more = NETTXF_more_data;
767 }
768
769 /* Populate request */
770 request = RING_GET_REQUEST ( &netfront->tx_fring,
771 netfront->tx_fring.req_prod_pvt );
772 if ( ( rc = netfront_push ( netfront, &netfront->tx, addr,
773 ( more ? NULL : iobuf ),
774 &request->id,
775 &request->gref ) ) != 0 ) {
776 return rc;
777 }
778 request->flags = ( NETTXF_data_validated | more );
779 request->offset = offset;
780 request->size = ( ( remaining == len ) ? len : frag_len );
781 DBGC2 ( netfront, "NETFRONT %s TX id %d ref %d is "
782 "%#08lx+%zx%s\n", xendev->key, request->id,
783 request->gref, addr, frag_len, ( more ? "..." : "" ) );
784
785 /* Move to next descriptor */
786 netfront->tx_fring.req_prod_pvt++;
787 addr += frag_len;
788 remaining -= frag_len;
789 offset = 0;
790 }
791
792 /* Push new descriptors and notify backend if applicable */
793 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY ( &netfront->tx_fring, notify );
794 if ( notify )
795 netfront_send_event ( netfront );
796
797 return 0;
798}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
#define ENOBUFS
No buffer space available.
Definition errno.h:499
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define NETTXF_data_validated
Definition netif.h:966
#define NETTXF_more_data
Definition netif.h:970

References addr, count, io_buffer::data, DBGC, DBGC2, ENOBUFS, iob_len(), xen_device::key, len, netdev, netfront_push(), netfront_send_event(), NETTXF_data_validated, NETTXF_more_data, NULL, offset, PAGE_SIZE, rc, request, RING_GET_REQUEST, RING_PUSH_REQUESTS_AND_CHECK_NOTIFY, netfront_nic::tx, netfront_nic::tx_fring, and netfront_nic::xendev.

◆ netfront_poll_tx()

void netfront_poll_tx ( struct net_device * netdev)
static

Poll for completed packets.

Parameters
netdevNetwork device

Definition at line 805 of file netfront.c.

805 {
806 struct netfront_nic *netfront = netdev->priv;
807 struct xen_device *xendev = netfront->xendev;
808 struct netif_tx_response *response;
809 struct io_buffer *iobuf;
810 int status;
811 int rc;
812
813 /* Consume any unconsumed responses */
814 while ( RING_HAS_UNCONSUMED_RESPONSES ( &netfront->tx_fring ) ) {
815
816 /* Get next response */
817 response = RING_GET_RESPONSE ( &netfront->tx_fring,
818 netfront->tx_fring.rsp_cons++ );
819
820 /* Retrieve from descriptor ring */
821 iobuf = netfront_pull ( netfront, &netfront->tx, response->id );
822 status = response->status;
823 if ( status >= NETIF_RSP_OKAY ) {
824 DBGC2 ( netfront, "NETFRONT %s TX id %d complete\n",
825 xendev->key, response->id );
826 if ( iobuf )
827 netdev_tx_complete ( netdev, iobuf );
828 } else {
829 rc = -EIO_NETIF_RSP ( status );
830 DBGC2 ( netfront, "NETFRONT %s TX id %d error %d: %s\n",
831 xendev->key, response->id, status,
832 strerror ( rc ) );
833 netdev_tx_complete_err ( netdev, iobuf, rc );
834 }
835 }
836}
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
Definition netdevice.c:471
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition netdevice.h:767
#define EIO_NETIF_RSP(status)
Definition netfront.c:59
#define NETIF_RSP_OKAY
Definition netif.h:1080
#define RING_GET_RESPONSE(_r, _idx)
Definition ring.h:246
#define RING_HAS_UNCONSUMED_RESPONSES(_r)
Definition ring.h:238
int16_t status
Definition netif.h:1032
uint16_t id
Definition netif.h:1031

References DBGC2, EIO_NETIF_RSP, netif_tx_response::id, xen_device::key, netdev, netdev_tx_complete(), netdev_tx_complete_err(), netfront_pull(), NETIF_RSP_OKAY, rc, RING_GET_RESPONSE, RING_HAS_UNCONSUMED_RESPONSES, netif_tx_response::status, status, strerror(), netfront_nic::tx, netfront_nic::tx_fring, and netfront_nic::xendev.

Referenced by netfront_poll().

◆ netfront_poll_rx()

void netfront_poll_rx ( struct net_device * netdev)
static

Poll for received packets.

Parameters
netdevNetwork device

Definition at line 843 of file netfront.c.

843 {
844 struct netfront_nic *netfront = netdev->priv;
845 struct xen_device *xendev = netfront->xendev;
846 struct netif_rx_response *response;
847 struct io_buffer *iobuf;
848 int status;
849 int more;
850 size_t len;
851 int rc;
852
853 /* Consume any unconsumed responses */
854 while ( RING_HAS_UNCONSUMED_RESPONSES ( &netfront->rx_fring ) ) {
855
856 /* Get next response */
857 response = RING_GET_RESPONSE ( &netfront->rx_fring,
858 netfront->rx_fring.rsp_cons++ );
859
860 /* Retrieve from descriptor ring */
861 iobuf = netfront_pull ( netfront, &netfront->rx, response->id );
862 status = response->status;
863 more = ( response->flags & NETRXF_more_data );
864
865 /* Report errors */
866 if ( status < 0 ) {
867 rc = -EIO_NETIF_RSP ( status );
868 DBGC2 ( netfront, "NETFRONT %s RX id %d error %d: %s\n",
869 xendev->key, response->id, status,
870 strerror ( rc ) );
871 netfront_discard ( netfront );
872 netdev_rx_err ( netdev, iobuf, rc );
873 continue;
874 }
875
876 /* Add to partial receive list */
877 len = status;
878 iob_reserve ( iobuf, response->offset );
879 iob_put ( iobuf, len );
880 DBGC2 ( netfront, "NETFRONT %s RX id %d complete "
881 "%#08lx+%zx%s\n", xendev->key, response->id,
882 virt_to_phys ( iobuf->data ), len,
883 ( more ? "..." : "" ) );
884 list_add_tail ( &iobuf->list, &netfront->rx_partial );
885
886 /* Wait until complete packet has been received */
887 if ( more )
888 continue;
889
890 /* Reassemble complete packet */
891 iobuf = iob_concatenate ( &netfront->rx_partial );
892 if ( ! iobuf ) {
893 DBGC2 ( netfront, "NETFRONT %s RX reassembly failed\n",
894 xendev->key );
895 netfront_discard ( netfront );
897 continue;
898 }
899
900 /* Hand off to network stack */
901 netdev_rx ( netdev, iobuf );
902 }
903}
struct io_buffer * iob_concatenate(struct list_head *list)
Concatenate I/O buffers into a single buffer.
Definition iobuf.c:250
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define iob_reserve(iobuf, len)
Definition iobuf.h:72
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
#define NETRXF_more_data
Definition netif.h:1053
int16_t status
Definition netif.h:1067
uint16_t offset
Definition netif.h:1065
uint16_t id
Definition netif.h:1064
uint16_t flags
Definition netif.h:1066

References io_buffer::data, DBGC2, EIO_NETIF_RSP, ENOMEM, netif_rx_response::flags, netif_rx_response::id, iob_concatenate(), iob_put, iob_reserve, xen_device::key, len, io_buffer::list, list_add_tail, netdev, netdev_rx(), netdev_rx_err(), netfront_discard(), netfront_pull(), NETRXF_more_data, NULL, netif_rx_response::offset, rc, RING_GET_RESPONSE, RING_HAS_UNCONSUMED_RESPONSES, netfront_nic::rx, netfront_nic::rx_fring, netfront_nic::rx_partial, netif_rx_response::status, status, strerror(), and netfront_nic::xendev.

Referenced by netfront_poll().

◆ netfront_poll()

void netfront_poll ( struct net_device * netdev)
static

Poll for completed and received packets.

Parameters
netdevNetwork device

Definition at line 910 of file netfront.c.

910 {
911
912 /* Poll for TX completions */
914
915 /* Poll for RX completions */
917
918 /* Refill RX descriptor ring */
920}
static void netfront_poll_rx(struct net_device *netdev)
Poll for received packets.
Definition netfront.c:843
static void netfront_poll_tx(struct net_device *netdev)
Poll for completed packets.
Definition netfront.c:805

References netdev, netfront_poll_rx(), netfront_poll_tx(), and netfront_refill_rx().

◆ netfront_probe()

int netfront_probe ( struct xen_device * xendev)
static

Probe Xen device.

Parameters
xendevXen device
Return values
rcReturn status code

Definition at line 943 of file netfront.c.

943 {
944 struct xen_hypervisor *xen = xendev->xen;
945 struct net_device *netdev;
946 struct netfront_nic *netfront;
947 int rc;
948
949 /* Allocate and initialise structure */
950 netdev = alloc_etherdev ( sizeof ( *netfront ) );
951 if ( ! netdev ) {
952 rc = -ENOMEM;
953 goto err_alloc;
954 }
956 netdev->dev = &xendev->dev;
957 netfront = netdev->priv;
958 netfront->xendev = xendev;
959 netfront->netdev = netdev;
960 INIT_LIST_HEAD ( &netfront->rx_partial );
961 DBGC ( netfront, "NETFRONT %s backend=\"%s\" in domain %ld\n",
963
964 /* Allocate grant references and initialise descriptor rings */
965 if ( ( rc = xengrant_alloc ( xen, netfront->refs,
966 NETFRONT_REF_COUNT ) ) != 0 ) {
967 DBGC ( netfront, "NETFRONT %s could not allocate grant "
968 "references: %s\n", xendev->key, strerror ( rc ) );
969 goto err_grant_alloc;
970 }
971 netfront_init_ring ( &netfront->tx, "tx-ring-ref",
972 netfront->refs[NETFRONT_REF_TX_RING],
974 &netfront->refs[NETFRONT_REF_TX_BASE],
975 netfront->tx_ids );
976 netfront_init_ring ( &netfront->rx, "rx-ring-ref",
977 netfront->refs[NETFRONT_REF_RX_RING],
979 &netfront->refs[NETFRONT_REF_RX_BASE],
980 netfront->rx_ids );
981
982 /* Fetch MAC address */
983 if ( ( rc = netfront_read_mac ( netfront, netdev->hw_addr ) ) != 0 )
984 goto err_read_mac;
985
986 /* Reset device. Ignore failures; allow the device to be
987 * registered so that reset errors can be observed by the user
988 * when attempting to open the device.
989 */
990 netfront_reset ( netfront );
991
992 /* Register network device */
993 if ( ( rc = register_netdev ( netdev ) ) != 0 )
994 goto err_register_netdev;
995
996 /* Set initial link state */
998
999 /* Add to list of netfront devices */
1000 list_add_tail ( &netfront->list, &netfront_devices );
1001
1003 return 0;
1004
1005 list_del ( &netfront->list );
1007 err_register_netdev:
1008 err_read_mac:
1009 xengrant_free ( xen, netfront->refs, NETFRONT_REF_COUNT );
1010 err_grant_alloc:
1012 netdev_put ( netdev );
1013 err_alloc:
1014 return rc;
1015}
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
static void xen_set_drvdata(struct xen_device *xendev, void *priv)
Set Xen device driver-private data.
Definition xenbus.h:70
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
static struct net_device_operations netfront_operations
Network device operations.
Definition netfront.c:923
static int netfront_read_mac(struct netfront_nic *netfront, void *hw_addr)
Fetch MAC address.
Definition netfront.c:129
#define NETFRONT_NUM_RX_DESC
Number of receive ring entries.
Definition netfront.h:20
@ NETFRONT_REF_TX_RING
Transmit ring grant reference index.
Definition netfront.h:38
@ NETFRONT_REF_COUNT
Total number of grant references required.
Definition netfront.h:46
@ NETFRONT_REF_TX_BASE
Transmit descriptor grant reference base index.
Definition netfront.h:40
@ NETFRONT_REF_RX_RING
Receive ring grant reference index.
Definition netfront.h:42
@ NETFRONT_REF_RX_BASE
Receive descriptor grant reference base index.
Definition netfront.h:44
#define NETFRONT_NUM_TX_DESC
Number of transmit ring entries.
Definition netfront.h:17
A network device.
Definition netdevice.h:353
grant_ref_t refs[NETFRONT_REF_COUNT]
Grant references.
Definition netfront.h:161
uint8_t rx_ids[NETFRONT_NUM_RX_DESC]
Receive I/O buffer IDs.
Definition netfront.h:184
struct io_buffer * tx_iobufs[NETFRONT_NUM_TX_DESC]
Transmit I/O buffers.
Definition netfront.h:173
struct net_device * netdev
Network device.
Definition netfront.h:164
struct io_buffer * rx_iobufs[NETFRONT_NUM_RX_DESC]
Receive I/O buffers.
Definition netfront.h:182
uint8_t tx_ids[NETFRONT_NUM_TX_DESC]
Transmit I/O buffer IDs.
Definition netfront.h:175
struct list_head list
List of netfront NICs.
Definition netfront.h:166
struct device dev
Generic iPXE device.
Definition xenbus.h:21
char * backend
Backend XenStore key.
Definition xenbus.h:27
int xengrant_alloc(struct xen_hypervisor *xen, grant_ref_t *refs, unsigned int count)
Allocate grant references.
Definition xengrant.c:149
void xengrant_free(struct xen_hypervisor *xen, grant_ref_t *refs, unsigned int count)
Free grant references.
Definition xengrant.c:215

References alloc_etherdev(), xen_device::backend, xen_device::backend_id, DBGC, xen_device::dev, ENOMEM, INIT_LIST_HEAD, xen_device::key, netfront_nic::list, list_add_tail, list_del, netdev, netfront_nic::netdev, netdev_init(), netdev_link_down(), netdev_nullify(), netdev_put(), NETFRONT_NUM_RX_DESC, NETFRONT_NUM_TX_DESC, netfront_operations, netfront_read_mac(), NETFRONT_REF_COUNT, NETFRONT_REF_RX_BASE, NETFRONT_REF_RX_RING, NETFRONT_REF_TX_BASE, NETFRONT_REF_TX_RING, netfront_reset(), rc, netfront_nic::refs, register_netdev(), netfront_nic::rx, netfront_nic::rx_ids, netfront_nic::rx_iobufs, netfront_nic::rx_partial, strerror(), netfront_nic::tx, netfront_nic::tx_ids, netfront_nic::tx_iobufs, unregister_netdev(), xen_device::xen, xen_set_drvdata(), netfront_nic::xendev, xengrant_alloc(), and xengrant_free().

◆ netfront_remove()

void netfront_remove ( struct xen_device * xendev)
static

Remove Xen device.

Parameters
xendevXen device

Definition at line 1022 of file netfront.c.

1022 {
1023 struct net_device *netdev = xen_get_drvdata ( xendev );
1024 struct netfront_nic *netfront = netdev->priv;
1025 struct xen_hypervisor *xen = xendev->xen;
1026
1027 /* Remove from list of netfront devices */
1028 list_del ( &netfront->list );
1029
1030 /* Unregister network device */
1032
1033 /* Free resources */
1034 xengrant_free ( xen, netfront->refs, NETFRONT_REF_COUNT );
1035
1036 /* Free network device */
1038 netdev_put ( netdev );
1039}
static void * xen_get_drvdata(struct xen_device *xendev)
Get Xen device driver-private data.
Definition xenbus.h:80

References netfront_nic::list, list_del, netdev, netdev_nullify(), netdev_put(), NETFRONT_REF_COUNT, netfront_nic::refs, unregister_netdev(), xen_device::xen, xen_get_drvdata(), and xengrant_free().

◆ XEN_ROM()

XEN_ROM ( "netfront" ,
"Xen netfront virtual NIC"  )

◆ netfront_net_probe()

int netfront_net_probe ( struct net_device * netdev,
void *priv __unused )
static

Inhibit emulated PCI devices.

Parameters
netdevNetwork device
privPrivate data
Return values
rcReturn status code

Definition at line 1066 of file netfront.c.

1067 {
1068 struct netfront_nic *netfront;
1069
1070 /* Inhibit emulated PCI devices matching an existing netfront device */
1071 list_for_each_entry ( netfront, &netfront_devices, list ) {
1072 if ( ( netdev->dev != netfront->netdev->dev ) &&
1073 ( netdev->ll_protocol->ll_addr_len == ETH_ALEN ) &&
1074 ( memcmp ( netdev->hw_addr, netfront->netdev->hw_addr,
1075 ETH_ALEN ) == 0 ) ) {
1076 DBGC ( netfront, "NETFRONT %s inhibiting emulated %s "
1077 "%s\n", netfront->xendev->key,
1078 netdev->dev->driver_name, netdev->dev->name );
1079 return -EEXIST;
1080 }
1081 }
1082
1083 return 0;
1084}
#define EEXIST
File exists.
Definition errno.h:389
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition netdevice.h:382
struct device * dev
Underlying hardware device.
Definition netdevice.h:365

References __unused, DBGC, net_device::dev, EEXIST, ETH_ALEN, net_device::hw_addr, xen_device::key, netfront_nic::list, list_for_each_entry, memcmp(), netdev, netfront_nic::netdev, priv, and netfront_nic::xendev.

Variable Documentation

◆ netfront_operations

struct net_device_operations netfront_operations
static
Initial value:
= {
.open = netfront_open,
.close = netfront_close,
.transmit = netfront_transmit,
.poll = netfront_poll,
}
static int netfront_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition netfront.c:728
static void netfront_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition netfront.c:910
static int netfront_open(struct net_device *netdev)
Open network device.
Definition netfront.c:579
static void netfront_close(struct net_device *netdev)
Close network device.
Definition netfront.c:675

Network device operations.

Definition at line 923 of file netfront.c.

923 {
924 .open = netfront_open,
925 .close = netfront_close,
926 .transmit = netfront_transmit,
927 .poll = netfront_poll,
928};

Referenced by netfront_probe().

◆ __xen_driver

struct xen_driver netfront_driver __xen_driver
Initial value:
= {
.name = "netfront",
.type = "vif",
.probe = netfront_probe,
.remove = netfront_remove,
}
static int netfront_probe(struct xen_device *xendev)
Probe Xen device.
Definition netfront.c:943
static void netfront_remove(struct xen_device *xendev)
Remove Xen device.
Definition netfront.c:1022

Xen netfront driver.

Definition at line 1042 of file netfront.c.

1042 {
1043 .name = "netfront",
1044 .type = "vif",
1045 .probe = netfront_probe,
1046 .remove = netfront_remove,
1047};

◆ __net_driver

struct net_driver netfront_net_driver __net_driver
Initial value:
= {
.name = "netfront",
}
static int netfront_net_probe(struct net_device *netdev, void *priv __unused)
Inhibit emulated PCI devices.
Definition netfront.c:1066

Emulated PCI device inhibitor driver.

Definition at line 1087 of file netfront.c.

1087 {
1088 .name = "netfront",
1089 .probe = netfront_net_probe,
1090};