Google is committed to advancing racial equity for Black communities. See how.

fuchsia.hardware.network.device

Generic Network Device interface.

The definitions herein provide the API surface to expose a hardware device as a network device interface to the system through the FIDL protocol fuchsia.hardware.network/Device. A network device interface is the data-plane contract that allows the networking stack to send and receive frames on a physical or virtual network. A device exposes this capability by implementing the NetworkDeviceImpl protocol, which allows a middleware implementation to bind to it and offer the FIDL protocol to applications.

The API contract is based on three key concepts:

  • Frame Types
  • Receive and Transmit buffers
  • Memory layout

Frame Types are the defined contract that is exposed to applications, which convey the data type contained in a tx or rx buffer. The supported frame types are defined in fuchsia.hardware.network/FrameType. Upon initialization, the middleware implementation will fetch the supported frame types from the device through the GetInfo call.

Receive and Transmit buffers are buffers that are headed to different directions: a receive buffer is a piece of data that is received from the network, and makes its way to the application layer. A transmit buffer travels in the opposite direction: it originates in the application layer and makes its way out into the network. The device implementation receives buffers from the NetworkDeviceIfc, which is offered by the middleware implementation.

A receive buffer flows from NetworkDeviceIfc into NetworkDeviceImpl through the NetworkDeviceImpl.QueueRxSpace method, which gives access to receive buffers. The diagram below illustrates the mechanism:

 ++++++++++++++++++++                      +++++++++++++++++++++
 |       (1)        |  => RxSpaceBuffer => |       (2)         |
 | NetworkDeviceIfc |                      | NetworkDeviceImpl |
 |       (4)        |  <=    RxBuffer   <= |       (3)         |  <= Network data
 ++++++++++++++++++++                      +++++++++++++++++++++
  • (1) NetworkDeviceIfc pushes available rx buffer space to NetworkDeviceImpl through NetworkDeviceImpl.QueueRxSpace.
  • (2) NetworkDeviceImpl retains the available space buffers until network data comes in.
  • (3) NetworkDeviceImpl receives data from the network, stores it in one of its available RxSpaceBuffers, making it a NetworkDeviceImpl.RxBuffer.
  • (4) NetworkDeviceImpl sends the fulfilled RxBuffer to NetworkDeviceIfc through NetworkDeviceIfc.CompleteRx, which, in turn, sends that data over to applications.

A receive buffer flows from NetworkDeviceIfc into NetworkDeviceImpl through the NetworkDeviceImpl.QueueTx method, and it's returned to NetworkDeviceIfc as a TxResult. The diagram below illustrates the mechanism:

 ++++++++++++++++++++                 +++++++++++++++++++++
 |       (1)        |  => TxBuffer => |       (2)         |
 | NetworkDeviceIfc |                 | NetworkDeviceImpl |
 |       (4)        |  <= TxResult <= |       (3)         |  => Network data
 ++++++++++++++++++++                 +++++++++++++++++++++
  • (1) NetworkDeviceIfc receives a transmit buffer from applications filled with data intended to be delivered to the network.
  • (2) NetworkDeviceIfc pushes the buffer into NetworkDeviceImpl through the NetworkDeviceImpl.QueueTx call.
  • (3) NetworkDeviceImpl sends the data contained in the buffer out into the network.
  • (4) When the data is successfully transmitted, NetworkDeviceImpl marks the transmission as complete referencing the buffer's identifier to NetworkDeviceIfc.CompleteTx.

PROTOCOLS

NetworkDeviceIfc

Defined in fuchsia.hardware.network.device/network-device.fidl

AddPort

Instantiates a new port with id.

id must not be currently in use by any other ports. ids may be reused once the provided port is destroyed by NetworkPort.Removed.

Port identifiers do not need to be stable across instantiations or reboots. Port identifiers don't need to be allocated in any specific order as long as MAX_PORTS is not exceeded.

  • request id new port identifier.
  • request port handle to network port implementation.

Request

NameType
id port_id
port NetworkPort

CompleteRx

Notifies interface of incoming rx data, contained in RxBuffer.

Callers should attempt to batch as many buffers as possible in a single call. Number of buffers in a single call must be limited to the DeviceInfo.rx_depth reported by the NetworkDeviceImpl that is returning the buffers.

Buffers with zero length are considered "unfulfilled". They're not reported to any sessions and the buffer space comprising them may be reused. Devices should return any outstanding buffer space as unfulfilled on stop. See NetworkDeviceImpl.Stop.

By calling CompleteRx the caller relinquishes ownership of all buffers that are being marked as complete.

  • request rx buffers containing incoming data.

Request

NameType
rx vector<RxBuffer>

CompleteTx

Notifies interface of complete transmit buffers.

Callers should attempt to batch as many buffers as possible in a single call.

Number of buffers in a single call must be limited to the DeviceInfo.tx_depth reported by the NetworkDeviceImpl that is returning the buffers.

By calling CompleteTx the caller relinquishes ownership of all buffers that are being returned.

  • request tx transmit results.

Request

NameType
tx vector<TxResult>

PortStatusChanged

Notifies the interface of status changes on port with id.

Port status changes must always be notified through StatusChanged. The interface will not poll ports for status via NetworkPort.GetStatus.

  • request id port identifier.
  • request new_status new port's status.

Request

NameType
id port_id
new_status PortStatus

RemovePort

Destroys port with id.

NOTE: Resources associated with the port must not be freed until NetworkPort.Removed is called.

  • request id removed port identifier.

Request

NameType
id port_id

Snoop

Notifies interface of a snooped tx frame.

Typically used by implementations that have the FEATURE_NO_AUTO_SNOOP bit set in DeviceInfo.device_features. Implementations that generate transmit traffic internally should use Snoop regardless of FEATURE_NO_AUTO_SNOOP being set.

Snooped frames are ALWAYS outbound frames that are being fed back into the interface for traffic snooping. Device implementations need to call NetworkDeviceIfc.Snoop ONLY if NetworkDeviceImpl.SetSnoop was set to true by the interface, otherwise any buffers in Snoop will be ignored.

  • request rx snooped transmit frames to be looped back as incoming data.

Request

NameType
rx vector<RxBuffer>

NetworkDeviceImpl

Defined in fuchsia.hardware.network.device/network-device.fidl

GetInfo

Gets information about the device.

Device information must not change over the course of the lifetime of the device.

  • response info device information.

Request

<EMPTY>

Response

NameType
info DeviceInfo

Init

Initializes the network device.

Init is only called once during the lifetime of the device to register iface as the callback target for the Network Device implementation.

Upon initialization, the device is expected to be in the "Stopped" state, the Start method will be called once the data path needs to be opened.

  • request iface handle to the device interface.
  • response s initialization status. A value other than ZX_OK will cause the device to unbind.

Request

NameType
iface NetworkDeviceIfc

Response

NameType
s zx/status

PrepareVmo

Informs device that a new VMO is being used to store frame data.

Implementers must store the VMO handle referenced by id until NetworkDeviceImpl.ReleaseVmo is called with the same id.

  • request id identifier used to reference this VMO.
  • request vmo VMO where frame data will be stored.

Request

NameType
id vmo_id
vmo handle<vmo>

QueueRxSpace

Enqueues a list of rx buffer space on the network device.

The driver takes ownership of the buffer and must complete the transaction (once network data arrives) using NetworkDeviceIfc.CompleteRx.

The total number of outstanding rx buffers given to a device will never exceed the reported DeviceInfo.rx_depth value. Which also means that no more than rx_depth buffers are going to be informed at once in a single call to QueueRxSpace.

Buffers enqueued while the device in is the stopped state must be returned with a zero length.

  • request buffers rx space buffers to be filled with network data when it arrives.

Request

NameType
buffers vector<RxSpaceBuffer>

QueueTx

Enqueues a list of buffers for transmission on the network device.

The driver takes ownership of the buffer and must complete the tx transaction by using NetworkDeviceIfc.CompleteTx operations once it is done with each buffer in buffers.

The total number of outstanding tx buffers given to a device will never exceed the reported DeviceInfo.tx_depth value. Which also means that no more than tx_depth buffers are going to be informed at once in a single call to QueueTx.

Buffers enqueued while the device in is the stopped state must be returned with an appropriate error. See TxResult.status for specific error codes.

  • request buffers tx buffers to enqueue for sending.

Request

NameType
buffers vector<TxBuffer>

ReleaseVmo

Device may dispose of all references to the VMO referenced by id.

No more buffers will be sent with this id.

ReleaseVmo is guaranteed to only be called when the implementation holds no buffers that reference that id.

  • request id VMO identifier.

Request

NameType
id vmo_id

SetSnoop

Informs the device that it should start or stop reporting snooped transmit frames through NetworkDeviceIfc.Snoop.

  • request snoop if true device should start reporting snooping frames. If false device should stop reporting snooped frames. Upon initialization, device assumes snop is false.

Request

NameType
snoop bool

Start

Starts the device's data path.

start signals to the device implementation that it should bring up its data path and be ready to receive tx frames and iface will start accepting rx frames.

The device is only considered started once Start returns successfully. Until then, the contract guarantees that no other data-path calls will be made to the device (QueueTx, RxAvailable, Stop, or a second call to Start), so implementers can safely assume or assert that this contract is upheld.

  • response s start status. ZX_OK indicates a successful start. ZX_ERR_ALREADY_BOUND indicates that the device has already been successfully started. Any other status value indicates an implementation specific error.

Request

<EMPTY>

Response

NameType
s zx/status

Stop

Stops the network device.

The device implementation must return all outstanding Tx and Rx buffers upon receiving this call. Any new buffers received in the stopped state must be returned with an appropriate error (tx) or unfulfilled (rx). See NetworkDeviceIfc.CompleteTx and NetworkDeviceIfc.CompleteRx for details.

The device implementation may perform any power saving measures after observing stop.

Request

<EMPTY>

Response

<EMPTY>

NetworkPort

Defined in fuchsia.hardware.network.device/network-device.fidl

GetInfo

Gets information about the port.

Port information must not change over the port's lifetime.

  • response info port information.

Request

<EMPTY>

Response

NameType
info PortInfo

GetMac

Gets an interface to the MAC addressing layer of the port.

Ports that do not support MAC addressing must return an empty interface. That means the generated-banjo bindings ctx and ops fields must both be null.

  • response mac_ifc mac addressing handle.

Request

<EMPTY>

Response

NameType
mac_ifc fuchsia.hardware.network.mac/MacAddr

GetStatus

Gets operational status of the port.

Changes to operational status must be reported via NetworkDeviceIfc.StatusChanged

  • response status snapshot of port's operational status.

Request

<EMPTY>

Response

NameType
status PortStatus

Removed

Notifies this port has been removed from the interface.

Resources associated with the port must only be freed upon receiving the Removed call.

Request

<EMPTY>

SetActive

Notifies the port that there are sessions interested in it.

An active port has sessions attached to it. Implementations may employ power saving or other strategies on disabled ports. Implementations that do employ such strategies:

  • should not report inbound frames for inactive ports;
  • must return errors for outbound frames destined to inactive ports.

All ports are inactive on creation.

  • request active true if port has sessions attached to it, false otherwise.

Request

NameType
active bool

STRUCTS

BufferMetadata

Defined in fuchsia.hardware.network.device/network-device.fidl

Metadata associated with a TxBuffer or an RxBuffer.

FieldTypeDescriptionDefault
port port_id

Destination or source port identifier for this buffer.

No default
info FrameInfo

Extra frame metadata information. The type of the FrameInfo union is defined by the value in info_type.

No default
info_type uint32

Type of data in info, as defined in fuchsia.hardware.network/InfoType.

No default
flags uint32

Frame tx or rx flags, as defined in fuchsia.hardware.network/RxFlags, fuchsia.hardware.network/TxFlags, and fuchsia.hardware.network/TxReturnFlags.

No default
frame_type uint8

Type of frame contained in this buffer, as defined in fuchsia.hardware.network/FrameType.

No default

BufferRegion

Defined in fuchsia.hardware.network.device/network-device.fidl

A contiguous memory region in a VMO.

Note that a BufferRegion is only contiguous in terms of the VMO it references, it does not necessarily translate into contiguous physical memory.

FieldTypeDescriptionDefault
vmo vmo_id

VMO backing this region.

No default
offset uint64

Offset, in bytes, of data chunk in VMO.

No default
length uint64

Length, in bytes, of data chunk in VMO.

No default

DeviceInfo

Defined in fuchsia.hardware.network.device/network-device.fidl

Static device information. DeviceInfo must not change for the entire lifetime of a device.

FieldTypeDescriptionDefault
device_features uint32

Device features

No default
tx_depth uint16

Maximum depth of tx frames in device's outgoing queue.

No default
rx_depth uint16

Maximum number of rx frames in a device's incoming queue.

No default
rx_threshold uint16

Rx depth threshold at which the device should be fed new rx buffers.

New buffer notifications from NetworkDeviceIfc may be skipped while the number of rx buffers held by the implementation is larger than rx_threshold. It is invalid to provide a value larger than rx_depth. rx_threshold = rx_depth is functionally equivalent to rx_threshold = rx_depth - 1.

A large value (close to rx_depth) may cause considerable CPU thrash for small rx completion transaction sizes, while a small value may cause the implementation to be starved of buffers. The typical choice of value is rx_depth / 2.

No default
max_buffer_parts uint8

Maximum virtual discontiguous buffer parts accepted by the device.

Devices that can't perform scatter-gather operations must set max_buffer_parts to 1.

Must be in the range [1, MAX_BUFFER_PARTS].

No default
max_buffer_length uint32

Maximum total length of buffers. May be set to zero for no maximum.

Devices that do not support scatter-gather DMA may set this to a value smaller than a page size to guarantee compatibility.

No default
buffer_alignment uint32

Alignment requirement for buffers relative to the start of VMOs.

Must be greater than zero.

No default
min_rx_buffer_length uint32

The minimum rx buffer length for correct operation, in bytes.

No default
min_tx_buffer_length uint32

The minimum tx buffer length for correct operation, in bytes.

This length accounts only for the buffer's body, and should not account for tx_head_length or tx_tail_length.

No default
tx_head_length uint16

Number of bytes requested as header bytes on tx buffers.

If set to zero, tx buffers will never contain header space. Otherwise, tx buffers will start at the beginning of the header space, and the header region will be informed.

No default
tx_tail_length uint16

Number of bytes requested as tail bytes on tx buffers.

If set to zero, tx buffers will never contain tail space. Otherwise, tx buffers will end at the end of the tail space, and the tail region will be informed.

No default
rx_accel vector<uint8>

Available Rx acceleration flags for this device, as defined in fuchsia.hardware.network/RxAcceleration.

rx_accel maps the RX_ACCEL_* flags in the frame descriptors with semantic acceleration features described by RxAcceleration. Position n of rx_accel conveys the meaning of the RX_ACCEL_n flag.

No default
tx_accel vector<uint8>

Available tx acceleration flags for this device, as defined in fuchsia.hardware.network/TxAcceleration.

tx_accel maps the TX_ACCEL_* flags in the frame descriptors with semantic acceleration features described by TxAcceleration. Position n of tx_accel conveys the meaning of the TX_ACCEL_n flag.

No default

NoInfo

Defined in fuchsia.hardware.network.device/network-device.fidl

No extra frame metadata, FrameInfo.info_type must be fuchsia.hardware.network/InfoType.NO_INFO.

FieldTypeDescriptionDefault
nothing uint8 No default

PortInfo

Defined in fuchsia.hardware.network.device/network-device.fidl

Static port information.

FieldTypeDescriptionDefault
port_class uint8

Port class, as defined in fuchsia.hardware.network/PortClass.

No default
rx_types vector<uint8>

Supported rx frame types, as defined by fuchsia.hardware.network/FrameType.

No default
tx_types vector<TxSupport>

Supported tx frame types.

No default

PortStatus

Defined in fuchsia.hardware.network.device/network-device.fidl

Dynamic port information.

PortStatus reflects the operational status of a port, changes to status are reported through NetworkDeviceIfc.StatusChanged.

FieldTypeDescriptionDefault
mtu uint32

Port's maximum transmission unit, in bytes.

No default
flags uint32

Port status flags.

Status flags, as defined in fuchsia.hardware.network/Status.

No default

RxBuffer

Defined in fuchsia.hardware.network.device/network-device.fidl

A buffer containing a single frame received by the device.

FieldTypeDescriptionDefault
meta BufferMetadata

Metadata associated with buffer.

No default
data vector<RxBufferPart>[4]

Fulfilled rx buffer space comprising this frame.

Must have at least one part.

No default

RxBufferPart

Defined in fuchsia.hardware.network.device/network-device.fidl

A single contiguous part of an RxBuffer, created from an RxSpaceBuffer.

FieldTypeDescriptionDefault
id buffer_id

The buffer identifier informed in the RxSpaceBuffer that originated this RxBuffer.

No default
offset uint32

Offset in bytes from RxSpaceBuffer's start where inbound data begins.

This is a relative offset within the region defined by the originating space, not an absolute offset in the space's VMO.

No default
length uint32

The total length in bytes written in the RxSpaceBuffer referenced by id, excluding any offset bytes.

No default

RxSpaceBuffer

Defined in fuchsia.hardware.network.device/network-device.fidl

A buffer with allocated space to receive frames in. An RxSpaceBuffer must always be returned as an RxBufferPart within an RxBuffer.

FieldTypeDescriptionDefault
id buffer_id

Unique buffer identifier.

No default
region BufferRegion

VMO region where buffer space is located.

No default

TxBuffer

Defined in fuchsia.hardware.network.device/network-device.fidl

A transmit buffer containing a single frame.

FieldTypeDescriptionDefault
id buffer_id

Unique buffer identifier.

No default
data vector<BufferRegion>[4]

Regions of VMO holding frame data.

No default
meta BufferMetadata

Metadata associated with this buffer.

No default
head_length uint16

Length of header bytes in the data contained in this buffer.

Will always be either 0 or the requested DeviceInfo.tx_head_length value. The head bytes are always at the beginning of the buffer.

No default
tail_length uint16

Length of tail bytes in the data contained in this buffer.

Will always be either 0 or the requested DeviceInfo.tx_tail_length value. The tail bytes are always at the end of the buffer.

No default

TxResult

Defined in fuchsia.hardware.network.device/network-device.fidl

The result of a tx operation, reported to NetworkDeviceIfc through NetworkDeviceIfc.CompleteTx.

FieldTypeDescriptionDefault
id buffer_id

The buffer identifier informed in the TxBuffer that originated this TxResult.

No default
status zx/status

The result status to report.

Error results map to their equivalents in fuchsia.hardware.network/TxReturnFlags.

  • ZX_OK if the frame was sent successfully.
  • ZX_ERR_NOT_SUPPORTED if any of the frame's flags are not supported.
  • ZX_ERR_NO_RESOURCES if the transmit failed to allocate space in its output queue for the frame.
  • ZX_ERR_UNAVAILABLE if the device is offline (or went offline before getting a confirmation that the frame was sent) or stopped.
  • ZX_ERR_INTERNAL or any other unlisted errors will be reported as a generic fuchsia.hardware.network/TxReturnFlags.TX_RET_ERROR.
No default

TxSupport

Defined in fuchsia.hardware.network.device/network-device.fidl

Supported tx frame types.

FieldTypeDescriptionDefault
type uint8

The frame type this support entry refers to.

No default
features uint32

The frame type-specific features supported.

No default
supported_flags uint32

The flags supported for the given frame type.

No default

UNIONS

FrameInfo strict

Defined in fuchsia.hardware.network.device/network-device.fidl

Extra frame sidecar metadata stored in BufferMetadata.

Ordinal
VariantTypeDescription
1 no_info NoInfo

No extra frame metadata.

CONSTANTS

NameValueTypeDescription
FEATURE_NO_AUTO_SNOOP 1 uint32

Disables automatic snooping for the device.

The generic NetworkDevice layer typically automatically copies all tx traffic to any snooping clients. Devices may turn off that behavior by setting the FEATURE_NO_AUTO_SNOOP flag.

Devices that disable auto-snooping SHOULD use the NetworkDeviceIfc.Snoop interface method to expose any tx frames they receive.

MAX_BUFFER_PARTS 4 uint32

Maximum number of disjoint parts a buffer may have.

MAX_PORTS 32 uint8

The maximum number of ports a device can have at once.

MAX_VMOS 32 uint8

The maximum number of concurrent shared VMOs that may exist.

TYPE ALIASES

NameValueDescription
buffer_id uint32

Buffer identifier.

Rx space buffers and tx buffers are identified by these when exchanged between interface and implementation.

port_id uint8

Port identifier.

Port identifiers are always in the range [0, MAX_PORTS).

vmo_id uint8

VMO identifier.

VMO identifiers are always in the range [0, MAX_VMOS).

VMO identifiers are reported to devices through NetworkDeviceImpl.PrepareVmo.