linux/drivers/net/ethernet/marvell/mv643xx_eth.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for Marvell Discovery (MV643XX) and Marvell Orion ethernet ports
 * Copyright (C) 2002 Matthew Dharm <[email protected]>
 *
 * Based on the 64360 driver from:
 * Copyright (C) 2002 Rabeeh Khoury <[email protected]>
 *		      Rabeeh Khoury <[email protected]>
 *
 * Copyright (C) 2003 PMC-Sierra, Inc.,
 *	written by Manish Lachwani
 *
 * Copyright (C) 2003 Ralf Baechle <[email protected]>
 *
 * Copyright (C) 2004-2006 MontaVista Software, Inc.
 *			   Dale Farnsworth <[email protected]>
 *
 * Copyright (C) 2004 Steven J. Hill <[email protected]>
 *				     <[email protected]>
 *
 * Copyright (C) 2007-2008 Marvell Semiconductor
 *			   Lennert Buytenhek <[email protected]>
 *
 * Copyright (C) 2013 Michael Stapelberg <[email protected]>
 */

#define pr_fmt(fmt)

#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <net/tso.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/phy.h>
#include <linux/mv643xx_eth.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_net.h>
#include <linux/of_mdio.h>

static char mv643xx_eth_driver_name[] =;
static char mv643xx_eth_driver_version[] =;


/*
 * Registers shared between all ports.
 */
#define PHY_ADDR
#define WINDOW_BASE(w)
#define WINDOW_SIZE(w)
#define WINDOW_REMAP_HIGH(w)
#define WINDOW_BAR_ENABLE
#define WINDOW_PROTECT(w)

/*
 * Main per-port registers.  These live at offset 0x0400 for
 * port #0, 0x0800 for port #1, and 0x0c00 for port #2.
 */
#define PORT_CONFIG
#define UNICAST_PROMISCUOUS_MODE
#define PORT_CONFIG_EXT
#define MAC_ADDR_LOW
#define MAC_ADDR_HIGH
#define SDMA_CONFIG
#define TX_BURST_SIZE_16_64BIT
#define TX_BURST_SIZE_4_64BIT
#define BLM_TX_NO_SWAP
#define BLM_RX_NO_SWAP
#define RX_BURST_SIZE_16_64BIT
#define RX_BURST_SIZE_4_64BIT
#define PORT_SERIAL_CONTROL
#define SET_MII_SPEED_TO_100
#define SET_GMII_SPEED_TO_1000
#define SET_FULL_DUPLEX_MODE
#define MAX_RX_PACKET_9700BYTE
#define DISABLE_AUTO_NEG_SPEED_GMII
#define DO_NOT_FORCE_LINK_FAIL
#define SERIAL_PORT_CONTROL_RESERVED
#define DISABLE_AUTO_NEG_FOR_FLOW_CTRL
#define DISABLE_AUTO_NEG_FOR_DUPLEX
#define FORCE_LINK_PASS
#define SERIAL_PORT_ENABLE
#define PORT_STATUS
#define TX_FIFO_EMPTY
#define TX_IN_PROGRESS
#define PORT_SPEED_MASK
#define PORT_SPEED_1000
#define PORT_SPEED_100
#define PORT_SPEED_10
#define FLOW_CONTROL_ENABLED
#define FULL_DUPLEX
#define LINK_UP
#define TXQ_COMMAND
#define TXQ_FIX_PRIO_CONF
#define PORT_SERIAL_CONTROL1
#define RGMII_EN
#define CLK125_BYPASS_EN
#define TX_BW_RATE
#define TX_BW_MTU
#define TX_BW_BURST
#define INT_CAUSE
#define INT_TX_END
#define INT_TX_END_0
#define INT_RX
#define INT_RX_0
#define INT_EXT
#define INT_CAUSE_EXT
#define INT_EXT_LINK_PHY
#define INT_EXT_TX
#define INT_MASK
#define INT_MASK_EXT
#define TX_FIFO_URGENT_THRESHOLD
#define RX_DISCARD_FRAME_CNT
#define RX_OVERRUN_FRAME_CNT
#define TXQ_FIX_PRIO_CONF_MOVED
#define TX_BW_RATE_MOVED
#define TX_BW_MTU_MOVED
#define TX_BW_BURST_MOVED
#define RXQ_CURRENT_DESC_PTR(q)
#define RXQ_COMMAND
#define TXQ_CURRENT_DESC_PTR(q)
#define TXQ_BW_TOKENS(q)
#define TXQ_BW_CONF(q)
#define TXQ_BW_WRR_CONF(q)

/*
 * Misc per-port registers.
 */
#define MIB_COUNTERS(p)
#define SPECIAL_MCAST_TABLE(p)
#define OTHER_MCAST_TABLE(p)
#define UNICAST_TABLE(p)


/*
 * SDMA configuration register default value.
 */
#if defined(__BIG_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE
#elif defined(__LITTLE_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE
#else
#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
#endif


/*
 * Misc definitions.
 */
#define DEFAULT_RX_QUEUE_SIZE
#define DEFAULT_TX_QUEUE_SIZE
#define SKB_DMA_REALIGN

/* Max number of allowed TCP segments for software TSO */
#define MV643XX_MAX_TSO_SEGS
#define MV643XX_MAX_SKB_DESCS

#define IS_TSO_HEADER(txq, addr)

#define DESC_DMA_MAP_SINGLE
#define DESC_DMA_MAP_PAGE

/*
 * RX/TX descriptors.
 */
#if defined(__BIG_ENDIAN)
struct rx_desc {
	u16 byte_cnt;		/* Descriptor buffer byte count		*/
	u16 buf_size;		/* Buffer size				*/
	u32 cmd_sts;		/* Descriptor command status		*/
	u32 next_desc_ptr;	/* Next descriptor pointer		*/
	u32 buf_ptr;		/* Descriptor buffer pointer		*/
};

struct tx_desc {
	u16 byte_cnt;		/* buffer byte count			*/
	u16 l4i_chk;		/* CPU provided TCP checksum		*/
	u32 cmd_sts;		/* Command/status field			*/
	u32 next_desc_ptr;	/* Pointer to next descriptor		*/
	u32 buf_ptr;		/* pointer to buffer for this descriptor*/
};
#elif defined(__LITTLE_ENDIAN)
struct rx_desc {};

struct tx_desc {};
#else
#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
#endif

/* RX & TX descriptor command */
#define BUFFER_OWNED_BY_DMA

/* RX & TX descriptor status */
#define ERROR_SUMMARY

/* RX descriptor status */
#define LAYER_4_CHECKSUM_OK
#define RX_ENABLE_INTERRUPT
#define RX_FIRST_DESC
#define RX_LAST_DESC
#define RX_IP_HDR_OK
#define RX_PKT_IS_IPV4
#define RX_PKT_IS_ETHERNETV2
#define RX_PKT_LAYER4_TYPE_MASK
#define RX_PKT_LAYER4_TYPE_TCP_IPV4
#define RX_PKT_IS_VLAN_TAGGED

/* TX descriptor command */
#define TX_ENABLE_INTERRUPT
#define GEN_CRC
#define TX_FIRST_DESC
#define TX_LAST_DESC
#define ZERO_PADDING
#define GEN_IP_V4_CHECKSUM
#define GEN_TCP_UDP_CHECKSUM
#define UDP_FRAME
#define MAC_HDR_EXTRA_4_BYTES
#define GEN_TCP_UDP_CHK_FULL
#define MAC_HDR_EXTRA_8_BYTES

#define TX_IHL_SHIFT


/* global *******************************************************************/
struct mv643xx_eth_shared_private {};

#define TX_BW_CONTROL_ABSENT
#define TX_BW_CONTROL_OLD_LAYOUT
#define TX_BW_CONTROL_NEW_LAYOUT

static int mv643xx_eth_open(struct net_device *dev);
static int mv643xx_eth_stop(struct net_device *dev);


/* per-port *****************************************************************/
struct mib_counters {};

struct rx_queue {};

struct tx_queue {};

struct mv643xx_eth_private {};


/* port register accessors **************************************************/
static inline u32 rdl(struct mv643xx_eth_private *mp, int offset)
{}

static inline u32 rdlp(struct mv643xx_eth_private *mp, int offset)
{}

static inline void wrl(struct mv643xx_eth_private *mp, int offset, u32 data)
{}

static inline void wrlp(struct mv643xx_eth_private *mp, int offset, u32 data)
{}


/* rxq/txq helper functions *************************************************/
static struct mv643xx_eth_private *rxq_to_mp(struct rx_queue *rxq)
{}

static struct mv643xx_eth_private *txq_to_mp(struct tx_queue *txq)
{}

static void rxq_enable(struct rx_queue *rxq)
{}

static void rxq_disable(struct rx_queue *rxq)
{}

static void txq_reset_hw_ptr(struct tx_queue *txq)
{}

static void txq_enable(struct tx_queue *txq)
{}

static void txq_disable(struct tx_queue *txq)
{}

static void txq_maybe_wake(struct tx_queue *txq)
{}

static int rxq_process(struct rx_queue *rxq, int budget)
{}

static int rxq_refill(struct rx_queue *rxq, int budget)
{}


/* tx ***********************************************************************/
static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
{}

static int skb_tx_csum(struct mv643xx_eth_private *mp, struct sk_buff *skb,
		       u16 *l4i_chk, u32 *command, int length)
{}

static inline int
txq_put_data_tso(struct net_device *dev, struct tx_queue *txq,
		 struct sk_buff *skb, char *data, int length,
		 bool last_tcp, bool is_last)
{}

static inline void
txq_put_hdr_tso(struct sk_buff *skb, struct tx_queue *txq, int length,
		u32 *first_cmd_sts, bool first_desc)
{}

static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb,
			  struct net_device *dev)
{}

static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb)
{}

static int txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb,
			  struct net_device *dev)
{}

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


/* tx napi ******************************************************************/
static void txq_kick(struct tx_queue *txq)
{}

static int txq_reclaim(struct tx_queue *txq, int budget, int force)
{}


/* tx rate control **********************************************************/
/*
 * Set total maximum TX rate (shared by all TX queues for this port)
 * to 'rate' bits per second, with a maximum burst of 'burst' bytes.
 */
static void tx_set_rate(struct mv643xx_eth_private *mp, int rate, int burst)
{}

static void txq_set_rate(struct tx_queue *txq, int rate, int burst)
{}

static void txq_set_fixed_prio_mode(struct tx_queue *txq)
{}


/* mii management interface *************************************************/
static void mv643xx_eth_adjust_link(struct net_device *dev)
{}

/* statistics ***************************************************************/
static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)
{}

static inline u32 mib_read(struct mv643xx_eth_private *mp, int offset)
{}

static void mib_counters_clear(struct mv643xx_eth_private *mp)
{}

static void mib_counters_update(struct mv643xx_eth_private *mp)
{}

static void mib_counters_timer_wrapper(struct timer_list *t)
{}


/* interrupt coalescing *****************************************************/
/*
 * Hardware coalescing parameters are set in units of 64 t_clk
 * cycles.  I.e.:
 *
 *	coal_delay_in_usec = 64000000 * register_value / t_clk_rate
 *
 *	register_value = coal_delay_in_usec * t_clk_rate / 64000000
 *
 * In the ->set*() methods, we round the computed register value
 * to the nearest integer.
 */
static unsigned int get_rx_coal(struct mv643xx_eth_private *mp)
{}

static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int usec)
{}

static unsigned int get_tx_coal(struct mv643xx_eth_private *mp)
{}

static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int usec)
{}


/* ethtool ******************************************************************/
struct mv643xx_eth_stats {};

#define SSTAT(m)

#define MIBSTAT(m)

static const struct mv643xx_eth_stats mv643xx_eth_stats[] =;

static int
mv643xx_eth_get_link_ksettings_phy(struct mv643xx_eth_private *mp,
				   struct ethtool_link_ksettings *cmd)
{}

static int
mv643xx_eth_get_link_ksettings_phyless(struct mv643xx_eth_private *mp,
				       struct ethtool_link_ksettings *cmd)
{}

static void
mv643xx_eth_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{}

static int
mv643xx_eth_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{}

static int
mv643xx_eth_get_link_ksettings(struct net_device *dev,
			       struct ethtool_link_ksettings *cmd)
{}

static int
mv643xx_eth_set_link_ksettings(struct net_device *dev,
			       const struct ethtool_link_ksettings *cmd)
{}

static void mv643xx_eth_get_drvinfo(struct net_device *dev,
				    struct ethtool_drvinfo *drvinfo)
{}

static int mv643xx_eth_get_coalesce(struct net_device *dev,
				    struct ethtool_coalesce *ec,
				    struct kernel_ethtool_coalesce *kernel_coal,
				    struct netlink_ext_ack *extack)
{}

static int mv643xx_eth_set_coalesce(struct net_device *dev,
				    struct ethtool_coalesce *ec,
				    struct kernel_ethtool_coalesce *kernel_coal,
				    struct netlink_ext_ack *extack)
{}

static void
mv643xx_eth_get_ringparam(struct net_device *dev, struct ethtool_ringparam *er,
			  struct kernel_ethtool_ringparam *kernel_er,
			  struct netlink_ext_ack *extack)
{}

static int
mv643xx_eth_set_ringparam(struct net_device *dev, struct ethtool_ringparam *er,
			  struct kernel_ethtool_ringparam *kernel_er,
			  struct netlink_ext_ack *extack)
{}


static int
mv643xx_eth_set_features(struct net_device *dev, netdev_features_t features)
{}

static void mv643xx_eth_get_strings(struct net_device *dev,
				    uint32_t stringset, uint8_t *data)
{}

static void mv643xx_eth_get_ethtool_stats(struct net_device *dev,
					  struct ethtool_stats *stats,
					  uint64_t *data)
{}

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

static const struct ethtool_ops mv643xx_eth_ethtool_ops =;


/* address handling *********************************************************/
static void uc_addr_get(struct mv643xx_eth_private *mp, unsigned char *addr)
{}

static void uc_addr_set(struct mv643xx_eth_private *mp, const u8 *addr)
{}

static u32 uc_addr_filter_mask(struct net_device *dev)
{}

static void mv643xx_eth_program_unicast_filter(struct net_device *dev)
{}

static int addr_crc(unsigned char *addr)
{}

static void mv643xx_eth_program_multicast_filter(struct net_device *dev)
{}

static void mv643xx_eth_set_rx_mode(struct net_device *dev)
{}

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


/* rx/tx queue initialisation ***********************************************/
static int rxq_init(struct mv643xx_eth_private *mp, int index)
{}

static void rxq_deinit(struct rx_queue *rxq)
{}

static int txq_init(struct mv643xx_eth_private *mp, int index)
{}

static void txq_deinit(struct tx_queue *txq)
{}


/* netdev ops and related ***************************************************/
static int mv643xx_eth_collect_events(struct mv643xx_eth_private *mp)
{}

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

static void handle_link_event(struct mv643xx_eth_private *mp)
{}

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

static inline void oom_timer_wrapper(struct timer_list *t)
{}

static void port_start(struct mv643xx_eth_private *mp)
{}

static void mv643xx_eth_recalc_skb_size(struct mv643xx_eth_private *mp)
{}

static int mv643xx_eth_open(struct net_device *dev)
{}

static void port_reset(struct mv643xx_eth_private *mp)
{}

static int mv643xx_eth_stop(struct net_device *dev)
{}

static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{}

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

static void tx_timeout_task(struct work_struct *ugly)
{}

static void mv643xx_eth_tx_timeout(struct net_device *dev, unsigned int txqueue)
{}

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


/* platform glue ************************************************************/
static void
mv643xx_eth_conf_mbus_windows(struct mv643xx_eth_shared_private *msp,
			      const struct mbus_dram_target_info *dram)
{}

static void infer_hw_params(struct mv643xx_eth_shared_private *msp)
{}

#if defined(CONFIG_OF)
static const struct of_device_id mv643xx_eth_shared_ids[] =;
MODULE_DEVICE_TABLE(of, mv643xx_eth_shared_ids);
#endif

#ifdef CONFIG_OF_IRQ
#define mv643xx_eth_property(_np, _name, _v)

static struct platform_device *port_platdev[3];

static void mv643xx_eth_shared_of_remove(void)
{}

static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev,
					  struct device_node *pnp)
{}

static int mv643xx_eth_shared_of_probe(struct platform_device *pdev)
{}

#else
static inline int mv643xx_eth_shared_of_probe(struct platform_device *pdev)
{
	return 0;
}

static inline void mv643xx_eth_shared_of_remove(void)
{
}
#endif

static int mv643xx_eth_shared_probe(struct platform_device *pdev)
{}

static void mv643xx_eth_shared_remove(struct platform_device *pdev)
{}

static struct platform_driver mv643xx_eth_shared_driver =;

static void phy_addr_set(struct mv643xx_eth_private *mp, int phy_addr)
{}

static int phy_addr_get(struct mv643xx_eth_private *mp)
{}

static void set_params(struct mv643xx_eth_private *mp,
		       struct mv643xx_eth_platform_data *pd)
{}

static int get_phy_mode(struct mv643xx_eth_private *mp)
{}

static struct phy_device *phy_scan(struct mv643xx_eth_private *mp,
				   int phy_addr)
{}

static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)
{}

static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
{}

static const struct net_device_ops mv643xx_eth_netdev_ops =;

static int mv643xx_eth_probe(struct platform_device *pdev)
{}

static void mv643xx_eth_remove(struct platform_device *pdev)
{}

static void mv643xx_eth_shutdown(struct platform_device *pdev)
{}

static struct platform_driver mv643xx_eth_driver =;

static struct platform_driver * const drivers[] =;

static int __init mv643xx_eth_init_module(void)
{}
module_init();

static void __exit mv643xx_eth_cleanup_module(void)
{}
module_exit(mv643xx_eth_cleanup_module);

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