Skip to content

Improve types for channels and lanes #348

Description

@cfzimmerman

Explanation

Dendrite refers to channels in connector code and lanes in serdes code. I believe the types used for representing these could be improved. Here are some concerns in the current design:

  • Should we actually have a distinction between channel and lane? This comment makes me question if we should.

    /// around the SDE's bf_pal_front_port_handle_t. This struct includes a
    /// connector ID and a channel ID (which the SDE frequently refers to as a
    /// 'lane'). (Note: despite the name, these are not the 'front panel ports'

  • There's a matrix of numbers involved. There's the maximum quantity of lanes/channels on a port and the lane/channel indexes. I believe the range of acceptable lane counts is 1..=8, and the range of acceptable channel counts is 1..=4. The indexes are then 0..8 and 0..4. Lane count currently uses u32.

// Currently the sidecar only has 4 channels per port. This is true for front
// panel, backplane, and the CPU port. If/when we add support for 400g front
// panel ports, this will need to change.
//
// TODO-cleanup: It would be nice not to duplicate this with the new
// port map in `dpd`. We could just provide this as an argument.
pub const CHANNELS_PER_SWITCH_PORT: u8 = 4;

/// Get the number of lanes configured for this port
pub(crate) fn lane_count(hdl: &Handle, port: PortHdl) -> AsicResult<u32> {
match hdl.phys_ports.lock().unwrap().get_tofino_port(port)?.channels.len() {
n if n < 1 || n > 8 => {
Err(AsicError::Internal(format!("configured port has {n} lanes")))
}
n => Ok(n as u32),
}
}

  • The channels used by a port are stored in a Vec<u8>. But afaict the SDE uses base + offset during port creation, so we'd never have a port using non-contiguous lanes.

/// The first channel / lane for this port.
pub channel: u8,
/// All channels / lanes used for this port.
pub channels: Vec<u8>,

Some non-contiguous tracking is required, but we also have a BTreeSet for available_channels.

// The number of total channels / lanes in the switch port.
//
// This is determined by the board layout, and is currently always 4.
channels: u8,
// The set of channels / lanes not yet allocated to a link.
available_channels: BTreeSet<u8>,

A final design will require further investigation, but I feel like we can use a more descriptive type than Vec<u8> for this. And if not, a doc comment is warranted.

Proposal

  • Decide whether we should continue differentiating lanes and channels in this code. Changes if warranted.
  • Explore if a newtype wrapper makes sense for lanes/channels. If keeping lanes and channels distinct, define and document how exactly they're different and why we're differentiating. Move boundary and range checking into the type(s).
  • Determine whether there's any more appropriate way to track channels than a Vec<u8>. If not, document why Vec is needed here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions