|  | // Copyright 2020 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; | 
|  |  | 
|  | /// 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`]. | 
|  | 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. | 
|  | Attach(struct { | 
|  | port PortId; | 
|  | rx_frames vector<FrameType>:MAX_FRAME_TYPES; | 
|  | }) -> (struct {}) 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. | 
|  | Detach(struct { | 
|  | port PortId; | 
|  | }) -> (struct {}) 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`. | 
|  | Close(); | 
|  | }; | 
|  |  | 
|  | /// Additional session options. | 
|  | 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. | 
|  | 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. | 
|  | 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; | 
|  | }; |