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

// SPDX-License-Identifier: GPL-2.0
/* Renesas Ethernet Switch device driver
 *
 * Copyright (C) 2022 Renesas Electronics Corporation
 */

#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/etherdevice.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/net_tstamp.h>
#include <linux/of.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/rtnetlink.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/sys_soc.h>

#include "rswitch.h"

static int rswitch_reg_wait(void __iomem *addr, u32 offs, u32 mask, u32 expected)
{}

static void rswitch_modify(void __iomem *addr, enum rswitch_reg reg, u32 clear, u32 set)
{}

/* Common Agent block (COMA) */
static void rswitch_reset(struct rswitch_private *priv)
{}

static void rswitch_clock_enable(struct rswitch_private *priv)
{}

static void rswitch_clock_disable(struct rswitch_private *priv)
{}

static bool rswitch_agent_clock_is_enabled(void __iomem *coma_addr,
					   unsigned int port)
{}

static void rswitch_agent_clock_ctrl(void __iomem *coma_addr, unsigned int port,
				     int enable)
{}

static int rswitch_bpool_config(struct rswitch_private *priv)
{}

static void rswitch_coma_init(struct rswitch_private *priv)
{}

/* R-Switch-2 block (TOP) */
static void rswitch_top_init(struct rswitch_private *priv)
{}

/* Forwarding engine block (MFWD) */
static void rswitch_fwd_init(struct rswitch_private *priv)
{}

/* Gateway CPU agent block (GWCA) */
static int rswitch_gwca_change_mode(struct rswitch_private *priv,
				    enum rswitch_gwca_mode mode)
{}

static int rswitch_gwca_mcast_table_reset(struct rswitch_private *priv)
{}

static int rswitch_gwca_axi_ram_reset(struct rswitch_private *priv)
{}

static bool rswitch_is_any_data_irq(struct rswitch_private *priv, u32 *dis, bool tx)
{}

static void rswitch_get_data_irq_status(struct rswitch_private *priv, u32 *dis)
{}

static void rswitch_enadis_data_irq(struct rswitch_private *priv,
				    unsigned int index, bool enable)
{}

static void rswitch_ack_data_irq(struct rswitch_private *priv,
				 unsigned int index)
{}

static unsigned int rswitch_next_queue_index(struct rswitch_gwca_queue *gq,
					     bool cur, unsigned int num)
{}

static unsigned int rswitch_get_num_cur_queues(struct rswitch_gwca_queue *gq)
{}

static bool rswitch_is_queue_rxed(struct rswitch_gwca_queue *gq)
{}

static int rswitch_gwca_queue_alloc_rx_buf(struct rswitch_gwca_queue *gq,
					   unsigned int start_index,
					   unsigned int num)
{}

static void rswitch_gwca_queue_free(struct net_device *ndev,
				    struct rswitch_gwca_queue *gq)
{}

static void rswitch_gwca_ts_queue_free(struct rswitch_private *priv)
{}

static int rswitch_gwca_queue_alloc(struct net_device *ndev,
				    struct rswitch_private *priv,
				    struct rswitch_gwca_queue *gq,
				    bool dir_tx, unsigned int ring_size)
{}

static void rswitch_desc_set_dptr(struct rswitch_desc *desc, dma_addr_t addr)
{}

static dma_addr_t rswitch_desc_get_dptr(const struct rswitch_desc *desc)
{}

static int rswitch_gwca_queue_format(struct net_device *ndev,
				     struct rswitch_private *priv,
				     struct rswitch_gwca_queue *gq)
{}

static void rswitch_gwca_ts_queue_fill(struct rswitch_private *priv,
				       unsigned int start_index,
				       unsigned int num)
{}

static int rswitch_gwca_queue_ext_ts_fill(struct net_device *ndev,
					  struct rswitch_gwca_queue *gq,
					  unsigned int start_index,
					  unsigned int num)
{}

static int rswitch_gwca_queue_ext_ts_format(struct net_device *ndev,
					    struct rswitch_private *priv,
					    struct rswitch_gwca_queue *gq)
{}

static int rswitch_gwca_linkfix_alloc(struct rswitch_private *priv)
{}

static void rswitch_gwca_linkfix_free(struct rswitch_private *priv)
{}

static int rswitch_gwca_ts_queue_alloc(struct rswitch_private *priv)
{}

static struct rswitch_gwca_queue *rswitch_gwca_get(struct rswitch_private *priv)
{}

static void rswitch_gwca_put(struct rswitch_private *priv,
			     struct rswitch_gwca_queue *gq)
{}

static int rswitch_txdmac_alloc(struct net_device *ndev)
{}

static void rswitch_txdmac_free(struct net_device *ndev)
{}

static int rswitch_txdmac_init(struct rswitch_private *priv, unsigned int index)
{}

static int rswitch_rxdmac_alloc(struct net_device *ndev)
{}

static void rswitch_rxdmac_free(struct net_device *ndev)
{}

static int rswitch_rxdmac_init(struct rswitch_private *priv, unsigned int index)
{}

static int rswitch_gwca_hw_init(struct rswitch_private *priv)
{}

static int rswitch_gwca_hw_deinit(struct rswitch_private *priv)
{}

static int rswitch_gwca_halt(struct rswitch_private *priv)
{}

static struct sk_buff *rswitch_rx_handle_desc(struct net_device *ndev,
					      struct rswitch_gwca_queue *gq,
					      struct rswitch_ext_ts_desc *desc)
{}

static bool rswitch_rx(struct net_device *ndev, int *quota)
{}

static void rswitch_tx_free(struct net_device *ndev)
{}

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

static void rswitch_queue_interrupt(struct net_device *ndev)
{}

static irqreturn_t rswitch_data_irq(struct rswitch_private *priv, u32 *dis)
{}

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

static int rswitch_gwca_request_irqs(struct rswitch_private *priv)
{}

static void rswitch_ts(struct rswitch_private *priv)
{}

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

static int rswitch_gwca_ts_request_irqs(struct rswitch_private *priv)
{}

/* Ethernet TSN Agent block (ETHA) and Ethernet MAC IP block (RMAC) */
static int rswitch_etha_change_mode(struct rswitch_etha *etha,
				    enum rswitch_etha_mode mode)
{}

static void rswitch_etha_read_mac_address(struct rswitch_etha *etha)
{}

static void rswitch_etha_write_mac_address(struct rswitch_etha *etha, const u8 *mac)
{}

static int rswitch_etha_wait_link_verification(struct rswitch_etha *etha)
{}

static void rswitch_rmac_setting(struct rswitch_etha *etha, const u8 *mac)
{}

static void rswitch_etha_enable_mii(struct rswitch_etha *etha)
{}

static int rswitch_etha_hw_init(struct rswitch_etha *etha, const u8 *mac)
{}

static int rswitch_etha_set_access(struct rswitch_etha *etha, bool read,
				   int phyad, int devad, int regad, int data)
{}

static int rswitch_etha_mii_read_c45(struct mii_bus *bus, int addr, int devad,
				     int regad)
{}

static int rswitch_etha_mii_write_c45(struct mii_bus *bus, int addr, int devad,
				      int regad, u16 val)
{}

/* Call of_node_put(port) after done */
static struct device_node *rswitch_get_port_node(struct rswitch_device *rdev)
{}

static int rswitch_etha_get_params(struct rswitch_device *rdev)
{}

static int rswitch_mii_register(struct rswitch_device *rdev)
{}

static void rswitch_mii_unregister(struct rswitch_device *rdev)
{}

static void rswitch_adjust_link(struct net_device *ndev)
{}

static void rswitch_phy_remove_link_mode(struct rswitch_device *rdev,
					 struct phy_device *phydev)
{}

static int rswitch_phy_device_init(struct rswitch_device *rdev)
{}

static void rswitch_phy_device_deinit(struct rswitch_device *rdev)
{}

static int rswitch_serdes_set_params(struct rswitch_device *rdev)
{}

static int rswitch_ether_port_init_one(struct rswitch_device *rdev)
{}

static void rswitch_ether_port_deinit_one(struct rswitch_device *rdev)
{}

static int rswitch_ether_port_init_all(struct rswitch_private *priv)
{}

static void rswitch_ether_port_deinit_all(struct rswitch_private *priv)
{}

static int rswitch_open(struct net_device *ndev)
{
	struct rswitch_device *rdev = netdev_priv(ndev);
	unsigned long flags;

	phy_start(ndev->phydev);

	napi_enable(&rdev->napi);
	netif_start_queue(ndev);

	spin_lock_irqsave(&rdev->priv->lock, flags);
	rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, true);
	rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, true);
	spin_unlock_irqrestore(&rdev->priv->lock, flags);

	if (bitmap_empty(rdev->priv->opened_ports, RSWITCH_NUM_PORTS))
		iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDIE);

	bitmap_set(rdev->priv->opened_ports, rdev->port, 1);

	return 0;
};

static int rswitch_stop(struct net_device *ndev)
{
	struct rswitch_device *rdev = netdev_priv(ndev);
	struct rswitch_gwca_ts_info *ts_info, *ts_info2;
	unsigned long flags;

	netif_tx_stop_all_queues(ndev);
	bitmap_clear(rdev->priv->opened_ports, rdev->port, 1);

	if (bitmap_empty(rdev->priv->opened_ports, RSWITCH_NUM_PORTS))
		iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDID);

	list_for_each_entry_safe(ts_info, ts_info2, &rdev->priv->gwca.ts_info_list, list) {
		if (ts_info->port != rdev->port)
			continue;
		dev_kfree_skb_irq(ts_info->skb);
		list_del(&ts_info->list);
		kfree(ts_info);
	}

	spin_lock_irqsave(&rdev->priv->lock, flags);
	rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, false);
	rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, false);
	spin_unlock_irqrestore(&rdev->priv->lock, flags);

	phy_stop(ndev->phydev);
	napi_disable(&rdev->napi);

	return 0;
};

static bool rswitch_ext_desc_set_info1(struct rswitch_device *rdev,
				       struct sk_buff *skb,
				       struct rswitch_ext_desc *desc)
{}

static bool rswitch_ext_desc_set(struct rswitch_device *rdev,
				 struct sk_buff *skb,
				 struct rswitch_ext_desc *desc,
				 dma_addr_t dma_addr, u16 len, u8 die_dt)
{}

static u8 rswitch_ext_desc_get_die_dt(unsigned int nr_desc, unsigned int index)
{}

static u16 rswitch_ext_desc_get_len(u8 die_dt, unsigned int orig_len)
{}

static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{}

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

static int rswitch_hwstamp_get(struct net_device *ndev, struct ifreq *req)
{}

static int rswitch_hwstamp_set(struct net_device *ndev, struct ifreq *req)
{}

static int rswitch_eth_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
{}

static const struct net_device_ops rswitch_netdev_ops =;

static int rswitch_get_ts_info(struct net_device *ndev, struct kernel_ethtool_ts_info *info)
{}

static const struct ethtool_ops rswitch_ethtool_ops =;

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

static void rswitch_etha_init(struct rswitch_private *priv, unsigned int index)
{}

static int rswitch_device_alloc(struct rswitch_private *priv, unsigned int index)
{}

static void rswitch_device_free(struct rswitch_private *priv, unsigned int index)
{}

static int rswitch_init(struct rswitch_private *priv)
{}

static const struct soc_device_attribute rswitch_soc_no_speed_change[]  =;

static int renesas_eth_sw_probe(struct platform_device *pdev)
{}

static void rswitch_deinit(struct rswitch_private *priv)
{}

static void renesas_eth_sw_remove(struct platform_device *pdev)
{}

static int renesas_eth_sw_suspend(struct device *dev)
{}

static int renesas_eth_sw_resume(struct device *dev)
{}

static DEFINE_SIMPLE_DEV_PM_OPS(renesas_eth_sw_pm_ops, renesas_eth_sw_suspend,
				renesas_eth_sw_resume);

static struct platform_driver renesas_eth_sw_driver_platform =;
module_platform_driver();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();