Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hw MAC address filter #60

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ ieee802_3_miim = "0.7"
cortex-m = "0.7"
log = { version = "0.4", optional = true }
defmt = { version = "0.3", optional = true }
bitflags = "1.3.2"

[dependencies.smoltcp]
version = "0.8"
Expand All @@ -36,7 +37,7 @@ features = ["medium-ethernet", "proto-ipv4"]
optional = true

[features]
default = [ "defmt" ]
default = ["defmt"]
device-selected = []
fence = []

Expand Down Expand Up @@ -64,8 +65,8 @@ stm32f779 = ["stm32f7xx-hal/stm32f779", "device-selected", "fence"]
smoltcp-phy = ["smoltcp"]

# Example features
example-nucleo-pins = [ ]
rtic-echo-example = [ "defmt", "smoltcp-phy", "smoltcp/defmt", "smoltcp/medium-ethernet", "smoltcp/socket-tcp" ]
example-nucleo-pins = []
rtic-echo-example = ["defmt", "smoltcp-phy", "smoltcp/defmt", "smoltcp/medium-ethernet", "smoltcp/socket-tcp"]

[dev-dependencies]
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
Expand Down
24 changes: 23 additions & 1 deletion examples/arp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ use cortex_m_rt::{entry, exception};

use cortex_m::interrupt::Mutex;
use stm32_eth::{
mac::{phy::BarePhy, Phy},
mac::{
frame_filter::{Filter, FilterConfig, Mac},
phy::BarePhy,
Phy,
},
stm32::{interrupt, CorePeripherals, Peripherals, SYST},
};

Expand Down Expand Up @@ -57,6 +61,15 @@ fn main() -> ! {
.unwrap();
eth_dma.enable_interrupt();

let some_mac = if eth_dma.tx_is_running() { 1 } else { 0 };

let filter_config = FilterConfig::filter_destinations(
Mac::new([some_mac, some_mac, some_mac, some_mac, some_mac, some_mac]),
&[],
);

eth_mac.configure_frame_filter(&Filter::Filter(filter_config));

let mut last_link_up = false;

let mut bare_phy = BarePhy::new(eth_mac.with_mii(mdio, mdc), PHY_ADDR, Default::default());
Expand Down Expand Up @@ -111,6 +124,15 @@ fn main() -> ! {
}
Err(TxError::WouldBlock) => defmt::info!("ARP failed"),
}

// while let Ok(message) = eth_dma.recv_next() {
// let mut chunks = message.chunks(6);

// let dst_mac = Mac::try_from(chunks.next().unwrap()).ok().unwrap();
// let src_mac = Mac::try_from(chunks.next().unwrap()).ok().unwrap();

// defmt::warn!("DA: {}, SA: {}", dst_mac, src_mac);
// }
} else {
defmt::info!("Down");
}
Expand Down
31 changes: 31 additions & 0 deletions src/mac/frame_filter/control.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/// The type of frame filtering that the MAC should perform
/// on received control frames,
#[derive(Debug, Clone)]

pub enum ControlFrameFilter {
/// Prevent all control frames from reaching
/// the application.
BlockAll,
/// Allow all control frames to reach the application,
/// except for PAUSE control frames.
NoPause,
/// Allow all control frames to reach the application.
AllowAll,
/// Block control frames that do not pass the
/// configured address filter, but allow those that do.
AddressFilter,
}

impl ControlFrameFilter {
/// Create a new [`ControlFrameFilter`] that filters out
/// all control frames.
pub const fn new() -> Self {
Self::BlockAll
}
}

impl Default for ControlFrameFilter {
fn default() -> Self {
Self::new()
}
}
59 changes: 59 additions & 0 deletions src/mac/frame_filter/destination.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/// The type of destination address filtering that
/// the MAC should apply to incoming frames.
#[derive(Debug, Clone)]
pub struct DaFilter {
/// Filtering to be performed based on perfect address matches.
pub perfect_filtering: PerfectDaFilterMode,
/// Enable or disable hash table filtering for destination
/// addresses.
pub hash_table_filtering: bool,
}

impl DaFilter {
/// Create a new [`DaFilter`] that does
/// not filter any frames.
pub const fn new() -> Self {
Self {
perfect_filtering: PerfectDaFilterMode::new(),
hash_table_filtering: false,
}
}
}

impl Default for DaFilter {
fn default() -> Self {
Self::new()
}
}

/// The type of destination address filtering that
/// the MAC should apply to incoming frames.
#[derive(Debug, Clone)]

pub enum PerfectDaFilterMode {
/// Filter frames by their Destination Address, based on
/// the addresses configured with [`AddressFilterType::Destination`].
///
/// [`AddressFilterType::Destination`]: `super::AddressFilterType::Destination`
Normal,
/// Filter frames by their Destination Address, based on
/// the inverse of the addresses configured with
/// [`AddressFilterType::Destination`].
///
/// [`AddressFilterType::Destination`]: `super::AddressFilterType::Destination`
Inverse,
}

impl PerfectDaFilterMode {
/// Create a new [`PerfectDaFilterMode`] that filters
/// out all frames.
pub const fn new() -> Self {
Self::Normal
}
}

impl Default for PerfectDaFilterMode {
fn default() -> Self {
Self::new()
}
}
25 changes: 25 additions & 0 deletions src/mac/frame_filter/hash_table.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#[derive(Debug, Clone)]
/// Configuration of the hash table used by the MAC for
/// destination address filtering.
pub struct HashTableValue {
/// The low register of the hash table.
pub low: u32,
/// The high register of the hash table.
pub high: u32,
}

impl HashTableValue {
/// Create a new hash table value that filters
/// out all frames.
pub const fn new() -> Self {
Self { low: 0, high: 0 }
}
}

/// By default, the hash table is configured so that
/// it filters out all frames.
impl Default for HashTableValue {
fn default() -> Self {
Self::new()
}
}
Loading