/** @file
|
|
Copyright (c) 2020 Jared McNeill <jmcneill@invisible.ca>
|
Copyright (c) 2020, ARM Limited. All rights reserved.
|
Copyright (c) 2020 Andrey Warkentin <andrey.warkentin@gmail.com>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
#ifndef BCM_GENET_DXE_H__
|
#define BCM_GENET_DXE_H__
|
|
#include <Uefi.h>
|
#include <Library/UefiLib.h>
|
#include <Protocol/BcmGenetPlatformDevice.h>
|
#include <Protocol/AdapterInformation.h>
|
#include <Protocol/ComponentName.h>
|
#include <Protocol/ComponentName2.h>
|
#include <Protocol/SimpleNetwork.h>
|
|
#include "GenericPhy.h"
|
|
#define LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask))
|
#define SHIFTOUT(__x, __mask) (((__x) & (__mask)) / LOWEST_SET_BIT (__mask))
|
#define SHIFTIN(__x, __mask) ((__x) * LOWEST_SET_BIT (__mask))
|
|
/*
|
* Aux control shadow register, bits 0-2 select function (0x00 to
|
* 0x07).
|
*/
|
#define BRGPHY_MII_AUXCTL 0x18 /* AUX control */
|
#define BRGPHY_AUXCTL_SHADOW_MISC 0x07
|
#define BRGPHY_AUXCTL_MISC_DATA_MASK 0x7ff8
|
#define BRGPHY_AUXCTL_MISC_READ_SHIFT 12
|
#define BRGPHY_AUXCTL_MISC_WRITE_EN 0x8000
|
#define BRGPHY_AUXCTL_MISC_RGMII_SKEW_EN 0x0200
|
|
/*
|
* Shadow register 0x1C, bit 15 is write enable,
|
* bits 14-10 select function (0x00 to 0x1F).
|
*/
|
#define BRGPHY_MII_SHADOW_1C 0x1C
|
#define BRGPHY_SHADOW_1C_WRITE_EN 0x8000
|
#define BRGPHY_SHADOW_1C_SELECT_MASK 0x7C00
|
#define BRGPHY_SHADOW_1C_DATA_MASK 0x03FF
|
|
/* Shadow 0x1C Clock Alignment Control Register (select value 0x03) */
|
#define BRGPHY_SHADOW_1C_CLK_CTRL (0x03 << 10)
|
#define BRGPHY_SHADOW_1C_GTXCLK_EN 0x0200
|
|
#define MAX_ETHERNET_PKT_SIZE 1500
|
|
#define GENET_VERSION 0x0a
|
#define GENET_MAX_PACKET_SIZE 1536
|
|
#define GENET_SYS_REV_CTRL 0x000
|
#define SYS_REV_MAJOR (BIT27|BIT26|BIT25|BIT24)
|
#define SYS_REV_MINOR (BIT19|BIT18|BIT17|BIT16)
|
#define GENET_SYS_PORT_CTRL 0x004
|
#define GENET_SYS_PORT_MODE_EXT_GPHY 3
|
#define GENET_SYS_RBUF_FLUSH_CTRL 0x008
|
#define GENET_SYS_RBUF_FLUSH_RESET BIT1
|
#define GENET_SYS_TBUF_FLUSH_CTRL 0x00c
|
#define GENET_EXT_RGMII_OOB_CTRL 0x08c
|
#define GENET_EXT_RGMII_OOB_ID_MODE_DISABLE BIT16
|
#define GENET_EXT_RGMII_OOB_RGMII_MODE_EN BIT6
|
#define GENET_EXT_RGMII_OOB_OOB_DISABLE BIT5
|
#define GENET_EXT_RGMII_OOB_RGMII_LINK BIT4
|
#define GENET_INTRL2_CPU_STAT 0x200
|
#define GENET_INTRL2_CPU_CLEAR 0x208
|
#define GENET_INTRL2_CPU_STAT_MASK 0x20c
|
#define GENET_INTRL2_CPU_SET_MASK 0x210
|
#define GENET_INTRL2_CPU_CLEAR_MASK 0x214
|
#define GENET_IRQ_MDIO_ERROR BIT24
|
#define GENET_IRQ_MDIO_DONE BIT23
|
#define GENET_IRQ_TXDMA_DONE BIT16
|
#define GENET_IRQ_RXDMA_DONE BIT13
|
#define GENET_RBUF_CTRL 0x300
|
#define GENET_RBUF_BAD_DIS BIT2
|
#define GENET_RBUF_ALIGN_2B BIT1
|
#define GENET_RBUF_64B_EN BIT0
|
#define GENET_RBUF_TBUF_SIZE_CTRL 0x3b4
|
#define GENET_UMAC_CMD 0x808
|
#define GENET_UMAC_CMD_LCL_LOOP_EN BIT15
|
#define GENET_UMAC_CMD_SW_RESET BIT13
|
#define GENET_UMAC_CMD_HD_EN BIT10
|
#define GENET_UMAC_CMD_PROMISC BIT4
|
#define GENET_UMAC_CMD_SPEED (BIT3|BIT2)
|
#define GENET_UMAC_CMD_SPEED_10 0
|
#define GENET_UMAC_CMD_SPEED_100 1
|
#define GENET_UMAC_CMD_SPEED_1000 2
|
#define GENET_UMAC_CMD_RXEN BIT1
|
#define GENET_UMAC_CMD_TXEN BIT0
|
#define GENET_UMAC_MAC0 0x80c
|
#define GENET_UMAC_MAC1 0x810
|
#define GENET_UMAC_MAX_FRAME_LEN 0x814
|
#define GENET_UMAC_TX_FLUSH 0xb34
|
#define GENET_UMAC_MIB_CTRL 0xd80
|
#define GENET_UMAC_MIB_RESET_TX BIT2
|
#define GENET_UMAC_MIB_RESET_RUNT BIT1
|
#define GENET_UMAC_MIB_RESET_RX BIT0
|
#define GENET_MDIO_CMD 0xe14
|
#define GENET_MDIO_START_BUSY BIT29
|
#define GENET_MDIO_READ BIT27
|
#define GENET_MDIO_WRITE BIT26
|
#define GENET_MDIO_PMD (BIT25|BIT24|BIT23|BIT22|BIT21)
|
#define GENET_MDIO_REG (BIT20|BIT19|BIT18|BIT17|BIT16)
|
#define GENET_UMAC_MDF_CTRL 0xe50
|
#define GENET_UMAC_MDF_ADDR0(n) (0xe54 + (n) * 0x8)
|
#define GENET_UMAC_MDF_ADDR1(n) (0xe58 + (n) * 0x8)
|
#define GENET_MAX_MDF_FILTER 17
|
|
#define GENET_DMA_DESC_COUNT 256
|
#define GENET_DMA_DESC_SIZE 12
|
#define GENET_DMA_DEFAULT_QUEUE 16
|
|
#define GENET_DMA_RING_SIZE 0x40
|
#define GENET_DMA_RINGS_SIZE (GENET_DMA_RING_SIZE * (GENET_DMA_DEFAULT_QUEUE + 1))
|
|
#define GENET_RX_BASE 0x2000
|
#define GENET_TX_BASE 0x4000
|
|
#define GENET_RX_DMA_RINGBASE(qid) (GENET_RX_BASE + 0xc00 + GENET_DMA_RING_SIZE * (qid))
|
#define GENET_RX_DMA_WRITE_PTR_LO(qid) (GENET_RX_DMA_RINGBASE(qid) + 0x00)
|
#define GENET_RX_DMA_WRITE_PTR_HI(qid) (GENET_RX_DMA_RINGBASE(qid) + 0x04)
|
#define GENET_RX_DMA_PROD_INDEX(qid) (GENET_RX_DMA_RINGBASE(qid) + 0x08)
|
#define GENET_RX_DMA_CONS_INDEX(qid) (GENET_RX_DMA_RINGBASE(qid) + 0x0c)
|
#define GENET_RX_DMA_RING_BUF_SIZE(qid) (GENET_RX_DMA_RINGBASE(qid) + 0x10)
|
#define GENET_RX_DMA_RING_BUF_SIZE_DESC_COUNT 0xffff0000
|
#define GENET_RX_DMA_RING_BUF_SIZE_BUF_LENGTH 0x0000ffff
|
#define GENET_RX_DMA_START_ADDR_LO(qid) (GENET_RX_DMA_RINGBASE(qid) + 0x14)
|
#define GENET_RX_DMA_START_ADDR_HI(qid) (GENET_RX_DMA_RINGBASE(qid) + 0x18)
|
#define GENET_RX_DMA_END_ADDR_LO(qid) (GENET_RX_DMA_RINGBASE(qid) + 0x1c)
|
#define GENET_RX_DMA_END_ADDR_HI(qid) (GENET_RX_DMA_RINGBASE(qid) + 0x20)
|
#define GENET_RX_DMA_XON_XOFF_THRES(qid) (GENET_RX_DMA_RINGBASE(qid) + 0x28)
|
#define GENET_RX_DMA_XON_XOFF_THRES_LO 0xffff0000
|
#define GENET_RX_DMA_XON_XOFF_THRES_HI 0x0000ffff
|
#define GENET_RX_DMA_READ_PTR_LO(qid) (GENET_RX_DMA_RINGBASE(qid) + 0x2c)
|
#define GENET_RX_DMA_READ_PTR_HI(qid) (GENET_RX_DMA_RINGBASE(qid) + 0x30)
|
|
#define GENET_TX_DMA_RINGBASE(qid) (GENET_TX_BASE + 0xc00 + GENET_DMA_RING_SIZE * (qid))
|
#define GENET_TX_DMA_READ_PTR_LO(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x00)
|
#define GENET_TX_DMA_READ_PTR_HI(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x04)
|
#define GENET_TX_DMA_CONS_INDEX(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x08)
|
#define GENET_TX_DMA_PROD_INDEX(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x0c)
|
#define GENET_TX_DMA_RING_BUF_SIZE(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x10)
|
#define GENET_TX_DMA_RING_BUF_SIZE_DESC_COUNT 0xffff0000
|
#define GENET_TX_DMA_RING_BUF_SIZE_BUF_LENGTH 0x0000ffff
|
#define GENET_TX_DMA_START_ADDR_LO(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x14)
|
#define GENET_TX_DMA_START_ADDR_HI(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x18)
|
#define GENET_TX_DMA_END_ADDR_LO(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x1c)
|
#define GENET_TX_DMA_END_ADDR_HI(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x20)
|
#define GENET_TX_DMA_MBUF_DONE_THRES(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x24)
|
#define GENET_TX_DMA_FLOW_PERIOD(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x28)
|
#define GENET_TX_DMA_WRITE_PTR_LO(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x2c)
|
#define GENET_TX_DMA_WRITE_PTR_HI(qid) (GENET_TX_DMA_RINGBASE(qid) + 0x30)
|
|
#define GENET_RX_DESC_STATUS(idx) (GENET_RX_BASE + GENET_DMA_DESC_SIZE * (idx) + 0x00)
|
#define GENET_RX_DESC_STATUS_BUFLEN (BIT27|BIT26|BIT25|BIT24|BIT23|BIT22|BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)
|
#define GENET_RX_DESC_STATUS_OWN BIT15
|
#define GENET_RX_DESC_STATUS_EOP BIT14
|
#define GENET_RX_DESC_STATUS_SOP BIT13
|
#define GENET_RX_DESC_STATUS_RX_ERROR BIT2
|
#define GENET_RX_DESC_ADDRESS_LO(idx) (GENET_RX_BASE + GENET_DMA_DESC_SIZE * (idx) + 0x04)
|
#define GENET_RX_DESC_ADDRESS_HI(idx) (GENET_RX_BASE + GENET_DMA_DESC_SIZE * (idx) + 0x08)
|
|
#define GENET_TX_DESC_STATUS(idx) (GENET_TX_BASE + GENET_DMA_DESC_SIZE * (idx) + 0x00)
|
#define GENET_TX_DESC_STATUS_BUFLEN (BIT27|BIT26|BIT25|BIT24|BIT23|BIT22|BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)
|
#define GENET_TX_DESC_STATUS_OWN BIT15
|
#define GENET_TX_DESC_STATUS_EOP BIT14
|
#define GENET_TX_DESC_STATUS_SOP BIT13
|
#define GENET_TX_DESC_STATUS_QTAG (BIT12|BIT11|BIT10|BIT9|BIT8|BIT7)
|
#define GENET_TX_DESC_STATUS_CRC BIT6
|
#define GENET_TX_DESC_ADDRESS_LO(idx) (GENET_TX_BASE + GENET_DMA_DESC_SIZE * (idx) + 0x04)
|
#define GENET_TX_DESC_ADDRESS_HI(idx) (GENET_TX_BASE + GENET_DMA_DESC_SIZE * (idx) + 0x08)
|
|
#define GENET_RX_DMA_RING_CFG (GENET_RX_BASE + 0x1040 + 0x00)
|
#define GENET_RX_DMA_CTRL (GENET_RX_BASE + 0x1040 + 0x04)
|
#define GENET_RX_DMA_CTRL_RBUF_EN(qid) (BIT1 << (qid))
|
#define GENET_RX_DMA_CTRL_EN BIT0
|
#define GENET_RX_SCB_BURST_SIZE (GENET_RX_BASE + 0x1040 + 0x0c)
|
|
#define GENET_TX_DMA_RING_CFG (GENET_TX_BASE + 0x1040 + 0x00)
|
#define GENET_TX_DMA_CTRL (GENET_TX_BASE + 0x1040 + 0x04)
|
#define GENET_TX_DMA_CTRL_RBUF_EN(qid) (BIT1 << (qid))
|
#define GENET_TX_DMA_CTRL_EN BIT0
|
#define GENET_TX_SCB_BURST_SIZE (GENET_TX_BASE + 0x1040 + 0x0c)
|
|
typedef struct {
|
EFI_PHYSICAL_ADDRESS PhysAddress;
|
VOID * Mapping;
|
} GENET_MAP_INFO;
|
|
typedef enum {
|
GENET_PHY_MODE_MII,
|
GENET_PHY_MODE_RGMII,
|
GENET_PHY_MODE_RGMII_RXID,
|
GENET_PHY_MODE_RGMII_TXID,
|
GENET_PHY_MODE_RGMII_ID,
|
} GENET_PHY_MODE;
|
|
typedef struct {
|
UINT32 Signature;
|
EFI_HANDLE ControllerHandle;
|
|
EFI_LOCK Lock;
|
EFI_EVENT ExitBootServicesEvent;
|
|
EFI_SIMPLE_NETWORK_PROTOCOL Snp;
|
EFI_SIMPLE_NETWORK_MODE SnpMode;
|
|
EFI_ADAPTER_INFORMATION_PROTOCOL Aip;
|
|
BCM_GENET_PLATFORM_DEVICE_PROTOCOL *Dev;
|
|
GENERIC_PHY_PRIVATE_DATA Phy;
|
|
UINT8 *TxBuffer[GENET_DMA_DESC_COUNT];
|
VOID *TxBufferMap[GENET_DMA_DESC_COUNT];
|
UINT8 TxQueued;
|
UINT16 TxNext;
|
UINT16 TxConsIndex;
|
UINT16 TxProdIndex;
|
|
EFI_PHYSICAL_ADDRESS RxBuffer;
|
GENET_MAP_INFO RxBufferMap[GENET_DMA_DESC_COUNT];
|
UINT16 RxConsIndex;
|
UINT16 RxProdIndex;
|
|
GENET_PHY_MODE PhyMode;
|
|
UINTN RegBase;
|
} GENET_PRIVATE_DATA;
|
|
extern EFI_COMPONENT_NAME_PROTOCOL gGenetComponentName;
|
extern EFI_COMPONENT_NAME2_PROTOCOL gGenetComponentName2;
|
extern EFI_DRIVER_BINDING_PROTOCOL mGenetDriverBinding;
|
|
extern CONST EFI_SIMPLE_NETWORK_PROTOCOL gGenetSimpleNetworkTemplate;
|
extern CONST EFI_ADAPTER_INFORMATION_PROTOCOL gGenetAdapterInfoTemplate;
|
|
#define GENET_DRIVER_SIGNATURE SIGNATURE_32('G', 'N', 'E', 'T')
|
#define GENET_PRIVATE_DATA_FROM_SNP_THIS(a) CR(a, GENET_PRIVATE_DATA, Snp, GENET_DRIVER_SIGNATURE)
|
#define GENET_PRIVATE_DATA_FROM_AIP_THIS(a) CR(a, GENET_PRIVATE_DATA, Aip, GENET_DRIVER_SIGNATURE)
|
|
#define GENET_RX_BUFFER(g, idx) ((UINT8 *)(UINTN)(g)->RxBuffer + GENET_MAX_PACKET_SIZE * (idx))
|
|
EFI_STATUS
|
EFIAPI
|
GenetPhyRead (
|
IN VOID *Priv,
|
IN UINT8 PhyAddr,
|
IN UINT8 Reg,
|
OUT UINT16 *Data
|
);
|
|
EFI_STATUS
|
EFIAPI
|
GenetPhyWrite (
|
IN VOID *Priv,
|
IN UINT8 PhyAddr,
|
IN UINT8 Reg,
|
IN UINT16 Data
|
);
|
|
EFI_STATUS
|
EFIAPI
|
GenetPhyResetAction (
|
IN VOID *Priv
|
);
|
|
VOID
|
EFIAPI
|
GenetPhyConfigure (
|
IN VOID *Priv,
|
IN GENERIC_PHY_SPEED Speed,
|
IN GENERIC_PHY_DUPLEX Duplex
|
);
|
|
VOID
|
GenetReset (
|
IN GENET_PRIVATE_DATA *Genet
|
);
|
|
VOID
|
EFIAPI
|
GenetSetMacAddress (
|
IN GENET_PRIVATE_DATA *Genet,
|
IN EFI_MAC_ADDRESS *MacAddr
|
);
|
|
VOID
|
GenetSetPhyMode (
|
IN GENET_PRIVATE_DATA *Genet,
|
IN GENET_PHY_MODE PhyMode
|
);
|
|
VOID
|
GenetEnableTxRx (
|
IN GENET_PRIVATE_DATA *Genet
|
);
|
|
VOID
|
GenetDisableTxRx (
|
IN GENET_PRIVATE_DATA *Genet
|
);
|
|
VOID
|
GenetSetPromisc (
|
IN GENET_PRIVATE_DATA *Genet,
|
IN BOOLEAN Enable
|
);
|
|
VOID
|
GenetEnableBroadcastFilter (
|
IN GENET_PRIVATE_DATA *Genet,
|
IN BOOLEAN Enable
|
);
|
|
VOID
|
GenetDmaInitRings (
|
IN GENET_PRIVATE_DATA *Genet
|
);
|
|
EFI_STATUS
|
GenetDmaAlloc (
|
IN GENET_PRIVATE_DATA *Genet
|
);
|
|
VOID
|
GenetDmaFree (
|
IN GENET_PRIVATE_DATA *Genet
|
);
|
|
VOID
|
GenetDmaTriggerTx (
|
IN GENET_PRIVATE_DATA *Genet,
|
IN UINT8 DescIndex,
|
IN EFI_PHYSICAL_ADDRESS PhysAddr,
|
IN UINTN NumberOfBytes
|
);
|
|
EFI_STATUS
|
GenetDmaMapRxDescriptor (
|
IN GENET_PRIVATE_DATA *Genet,
|
IN UINT8 DescIndex
|
);
|
|
VOID
|
GenetDmaUnmapRxDescriptor (
|
IN GENET_PRIVATE_DATA *Genet,
|
IN UINT8 DescIndex
|
);
|
|
VOID
|
GenetTxIntr (
|
IN GENET_PRIVATE_DATA *Genet,
|
OUT VOID **TxBuf
|
);
|
|
UINT32
|
GenetRxPending (
|
IN GENET_PRIVATE_DATA *Genet
|
);
|
|
UINT32
|
GenetTxPending (
|
IN GENET_PRIVATE_DATA *Genet
|
);
|
|
EFI_STATUS
|
GenetRxIntr (
|
IN GENET_PRIVATE_DATA *Genet,
|
OUT UINT8 *DescIndex,
|
OUT UINTN *FrameLength
|
);
|
|
VOID
|
GenetRxComplete (
|
IN GENET_PRIVATE_DATA *Genet
|
);
|
|
#endif /* GENET_UTIL_H__ */
|