linux/drivers/net/ethernet/cadence/macb_main.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Cadence MACB/GEM Ethernet Controller driver
 *
 * Copyright (C) 2004-2006 Atmel Corporation
 */

#define pr_fmt(fmt)
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/crc32.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/circ_buf.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/phylink.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/iopoll.h>
#include <linux/phy/phy.h>
#include <linux/pm_runtime.h>
#include <linux/ptp_classify.h>
#include <linux/reset.h>
#include <linux/firmware/xlnx-zynqmp.h>
#include <linux/inetdevice.h>
#include "macb.h"

/* This structure is only used for MACB on SiFive FU540 devices */
struct sifive_fu540_macb_mgmt {};

#define MACB_RX_BUFFER_SIZE
#define RX_BUFFER_MULTIPLE

#define DEFAULT_RX_RING_SIZE
#define MIN_RX_RING_SIZE
#define MAX_RX_RING_SIZE
#define RX_RING_BYTES(bp)

#define DEFAULT_TX_RING_SIZE
#define MIN_TX_RING_SIZE
#define MAX_TX_RING_SIZE
#define TX_RING_BYTES(bp)

/* level of occupied TX descriptors under which we wake up TX process */
#define MACB_TX_WAKEUP_THRESH(bp)

#define MACB_RX_INT_FLAGS
#define MACB_TX_ERR_FLAGS
#define MACB_TX_INT_FLAGS

/* Max length of transmit frame must be a multiple of 8 bytes */
#define MACB_TX_LEN_ALIGN
#define MACB_MAX_TX_LEN
/* Limit maximum TX length as per Cadence TSO errata. This is to avoid a
 * false amba_error in TX path from the DMA assuming there is not enough
 * space in the SRAM (16KB) even when there is.
 */
#define GEM_MAX_TX_LEN

#define GEM_MTU_MIN_SIZE
#define MACB_NETIF_LSO

#define MACB_WOL_ENABLED

#define HS_SPEED_10000M
#define MACB_SERDES_RATE_10G

/* Graceful stop timeouts in us. We should allow up to
 * 1 frame time (10 Mbits/s, full-duplex, ignoring collisions)
 */
#define MACB_HALT_TIMEOUT
#define MACB_PM_TIMEOUT

#define MACB_MDIO_TIMEOUT

/* DMA buffer descriptor might be different size
 * depends on hardware configuration:
 *
 * 1. dma address width 32 bits:
 *    word 1: 32 bit address of Data Buffer
 *    word 2: control
 *
 * 2. dma address width 64 bits:
 *    word 1: 32 bit address of Data Buffer
 *    word 2: control
 *    word 3: upper 32 bit address of Data Buffer
 *    word 4: unused
 *
 * 3. dma address width 32 bits with hardware timestamping:
 *    word 1: 32 bit address of Data Buffer
 *    word 2: control
 *    word 3: timestamp word 1
 *    word 4: timestamp word 2
 *
 * 4. dma address width 64 bits with hardware timestamping:
 *    word 1: 32 bit address of Data Buffer
 *    word 2: control
 *    word 3: upper 32 bit address of Data Buffer
 *    word 4: unused
 *    word 5: timestamp word 1
 *    word 6: timestamp word 2
 */
static unsigned int macb_dma_desc_get_size(struct macb *bp)
{}

static unsigned int macb_adj_dma_desc_idx(struct macb *bp, unsigned int desc_idx)
{}

#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
static struct macb_dma_desc_64 *macb_64b_desc(struct macb *bp, struct macb_dma_desc *desc)
{}
#endif

/* Ring buffer accessors */
static unsigned int macb_tx_ring_wrap(struct macb *bp, unsigned int index)
{}

static struct macb_dma_desc *macb_tx_desc(struct macb_queue *queue,
					  unsigned int index)
{}

static struct macb_tx_skb *macb_tx_skb(struct macb_queue *queue,
				       unsigned int index)
{}

static dma_addr_t macb_tx_dma(struct macb_queue *queue, unsigned int index)
{}

static unsigned int macb_rx_ring_wrap(struct macb *bp, unsigned int index)
{}

static struct macb_dma_desc *macb_rx_desc(struct macb_queue *queue, unsigned int index)
{}

static void *macb_rx_buffer(struct macb_queue *queue, unsigned int index)
{}

/* I/O accessors */
static u32 hw_readl_native(struct macb *bp, int offset)
{}

static void hw_writel_native(struct macb *bp, int offset, u32 value)
{}

static u32 hw_readl(struct macb *bp, int offset)
{}

static void hw_writel(struct macb *bp, int offset, u32 value)
{}

/* Find the CPU endianness by using the loopback bit of NCR register. When the
 * CPU is in big endian we need to program swapped mode for management
 * descriptor access.
 */
static bool hw_is_native_io(void __iomem *addr)
{}

static bool hw_is_gem(void __iomem *addr, bool native_io)
{}

static void macb_set_hwaddr(struct macb *bp)
{}

static void macb_get_hwaddr(struct macb *bp)
{}

static int macb_mdio_wait_for_idle(struct macb *bp)
{}

static int macb_mdio_read_c22(struct mii_bus *bus, int mii_id, int regnum)
{}

static int macb_mdio_read_c45(struct mii_bus *bus, int mii_id, int devad,
			      int regnum)
{}

static int macb_mdio_write_c22(struct mii_bus *bus, int mii_id, int regnum,
			       u16 value)
{}

static int macb_mdio_write_c45(struct mii_bus *bus, int mii_id,
			       int devad, int regnum,
			       u16 value)
{}

static void macb_init_buffers(struct macb *bp)
{}

/**
 * macb_set_tx_clk() - Set a clock to a new frequency
 * @bp:		pointer to struct macb
 * @speed:	New frequency in Hz
 */
static void macb_set_tx_clk(struct macb *bp, int speed)
{}

static void macb_usx_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
				 phy_interface_t interface, int speed,
				 int duplex)
{}

static void macb_usx_pcs_get_state(struct phylink_pcs *pcs,
				   struct phylink_link_state *state)
{}

static int macb_usx_pcs_config(struct phylink_pcs *pcs,
			       unsigned int neg_mode,
			       phy_interface_t interface,
			       const unsigned long *advertising,
			       bool permit_pause_to_mac)
{}

static void macb_pcs_get_state(struct phylink_pcs *pcs,
			       struct phylink_link_state *state)
{}

static void macb_pcs_an_restart(struct phylink_pcs *pcs)
{}

static int macb_pcs_config(struct phylink_pcs *pcs,
			   unsigned int neg_mode,
			   phy_interface_t interface,
			   const unsigned long *advertising,
			   bool permit_pause_to_mac)
{}

static const struct phylink_pcs_ops macb_phylink_usx_pcs_ops =;

static const struct phylink_pcs_ops macb_phylink_pcs_ops =;

static void macb_mac_config(struct phylink_config *config, unsigned int mode,
			    const struct phylink_link_state *state)
{}

static void macb_mac_link_down(struct phylink_config *config, unsigned int mode,
			       phy_interface_t interface)
{}

static void macb_mac_link_up(struct phylink_config *config,
			     struct phy_device *phy,
			     unsigned int mode, phy_interface_t interface,
			     int speed, int duplex,
			     bool tx_pause, bool rx_pause)
{}

static struct phylink_pcs *macb_mac_select_pcs(struct phylink_config *config,
					       phy_interface_t interface)
{}

static const struct phylink_mac_ops macb_phylink_ops =;

static bool macb_phy_handle_exists(struct device_node *dn)
{}

static int macb_phylink_connect(struct macb *bp)
{}

static void macb_get_pcs_fixed_state(struct phylink_config *config,
				     struct phylink_link_state *state)
{}

/* based on au1000_eth. c*/
static int macb_mii_probe(struct net_device *dev)
{}

static int macb_mdiobus_register(struct macb *bp)
{}

static int macb_mii_init(struct macb *bp)
{}

static void macb_update_stats(struct macb *bp)
{}

static int macb_halt_tx(struct macb *bp)
{}

static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb, int budget)
{}

static void macb_set_addr(struct macb *bp, struct macb_dma_desc *desc, dma_addr_t addr)
{}

static dma_addr_t macb_get_addr(struct macb *bp, struct macb_dma_desc *desc)
{}

static void macb_tx_error_task(struct work_struct *work)
{}

static bool ptp_one_step_sync(struct sk_buff *skb)
{}

static int macb_tx_complete(struct macb_queue *queue, int budget)
{}

static void gem_rx_refill(struct macb_queue *queue)
{}

/* Mark DMA descriptors from begin up to and not including end as unused */
static void discard_partial_frame(struct macb_queue *queue, unsigned int begin,
				  unsigned int end)
{}

static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,
		  int budget)
{}

static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,
			 unsigned int first_frag, unsigned int last_frag)
{}

static inline void macb_init_rx_ring(struct macb_queue *queue)
{}

static int macb_rx(struct macb_queue *queue, struct napi_struct *napi,
		   int budget)
{}

static bool macb_rx_pending(struct macb_queue *queue)
{}

static int macb_rx_poll(struct napi_struct *napi, int budget)
{}

static void macb_tx_restart(struct macb_queue *queue)
{}

static bool macb_tx_complete_pending(struct macb_queue *queue)
{}

static int macb_tx_poll(struct napi_struct *napi, int budget)
{}

static void macb_hresp_error_task(struct tasklet_struct *t)
{}

static irqreturn_t macb_wol_interrupt(int irq, void *dev_id)
{}

static irqreturn_t gem_wol_interrupt(int irq, void *dev_id)
{}

static irqreturn_t macb_interrupt(int irq, void *dev_id)
{}

#ifdef CONFIG_NET_POLL_CONTROLLER
/* Polling receive - used by netconsole and other diagnostic tools
 * to allow network i/o with interrupts disabled.
 */
static void macb_poll_controller(struct net_device *dev)
{}
#endif

static unsigned int macb_tx_map(struct macb *bp,
				struct macb_queue *queue,
				struct sk_buff *skb,
				unsigned int hdrlen)
{}

static netdev_features_t macb_features_check(struct sk_buff *skb,
					     struct net_device *dev,
					     netdev_features_t features)
{}

static inline int macb_clear_csum(struct sk_buff *skb)
{}

static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
{}

static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
{}

static void macb_init_rx_buffer_size(struct macb *bp, size_t size)
{}

static void gem_free_rx_buffers(struct macb *bp)
{}

static void macb_free_rx_buffers(struct macb *bp)
{}

static void macb_free_consistent(struct macb *bp)
{}

static int gem_alloc_rx_buffers(struct macb *bp)
{}

static int macb_alloc_rx_buffers(struct macb *bp)
{}

static int macb_alloc_consistent(struct macb *bp)
{}

static void macb_init_tieoff(struct macb *bp)
{}

static void gem_init_rings(struct macb *bp)
{}

static void macb_init_rings(struct macb *bp)
{}

static void macb_reset_hw(struct macb *bp)
{}

static u32 gem_mdc_clk_div(struct macb *bp)
{}

static u32 macb_mdc_clk_div(struct macb *bp)
{}

/* Get the DMA bus width field of the network configuration register that we
 * should program.  We find the width from decoding the design configuration
 * register to find the maximum supported data bus width.
 */
static u32 macb_dbw(struct macb *bp)
{}

/* Configure the receive DMA engine
 * - use the correct receive buffer size
 * - set best burst length for DMA operations
 *   (if not supported by FIFO, it will fallback to default)
 * - set both rx/tx packet buffers to full memory size
 * These are configurable parameters for GEM.
 */
static void macb_configure_dma(struct macb *bp)
{}

static void macb_init_hw(struct macb *bp)
{}

/* The hash address register is 64 bits long and takes up two
 * locations in the memory map.  The least significant bits are stored
 * in EMAC_HSL and the most significant bits in EMAC_HSH.
 *
 * The unicast hash enable and the multicast hash enable bits in the
 * network configuration register enable the reception of hash matched
 * frames. The destination address is reduced to a 6 bit index into
 * the 64 bit hash register using the following hash function.  The
 * hash function is an exclusive or of every sixth bit of the
 * destination address.
 *
 * hi[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47]
 * hi[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46]
 * hi[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45]
 * hi[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44]
 * hi[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43]
 * hi[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42]
 *
 * da[0] represents the least significant bit of the first byte
 * received, that is, the multicast/unicast indicator, and da[47]
 * represents the most significant bit of the last byte received.  If
 * the hash index, hi[n], points to a bit that is set in the hash
 * register then the frame will be matched according to whether the
 * frame is multicast or unicast.  A multicast match will be signalled
 * if the multicast hash enable bit is set, da[0] is 1 and the hash
 * index points to a bit set in the hash register.  A unicast match
 * will be signalled if the unicast hash enable bit is set, da[0] is 0
 * and the hash index points to a bit set in the hash register.  To
 * receive all multicast frames, the hash register should be set with
 * all ones and the multicast hash enable bit should be set in the
 * network configuration register.
 */

static inline int hash_bit_value(int bitnr, __u8 *addr)
{}

/* Return the hash index value for the specified address. */
static int hash_get_index(__u8 *addr)
{}

/* Add multicast addresses to the internal multicast-hash table. */
static void macb_sethashtable(struct net_device *dev)
{}

/* Enable/Disable promiscuous and multicast modes. */
static void macb_set_rx_mode(struct net_device *dev)
{}

static int macb_open(struct net_device *dev)
{}

static int macb_close(struct net_device *dev)
{}

static int macb_change_mtu(struct net_device *dev, int new_mtu)
{}

static int macb_set_mac_addr(struct net_device *dev, void *addr)
{}

static void gem_update_stats(struct macb *bp)
{}

static struct net_device_stats *gem_get_stats(struct macb *bp)
{}

static void gem_get_ethtool_stats(struct net_device *dev,
				  struct ethtool_stats *stats, u64 *data)
{}

static int gem_get_sset_count(struct net_device *dev, int sset)
{}

static void gem_get_ethtool_strings(struct net_device *dev, u32 sset, u8 *p)
{}

static struct net_device_stats *macb_get_stats(struct net_device *dev)
{}

static int macb_get_regs_len(struct net_device *netdev)
{}

static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,
			  void *p)
{}

static void macb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{}

static int macb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{}

static int macb_get_link_ksettings(struct net_device *netdev,
				   struct ethtool_link_ksettings *kset)
{}

static int macb_set_link_ksettings(struct net_device *netdev,
				   const struct ethtool_link_ksettings *kset)
{}

static void macb_get_ringparam(struct net_device *netdev,
			       struct ethtool_ringparam *ring,
			       struct kernel_ethtool_ringparam *kernel_ring,
			       struct netlink_ext_ack *extack)
{}

static int macb_set_ringparam(struct net_device *netdev,
			      struct ethtool_ringparam *ring,
			      struct kernel_ethtool_ringparam *kernel_ring,
			      struct netlink_ext_ack *extack)
{}

#ifdef CONFIG_MACB_USE_HWSTAMP
static unsigned int gem_get_tsu_rate(struct macb *bp)
{}

static s32 gem_get_ptp_max_adj(void)
{}

static int gem_get_ts_info(struct net_device *dev,
			   struct kernel_ethtool_ts_info *info)
{}

static struct macb_ptp_info gem_ptp_info =;
#endif

static int macb_get_ts_info(struct net_device *netdev,
			    struct kernel_ethtool_ts_info *info)
{}

static void gem_enable_flow_filters(struct macb *bp, bool enable)
{}

static void gem_prog_cmp_regs(struct macb *bp, struct ethtool_rx_flow_spec *fs)
{}

static int gem_add_flow_filter(struct net_device *netdev,
		struct ethtool_rxnfc *cmd)
{}

static int gem_del_flow_filter(struct net_device *netdev,
		struct ethtool_rxnfc *cmd)
{}

static int gem_get_flow_entry(struct net_device *netdev,
		struct ethtool_rxnfc *cmd)
{}

static int gem_get_all_flow_entries(struct net_device *netdev,
		struct ethtool_rxnfc *cmd, u32 *rule_locs)
{}

static int gem_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
		u32 *rule_locs)
{}

static int gem_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
{}

static const struct ethtool_ops macb_ethtool_ops =;

static const struct ethtool_ops gem_ethtool_ops =;

static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{}

static int macb_hwtstamp_get(struct net_device *dev,
			     struct kernel_hwtstamp_config *cfg)
{}

static int macb_hwtstamp_set(struct net_device *dev,
			     struct kernel_hwtstamp_config *cfg,
			     struct netlink_ext_ack *extack)
{}

static inline void macb_set_txcsum_feature(struct macb *bp,
					   netdev_features_t features)
{}

static inline void macb_set_rxcsum_feature(struct macb *bp,
					   netdev_features_t features)
{}

static inline void macb_set_rxflow_feature(struct macb *bp,
					   netdev_features_t features)
{}

static int macb_set_features(struct net_device *netdev,
			     netdev_features_t features)
{}

static void macb_restore_features(struct macb *bp)
{}

static const struct net_device_ops macb_netdev_ops =;

/* Configure peripheral capabilities according to device tree
 * and integration options used
 */
static void macb_configure_caps(struct macb *bp,
				const struct macb_config *dt_conf)
{}

static void macb_probe_queues(void __iomem *mem,
			      bool native_io,
			      unsigned int *queue_mask,
			      unsigned int *num_queues)
{}

static void macb_clks_disable(struct clk *pclk, struct clk *hclk, struct clk *tx_clk,
			      struct clk *rx_clk, struct clk *tsu_clk)
{}

static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
			 struct clk **hclk, struct clk **tx_clk,
			 struct clk **rx_clk, struct clk **tsu_clk)
{}

static int macb_init(struct platform_device *pdev)
{}

static const struct macb_usrio_config macb_default_usrio =;

#if defined(CONFIG_OF)
/* 1518 rounded up */
#define AT91ETHER_MAX_RBUFF_SZ
/* max number of receive buffers */
#define AT91ETHER_MAX_RX_DESCR

static struct sifive_fu540_macb_mgmt *mgmt;

static int at91ether_alloc_coherent(struct macb *lp)
{}

static void at91ether_free_coherent(struct macb *lp)
{}

/* Initialize and start the Receiver and Transmit subsystems */
static int at91ether_start(struct macb *lp)
{}

static void at91ether_stop(struct macb *lp)
{}

/* Open the ethernet interface */
static int at91ether_open(struct net_device *dev)
{}

/* Close the interface */
static int at91ether_close(struct net_device *dev)
{}

/* Transmit packet */
static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb,
					struct net_device *dev)
{}

/* Extract received frame from buffer descriptors and sent to upper layers.
 * (Called from interrupt context)
 */
static void at91ether_rx(struct net_device *dev)
{}

/* MAC interrupt handler */
static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
{}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void at91ether_poll_controller(struct net_device *dev)
{}
#endif

static const struct net_device_ops at91ether_netdev_ops =;

static int at91ether_clk_init(struct platform_device *pdev, struct clk **pclk,
			      struct clk **hclk, struct clk **tx_clk,
			      struct clk **rx_clk, struct clk **tsu_clk)
{}

static int at91ether_init(struct platform_device *pdev)
{}

static unsigned long fu540_macb_tx_recalc_rate(struct clk_hw *hw,
					       unsigned long parent_rate)
{}

static long fu540_macb_tx_round_rate(struct clk_hw *hw, unsigned long rate,
				     unsigned long *parent_rate)
{}

static int fu540_macb_tx_set_rate(struct clk_hw *hw, unsigned long rate,
				  unsigned long parent_rate)
{}

static const struct clk_ops fu540_c000_ops =;

static int fu540_c000_clk_init(struct platform_device *pdev, struct clk **pclk,
			       struct clk **hclk, struct clk **tx_clk,
			       struct clk **rx_clk, struct clk **tsu_clk)
{}

static int fu540_c000_init(struct platform_device *pdev)
{}

static int init_reset_optional(struct platform_device *pdev)
{}

static const struct macb_usrio_config sama7g5_usrio =;

static const struct macb_config fu540_c000_config =;

static const struct macb_config at91sam9260_config =;

static const struct macb_config sama5d3macb_config =;

static const struct macb_config pc302gem_config =;

static const struct macb_config sama5d2_config =;

static const struct macb_config sama5d29_config =;

static const struct macb_config sama5d3_config =;

static const struct macb_config sama5d4_config =;

static const struct macb_config emac_config =;

static const struct macb_config np4_config =;

static const struct macb_config zynqmp_config =;

static const struct macb_config zynq_config =;

static const struct macb_config mpfs_config =;

static const struct macb_config sama7g5_gem_config =;

static const struct macb_config sama7g5_emac_config =;

static const struct macb_config versal_config =;

static const struct of_device_id macb_dt_ids[] =;
MODULE_DEVICE_TABLE(of, macb_dt_ids);
#endif /* CONFIG_OF */

static const struct macb_config default_gem_config =;

static int macb_probe(struct platform_device *pdev)
{}

static void macb_remove(struct platform_device *pdev)
{}

static int __maybe_unused macb_suspend(struct device *dev)
{}

static int __maybe_unused macb_resume(struct device *dev)
{}

static int __maybe_unused macb_runtime_suspend(struct device *dev)
{}

static int __maybe_unused macb_runtime_resume(struct device *dev)
{}

static const struct dev_pm_ops macb_pm_ops =;

static struct platform_driver macb_driver =;

module_platform_driver();

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