blob: 93221d7348f2c65c837c20e737e5047004c4ec17 [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.hardware.network;
using zx;
using fuchsia.net;
// WARNING: This file contains types that are being removed from the SDK. The
// definitions below are duplicated in the other files within this directory.
// Prefer to edit those files rather than this one.
// TODO(https://fxbug.dev/42071737): Remove this file when permissible.
/// Maximum numbers of supported frame types for rx or tx.
// NOTE(brunodalbo) 4 seems a sensible number for maximum number of frame types
// supported by a single device. Most common use cases are going to use 1 or 2
// types (1 if device operates at L2, 2 if at L3).
@available(removed=12)
const MAX_FRAME_TYPES uint32 = 4;
/// Maximum length of session label.
@available(removed=12)
const MAX_SESSION_NAME uint32 = 64;
/// Maximum number of acceleration flags.
///
/// Each descriptor has 16 bits of space for acceleration flags ([`RxFlags`] and
/// [`TxFlags`]) thus the maximum number of reported accelerations is 16. Each
/// descriptor reports which accelerations were applied (`RxFlags`) or are
/// requested (`TxFlags`) by mapping indexes in the vector of supported
/// accelerations ([`Info.rx_accel`] and ([`Info.tx_accel`]) to bits in the
/// respective acceleration flags bitfield.
@available(removed=12)
const MAX_ACCEL_FLAGS uint32 = 16;
/// Network device information.
@available(removed=12)
type DeviceInfo = table {
/// Minimum descriptor length, in 64-bit words. Required.
///
/// The minimum length that each buffer descriptor must have for correct
/// operation with this device. Devices that support extra frame metadata
/// inform larger minimum descriptor lengths that reflect the minimum space
/// needed to be able to store frame metadata.
1: min_descriptor_length uint8;
/// Accepted descriptor version. Required.
2: descriptor_version uint8;
/// Maximum number of items in rx FIFO (per session). Required.
///
/// `rx_depth` is calculated based on the size of the actual backing
/// hardware rx queue.
3: rx_depth uint16;
/// Maximum number of items in tx FIFO (per session). Required.
///
/// `tx_depth` is calculated based on the size of the actual backing
/// hardware tx queue.
4: tx_depth uint16;
/// Alignment requirement for buffers in the data VMO.
///
/// All buffers in the data VMO *must* be aligned to `buffer_alignment`
/// relative to the start of the VMO. `buffer_alignment == 0` is never
/// reported. Required.
5: buffer_alignment uint32;
/// Maximum supported length of buffers in the data VMO, in bytes.
///
/// Absent if no maximum buffer length is defined. Must be nonzero.
6: max_buffer_length uint32;
/// The minimum rx buffer length required for device. Required.
7: min_rx_buffer_length uint32;
/// The minimum tx buffer length required for the device. Required.
///
/// This value accounts only for tx payload length, `min_tx_buffer_head` and
/// `min_tx_buffer_tail` are not part of this value.
///
/// Clients must zero pad outgoing frames to meet the required minimum
/// length.
8: min_tx_buffer_length uint32;
/// The number of bytes the device requests be free as `head` space in a tx
/// buffer. Required.
9: min_tx_buffer_head uint16;
/// The amount of bytes the device requests be free as `tail` space in a tx
/// buffer. Required.
10: min_tx_buffer_tail uint16;
/// Maximum descriptor chain length accepted by the device. Required.
11: max_buffer_parts uint8;
/// Available rx acceleration flags for this device.
///
/// `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.
///
/// Interpreted as empty if not provided.
12: rx_accel vector<RxAcceleration>:MAX_ACCEL_FLAGS;
/// Available tx acceleration flags for this device.
///
/// `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.
///
/// Interpreted as empty if not provided.
13: tx_accel vector<TxAcceleration>:MAX_ACCEL_FLAGS;
};
/// A Network Device.
@available(removed=12)
closed protocol Device {
/// Obtain information about device
///
/// - response `info` device information.
strict GetInfo() -> (struct {
info DeviceInfo;
});
/// Opens a new session with the network device.
///
/// + request `session_name` is used as a debugging label attached to this
/// session.
/// + request `session_info` contains the necessary information to setup the
/// session's data exchange.
/// - response `session` a handle to control the session.
/// - response `fifos` data-plane FIFOs attached to the session.
/// * error `ZX_ERR_NOT_SUPPORTED` if `session_info` contains not supported
/// frame types or descriptors set up.
/// * error `ZX_ERR_INVALID_ARGS` if `session_info` is missing fields or
/// contains invalid information.
/// * error `ZX_ERR_INTERNAL` if the data VMO is rejected by the underlying
/// device.
strict OpenSession(resource struct {
session_name string:MAX_SESSION_NAME;
session_info SessionInfo;
}) -> (resource struct {
session client_end:Session;
fifos Fifos;
}) error zx.Status;
/// Connects to a port the given `id`.
///
/// + request `id` port to connect to.
/// + request `port` server end of port channel.
///
/// `port` is closed with a `ZX_ERR_NOT_FOUND` epitaph if no port with `id`
/// exists.
strict GetPort(resource struct {
id PortId;
port server_end:Port;
});
/// Connects a [`PortWatcher`] to this device.
///
/// + request `watcher` server end of watcher channel.
strict GetPortWatcher(resource struct {
watcher server_end:PortWatcher;
});
/// Establishes a new connection to this device.
///
/// + request `device` the server end for the new connection.
strict Clone(resource struct {
device server_end:Device;
});
};
/// Provides iteration over and updates for ports attached to a device.
@available(removed=12)
closed protocol PortWatcher {
/// Get the next port event.
///
/// The first N calls return [`DevicePortEvent.existing`] where N is the
/// number of ports present on the device at the time of the watcher's
/// creation. The next call returns [`DevicePortEvent.idle`] to indicate the
/// end of existing ports. Subsequent calls block until a port is added
/// ([`DevicePortEvent.added`]) or removed ([`DevicePortEvent.removed`]).
///
/// The server closes the `PortWatcher` channel with `ZX_ERR_CANCELED` if
/// the number of unread events reaches a server-selected limit that is at
/// least two times [`MAX_PORTS`]. Clients are encouraged to maintain a
/// hanging call to `Watch` at all times to avoid triggering this condition.
///
/// - response `event` next port event.
strict Watch() -> (struct {
event DevicePortEvent;
});
};
// TODO(https://fxbug.dev/42159332): Use built-in empty struct when available.
@available(removed=12)
type Empty = struct {};
/// Port creation and destruction events.
// TODO(https://fxbug.dev/42145610): `PortEvent` is probably a better name here,
// but it causes rust binding errors.
@available(removed=12)
type DevicePortEvent = strict union {
/// Port existed when watcher was created.
1: existing PortId;
/// New port was added to device.
2: added PortId;
/// Port was removed from the device.
3: removed PortId;
/// Exhausted list of existing ports.
4: idle Empty;
};
/// Types of frames.
@available(removed=12)
type FrameType = strict enum : uint8 {
ETHERNET = 0x01;
IPV4 = 0x02;
IPV6 = 0x03;
};
/// Blanket definition for raw frames.
///
/// Devices that do not perform any sort of parsing of outbound traffic should
/// define `FRAME_FEATURES_RAW` in the [`FrameTypeSupport`] entry.
@available(removed=12)
const FRAME_FEATURES_RAW uint32 = 1;
/// Ethernet frame sub-types and features.
@available(removed=12)
type EthernetFeatures = strict bits : uint32 {
/// Device supports any type of ethernet frame.
///
/// Same as specifying all other flags. Used by devices that do not inspect
/// or parse outbound traffic.
RAW = 1;
/// Device supports EthernetII frames.
ETHERNET_II = 2;
/// Device supports 802.1q VLAN additions.
E_802_1_Q = 4;
/// Device supports 802.1 q-in-q Multiple VLAN tagging additions.
///
/// Only meaningful if `E_802_1_Q` is also present.
E_802_1_Q_IN_Q = 8;
/// Device supports 802.3 LLC + SNAP Ethernet frame format.
E_802_3_LLC_SNAP = 16;
};
/// Specifies a frame type and features and supported flags associated with that
/// type.
///
/// This is used by clients to read the supported frames on the tx path for a
/// given Network Device.
///
/// Some Network Devices may parse outgoing frames to perform frame
/// transformation or specific hardware support. Each frame type has an
/// associated [`FrameTypeSupport.features`] bits enumeration that lists
/// FrameType-specific features that may or may not be supported. Devices that
/// do not perform parsing are encouraged to just use the [`FRAME_FEATURES_RAW`]
/// bit in `features`, which informs the client that all frame features are
/// allowed.
@available(removed=12)
type FrameTypeSupport = struct {
/// The frame type this support entry refers to.
type FrameType;
/// The frame type-specific features supported.
features uint32;
/// The flags supported for the given frame type.
supported_flags TxFlags;
};
/// Maximum number of chained descriptors that describe a single frame.
@available(removed=12)
const MAX_DESCRIPTOR_CHAIN uint8 = 4;
/// The type of metadata information appended to a frame.
@available(removed=12)
type InfoType = strict enum : uint32 {
/// No extra information is available.
NO_INFO = 0x00;
};
/// Available rx acceleration features.
///
/// Features are mapped to the `RX_ACCEL_*` bits in descriptors by the available
/// values reported in [`Info.rx_accel`].
@available(removed=12)
type RxAcceleration = strict enum : uint8 {
/// Inbound rx frame validated the Ethernet Frame Check Sequence.
VALIDATED_ETHERNET_FCS = 0;
/// Inbound rx frame validated the IPv4 checksum.
VALIDATED_IPV4_CHECKSUM = 1;
/// Inbound rx frame validated the TCP checksum.
VALIDATED_TCP_CHECKSUM = 2;
/// Inbound rx frame validated the UDP checksum.
VALIDATED_UDP_CHECKSUM = 3;
};
/// Available tx acceleration features.
///
/// Features are mapped to the `TX_ACCEL_*` bits in descriptors by the available
/// values reported in [`Info.tx_accel`].
@available(removed=12)
type TxAcceleration = strict enum : uint8 {
/// Request that device calculate the Ethernet Frame Check Sequence and
/// write it in place.
COMPUTE_ETHERNET_FCS = 0;
/// Request that the device calculate the IPv4 checksum and write it in
/// place.
COMPUTE_IPV4_CHECKSUM = 1;
/// Request that the device calculate the TCP checksum and write it in
/// place.
COMPUTE_TCP_CHECKSUM = 2;
/// Request that the device calculate the UDP checksum and write it in
/// place.
COMPUTE_UDP_CHECKSUM = 3;
// Future expansions: TCP segmentation acceleration
};
/// Flags set by a Device when handing a buffer to a client on the rx path.
///
/// Set by devices on the `inbound_flags` field of an rx descriptor.
@available(removed=12)
type RxFlags = strict bits : uint32 {
/// Acceleration flag 0.
///
/// Acceleration flags are mapped to the acceleration features reported by
/// the [`Device`] in [`Info.rx_accel`]. The n-th feature in `rx_accel` maps
/// to the `RX_ACCEL_n` `RxFlag`.
RX_ACCEL_0 = 0x00000001;
RX_ACCEL_1 = 0x00000002;
RX_ACCEL_2 = 0x00000004;
RX_ACCEL_3 = 0x00000008;
RX_ACCEL_4 = 0x00000010;
RX_ACCEL_5 = 0x00000020;
RX_ACCEL_6 = 0x00000040;
RX_ACCEL_7 = 0x00000080;
RX_ACCEL_8 = 0x00000100;
RX_ACCEL_9 = 0x00000200;
RX_ACCEL_10 = 0x00000400;
RX_ACCEL_11 = 0x00000800;
RX_ACCEL_12 = 0x00001000;
RX_ACCEL_13 = 0x00002000;
RX_ACCEL_14 = 0x00004000;
RX_ACCEL_15 = 0x00008000;
// RESERVED - bits 16 to 28 reserved for future expansions
/// Device experienced a hardware rx overrun.
///
/// Rx overruns are typically set by hardware controllers when a frame event
/// was detected but the frame data couldn't be captured. Devices should
/// clear the controller flag once this is set on an inbound frame, so
/// future overruns can be detected and reported.
RX_OVERRUN = 0x20000000;
/// This bit is set if frame validation is performed (such as by hardware
/// acceleration features) and fails.
///
/// It's important to note that some devices may simply discard frames for
/// which validation fails and never notify the client. Rx frames that
/// failed validation are only transmitted to the client if the
/// `SessionFlags::REPORT_INVALID_RX` option is selected when creating a
/// session.
RX_VALIDATION_ERROR = 0x40000000;
/// This is an echoed tx frame, created by a tx request.
///
/// Can only be set in sessions that have the `LISTEN_TX` flag.
RX_ECHOED_TX = 0x80000000;
};
/// Flags set by a Client when handing a buffer to a client on the tx path.
///
/// Set by Clients on the `inbound_flags` field of a tx descriptor.
@available(removed=12)
type TxFlags = strict bits : uint32 {
/// Acceleration flag 0.
///
/// Acceleration flags are mapped to the acceleration features reported by
/// the [`Device`] in [`Info.tx_accel`]. The n-th feature in `tx_accel` maps
/// to the `TX_ACCEL_n` `TxFlag`.
TX_ACCEL_0 = 0x00000001;
TX_ACCEL_1 = 0x00000002;
TX_ACCEL_2 = 0x00000004;
TX_ACCEL_3 = 0x00000008;
TX_ACCEL_4 = 0x00000010;
TX_ACCEL_5 = 0x00000020;
TX_ACCEL_6 = 0x00000040;
TX_ACCEL_7 = 0x00000080;
TX_ACCEL_8 = 0x00000100;
TX_ACCEL_9 = 0x00000200;
TX_ACCEL_10 = 0x00000400;
TX_ACCEL_11 = 0x00000800;
TX_ACCEL_12 = 0x00001000;
TX_ACCEL_13 = 0x00002000;
TX_ACCEL_14 = 0x00004000;
TX_ACCEL_15 = 0x00008000;
};
/// Flags set by a Device when returning a tx buffer back to a client.
///
/// Set by Devices on the `return_flags` field of a tx descriptor.
@available(removed=12)
type TxReturnFlags = strict bits : uint32 {
/// Requested operation in `inbound_flags` is not supported; the frame was
/// not sent.
///
/// Always set in conjunction with `TX_RET_ERROR`.
TX_RET_NOT_SUPPORTED = 1;
/// Could not allocate resources to send frame.
///
/// Always set in conjunction with `TX_RET_ERROR`.
TX_RET_OUT_OF_RESOURCES = 2;
/// Device is not available (offline or disconnected); the frame was not
/// sent.
///
/// Always set in conjunction with `TX_RET_ERROR`.
TX_RET_NOT_AVAILABLE = 4;
// An error occurred sending this frame.
TX_RET_ERROR = 0x80000000;
};
/// An instance of a network device exposed on devfs.
// NOTE(brunodalbo) This protocol exists to sidestep the fact that the DDK
// doesn't allow devices to own their channels. The Device framework implicitly
// composes fuchsia.device/Controller on channels obtained through devfs, and
// the "composed" implementation is always provided by the framework itself. At
// the time of this writing it is unclear what is going to replace that or when,
// only that there is a desire to improve the pattern. The expectation is that
// pattern will be improved with Unified Services (https://fxbug.dev/42160684) and
// Drivers as Components (https://fxbug.dev/42108351).
@available(removed=12)
closed protocol DeviceInstance {
/// Connects to the [`Device`] implementation.
///
/// + request `device` device handle.
strict GetDevice(resource struct {
device server_end:Device;
});
};
/// The address filtering mode supported by MAC devices.
@available(removed=12)
type MacFilterMode = strict enum {
/// Device accepts only unicast frames addressed to its own unicast address,
/// or multicast frames that are part of the multicast address filter list.
MULTICAST_FILTER = 0;
/// Device accepts unicast frames addressed to its own unicast address, or
/// any multicast frames.
MULTICAST_PROMISCUOUS = 1;
/// Device accepts all frames.
PROMISCUOUS = 2;
};
@available(removed=12)
closed protocol MacAddressing {
/// Gets the Device's current unicast MAC address.
///
/// Implementers of this API do not need to return a uniquely identifiable
/// MAC; the unicast address returned is the one that is *currently* in use
/// to filter unicast frames, or that identifies the device on a link it's
/// *currently* on. Users of this API must not rely on the stability or
/// uniqueness of the returned value to identify or disambiguate device
/// instances.
///
/// - response `address` device's unicast MAC address.
strict GetUnicastAddress() -> (struct {
address fuchsia.net.MacAddress;
});
// TODO(https://fxbug.dev/42120438) enable an API like the one below to be
// notified of changes to the Unicast MAC once plumbed through the banjo
// protocol as well. WatchUnicastAddress() -> (Mac address);
/// Sets requested operating mode of this device to `mode`.
///
/// The requested mode is attached to the current client connection to the
/// device. Because multiple clients can be attached to the same device at
/// once, the mode with the least restrictions is the one actively put into
/// effect into the underlying device implementation.
///
/// If the device does not support the requested mode, but supports a mode
/// that is more open than the requested one, `SetMode` succeeds regardless.
/// Otherwise, if the device only supports *more restrictive* modes than the
/// one requested, `SetMode` returns `ZX_ERR_NOT_SUPPORTED`.
///
/// Clients must be aware that the resource being accessed is shared, and
/// that the device may be effectively operating at a more open level than
/// the one that was requested (although never at one more restrictive).
///
/// + request `mode` request mode to attach to.
/// - response `status` `ZX_ERR_NOT_SUPPORTED` it the device only supports
/// mode more restrictive than the one requested.
strict SetMode(struct {
mode MacFilterMode;
}) -> (struct {
status zx.Status;
});
/// Adds multicast address to the list of multicast groups.
///
/// The list of multicast addresses kept is untouched by calls to `SetMode`.
/// If the device's mode is not `MULTICAST_FILTER`, the list of multicast
/// addresses is ignored.
///
/// + request `address` multicast address to add to the list.
/// - response `status` `ZX_ERR_INVALID_ARGS` if `address` is not a
/// multicast address.
strict AddMulticastAddress(struct {
address fuchsia.net.MacAddress;
}) -> (struct {
status zx.Status;
});
/// Removes multicast address from the list of multicast groups.
///
/// + request `address` multicast address to remove from the list.
/// - response `status` `ZX_ERR_INVALID_ARGS` if `address` is not a
/// multicast address.
strict RemoveMulticastAddress(struct {
address fuchsia.net.MacAddress;
}) -> (struct {
status zx.Status;
});
};
/// The maximum number of status samples that can be buffered by a
/// [`StatusWatcher`].
@available(removed=12)
const MAX_STATUS_BUFFER uint32 = 50;
/// The maximum number of ports attached to a device at a given time.
@available(removed=12)
const MAX_PORTS uint8 = 32;
/// The base identifier of a port within a device. Always less than
/// [`MAX_PORTS`].
@available(removed=12)
alias BasePortId = uint8;
/// A device port identifier.
@available(removed=12)
type PortId = struct {
/// The base identifier for the port.
///
/// Generally identifies a port instance in hardware.
base BasePortId;
/// An implementation-defined identifier that is guaranteed to change on
/// every instantiation of the identified port.
salt uint8;
};
/// Network port class.
@available(removed=12)
alias PortClass = DeviceClass;
/// Port status bits, reported in [`PortStatus.flags`].
@available(removed=12)
type StatusFlags = strict bits : uint32 {
/// Port is online, i.e., data path is open and any ongoing sessions may
/// send and receive frames.
ONLINE = 0x01;
};
/// Dynamic port information.
@available(removed=12)
type PortStatus = table {
/// Port status flags.
1: flags StatusFlags;
/// Maximum transmit unit for this port, in bytes.
///
/// The reported MTU is the size of an entire frame, including any header
/// and trailer bytes for whatever protocols this port supports.
2: mtu uint32;
};
/// Provides a way to receive updates on port status changes.
@available(removed=12)
closed protocol StatusWatcher {
/// `WatchStatus` blocks until the port's status has changed.
///
/// The first call to `WatchStatus` returns immediately with the current
/// port status, subsequent calls complete when the port status differs from
/// the last one that was returned through this `StatusWatcher`.
///
/// If `StatusWatcher` was created with a buffer value larger than 1,
/// `WatchStatus` may return a queued status change, depending on how many
/// status changed happened since the last call to `WatchStatus`.
///
/// - response `device_status` the most recent port status.
strict WatchStatus() -> (struct {
port_status PortStatus;
});
};
/// Logical port information.
@available(removed=12)
type PortInfo = table {
/// Port's identifier. Required.
1: id PortId;
/// Port's class. Required.
2: class PortClass;
/// Supported rx frame types on this port. Required.
///
/// Clients may open sessions subscribing to a subset of `rx_types` frame
/// types on this port.
3: rx_types vector<FrameType>:MAX_FRAME_TYPES;
/// Supported tx frame types on this port. Required.
///
/// Frames destined to this port whose frame type is not in `tx_types` are
/// returned with an error.
///
/// Some network devices may need to perform partial frame parsing and
/// serialization and, for that reason, `tx_types` is a vector of
/// [`FrameTypeSupport`] which includes specific features per frame type.
/// For example, a device that supports Ethernet frames but needs to convert
/// the Ethernet header may only support standard Ethernet II frames, and
/// not any "raw" Ethernet frame.
4: tx_types vector<FrameTypeSupport>:MAX_FRAME_TYPES;
};
/// A logical port belonging to a [`Device`].
@available(removed=12)
closed protocol Port {
/// Obtain information about port.
///
/// - response `info` port information.
strict GetInfo() -> (struct {
info PortInfo;
});
/// Obtain the operating port status.
///
/// - response `status` snapshot of port's current status.
strict GetStatus() -> (struct {
status PortStatus;
});
/// Connects to a [`StatusWatcher`] to observe port status changes.
///
/// + request `watcher` handle to the status watcher.
/// + request `buffer` the number of status changes that the client requests
/// to be stored by `StatusWatcher`. Values are capped at
/// [`MAX_STATUS_BUFFER`]. A value of 0 or 1 causes the `StatusWatcher` to
/// not keep any buffers on status changed. Clients that need to observe all
/// changes to status (as opposed to only the current state) are encouraged
/// to set a buffer value larger than 1, so that all edges can be observed.
/// If `StatusWatcher`'s internal queue is filled and new status changes
/// occur, the oldest samples will be dropped to make room for new ones.
strict GetStatusWatcher(resource struct {
watcher server_end:StatusWatcher;
buffer uint32;
});
/// Connects to a [`MacAddressing`] associated with the port.
///
/// + request `mac` mac handle. Closed with `ZX_ERR_NOT_SUPPORTED` if this
/// port does not support mac addressing.
strict GetMac(resource struct {
mac server_end:MacAddressing;
});
/// Connects to the [`Device`] this port belongs to.
///
/// + request `device` grants access to the parent device.
strict GetDevice(resource struct {
device server_end:Device;
});
/// Establishes a new connection to this port.
///
/// + request `port` the server end for the new connection.
strict Clone(resource struct {
port server_end:Port;
});
/// Retrieves a snapshot of traffic counters on this port.
@available(added=10)
strict GetCounters() -> (table {
/// The total number of ingress frames on this port.
1: rx_frames uint64;
/// The total number of ingress bytes on this port.
2: rx_bytes uint64;
/// The total number of egress frames on this port.
3: tx_frames uint64;
/// The total number of egress bytes on this port.
4: tx_bytes uint64;
});
};
/// Represents a session with a Network device.
///
/// A session has a data plane and a control plane. The `Session` protocol
/// represents the control plane of the session and the FIFOs and VMOs exchanged
/// during the [`Device.OpenSession`] call are the data plane. Lifetime of the
/// session is controlled by a `Session` protocol handle.
///
/// Sessions must attach to ports of interest to start receiving and sending
/// data. Sessions are always created with no ports attached.
///
/// If a port is destroyed from the underlying device, it is automatically
/// detached from the session.
///
/// Inbound traffic is dispatched to all open sessions. Devices typically
/// operate with a single primary session, see [`SessionFlags.PRIMARY`]. Each
/// additional open session to the same device causes data copy overhead on the
/// device's data path.
///
/// The session is closed with an error epitaph if an invalid buffer descriptor
/// is sent over either the tx or rx FIFOs. Invalid descriptors include:
/// - Descriptor index larger than [`SessionInfo.descriptor_count`].
/// - Descriptor chains larger than [`MAX_DESCRIPTOR_CHAIN`].
/// - rx buffers smaller than [`Info.min_rx_buffer_length`].
/// - tx buffers smaller than [`Info.min_tx_buffer_length`].
/// - tx buffers not respecting [`Info.min_tx_buffer_head`] or
/// [`Info.min_tx_buffer_tail`].
@available(removed=12)
closed protocol Session {
/// Attaches the session to `port`.
///
/// Once attached, the session starts to receive the subscribed frames over
/// the data FIFOs and it may send frames destined to the specified `port`.
///
/// + request `port` port to subscribe to.
/// + request `rx_frames` Frame types of interest on the port.
/// * error `ZX_ERR_NOT_FOUND` if `port` is not valid.
/// * error `ZX_ERR_INVALID_ARGS` if `rx_frames` is not a subset of the
/// port's supported frames.
/// * error `ZX_ERR_ALREADY_BOUND` if `port` is already attached.
strict Attach(struct {
port PortId;
rx_frames vector<FrameType>:MAX_FRAME_TYPES;
}) -> () error zx.Status;
/// Detaches the session from `port`.
///
/// Once detached, the session stops receiving frames from `port`. Frames
/// sent to a detached port may be returned with an error. It is not
/// necessary to call `Detach` on ports that are removed from the device,
/// doing so causes `ZX_ERR_NOT_FOUND` to be returned.
///
/// + request `port` port to subscribe to.
/// * error `ZX_ERR_NOT_FOUND` if the session is not currently attached to
/// the port.
strict Detach(struct {
port PortId;
}) -> () error zx.Status;
/// Cleanly closes a session.
///
/// This will cause the session to send a `ZX_ERR_CANCELLED` epitaph and
/// proceed to close the Session channel. Clients may only assume that they
/// own all the buffers that are currently owned by the session (sent over
/// either the rx or tx FIFOs) once the epitaph is received. Closing the rx
/// or tx FIFO is equivalent to calling `Close`.
strict Close();
};
/// Additional session options.
@available(removed=12)
type SessionFlags = strict bits : uint16 {
/// Attach as primary session.
///
/// Sessions marked with the `PRIMARY` bit get the following different
/// treatment:
/// - If no PRIMARY sessions are attached, the device will *not* serve rx
/// frames to non-PRIMARY sessions.
/// - If there's only one PRIMARY session active, it may get a zero-copy
/// data path from the the backing hardware, if the underlying
/// implementation supports it.
PRIMARY = 0x0001;
/// Listen for outgoing frames.
///
/// `LISTEN_TX` sessions receive any outgoing frames (from all sessions) on
/// its rx path. Can be used for snooping traffic. Sessions marked with
/// `LISTEN_TX` may also send frames, but they should keep in mind that
/// they'll ALWAYS receive those frames back on their rx path (no origin
/// session filtering is performed).
LISTEN_TX = 0x0002;
/// Receive invalid rx frames.
///
/// Sessions marked with `REPORT_INVALID_RX` are interested in receiving
/// frames that were rejected by internal device checks or payload
/// validation performed by hardware. Due to the nature of some hardware
/// platforms, sessions marked with `REPORT_INVALID_RX` may still not
/// receive frames that fail validation if the hardware implementation
/// simply drops the frame and doesn't expose it to the software stack.
/// Sessions NOT marked with `REPORT_INVALID_RX`, in contrast, will NEVER
/// receive an rx frame with the `RX_VALIDATION_ERROR` flag set.
REPORT_INVALID_RX = 0x0004;
};
/// Data-plane FIFOs.
@available(removed=12)
type Fifos = resource struct {
/// Handle for the rx FIFO.
///
/// Clients must write 16-bit descriptor indexes to this FIFO to be able to
/// receive frames.
rx zx.Handle:FIFO;
/// Handle for the tx FIFO.
///
/// Clients write 16-bit descriptor indexes to this FIFO to enqueue outgoing
/// frames.
tx zx.Handle:FIFO;
};
/// Session configuration.
@available(removed=12)
type SessionInfo = resource table {
/// VMO containing the descriptors. Required.
///
/// 16-bit indices transmitted over the FIFOs index a descriptor in this VMO
/// (byte offset = descriptor_length * 8 * index).
1: descriptors zx.Handle:VMO;
/// VMO containing frame data. Required.
///
/// Descriptors contain byte-offsets that are used to index arbitrary
/// regions in `data`.
2: data zx.Handle:VMO;
/// Requested descriptor version. Required.
///
/// If the network device does not support the requested descriptor version,
/// [`Device.OpenSession`] fails with `ZX_ERR_NOT_SUPPORTED`.
3: descriptor_version uint8;
/// Descriptor length, in 64-bit words. Required.
///
/// The length of each descriptor in the `descriptors` VMO. This is used as
/// a multiplier to find byte offsets in `descriptors` given a descriptor
/// index passed through the rx or tx FIFOs.
4: descriptor_length uint8;
/// Total number of descriptors that can be used by this session. Required.
///
/// Descriptor indices transferred through either the rx or tx FIFO must be
/// in the range [0, `descriptor_count`).
5: descriptor_count uint16;
/// Extra options. Interpreted as empty bitmask if absent.
6: options SessionFlags;
};