diff --git a/drv/transceivers-server/src/main.rs b/drv/transceivers-server/src/main.rs index d3bd52718..0e4798c5f 100644 --- a/drv/transceivers-server/src/main.rs +++ b/drv/transceivers-server/src/main.rs @@ -21,7 +21,7 @@ use drv_sidecar_front_io::{ }, Reg, }; -use drv_sidecar_seq_api::{SeqError, Sequencer}; +use drv_sidecar_seq_api::{SeqError, Sequencer, TofinoSeqState}; use drv_transceivers_api::{ ModuleStatus, TransceiversError, NUM_PORTS, TRANSCEIVER_TEMPERATURE_SENSORS, }; @@ -78,6 +78,7 @@ enum Trace { DisablingPorts(LogicalPortMask), DisableFailed(usize, LogicalPortMask), ClearDisabledPorts(LogicalPortMask), + SeqError(SeqError), } counted_ringbuf!(Trace, 16, Trace::None); @@ -193,21 +194,26 @@ impl ServerImpl { self.system_led_state } - fn update_leds(&mut self) { - // handle port LEDs + fn update_leds(&mut self, seq_state: TofinoSeqState) { let mut next_state = LogicalPortMask(0); - for (i, state) in self.led_states.0.into_iter().enumerate() { - let i = LogicalPort(i as u8); - match state { - LedState::On => next_state.set(i), - LedState::Blink => { - if self.blink_on { - next_state.set(i) + + // We only turn transceiver LEDs on when Sidecar is in A0, since that is when there can be + // meaningful link activity happening. When outside of A0, we default the LEDs to off. + if seq_state == TofinoSeqState::A0 { + for (i, state) in self.led_states.0.into_iter().enumerate() { + let i = LogicalPort(i as u8); + match state { + LedState::On => next_state.set(i), + LedState::Blink => { + if self.blink_on { + next_state.set(i) + } } + LedState::Off => (), } - LedState::Off => (), } } + if let Err(e) = self.leds.update_led_state(next_state) { ringbuf_entry!(Trace::LEDUpdateError(e)); } @@ -512,9 +518,9 @@ impl ServerImpl { // the `sensors` and `thermal` tasks. } - fn handle_i2c_loop(&mut self) { + fn handle_i2c_loop(&mut self, seq_state: TofinoSeqState) { if self.leds_initialized { - self.update_leds(); + self.update_leds(seq_state); let errors = match self.leds.error_summary() { Ok(errs) => errs, Err(e) => { @@ -719,10 +725,23 @@ fn main() -> ! { for t in multitimer.iter_fired() { match t { Timers::I2C => { + // Check what power state we are in since that can impact LED state which is + // part of the I2C loop. + let seq_state = + seq.tofino_seq_state().unwrap_or_else(|e| { + // The failure path here is that we cannot get the state from the FPGA. + // If we cannot communicate with the FPGA then something has likely went + // rather wrong, and we are probably not in A0. For handling the error + // we will assume to be in the Init state, since that is what the main + // sequencer does as well. + ringbuf_entry!(Trace::SeqError(e)); + TofinoSeqState::Init + }); + // Handle the Front IO status checking as part of this // loop because the frequency is what we had before and // the server itself has no knowledge of the sequencer. - server.handle_i2c_loop(); + server.handle_i2c_loop(seq_state); } Timers::SPI => { if server.front_io_board_present == FrontIOStatus::Ready {