use super::config::{MAC_FILTER_SLOTS, MacAddressFilter, MacFilterType};
use super::emac::Emac;
use super::error::{ConfigError, DmaError, Result};
use crate::internal::register::mac::MacRegs;
impl<const RX_BUFS: usize, const TX_BUFS: usize, const BUF_SIZE: usize>
Emac<RX_BUFS, TX_BUFS, BUF_SIZE>
{
pub fn add_mac_filter(&mut self, addr: &[u8; 6]) -> Result<usize> {
if MacRegs::find_mac_filter(addr).is_some() {
return Err(ConfigError::AlreadyInitialized.into());
}
let slot = MacRegs::find_free_mac_filter_slot().ok_or(DmaError::NoDescriptorsAvailable)?;
MacRegs::set_mac_filter(slot, addr, false, 0);
Ok(slot)
}
pub fn add_mac_filter_config(&mut self, filter: &MacAddressFilter) -> Result<usize> {
if MacRegs::find_mac_filter(&filter.address).is_some() {
return Err(ConfigError::AlreadyInitialized.into());
}
let slot = MacRegs::find_free_mac_filter_slot().ok_or(DmaError::NoDescriptorsAvailable)?;
let is_source = matches!(filter.filter_type, MacFilterType::Source);
MacRegs::set_mac_filter(slot, &filter.address, is_source, filter.byte_mask);
Ok(slot)
}
pub fn remove_mac_filter(&mut self, addr: &[u8; 6]) -> Result<()> {
let slot = MacRegs::find_mac_filter(addr).ok_or(DmaError::InvalidLength)?;
MacRegs::clear_mac_filter(slot);
Ok(())
}
pub fn clear_mac_filters(&mut self) {
MacRegs::clear_all_mac_filters();
}
pub fn mac_filter_count(&self) -> usize {
let mut count = 0;
for slot in 1..=MAC_FILTER_SLOTS {
if MacRegs::is_mac_filter_enabled(slot) == Some(true) {
count += 1;
}
}
count
}
pub fn has_free_mac_filter_slot(&self) -> bool {
MacRegs::find_free_mac_filter_slot().is_some()
}
}
impl<const RX_BUFS: usize, const TX_BUFS: usize, const BUF_SIZE: usize>
Emac<RX_BUFS, TX_BUFS, BUF_SIZE>
{
pub fn add_hash_filter(&mut self, addr: &[u8; 6]) -> u8 {
let index = MacRegs::compute_hash_index(addr);
MacRegs::set_hash_bit(index);
index
}
pub fn remove_hash_filter(&mut self, addr: &[u8; 6]) -> u8 {
let index = MacRegs::compute_hash_index(addr);
MacRegs::clear_hash_bit(index);
index
}
pub fn check_hash_filter(&self, addr: &[u8; 6]) -> bool {
let index = MacRegs::compute_hash_index(addr);
MacRegs::is_hash_bit_set(index)
}
pub fn clear_hash_table(&mut self) {
MacRegs::clear_hash_table();
}
pub fn hash_table(&self) -> u64 {
MacRegs::hash_table()
}
pub fn set_hash_table(&mut self, value: u64) {
MacRegs::set_hash_table(value);
}
pub fn enable_hash_multicast(&mut self, enable: bool) {
MacRegs::enable_hash_multicast(enable);
if enable {
MacRegs::set_pass_all_multicast(false);
}
}
pub fn enable_hash_unicast(&mut self, enable: bool) {
MacRegs::enable_hash_unicast(enable);
}
pub fn compute_hash_index(addr: &[u8; 6]) -> u8 {
MacRegs::compute_hash_index(addr)
}
}
impl<const RX_BUFS: usize, const TX_BUFS: usize, const BUF_SIZE: usize>
Emac<RX_BUFS, TX_BUFS, BUF_SIZE>
{
pub fn set_vlan_filter(&mut self, vid: u16) {
MacRegs::set_vlan_id_filter(vid);
MacRegs::enable_vlan_filter(true);
}
pub fn configure_vlan_filter(&mut self, vid: u16, vid_only: bool, inverse: bool, svlan: bool) {
MacRegs::configure_vlan_filter(vid, vid_only, inverse, svlan);
MacRegs::enable_vlan_filter(true);
}
pub fn disable_vlan_filter(&mut self) {
MacRegs::clear_vlan_filter();
}
pub fn is_vlan_filter_enabled(&self) -> bool {
MacRegs::is_vlan_filter_enabled()
}
pub fn vlan_filter_id(&self) -> u16 {
MacRegs::get_vlan_id_filter()
}
}