linux/drivers/net/ethernet/renesas/sh_eth.c

// SPDX-License-Identifier: GPL-2.0
/*  SuperH Ethernet device driver
 *
 *  Copyright (C) 2014 Renesas Electronics Corporation
 *  Copyright (C) 2006-2012 Nobuhiro Iwamatsu
 *  Copyright (C) 2008-2014 Renesas Solutions Corp.
 *  Copyright (C) 2013-2017 Cogent Embedded, Inc.
 *  Copyright (C) 2014 Codethink Limited
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/mdio-bitbang.h>
#include <linux/netdevice.h>
#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/phy.h>
#include <linux/cache.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/sh_eth.h>
#include <linux/of_mdio.h>

#include "sh_eth.h"

#define SH_ETH_DEF_MSG_ENABLE

#define SH_ETH_OFFSET_INVALID

#define SH_ETH_OFFSET_DEFAULTS

/* use some intentionally tricky logic here to initialize the whole struct to
 * 0xffff, but then override certain fields, requiring us to indicate that we
 * "know" that there are overrides in this structure, and we'll need to disable
 * that warning from W=1 builds. GCC has supported this option since 4.2.X, but
 * the macros available to do this only define GCC 8.
 */
__diag_push();
__diag_ignore_all("-Woverride-init",
	      "logic to initialize all and then override some is OK");
static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] =;

static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] =;

static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] =;

static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] =;
__diag_pop();

static void sh_eth_rcv_snd_disable(struct net_device *ndev);
static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev);

static void sh_eth_write(struct net_device *ndev, u32 data, int enum_index)
{}

static u32 sh_eth_read(struct net_device *ndev, int enum_index)
{}

static void sh_eth_modify(struct net_device *ndev, int enum_index, u32 clear,
			  u32 set)
{}

static u16 sh_eth_tsu_get_offset(struct sh_eth_private *mdp, int enum_index)
{}

static void sh_eth_tsu_write(struct sh_eth_private *mdp, u32 data,
			     int enum_index)
{}

static u32 sh_eth_tsu_read(struct sh_eth_private *mdp, int enum_index)
{}

static void sh_eth_soft_swap(char *src, int len)
{}

static void sh_eth_select_mii(struct net_device *ndev)
{}

static void sh_eth_set_duplex(struct net_device *ndev)
{}

static void sh_eth_chip_reset(struct net_device *ndev)
{}

static int sh_eth_soft_reset(struct net_device *ndev)
{}

static int sh_eth_check_soft_reset(struct net_device *ndev)
{}

static int sh_eth_soft_reset_gether(struct net_device *ndev)
{}

static void sh_eth_set_rate_gether(struct net_device *ndev)
{}

#ifdef CONFIG_OF
/* R7S72100 */
static struct sh_eth_cpu_data r7s72100_data =;

static void sh_eth_chip_reset_r8a7740(struct net_device *ndev)
{}

/* R8A7740 */
static struct sh_eth_cpu_data r8a7740_data =;

/* There is CPU dependent code */
static void sh_eth_set_rate_rcar(struct net_device *ndev)
{}

/* R-Car Gen1 */
static struct sh_eth_cpu_data rcar_gen1_data =;

/* R-Car Gen2 and RZ/G1 */
static struct sh_eth_cpu_data rcar_gen2_data =;

/* R8A77980 */
static struct sh_eth_cpu_data r8a77980_data =;

/* R7S9210 */
static struct sh_eth_cpu_data r7s9210_data =;
#endif /* CONFIG_OF */

static void sh_eth_set_rate_sh7724(struct net_device *ndev)
{}

/* SH7724 */
static struct sh_eth_cpu_data sh7724_data =;

static void sh_eth_set_rate_sh7757(struct net_device *ndev)
{}

/* SH7757 */
static struct sh_eth_cpu_data sh7757_data =;

#define SH_GIGA_ETH_BASE
#define GIGA_MALR(port)
#define GIGA_MAHR(port)
static void sh_eth_chip_reset_giga(struct net_device *ndev)
{}

static void sh_eth_set_rate_giga(struct net_device *ndev)
{}

/* SH7757(GETHERC) */
static struct sh_eth_cpu_data sh7757_data_giga =;

/* SH7734 */
static struct sh_eth_cpu_data sh7734_data =;

/* SH7763 */
static struct sh_eth_cpu_data sh7763_data =;

static struct sh_eth_cpu_data sh7619_data =;

static struct sh_eth_cpu_data sh771x_data =;

static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
{}

static void sh_eth_set_receive_align(struct sk_buff *skb)
{}

/* Program the hardware MAC address from dev->dev_addr. */
static void update_mac_address(struct net_device *ndev)
{}

/* Get MAC address from SuperH MAC address register
 *
 * SuperH's Ethernet device doesn't have 'ROM' to MAC address.
 * This driver get MAC address that use by bootloader(U-boot or sh-ipl+g).
 * When you want use this device, you must set MAC address in bootloader.
 *
 */
static void read_mac_address(struct net_device *ndev, unsigned char *mac)
{}

struct bb_info {};

static void sh_mdio_ctrl(struct mdiobb_ctrl *ctrl, u32 mask, int set)
{}

/* Data I/O pin control */
static void sh_mmd_ctrl(struct mdiobb_ctrl *ctrl, int bit)
{}

/* Set bit data*/
static void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit)
{}

/* Get bit data*/
static int sh_get_mdio(struct mdiobb_ctrl *ctrl)
{}

/* MDC pin control */
static void sh_mdc_ctrl(struct mdiobb_ctrl *ctrl, int bit)
{}

/* mdio bus control struct */
static const struct mdiobb_ops bb_ops =;

/* free Tx skb function */
static int sh_eth_tx_free(struct net_device *ndev, bool sent_only)
{}

/* free skb and descriptor buffer */
static void sh_eth_ring_free(struct net_device *ndev)
{}

/* format skb and descriptor buffer */
static void sh_eth_ring_format(struct net_device *ndev)
{}

/* Get skb and descriptor buffer */
static int sh_eth_ring_init(struct net_device *ndev)
{}

static int sh_eth_dev_init(struct net_device *ndev)
{}

static void sh_eth_dev_exit(struct net_device *ndev)
{}

static void sh_eth_rx_csum(struct sk_buff *skb)
{}

/* Packet receive function */
static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
{}

static void sh_eth_rcv_snd_disable(struct net_device *ndev)
{}

static void sh_eth_rcv_snd_enable(struct net_device *ndev)
{}

/* E-MAC interrupt handler */
static void sh_eth_emac_interrupt(struct net_device *ndev)
{}

/* error control function */
static void sh_eth_error(struct net_device *ndev, u32 intr_status)
{}

static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
{}

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

/* PHY state control function */
static void sh_eth_adjust_link(struct net_device *ndev)
{}

/* PHY init function */
static int sh_eth_phy_init(struct net_device *ndev)
{}

/* PHY control start function */
static int sh_eth_phy_start(struct net_device *ndev)
{}

/* If it is ever necessary to increase SH_ETH_REG_DUMP_MAX_REGS, the
 * version must be bumped as well.  Just adding registers up to that
 * limit is fine, as long as the existing register indices don't
 * change.
 */
#define SH_ETH_REG_DUMP_VERSION
#define SH_ETH_REG_DUMP_MAX_REGS

static size_t __sh_eth_get_regs(struct net_device *ndev, u32 *buf)
{}

static int sh_eth_get_regs_len(struct net_device *ndev)
{}

static void sh_eth_get_regs(struct net_device *ndev, struct ethtool_regs *regs,
			    void *buf)
{}

static u32 sh_eth_get_msglevel(struct net_device *ndev)
{}

static void sh_eth_set_msglevel(struct net_device *ndev, u32 value)
{}

static const char sh_eth_gstrings_stats[][ETH_GSTRING_LEN] =;
#define SH_ETH_STATS_LEN

static int sh_eth_get_sset_count(struct net_device *netdev, int sset)
{}

static void sh_eth_get_ethtool_stats(struct net_device *ndev,
				     struct ethtool_stats *stats, u64 *data)
{}

static void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
{}

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

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

static void sh_eth_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
{}

static int sh_eth_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
{}

static const struct ethtool_ops sh_eth_ethtool_ops =;

/* network device open function */
static int sh_eth_open(struct net_device *ndev)
{}

/* Timeout function */
static void sh_eth_tx_timeout(struct net_device *ndev, unsigned int txqueue)
{}

/* Packet transmit function */
static netdev_tx_t sh_eth_start_xmit(struct sk_buff *skb,
				     struct net_device *ndev)
{}

/* The statistics registers have write-clear behaviour, which means we
 * will lose any increment between the read and write.  We mitigate
 * this by only clearing when we read a non-zero value, so we will
 * never falsely report a total of zero.
 */
static void
sh_eth_update_stat(struct net_device *ndev, unsigned long *stat, int reg)
{}

static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
{}

/* device close function */
static int sh_eth_close(struct net_device *ndev)
{}

static int sh_eth_change_mtu(struct net_device *ndev, int new_mtu)
{}

/* For TSU_POSTn. Please refer to the manual about this (strange) bitfields */
static u32 sh_eth_tsu_get_post_mask(int entry)
{}

static u32 sh_eth_tsu_get_post_bit(struct sh_eth_private *mdp, int entry)
{}

static void sh_eth_tsu_enable_cam_entry_post(struct net_device *ndev,
					     int entry)
{}

static bool sh_eth_tsu_disable_cam_entry_post(struct net_device *ndev,
					      int entry)
{}

static int sh_eth_tsu_busy(struct net_device *ndev)
{}

static int sh_eth_tsu_write_entry(struct net_device *ndev, u16 offset,
				  const u8 *addr)
{}

static void sh_eth_tsu_read_entry(struct net_device *ndev, u16 offset, u8 *addr)
{}


static int sh_eth_tsu_find_entry(struct net_device *ndev, const u8 *addr)
{}

static int sh_eth_tsu_find_empty(struct net_device *ndev)
{}

static int sh_eth_tsu_disable_cam_entry_table(struct net_device *ndev,
					      int entry)
{}

static int sh_eth_tsu_add_entry(struct net_device *ndev, const u8 *addr)
{}

static int sh_eth_tsu_del_entry(struct net_device *ndev, const u8 *addr)
{}

static int sh_eth_tsu_purge_all(struct net_device *ndev)
{}

static void sh_eth_tsu_purge_mcast(struct net_device *ndev)
{}

/* Update promiscuous flag and multicast filter */
static void sh_eth_set_rx_mode(struct net_device *ndev)
{}

static void sh_eth_set_rx_csum(struct net_device *ndev, bool enable)
{}

static int sh_eth_set_features(struct net_device *ndev,
			       netdev_features_t features)
{}

static int sh_eth_get_vtag_index(struct sh_eth_private *mdp)
{}

static int sh_eth_vlan_rx_add_vid(struct net_device *ndev,
				  __be16 proto, u16 vid)
{}

static int sh_eth_vlan_rx_kill_vid(struct net_device *ndev,
				   __be16 proto, u16 vid)
{}

/* SuperH's TSU register init function */
static void sh_eth_tsu_init(struct sh_eth_private *mdp)
{}

/* MDIO bus release function */
static int sh_mdio_release(struct sh_eth_private *mdp)
{}

static int sh_mdiobb_read_c22(struct mii_bus *bus, int phy, int reg)
{}

static int sh_mdiobb_write_c22(struct mii_bus *bus, int phy, int reg, u16 val)
{}

static int sh_mdiobb_read_c45(struct mii_bus *bus, int phy, int devad, int reg)
{}

static int sh_mdiobb_write_c45(struct mii_bus *bus, int phy, int devad,
			       int reg, u16 val)
{}

/* MDIO bus init function */
static int sh_mdio_init(struct sh_eth_private *mdp,
			struct sh_eth_plat_data *pd)
{}

static const u16 *sh_eth_get_register_offset(int register_type)
{}

static const struct net_device_ops sh_eth_netdev_ops =;

static const struct net_device_ops sh_eth_netdev_ops_tsu =;

#ifdef CONFIG_OF
static struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev)
{}

static const struct of_device_id sh_eth_match_table[] =;
MODULE_DEVICE_TABLE(of, sh_eth_match_table);
#else
static inline struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev)
{
	return NULL;
}
#endif

static int sh_eth_drv_probe(struct platform_device *pdev)
{}

static void sh_eth_drv_remove(struct platform_device *pdev)
{}

#ifdef CONFIG_PM
#ifdef CONFIG_PM_SLEEP
static int sh_eth_wol_setup(struct net_device *ndev)
{}

static int sh_eth_wol_restore(struct net_device *ndev)
{}

static int sh_eth_suspend(struct device *dev)
{}

static int sh_eth_resume(struct device *dev)
{}
#endif

static int sh_eth_runtime_nop(struct device *dev)
{}

static const struct dev_pm_ops sh_eth_dev_pm_ops =;
#define SH_ETH_PM_OPS
#else
#define SH_ETH_PM_OPS
#endif

static const struct platform_device_id sh_eth_id_table[] =;
MODULE_DEVICE_TABLE(platform, sh_eth_id_table);

static struct platform_driver sh_eth_driver =;

module_platform_driver();

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