pub const MAX_FRAME_SIZE: usize = 1522;
pub const MTU: usize = 1500;
pub const ETH_HEADER_SIZE: usize = 14;
pub const CRC_SIZE: usize = 4;
pub const VLAN_TAG_SIZE: usize = 4;
pub const DEFAULT_BUFFER_SIZE: usize = 1600;
pub const MIN_FRAME_SIZE: usize = 60;
pub const DEFAULT_RX_BUFFERS: usize = 10;
pub const DEFAULT_TX_BUFFERS: usize = 10;
pub const SOFT_RESET_TIMEOUT_MS: u32 = 100;
pub const RESET_POLL_INTERVAL_US: u32 = 100;
pub const MII_BUSY_TIMEOUT: u32 = 100_000;
pub const FLUSH_TIMEOUT: u32 = 100_000;
pub const RMII_CLK_HZ: u32 = 50_000_000;
pub const MII_100M_CLK_HZ: u32 = 25_000_000;
pub const MII_10M_CLK_HZ: u32 = 2_500_000;
pub const MDC_MAX_FREQ_HZ: u32 = 2_500_000;
pub const PAUSE_TIME_MAX: u16 = 0xFFFF;
pub const DEFAULT_FLOW_LOW_WATER: usize = 3;
pub const DEFAULT_FLOW_HIGH_WATER: usize = 6;
#[allow(dead_code)]
pub const CSR_CLOCK_DIV_42: u32 = 0;
#[allow(dead_code)]
pub const CSR_CLOCK_DIV_62: u32 = 1;
#[allow(dead_code)]
pub const CSR_CLOCK_DIV_16: u32 = 2;
#[allow(dead_code)]
pub const CSR_CLOCK_DIV_26: u32 = 3;
#[allow(dead_code)]
pub const CSR_CLOCK_DIV_102: u32 = 4;
#[allow(dead_code)]
pub const CSR_CLOCK_DIV_124: u32 = 5;
pub const DEFAULT_MAC_ADDR: [u8; 6] = [0x02, 0x00, 0x00, 0x00, 0x00, 0x01];
pub const MAC_ADDR_LEN: usize = 6;
pub const TX_DMA_STATE_SHIFT: u32 = 20;
pub const TX_DMA_STATE_MASK: u32 = 0x7;
#[allow(dead_code)]
pub const RX_DMA_STATE_SHIFT: u32 = 17;
#[allow(dead_code)]
pub const RX_DMA_STATE_MASK: u32 = 0x7;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn max_frame_size_includes_all_headers() {
assert_eq!(
MAX_FRAME_SIZE,
MTU + ETH_HEADER_SIZE + CRC_SIZE + VLAN_TAG_SIZE
);
}
#[test]
fn max_frame_size_is_1522() {
assert_eq!(MAX_FRAME_SIZE, 1522);
}
#[test]
fn mtu_is_standard_ethernet() {
assert_eq!(MTU, 1500);
}
#[test]
fn eth_header_size_is_14_bytes() {
assert_eq!(ETH_HEADER_SIZE, 14);
}
#[test]
fn crc_size_is_4_bytes() {
assert_eq!(CRC_SIZE, 4);
}
#[test]
fn min_frame_size_is_60_bytes() {
assert_eq!(MIN_FRAME_SIZE, 60);
}
#[test]
fn default_buffer_size_exceeds_max_frame() {
assert!(DEFAULT_BUFFER_SIZE >= MAX_FRAME_SIZE);
}
#[test]
fn default_buffer_counts_are_reasonable() {
assert!(DEFAULT_RX_BUFFERS >= 2);
assert!(DEFAULT_TX_BUFFERS >= 2);
assert!(DEFAULT_RX_BUFFERS <= 32);
assert!(DEFAULT_TX_BUFFERS <= 32);
}
#[test]
fn soft_reset_timeout_is_reasonable() {
assert!(SOFT_RESET_TIMEOUT_MS >= 10);
assert!(SOFT_RESET_TIMEOUT_MS <= 1000);
}
#[test]
fn mii_busy_timeout_is_positive() {
assert!(MII_BUSY_TIMEOUT > 0);
}
#[test]
fn flush_timeout_is_positive() {
assert!(FLUSH_TIMEOUT > 0);
}
#[test]
fn rmii_clock_is_50mhz() {
assert_eq!(RMII_CLK_HZ, 50_000_000);
}
#[test]
fn mii_100m_clock_is_25mhz() {
assert_eq!(MII_100M_CLK_HZ, 25_000_000);
}
#[test]
fn mii_10m_clock_is_2_5mhz() {
assert_eq!(MII_10M_CLK_HZ, 2_500_000);
}
#[test]
fn mdc_max_freq_per_ieee_802_3() {
assert_eq!(MDC_MAX_FREQ_HZ, 2_500_000);
}
#[test]
fn mii_10m_equals_mdc_max() {
assert_eq!(MII_10M_CLK_HZ, MDC_MAX_FREQ_HZ);
}
#[test]
fn pause_time_max_is_16_bits() {
assert_eq!(PAUSE_TIME_MAX, 0xFFFF);
}
#[test]
fn flow_control_water_marks_ordered() {
assert!(DEFAULT_FLOW_LOW_WATER < DEFAULT_FLOW_HIGH_WATER);
}
#[test]
fn flow_control_water_marks_fit_buffers() {
assert!(DEFAULT_FLOW_HIGH_WATER <= DEFAULT_RX_BUFFERS);
}
#[test]
fn csr_clock_dividers_are_sequential() {
assert_eq!(CSR_CLOCK_DIV_42, 0);
assert_eq!(CSR_CLOCK_DIV_62, 1);
assert_eq!(CSR_CLOCK_DIV_16, 2);
assert_eq!(CSR_CLOCK_DIV_26, 3);
assert_eq!(CSR_CLOCK_DIV_102, 4);
assert_eq!(CSR_CLOCK_DIV_124, 5);
}
#[test]
fn csr_clock_dividers_fit_in_3_bits() {
assert!(CSR_CLOCK_DIV_42 < 8);
assert!(CSR_CLOCK_DIV_62 < 8);
assert!(CSR_CLOCK_DIV_16 < 8);
assert!(CSR_CLOCK_DIV_26 < 8);
assert!(CSR_CLOCK_DIV_102 < 8);
assert!(CSR_CLOCK_DIV_124 < 8);
}
#[test]
fn mac_addr_len_is_6() {
assert_eq!(MAC_ADDR_LEN, 6);
}
#[test]
fn default_mac_is_locally_administered() {
assert_eq!(DEFAULT_MAC_ADDR[0] & 0x02, 0x02);
}
#[test]
fn default_mac_is_unicast() {
assert_eq!(DEFAULT_MAC_ADDR[0] & 0x01, 0x00);
}
#[test]
fn default_mac_has_correct_length() {
assert_eq!(DEFAULT_MAC_ADDR.len(), MAC_ADDR_LEN);
}
#[test]
fn dma_state_masks_are_3_bits() {
assert_eq!(TX_DMA_STATE_MASK, 0x7);
assert_eq!(RX_DMA_STATE_MASK, 0x7);
}
#[test]
fn tx_dma_state_shift_position() {
assert_eq!(TX_DMA_STATE_SHIFT, 20);
}
#[test]
fn rx_dma_state_shift_position() {
assert_eq!(RX_DMA_STATE_SHIFT, 17);
}
#[test]
fn dma_state_fields_dont_overlap() {
let tx_bits = TX_DMA_STATE_MASK << TX_DMA_STATE_SHIFT;
let rx_bits = RX_DMA_STATE_MASK << RX_DMA_STATE_SHIFT;
assert_eq!(tx_bits & rx_bits, 0, "TX and RX DMA state fields overlap");
}
}