From: Bartosz Szczepanek bsz@semihalf.com
Driver produces MDIO protocol in order to enable network PHY access via SMI interface. Base address is configurable via PCD.
Contributed-under: TianoCore Contribution Agreemeent 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com --- Documentation/Marvell/PortingGuide/Mdio.txt | 7 + Documentation/Marvell/UserGuide.txt | 1 + Drivers/Net/MdioDxe/MdioDxe.c | 235 ++++++++++++++++++++++++++++ Drivers/Net/MdioDxe/MdioDxe.h | 57 +++++++ Drivers/Net/MdioDxe/MdioDxe.inf | 68 ++++++++ Platforms/Marvell/Marvell.dec | 5 +- 6 files changed, 372 insertions(+), 1 deletion(-) create mode 100644 Documentation/Marvell/PortingGuide/Mdio.txt create mode 100644 Drivers/Net/MdioDxe/MdioDxe.c create mode 100644 Drivers/Net/MdioDxe/MdioDxe.h create mode 100644 Drivers/Net/MdioDxe/MdioDxe.inf
diff --git a/Documentation/Marvell/PortingGuide/Mdio.txt b/Documentation/Marvell/PortingGuide/Mdio.txt new file mode 100644 index 0000000..1aeca94 --- /dev/null +++ b/Documentation/Marvell/PortingGuide/Mdio.txt @@ -0,0 +1,7 @@ +MDIO driver configuration +------------------------- +MDIO driver provides access to network PHYs' registers via EFI_MDIO_READ and +EFI_MDIO_WRITE functions (EFI_MDIO_PROTOCOL). Following PCD is required: + + gMarvellTokenSpaceGuid.PcdMdioBaseAddress + (base address of SMI management register) diff --git a/Documentation/Marvell/UserGuide.txt b/Documentation/Marvell/UserGuide.txt index b868eda..228a848 100644 --- a/Documentation/Marvell/UserGuide.txt +++ b/Documentation/Marvell/UserGuide.txt @@ -10,6 +10,7 @@ Table of contents: comphy - PortingGuide/ComPhy.txt i2c - PortingGuide/I2c.txt icu - PortingGuide/IcuLib.txt + mdio - PortingGuide/Mdio.txt mpp - PortingGuide/Mpp.txt ramdisk - PortingGuide/Ramdisk.txt reset library - PortingGuide/Reset.txt diff --git a/Drivers/Net/MdioDxe/MdioDxe.c b/Drivers/Net/MdioDxe/MdioDxe.c new file mode 100644 index 0000000..b0d04c0 --- /dev/null +++ b/Drivers/Net/MdioDxe/MdioDxe.c @@ -0,0 +1,235 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include <Protocol/DriverBinding.h> +#include <Protocol/Mdio.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiBootServicesTableLib.h> + +#include "MdioDxe.h" + +UINT64 MdioBase = 0; + +EFI_STATUS +MdioCheckParam ( + INTN PhyAddr, + INTN RegOff + ) +{ + if (PhyAddr > MVEBU_PHY_ADDR_MASK) { + DEBUG((DEBUG_ERROR, "Invalid PHY address %d\n", PhyAddr)); + return EFI_INVALID_PARAMETER; + } + + if (RegOff > MVEBU_PHY_REG_MASK) { + DEBUG((DEBUG_ERROR, "Invalid register offset %d\n", RegOff)); + return EFI_INVALID_PARAMETER; + } + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MdioWaitReady ( + VOID + ) +{ + UINT32 Timeout = MVEBU_SMI_TIMEOUT; + UINT32 MdioReg; + + /* wait till the SMI is not busy */ + do { + /* read smi register */ + MdioReg = MmioRead32(MdioBase); + if (Timeout-- == 0) { + DEBUG((DEBUG_ERROR, "SMI busy Timeout\n")); + return EFI_TIMEOUT; + } + } while (MdioReg & MVEBU_SMI_BUSY); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MdioWaitValid ( + VOID + ) +{ + UINT32 Timeout = MVEBU_SMI_TIMEOUT; + UINT32 MdioReg; + + /* wait till read value is ready */ + do { + /* read smi register */ + MdioReg = MmioRead32 (MdioBase); + if (Timeout-- == 0) { + DEBUG((DEBUG_ERROR, "SMI read ready time-out\n")); + return EFI_TIMEOUT; + } + } while (!(MdioReg & MVEBU_SMI_READ_VALID)); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MdioOperation ( + IN CONST EFI_MDIO_PROTOCOL *This, + IN UINT32 PhyAddr, + IN UINT32 RegOff, + IN BOOLEAN Write, + IN OUT UINT32 *Data + ) +{ + UINT32 MdioReg; + EFI_STATUS Status; + + Status = MdioCheckParam (PhyAddr, RegOff); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "MdioDxe: wrong parameters\n")); + return Status; + } + + /* wait till the SMI is not busy */ + Status = MdioWaitReady (); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "MdioDxe: MdioWaitReady error\n")); + return Status; + } + + /* fill the phy addr and reg offset and write opcode and data */ + MdioReg = (PhyAddr << MVEBU_SMI_DEV_ADDR_OFFS) + | (RegOff << MVEBU_SMI_REG_ADDR_OFFS); + if (Write) { + MdioReg &= ~MVEBU_SMI_OPCODE_READ; + MdioReg |= (*Data << MVEBU_SMI_DATA_OFFS); + } else { + MdioReg |= MVEBU_SMI_OPCODE_READ; + } + + /* write the smi register */ + MdioRegWrite32 (MdioReg, MdioBase); + + /* make sure that the write transaction is over */ + Status = Write ? MdioWaitReady () : MdioWaitValid (); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "MdioDxe: MdioWaitReady error\n")); + return Status; + } + + if (!Write) { + *Data = MmioRead32 (MdioBase) & MVEBU_SMI_DATA_MASK; + } + + return EFI_SUCCESS; +} + +UINT32 +MdioRead ( + IN CONST EFI_MDIO_PROTOCOL *This, + IN UINT32 PhyAddr, + IN UINT32 RegOff + ) +{ + EFI_STATUS Status; + UINT32 Data; + + Status = MdioOperation ( + This, + PhyAddr, + RegOff, + FALSE, + &Data + ); + + return EFI_ERROR(Status) ? 0 : Data; +} + +EFI_STATUS +MdioWrite ( + IN CONST EFI_MDIO_PROTOCOL *This, + IN UINT32 PhyAddr, + IN UINT32 RegOff, + IN UINT32 Data + ) +{ + return MdioOperation ( + This, + PhyAddr, + RegOff, + TRUE, + &Data + ); +} + +EFI_STATUS +EFIAPI +MdioDxeInitialise ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_MDIO_PROTOCOL *Mdio; + EFI_STATUS Status; + EFI_HANDLE Handle = NULL; + + Mdio = AllocateZeroPool (sizeof (EFI_MDIO_PROTOCOL)); + Mdio->Read = MdioRead; + Mdio->Write = MdioWrite; + MdioBase = PcdGet64 (PcdMdioBaseAddress); + if (MdioBase == 0) { + DEBUG((DEBUG_ERROR, "MdioDxe: PcdMdioBaseAddress not set\n")); + return EFI_INVALID_PARAMETER; + } + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiMdioProtocolGuid, Mdio, + NULL + ); + + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "Failed to install interfaces\n")); + return Status; + } + + return EFI_SUCCESS; +} diff --git a/Drivers/Net/MdioDxe/MdioDxe.h b/Drivers/Net/MdioDxe/MdioDxe.h new file mode 100644 index 0000000..b41a1e6 --- /dev/null +++ b/Drivers/Net/MdioDxe/MdioDxe.h @@ -0,0 +1,57 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#ifndef __MDIO_DXE_H__ +#define __MDIO_DXE_H__ + +#include <Uefi.h> + +#define MVEBU_SMI_TIMEOUT 10000 + +/* SMI register fields */ +#define MVEBU_SMI_DATA_OFFS 0 /* Data */ +#define MVEBU_SMI_DATA_MASK (0xffff << MVEBU_SMI_DATA_OFFS) +#define MVEBU_SMI_DEV_ADDR_OFFS 16 /* PHY device address */ +#define MVEBU_SMI_REG_ADDR_OFFS 21 /* PHY device reg addr*/ +#define MVEBU_SMI_OPCODE_OFFS 26 /* Write/Read opcode */ +#define MVEBU_SMI_OPCODE_READ (1 << MVEBU_SMI_OPCODE_OFFS) +#define MVEBU_SMI_READ_VALID (1 << 27) /* Read Valid */ +#define MVEBU_SMI_BUSY (1 << 28) /* Busy */ + +#define MVEBU_PHY_REG_MASK 0x1f +#define MVEBU_PHY_ADDR_MASK 0x1f + +#define MdioRegWrite32(x, y) MmioWrite32((y), (x)) + +#endif // __MDIO_DXE_H__ diff --git a/Drivers/Net/MdioDxe/MdioDxe.inf b/Drivers/Net/MdioDxe/MdioDxe.inf new file mode 100644 index 0000000..ad6093e --- /dev/null +++ b/Drivers/Net/MdioDxe/MdioDxe.inf @@ -0,0 +1,68 @@ +# Copyright (C) 2016 Marvell International Ltd. +# +# Marvell BSD License Option +# +# If you received this File from Marvell, you may opt to use, redistribute and/or +# modify this File under the following licensing terms. +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Marvell nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MdioDxe + FILE_GUID = 59fc3843-d8d4-40ba-ae07-38967138509c + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = MdioDxeInitialise + +[Sources.common] + MdioDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + ArmPkg/ArmPkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + IoLib + PcdLib + BaseLib + BaseMemoryLib + DebugLib + UefiLib + UefiDriverEntryPoint + UefiBootServicesTableLib + +[Protocols] + gEfiMdioProtocolGuid + +[Pcd] + gMarvellTokenSpaceGuid.PcdMdioBaseAddress + +[Depex] + TRUE diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index d7ef725..0a6d3e9 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -202,7 +202,10 @@ gMarvellTokenSpaceGuid.PcdUtmiPhyRegUsbCfg|{ 0 }|VOID*|0x30000207 gMarvellTokenSpaceGuid.PcdUtmiPhyRegUtmiCfg|{ 0 }|VOID*|0x30000208 gMarvellTokenSpaceGuid.PcdUtmiPhyUtmiPort|{ 0 }|VOID*|0x30000209 - + +#MDIO + gMarvellTokenSpaceGuid.PcdMdioBaseAddress|0|UINT64|0x3000043 + [Protocols] gEfiEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} gEfiSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }}