From b13bf72c17d0da8b5eb73365fc70062aba70ea76 Mon Sep 17 00:00:00 2001 From: Astro Date: Thu, 30 May 2019 02:42:42 +0200 Subject: [PATCH] eth: begin phy communication --- src/eth/mod.rs | 52 +++++++++++++++++++++++++++++++++++++++++++++- src/eth/phy/mod.rs | 8 +++++++ src/eth/regs.rs | 15 +++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/eth/phy/mod.rs diff --git a/src/eth/mod.rs b/src/eth/mod.rs index fa859ae..1f51d71 100644 --- a/src/eth/mod.rs +++ b/src/eth/mod.rs @@ -1,6 +1,7 @@ use crate::regs::*; use crate::slcr; +pub mod phy; mod regs; pub struct Eth { @@ -13,6 +14,7 @@ impl Eth { // MDIO slcr.mio_pin_53.write( slcr::MioPin53::zeroed() + .tri_enable(true) .l3_sel(0b100) .io_type(slcr::IoBufferType::Lvcmos18) .pullup(true) @@ -20,7 +22,6 @@ impl Eth { // MDC slcr.mio_pin_52.write( slcr::MioPin52::zeroed() - .tri_enable(true) .l3_sel(0b100) .io_type(slcr::IoBufferType::Lvcmos18) .pullup(true) @@ -220,5 +221,54 @@ impl Eth { .copy_all(true) .mdc_clk_div(0b111) ); + // TODO: mac addr + // TODO: Program the DMA Configuration register (gem.dma_cfg). + + self.regs.net_ctrl.write( + regs::NetCtrl::zeroed() + .mgmt_port_en(true) + .tx_en(true) + .rx_en(true) + ); + } + + fn wait_phy_idle(&self) { + let mut timeout = 5_000_000; + while !self.regs.net_status.read().phy_mgmt_idle() { + timeout -= 1; + if timeout == 0 { + break + } + } + } +} + +impl phy::PhyAccess for Eth { + fn read_phy(&mut self, addr: u8, reg: u8) -> u16 { + self.wait_phy_idle(); + self.regs.phy_maint.write( + regs::PhyMaint::zeroed() + .clause_22(true) + .operation(regs::PhyOperation::Read) + .phy_addr(addr) + .reg_addr(reg) + .must_10(0b10) + ); + self.wait_phy_idle(); + self.regs.phy_maint.read().data() + } + + fn write_phy(&mut self, addr: u8, reg: u8, data: u16) { + self.wait_phy_idle(); + self.regs.phy_maint.write( + regs::PhyMaint::zeroed() + .clause_22(true) + .operation(regs::PhyOperation::Write) + .phy_addr(addr) + .reg_addr(reg) + .must_10(0b10) + .data(data) + ); + self.wait_phy_idle(); } } diff --git a/src/eth/phy/mod.rs b/src/eth/phy/mod.rs new file mode 100644 index 0000000..fe2576c --- /dev/null +++ b/src/eth/phy/mod.rs @@ -0,0 +1,8 @@ +pub trait PhyAccess { + fn read_phy(&mut self, addr: u8, reg: u8) -> u16; + fn write_phy(&mut self, addr: u8, reg: u8, data: u16); +} + +pub trait PhyDevice { + fn init() -> Self; +} diff --git a/src/eth/regs.rs b/src/eth/regs.rs index 7dcd960..60d81e9 100644 --- a/src/eth/regs.rs +++ b/src/eth/regs.rs @@ -124,7 +124,22 @@ impl RegisterBlock { } register!(net_ctrl, NetCtrl, RW, u32); +register_bit!(net_ctrl, loopback_local, 1); +register_bit!(net_ctrl, rx_en, 2); +register_bit!(net_ctrl, tx_en, 3); +register_bit!(net_ctrl, mgmt_port_en, 4); register_bit!(net_ctrl, clear_stat_regs, 5); +register_bit!(net_ctrl, incr_stat_regs, 6); +register_bit!(net_ctrl, wren_stat_regs, 7); +register_bit!(net_ctrl, back_pressure, 8); +register_bit!(net_ctrl, start_tx, 9); +register_bit!(net_ctrl, tx_halt, 10); +register_bit!(net_ctrl, tx_pause_frame, 11); +register_bit!(net_ctrl, tx_zeroq_pause_frame, 12); +register_bit!(net_ctrl, str_rx_timestamp, 15); +register_bit!(net_ctrl, en_pfc_pri_pause_rx, 16); +register_bit!(net_ctrl, tx_pfc_pri_pri_pause_frame, 17); +register_bit!(net_ctrl, flush_next_rx_dpram_pkt, 18); register!(net_cfg, NetCfg, RW, u32); register_bit!(net_cfg,