linux/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * dwmac-sun8i.c - Allwinner sun8i DWMAC specific glue layer
 *
 * Copyright (C) 2017 Corentin Labbe <[email protected]>
 */

#include <linux/clk.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/mdio-mux.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/regmap.h>
#include <linux/stmmac.h>

#include "stmmac.h"
#include "stmmac_platform.h"

/* General notes on dwmac-sun8i:
 * Locking: no locking is necessary in this file because all necessary locking
 *		is done in the "stmmac files"
 */

/* struct emac_variant - Describe dwmac-sun8i hardware variant
 * @default_syscon_value:	The default value of the EMAC register in syscon
 *				This value is used for disabling properly EMAC
 *				and used as a good starting value in case of the
 *				boot process(uboot) leave some stuff.
 * @syscon_field		reg_field for the syscon's gmac register
 * @soc_has_internal_phy:	Does the MAC embed an internal PHY
 * @support_mii:		Does the MAC handle MII
 * @support_rmii:		Does the MAC handle RMII
 * @support_rgmii:		Does the MAC handle RGMII
 *
 * @rx_delay_max:		Maximum raw value for RX delay chain
 * @tx_delay_max:		Maximum raw value for TX delay chain
 *				These two also indicate the bitmask for
 *				the RX and TX delay chain registers. A
 *				value of zero indicates this is not supported.
 */
struct emac_variant {};

/* struct sunxi_priv_data - hold all sunxi private data
 * @ephy_clk:	reference to the optional EPHY clock for the internal PHY
 * @regulator:	reference to the optional regulator
 * @rst_ephy:	reference to the optional EPHY reset for the internal PHY
 * @variant:	reference to the current board variant
 * @regmap:	regmap for using the syscon
 * @internal_phy_powered: Does the internal PHY is enabled
 * @use_internal_phy: Is the internal PHY selected for use
 * @mux_handle:	Internal pointer used by mdio-mux lib
 */
struct sunxi_priv_data {};

/* EMAC clock register @ 0x30 in the "system control" address range */
static const struct reg_field sun8i_syscon_reg_field =;

/* EMAC clock register @ 0x164 in the CCU address range */
static const struct reg_field sun8i_ccu_reg_field =;

static const struct emac_variant emac_variant_h3 =;

static const struct emac_variant emac_variant_v3s =;

static const struct emac_variant emac_variant_a83t =;

static const struct emac_variant emac_variant_r40 =;

static const struct emac_variant emac_variant_a64 =;

static const struct emac_variant emac_variant_h6 =;

#define EMAC_BASIC_CTL0
#define EMAC_BASIC_CTL1
#define EMAC_INT_STA
#define EMAC_INT_EN
#define EMAC_TX_CTL0
#define EMAC_TX_CTL1
#define EMAC_TX_FLOW_CTL
#define EMAC_TX_DESC_LIST
#define EMAC_RX_CTL0
#define EMAC_RX_CTL1
#define EMAC_RX_DESC_LIST
#define EMAC_RX_FRM_FLT
#define EMAC_MDIO_CMD
#define EMAC_MDIO_DATA
#define EMAC_MACADDR_HI(reg)
#define EMAC_MACADDR_LO(reg)
#define EMAC_TX_DMA_STA
#define EMAC_TX_CUR_DESC
#define EMAC_TX_CUR_BUF
#define EMAC_RX_DMA_STA
#define EMAC_RX_CUR_DESC
#define EMAC_RX_CUR_BUF

/* Use in EMAC_BASIC_CTL0 */
#define EMAC_DUPLEX_FULL
#define EMAC_LOOPBACK
#define EMAC_SPEED_1000
#define EMAC_SPEED_100
#define EMAC_SPEED_10

/* Use in EMAC_BASIC_CTL1 */
#define EMAC_BURSTLEN_SHIFT

/* Used in EMAC_RX_FRM_FLT */
#define EMAC_FRM_FLT_RXALL
#define EMAC_FRM_FLT_CTL
#define EMAC_FRM_FLT_MULTICAST

/* Used in RX_CTL1*/
#define EMAC_RX_MD
#define EMAC_RX_TH_MASK
#define EMAC_RX_TH_32
#define EMAC_RX_TH_64
#define EMAC_RX_TH_96
#define EMAC_RX_TH_128
#define EMAC_RX_DMA_EN
#define EMAC_RX_DMA_START

/* Used in TX_CTL1*/
#define EMAC_TX_MD
#define EMAC_TX_NEXT_FRM
#define EMAC_TX_TH_MASK
#define EMAC_TX_TH_64
#define EMAC_TX_TH_128
#define EMAC_TX_TH_192
#define EMAC_TX_TH_256
#define EMAC_TX_DMA_EN
#define EMAC_TX_DMA_START

/* Used in RX_CTL0 */
#define EMAC_RX_RECEIVER_EN
#define EMAC_RX_DO_CRC
#define EMAC_RX_FLOW_CTL_EN

/* Used in TX_CTL0 */
#define EMAC_TX_TRANSMITTER_EN

/* Used in EMAC_TX_FLOW_CTL */
#define EMAC_TX_FLOW_CTL_EN

/* Used in EMAC_INT_STA */
#define EMAC_TX_INT
#define EMAC_TX_DMA_STOP_INT
#define EMAC_TX_BUF_UA_INT
#define EMAC_TX_TIMEOUT_INT
#define EMAC_TX_UNDERFLOW_INT
#define EMAC_TX_EARLY_INT
#define EMAC_RX_INT
#define EMAC_RX_BUF_UA_INT
#define EMAC_RX_DMA_STOP_INT
#define EMAC_RX_TIMEOUT_INT
#define EMAC_RX_OVERFLOW_INT
#define EMAC_RX_EARLY_INT
#define EMAC_RGMII_STA_INT

#define EMAC_INT_MSK_COMMON
#define EMAC_INT_MSK_TX
#define EMAC_INT_MSK_RX

#define MAC_ADDR_TYPE_DST

/* H3 specific bits for EPHY */
#define H3_EPHY_ADDR_SHIFT
#define H3_EPHY_CLK_SEL
#define H3_EPHY_LED_POL
#define H3_EPHY_SHUTDOWN
#define H3_EPHY_SELECT
#define H3_EPHY_MUX_MASK
#define DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID
#define DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID

/* H3/A64 specific bits */
#define SYSCON_RMII_EN

/* Generic system control EMAC_CLK bits */
#define SYSCON_ETXDC_SHIFT
#define SYSCON_ERXDC_SHIFT
/* EMAC PHY Interface Type */
#define SYSCON_EPIT
#define SYSCON_ETCS_MASK
#define SYSCON_ETCS_MII
#define SYSCON_ETCS_EXT_GMII
#define SYSCON_ETCS_INT_GMII

/* sun8i_dwmac_dma_reset() - reset the EMAC
 * Called from stmmac via stmmac_dma_ops->reset
 */
static int sun8i_dwmac_dma_reset(void __iomem *ioaddr)
{}

/* sun8i_dwmac_dma_init() - initialize the EMAC
 * Called from stmmac via stmmac_dma_ops->init
 */
static void sun8i_dwmac_dma_init(void __iomem *ioaddr,
				 struct stmmac_dma_cfg *dma_cfg, int atds)
{}

static void sun8i_dwmac_dma_init_rx(struct stmmac_priv *priv,
				    void __iomem *ioaddr,
				    struct stmmac_dma_cfg *dma_cfg,
				    dma_addr_t dma_rx_phy, u32 chan)
{}

static void sun8i_dwmac_dma_init_tx(struct stmmac_priv *priv,
				    void __iomem *ioaddr,
				    struct stmmac_dma_cfg *dma_cfg,
				    dma_addr_t dma_tx_phy, u32 chan)
{}

/* sun8i_dwmac_dump_regs() - Dump EMAC address space
 * Called from stmmac_dma_ops->dump_regs
 * Used for ethtool
 */
static void sun8i_dwmac_dump_regs(struct stmmac_priv *priv,
				  void __iomem *ioaddr, u32 *reg_space)
{}

/* sun8i_dwmac_dump_mac_regs() - Dump EMAC address space
 * Called from stmmac_ops->dump_regs
 * Used for ethtool
 */
static void sun8i_dwmac_dump_mac_regs(struct mac_device_info *hw,
				      u32 *reg_space)
{}

static void sun8i_dwmac_enable_dma_irq(struct stmmac_priv *priv,
				       void __iomem *ioaddr, u32 chan,
				       bool rx, bool tx)
{}

static void sun8i_dwmac_disable_dma_irq(struct stmmac_priv *priv,
					void __iomem *ioaddr, u32 chan,
					bool rx, bool tx)
{}

static void sun8i_dwmac_dma_start_tx(struct stmmac_priv *priv,
				     void __iomem *ioaddr, u32 chan)
{}

static void sun8i_dwmac_enable_dma_transmission(void __iomem *ioaddr)
{}

static void sun8i_dwmac_dma_stop_tx(struct stmmac_priv *priv,
				    void __iomem *ioaddr, u32 chan)
{}

static void sun8i_dwmac_dma_start_rx(struct stmmac_priv *priv,
				     void __iomem *ioaddr, u32 chan)
{}

static void sun8i_dwmac_dma_stop_rx(struct stmmac_priv *priv,
				    void __iomem *ioaddr, u32 chan)
{}

static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
				     void __iomem *ioaddr,
				     struct stmmac_extra_stats *x, u32 chan,
				     u32 dir)
{}

static void sun8i_dwmac_dma_operation_mode_rx(struct stmmac_priv *priv,
					      void __iomem *ioaddr, int mode,
					      u32 channel, int fifosz, u8 qmode)
{}

static void sun8i_dwmac_dma_operation_mode_tx(struct stmmac_priv *priv,
					      void __iomem *ioaddr, int mode,
					      u32 channel, int fifosz, u8 qmode)
{}

static const struct stmmac_dma_ops sun8i_dwmac_dma_ops =;

static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv);

static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
{}

static void sun8i_dwmac_core_init(struct mac_device_info *hw,
				  struct net_device *dev)
{}

static void sun8i_dwmac_set_mac(void __iomem *ioaddr, bool enable)
{}

/* Set MAC address at slot reg_n
 * All slot > 0 need to be enabled with MAC_ADDR_TYPE_DST
 * If addr is NULL, clear the slot
 */
static void sun8i_dwmac_set_umac_addr(struct mac_device_info *hw,
				      const unsigned char *addr,
				      unsigned int reg_n)
{}

static void sun8i_dwmac_get_umac_addr(struct mac_device_info *hw,
				      unsigned char *addr,
				      unsigned int reg_n)
{}

/* caution this function must return non 0 to work */
static int sun8i_dwmac_rx_ipc_enable(struct mac_device_info *hw)
{}

static void sun8i_dwmac_set_filter(struct mac_device_info *hw,
				   struct net_device *dev)
{}

static void sun8i_dwmac_flow_ctrl(struct mac_device_info *hw,
				  unsigned int duplex, unsigned int fc,
				  unsigned int pause_time, u32 tx_cnt)
{}

static int sun8i_dwmac_reset(struct stmmac_priv *priv)
{}

/* Search in mdio-mux node for internal PHY node and get its clk/reset */
static int get_ephy_nodes(struct stmmac_priv *priv)
{}

static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv)
{}

static void sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data *gmac)
{}

/* MDIO multiplexing switch function
 * This function is called by the mdio-mux layer when it thinks the mdio bus
 * multiplexer needs to switch.
 * 'current_child' is the current value of the mux register
 * 'desired_child' is the value of the 'reg' property of the target child MDIO
 * node.
 * The first time this function is called, current_child == -1.
 * If current_child == desired_child, then the mux is already set to the
 * correct bus.
 */
static int mdio_mux_syscon_switch_fn(int current_child, int desired_child,
				     void *data)
{}

static int sun8i_dwmac_register_mdio_mux(struct stmmac_priv *priv)
{}

static int sun8i_dwmac_set_syscon(struct device *dev,
				  struct plat_stmmacenet_data *plat)
{}

static void sun8i_dwmac_unset_syscon(struct sunxi_priv_data *gmac)
{}

static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
{}

static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
{}

static const struct stmmac_ops sun8i_dwmac_ops =;

static struct mac_device_info *sun8i_dwmac_setup(void *ppriv)
{}

static struct regmap *sun8i_dwmac_get_syscon_from_dev(struct device_node *node)
{}

static int sun8i_dwmac_probe(struct platform_device *pdev)
{}

static void sun8i_dwmac_remove(struct platform_device *pdev)
{}

static void sun8i_dwmac_shutdown(struct platform_device *pdev)
{}

static const struct of_device_id sun8i_dwmac_match[] =;
MODULE_DEVICE_TABLE(of, sun8i_dwmac_match);

static struct platform_driver sun8i_dwmac_driver =;
module_platform_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();