176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef _GPXE_NETDEVICE_H
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define _GPXE_NETDEVICE_H
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** @file
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Network device management
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1076d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL2_OR_LATER );
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdint.h>
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/list.h>
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/tables.h>
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/refcnt.h>
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/settings.h>
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct io_buffer;
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct net_device;
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct net_protocol;
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct ll_protocol;
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct device;
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Maximum length of a hardware address
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The longest currently-supported link-layer address is for IPoIB.
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MAX_HW_ADDR_LEN 8
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Maximum length of a link-layer address
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The longest currently-supported link-layer address is for IPoIB.
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MAX_LL_ADDR_LEN 20
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Maximum length of a link-layer header
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The longest currently-supported link-layer header is for 802.11: a
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 24-byte frame header plus an 8-byte 802.3 LLC/SNAP header.  (The
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * IPoIB link-layer pseudo-header doesn't actually include link-layer
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * addresses; see ipoib.c for details).
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MAX_LL_HEADER_LEN 32
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Maximum length of a network-layer address */
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MAX_NET_ADDR_LEN 4
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * A network-layer protocol
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct net_protocol {
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Protocol name */
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	const char *name;
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/**
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Process received packet
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v iobuf	I/O buffer
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v netdev	Network device
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v ll_source	Link-layer source address
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This method takes ownership of the I/O buffer.
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev,
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       const void *ll_source );
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/**
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Transcribe network-layer address
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v net_addr	Network-layer address
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @ret string	Human-readable transcription of address
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This method should convert the network-layer address into a
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * human-readable format (e.g. dotted quad notation for IPv4).
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * The buffer used to hold the transcription is statically
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * allocated.
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	const char * ( *ntoa ) ( const void * net_addr );
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Network-layer protocol
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is an ETH_P_XXX constant, in network-byte order
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t net_proto;
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Network-layer address length */
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t net_addr_len;
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * A link-layer protocol
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct ll_protocol {
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Protocol name */
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	const char *name;
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/**
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Add link-layer header
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v netdev		Network device
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v iobuf		I/O buffer
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v ll_dest		Link-layer destination address
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v ll_source		Source link-layer address
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v net_proto		Network-layer protocol, in network-byte order
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @ret rc		Return status code
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int ( * push ) ( struct net_device *netdev, struct io_buffer *iobuf,
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			 const void *ll_dest, const void *ll_source,
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			 uint16_t net_proto );
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/**
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Remove link-layer header
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v netdev		Network device
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v iobuf		I/O buffer
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @ret ll_dest		Link-layer destination address
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @ret ll_source	Source link-layer address
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @ret net_proto	Network-layer protocol, in network-byte order
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @ret rc		Return status code
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int ( * pull ) ( struct net_device *netdev, struct io_buffer *iobuf,
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			 const void **ll_dest, const void **ll_source,
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			 uint16_t *net_proto );
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/**
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Initialise link-layer address
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v hw_addr		Hardware address
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v ll_addr		Link-layer address to fill in
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void ( * init_addr ) ( const void *hw_addr, void *ll_addr );
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/**
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Transcribe link-layer address
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v ll_addr		Link-layer address
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @ret string		Human-readable transcription of address
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This method should convert the link-layer address into a
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * human-readable format.
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * The buffer used to hold the transcription is statically
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * allocated.
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	const char * ( * ntoa ) ( const void *ll_addr );
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/**
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Hash multicast address
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v af		Address family
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v net_addr		Network-layer address
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v ll_addr		Link-layer address to fill in
14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @ret rc		Return status code
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int ( * mc_hash ) ( unsigned int af, const void *net_addr,
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    void *ll_addr );
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/**
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Generate Ethernet-compatible compressed link-layer address
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v ll_addr		Link-layer address
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v eth_addr		Ethernet-compatible address to fill in
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int ( * eth_addr ) ( const void *ll_addr, void *eth_addr );
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Link-layer protocol
15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is an ARPHRD_XXX constant, in network byte order.
16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t ll_proto;
16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Hardware address length */
16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t hw_addr_len;
16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Link-layer address length */
16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t ll_addr_len;
16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Link-layer header length */
16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t ll_header_len;
16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Network device operations */
17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct net_device_operations {
17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Open network device
17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v netdev	Network device
17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @ret rc	Return status code
17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This method should allocate RX I/O buffers and enable
17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * the hardware to start transmitting and receiving packets.
18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int ( * open ) ( struct net_device *netdev );
18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Close network device
18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v netdev	Network device
18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This method should stop the flow of packets, and free up
18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * any packets that are currently in the device's TX queue.
18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void ( * close ) ( struct net_device *netdev );
19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Transmit packet
19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v netdev	Network device
19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v iobuf	I/O buffer
19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @ret rc	Return status code
19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This method should cause the hardware to initiate
19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * transmission of the I/O buffer.
19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * If this method returns success, the I/O buffer remains
20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * owned by the net device's TX queue, and the net device must
20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * eventually call netdev_tx_complete() to free the buffer.
20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * If this method returns failure, the I/O buffer is
20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * immediately released; the failure is interpreted as
20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * "failure to enqueue buffer".
20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This method is guaranteed to be called only when the device
20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * is open.
20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int ( * transmit ) ( struct net_device *netdev,
21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			     struct io_buffer *iobuf );
21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Poll for completed and received packets
21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v netdev	Network device
21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This method should cause the hardware to check for
21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * completed transmissions and received packets.  Any received
21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * packets should be delivered via netdev_rx().
21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This method is guaranteed to be called only when the device
22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * is open.
22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void ( * poll ) ( struct net_device *netdev );
22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Enable or disable interrupts
22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v netdev	Network device
22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * @v enable	Interrupts should be enabled
22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void ( * irq ) ( struct net_device *netdev, int enable );
22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Network device error */
23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct net_device_error {
23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Error status code */
23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int rc;
23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Error count */
23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int count;
23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Maximum number of unique errors that we will keep track of */
24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define NETDEV_MAX_UNIQUE_ERRORS 4
24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Network device statistics */
24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct net_device_stats {
24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Count of successful completions */
24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int good;
24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Count of error completions */
24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int bad;
24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Error breakdowns */
24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct net_device_error errors[NETDEV_MAX_UNIQUE_ERRORS];
25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * A network device
25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This structure represents a piece of networking hardware.  It has
25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * properties such as a link-layer address and methods for
25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * transmitting and receiving raw packets.
25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Note that this structure must represent a generic network device,
26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * not just an Ethernet device.
26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct net_device {
26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reference counter */
26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct refcnt refcnt;
26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** List of network devices */
26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct list_head list;
26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** List of open network devices */
26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct list_head open_list;
26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Name of this network device */
27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	char name[8];
27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Underlying hardware device */
27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct device *dev;
27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Network device operations */
27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct net_device_operations *op;
27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Link-layer protocol */
27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct ll_protocol *ll_protocol;
27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Hardware address
28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is an address which is an intrinsic property of the
28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * hardware, e.g. an address held in EEPROM.
28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Note that the hardware address may not be the same length
28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * as the link-layer address.
28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t hw_addr[MAX_HW_ADDR_LEN];
28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Link-layer address
28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is the current link-layer address assigned to the
29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * device.  It can be changed at runtime.
29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t ll_addr[MAX_LL_ADDR_LEN];
29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Link-layer broadcast address */
29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	const uint8_t *ll_broadcast;
29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Current device state
29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is the bitwise-OR of zero or more NETDEV_XXX constants.
30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int state;
30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Link status code
30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Zero indicates that the link is up; any other value
30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * indicates the error preventing link-up.
30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int link_rc;
30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Maximum packet length
30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This length includes any link-layer headers.
31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	size_t max_pkt_len;
31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** TX packet queue */
31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct list_head tx_queue;
31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** RX packet queue */
31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct list_head rx_queue;
31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** TX statistics */
31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct net_device_stats tx_stats;
31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** RX statistics */
32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct net_device_stats rx_stats;
32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
32276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Configuration settings applicable to this device */
32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct generic_settings settings;
32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Driver private data */
32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void *priv;
32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
32976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Network device is open */
33076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define NETDEV_OPEN 0x0001
33176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
33276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Link-layer protocol table */
33376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LL_PROTOCOLS __table ( struct ll_protocol, "ll_protocols" )
33476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
33576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Declare a link-layer protocol */
33676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __ll_protocol  __table_entry ( LL_PROTOCOLS, 01 )
33776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
33876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Network-layer protocol table */
33976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define NET_PROTOCOLS __table ( struct net_protocol, "net_protocols" )
34076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
34176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Declare a network-layer protocol */
34276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __net_protocol __table_entry ( NET_PROTOCOLS, 01 )
34376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
34476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern struct list_head net_devices;
34576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern struct net_device_operations null_netdev_operations;
34676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern struct settings_operations netdev_settings_operations;
34776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
34876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
34976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Initialise a network device
35076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
35176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev		Network device
35276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v op		Network device operations
35376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
35476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void netdev_init ( struct net_device *netdev,
35576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				 struct net_device_operations *op ) {
35676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev->op = op;
35776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
35876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
35976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
36076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Stop using a network device
36176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
36276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev		Network device
36376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
36476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Drivers should call this method immediately before the final call
36576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * to netdev_put().
36676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
36776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void netdev_nullify ( struct net_device *netdev ) {
36876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev->op = &null_netdev_operations;
36976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
37076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
37176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
37276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Get printable network device link-layer address
37376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
37476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev		Network device
37576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret name		Link-layer address
37676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
37776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline const char * netdev_addr ( struct net_device *netdev ) {
37876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return netdev->ll_protocol->ntoa ( netdev->ll_addr );
37976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
38076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
38176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Iterate over all network devices */
38276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define for_each_netdev( netdev ) \
38376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	list_for_each_entry ( (netdev), &net_devices, list )
38476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
38576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** There exist some network devices
38676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
38776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret existence	Existence of network devices
38876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
38976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline int have_netdevs ( void ) {
39076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return ( ! list_empty ( &net_devices ) );
39176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
39276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
39376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
39476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Get reference to network device
39576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
39676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev		Network device
39776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret netdev		Network device
39876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
39976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __attribute__ (( always_inline )) struct net_device *
40076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmannetdev_get ( struct net_device *netdev ) {
40176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ref_get ( &netdev->refcnt );
40276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return netdev;
40376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
40476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
40576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
40676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Drop reference to network device
40776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
40876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev		Network device
40976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
41076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __attribute__ (( always_inline )) void
41176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmannetdev_put ( struct net_device *netdev ) {
41276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ref_put ( &netdev->refcnt );
41376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
41476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
41576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
41676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Get driver private area for this network device
41776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
41876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev		Network device
41976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret priv		Driver private area for this network device
42076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
42176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __attribute__ (( always_inline )) void *
42276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmannetdev_priv ( struct net_device *netdev ) {
42376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        return netdev->priv;
42476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
42576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
42676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
42776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Get per-netdevice configuration settings block
42876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
42976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev		Network device
43076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret settings	Settings block
43176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
43276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __attribute__ (( always_inline )) struct settings *
43376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmannetdev_settings ( struct net_device *netdev ) {
43476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return &netdev->settings.settings;
43576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
43676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
43776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
43876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Initialise a per-netdevice configuration settings block
43976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
44076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v generics		Generic settings block
44176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v refcnt		Containing object reference counter, or NULL
44276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v name		Settings block name
44376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
44476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __attribute__ (( always_inline )) void
44576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmannetdev_settings_init ( struct net_device *netdev ) {
44676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	generic_settings_init ( &netdev->settings,
44776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				&netdev->refcnt, netdev->name );
44876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev->settings.settings.op = &netdev_settings_operations;
44976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
45076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
45176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
45276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Mark network device as having link up
45376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
45476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev		Network device
45576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
45676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __attribute__ (( always_inline )) void
45776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmannetdev_link_up ( struct net_device *netdev ) {
45876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev->link_rc = 0;
45976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
46076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
46176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
46276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Mark network device as having link down due to a specific error
46376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
46476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev		Network device
46576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rc		Link status code
46676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
46776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __attribute__ (( always_inline )) void
46876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmannetdev_link_err ( struct net_device *netdev, int rc ) {
46976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev->link_rc = rc;
47076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
47176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
47276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
47376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Check link state of network device
47476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
47576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev		Network device
47676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret link_up		Link is up
47776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
47876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __attribute__ (( always_inline )) int
47976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmannetdev_link_ok ( struct net_device *netdev ) {
48076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return ( netdev->link_rc == 0 );
48176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
48276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
48376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void netdev_link_down ( struct net_device *netdev );
48476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
48576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void netdev_tx_complete_err ( struct net_device *netdev,
48676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				 struct io_buffer *iobuf, int rc );
48776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void netdev_tx_complete_next_err ( struct net_device *netdev, int rc );
48876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf );
48976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void netdev_rx_err ( struct net_device *netdev,
49076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    struct io_buffer *iobuf, int rc );
49176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void netdev_poll ( struct net_device *netdev );
49276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev );
49376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern struct net_device * alloc_netdev ( size_t priv_size );
49476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int register_netdev ( struct net_device *netdev );
49576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int netdev_open ( struct net_device *netdev );
49676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void netdev_close ( struct net_device *netdev );
49776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void unregister_netdev ( struct net_device *netdev );
49876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void netdev_irq ( struct net_device *netdev, int enable );
49976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern struct net_device * find_netdev ( const char *name );
50076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern struct net_device * find_netdev_by_location ( unsigned int bus_type,
50176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman						     unsigned int location );
50276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern struct net_device * last_opened_netdev ( void );
50376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
50476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    struct net_protocol *net_protocol, const void *ll_dest );
50576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
50676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    uint16_t net_proto, const void *ll_source );
50776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
50876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
50976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Complete network transmission
51076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
51176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev		Network device
51276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v iobuf		I/O buffer
51376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
51476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The packet must currently be in the network device's TX queue.
51576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
51676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void netdev_tx_complete ( struct net_device *netdev,
51776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					struct io_buffer *iobuf ) {
51876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev_tx_complete_err ( netdev, iobuf, 0 );
51976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
52076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
52176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
52276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Complete network transmission
52376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
52476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev		Network device
52576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
52676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Completes the oldest outstanding packet in the TX queue.
52776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
52876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void netdev_tx_complete_next ( struct net_device *netdev ) {
52976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev_tx_complete_next_err ( netdev, 0 );
53076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
53176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
53276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* _GPXE_NETDEVICE_H */
533