| // 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; |
| }; |