1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
45//! Device queues.
67use alloc::collections::VecDeque;
89use netstack3_base::{ErrorAndSerializer, WorkQueueReport};
10use packet::SerializeError;
1112use crate::internal::base::DeviceSendFrameError;
1314pub(crate) mod api;
15mod fifo;
16pub(crate) mod rx;
17pub(crate) mod tx;
1819/// The maximum number of elements that can be in the RX queue.
20const MAX_RX_QUEUED_LEN: usize = 10000;
21/// The maximum number of elements that can be in the TX queue.
22const MAX_TX_QUEUED_LEN: usize = 10000;
2324/// Error returned when the receive queue is full.
25#[derive(Debug, PartialEq, Eq)]
26pub struct ReceiveQueueFullError<T>(pub T);
2728#[derive(Debug, PartialEq, Eq)]
29pub enum TransmitQueueFrameError<S> {
30 NoQueue(DeviceSendFrameError),
31 QueueFull(S),
32 SerializeError(ErrorAndSerializer<SerializeError<()>, S>),
33}
3435/// The state used to dequeue and handle frames from the device queue.
36pub struct DequeueState<Meta, Buffer> {
37 dequeued_frames: VecDeque<(Meta, Buffer)>,
38}
3940impl<Meta, Buffer> Default for DequeueState<Meta, Buffer> {
41fn default() -> DequeueState<Meta, Buffer> {
42 DequeueState {
43// Make sure we can dequeue up to `BatchSize` frames without
44 // needing to reallocate.
45dequeued_frames: VecDeque::with_capacity(BatchSize::MAX),
46 }
47 }
48}
4950#[derive(Debug, PartialEq, Eq)]
51enum EnqueueResult {
52 QueueWasPreviouslyEmpty,
53 QueuePreviouslyWasOccupied,
54}
5556#[derive(Debug)]
57enum DequeueResult {
58 MoreStillQueued,
59 NoMoreLeft,
60}
6162impl From<DequeueResult> for WorkQueueReport {
63fn from(value: DequeueResult) -> Self {
64match value {
65 DequeueResult::MoreStillQueued => Self::Pending,
66 DequeueResult::NoMoreLeft => Self::AllDone,
67 }
68 }
69}
7071/// A type representing an operation count in a queue (e.g. the number of
72/// packets allowed to be dequeued in a single operation).
73///
74/// `BatchSize` is always capped at the maximum supported batch size for the
75/// queue and defaults to that value.
76#[derive(Copy, Clone, Debug, Eq, PartialEq)]
77pub struct BatchSize(usize);
7879impl BatchSize {
80/// The maximum usize value that `BatchSize` can assume.
81 ///
82 /// Restricting the amount of work that can be done at once in a queue
83 /// serves two purposes:
84 ///
85 /// - It sets an upper bound on the amount of work that can be done before
86 /// yielding the thread to other work.
87 /// - It sets an upper bound of memory consumption set aside for dequeueing,
88 /// because dequeueing takes frames from the queue and "stages" them in a
89 /// separate context.
90pub const MAX: usize = 100;
9192/// Creates a new `BatchSize` with a value of `v` saturating to
93 /// [`BatchSize::MAX`].
94pub fn new_saturating(v: usize) -> Self {
95Self(v.min(Self::MAX))
96 }
97}
9899impl From<BatchSize> for usize {
100fn from(BatchSize(v): BatchSize) -> Self {
101 v
102 }
103}
104105impl Default for BatchSize {
106fn default() -> Self {
107Self(Self::MAX)
108 }
109}