/** @file This file implements the hardware register access functions of the e1000 driver. Copyright (c) 2021, Oracle and/or its affiliates.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include "E1kNet.h" EFI_STATUS EFIAPI E1kNetRegWrite32 ( IN E1K_NET_DEV *Dev, IN UINT32 Addr, IN UINT32 Data ) { EFI_STATUS Status; Status = Dev->PciIo->Io.Write ( Dev->PciIo, EfiPciIoWidthUint32, PCI_BAR_IDX2, 0, // IOADDR 1, &Addr ); if (!EFI_ERROR (Status)) { Status = Dev->PciIo->Io.Write ( Dev->PciIo, EfiPciIoWidthUint32, PCI_BAR_IDX2, 4, // IODATA 1, &Data ); } return Status; } EFI_STATUS EFIAPI E1kNetRegRead32 ( IN E1K_NET_DEV *Dev, IN UINT32 Addr, OUT UINT32 *Data ) { EFI_STATUS Status; Status = Dev->PciIo->Io.Write ( Dev->PciIo, EfiPciIoWidthUint32, PCI_BAR_IDX2, 0, // IOADDR 1, &Addr ); if (!EFI_ERROR (Status)) { return Dev->PciIo->Io.Read ( Dev->PciIo, EfiPciIoWidthUint32, PCI_BAR_IDX2, 4, // IODATA 1, Data ); } return Status; } EFI_STATUS EFIAPI E1kNetRegSet32 ( IN E1K_NET_DEV *Dev, IN UINT32 Addr, IN UINT32 Set) { UINT32 Reg; EFI_STATUS Status; Status = E1kNetRegRead32 (Dev, Addr, &Reg); if (EFI_ERROR (Status)) { return Status; } Reg |= Set; Status = E1kNetRegWrite32 (Dev, Addr, Reg); if (EFI_ERROR (Status)) { return Status; } return EFI_SUCCESS; } EFI_STATUS EFIAPI E1kNetRegClear32 ( IN E1K_NET_DEV *Dev, IN UINT32 Addr, IN UINT32 Clear) { UINT32 Reg; EFI_STATUS Status; Status = E1kNetRegRead32 (Dev, Addr, &Reg); if (EFI_ERROR (Status)) { return Status; } Reg &= ~Clear; Status = E1kNetRegWrite32 (Dev, Addr, Reg); if (EFI_ERROR (Status)) { return Status; } return EFI_SUCCESS; } EFI_STATUS EFIAPI E1kNetDevReset ( IN E1K_NET_DEV *Dev ) { EFI_STATUS Status; // // Reset hardware // Status = E1kNetRegSet32 (Dev, E1K_REG_CTRL, E1K_REG_CTRL_RST); if (EFI_ERROR (Status)) { return Status; } // // Wait for the reset to complete // for (;;) { UINT32 Ctrl; Status = E1kNetRegRead32 (Dev, E1K_REG_CTRL, &Ctrl); if (EFI_ERROR (Status)) { return Status; } /// @todo Timeout? if (!(Ctrl & E1K_REG_CTRL_RST)) break; } // // Reset the PHY. // Status = E1kNetRegSet32 (Dev, E1K_REG_CTRL, E1K_REG_CTRL_PHY_RST); if (EFI_ERROR (Status)) { return Status; } // // Wait for the specified amount of 3us and de-assert the PHY reset signal. // gBS->Stall(3); Status = E1kNetRegClear32 (Dev, E1K_REG_CTRL, E1K_REG_CTRL_PHY_RST); if (EFI_ERROR (Status)) { return Status; } return EFI_SUCCESS; }