On Mon, Jun 29, 2026 at 07:42:43PM +0300, Ruinskiy, Dima wrote: > Hi AceLan, > > Some more comments below. > > On 22/06/2026 4:57, Chia-Lin Kao (AceLan) wrote: > > > > > > > Because 100 iterations of 100msec each - this translates to up-to 10 > > > seconds, no? > > Yes, just in case it takes longer. > > I think 5 seconds should be enough if you feel this is feasible. > 5 seconds also sounds excessive, assuming the majority of the systems do not > support / enable MAC passthrough via the FW feature (and I have a hunch it > is the case). 2 seconds... maybe, but then you say that in some rare cases > it exceeds 2 seconds as well. What if in some even rare cases it exceeds > 5/10 seconds? Perhaps because of some glitch it will not come up at all on > this cycle. Should the driver always wait? > > > I wish we can detect if the MAC passthrough is enabled, so that we > > know if we need to poll for the MAC address. > Unfortunately, like you I am not aware of any way for the driver to know > whether MAC passthrough via FW is enabled. Because of this we have been > exploring a simpler way to support this feature via ACPI objects (which are > set by the BIOS when MAC passthrough is enabled and are easy for the driver > to query). I know some vendors have already implemented it, and I am > currently drafting a patch to send. Any good news about this patch?
> > > For the FW interrupt mechanism also needs BIOS support, and we don't > > have the power to push this. > The mechanism I have in mind does not require BIOS support - the I225/I226 > FW already supports the required interrupt, AFAIK - it merely needs to be > enabled in the igc driver. With that said, there still remains the question > of how to notify the network stack above us that the MAC address has changed > post-probe - and whether it is even supported. > > --Dima > > > > > > > > > Thanks, > > > Dima. > > > > > > > > > > > > Signed-off-by: Chia-Lin Kao (AceLan) <[email protected]> > > > > > --- > > > > > drivers/net/ethernet/intel/igc/igc_main.c | 48 > > > > > +++++++++++++++++++++++ > > > > > 1 file changed, 48 insertions(+) > > > > > > > > > > diff --git a/drivers/net/ethernet/intel/igc/igc_main.c > > > > > b/drivers/net/ethernet/intel/igc/igc_main.c > > > > > index 2c9e2dfd8499..fa9752ed8bc5 100644 > > > > > --- a/drivers/net/ethernet/intel/igc/igc_main.c > > > > > +++ b/drivers/net/ethernet/intel/igc/igc_main.c > > > > > @@ -11,6 +11,7 @@ > > > > > #include <net/pkt_sched.h> > > > > > #include <linux/bpf_trace.h> > > > > > #include <net/xdp_sock_drv.h> > > > > > +#include <linux/etherdevice.h> > > > > > #include <linux/pci.h> > > > > > #include <linux/mdio.h> > > > > > > > > > > @@ -69,6 +70,52 @@ static const struct pci_device_id igc_pci_tbl[] = { > > > > > > > > > > MODULE_DEVICE_TABLE(pci, igc_pci_tbl); > > > > > > > > > > +static void igc_read_rar0(struct igc_hw *hw, u8 *addr, u32 *ral, u32 > > > > > +*rah) { > > > > > + *ral = rd32(IGC_RAL(0)); > > > > > + *rah = rd32(IGC_RAH(0)); > > > > > + > > > > > + addr[0] = *ral & 0xff; > > > > > + addr[1] = (*ral >> 8) & 0xff; > > > > > + addr[2] = (*ral >> 16) & 0xff; > > > > > + addr[3] = (*ral >> 24) & 0xff; > > > > > + addr[4] = *rah & 0xff; > > > > > + addr[5] = (*rah >> 8) & 0xff; > > > > > +} > > > > > + > > > > > +static bool igc_is_lmvp_device(struct pci_dev *pdev) { > > > > > + switch (pdev->device) { > > > > > + case IGC_DEV_ID_I225_LMVP: > > > > > + case IGC_DEV_ID_I226_LMVP: > > > > > + return true; > > > > > + default: > > > > > + return false; > > > > > + } > > > > > +} > > > > > + > > > > > +static void igc_wait_for_lmvp_mac_passthrough(struct pci_dev *pdev, > > > > > + struct igc_hw *hw) > > > > > +{ > > > > > + u8 addr[ETH_ALEN] __aligned(2); > > > > > + u32 orig_ral, orig_rah; > > > > > + u32 ral, rah; > > > > > + int i; > > > > > + > > > > > + if (!igc_is_lmvp_device(pdev)) > > > > > + return; > > > > > + > > > > > + igc_read_rar0(hw, addr, &orig_ral, &orig_rah); > > > > > + > > > > > + for (i = 0; i < 100; i++) { > > > > > + msleep(100); > > > > > + igc_read_rar0(hw, addr, &ral, &rah); > > > > > + if ((ral != orig_ral || rah != orig_rah) && > > > > > + is_valid_ether_addr(addr)) > > > > > + return; > > > > > + } > > > > > +} > > > > > + > > > > > enum latency_range { > > > > > lowest_latency = 0, > > > > > low_latency = 1, > > > > > @@ -7259,6 +7306,7 @@ static int igc_probe(struct pci_dev *pdev, > > > > > * known good starting state > > > > > */ > > > > > hw->mac.ops.reset_hw(hw); > > > > > + igc_wait_for_lmvp_mac_passthrough(pdev, hw); > > > > > > > > > > if (igc_get_flash_presence_i225(hw)) { > > > > > if (hw->nvm.ops.validate(hw) < 0) { > > > > > -- > > > > > 2.53.0 > > > > > > > >
