drivers/net/ethernet/renesas/rswitch_main.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/renesas/rswitch_main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/renesas/rswitch_main.c
Extension
.c
Size
57296 bytes
Lines
2295
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct net_device_ops rswitch_netdev_ops = {
	.ndo_open = rswitch_open,
	.ndo_stop = rswitch_stop,
	.ndo_start_xmit = rswitch_start_xmit,
	.ndo_get_stats = rswitch_get_stats,
	.ndo_eth_ioctl = phy_do_ioctl_running,
	.ndo_get_port_parent_id = rswitch_get_port_parent_id,
	.ndo_get_phys_port_name = rswitch_get_phys_port_name,
	.ndo_validate_addr = eth_validate_addr,
	.ndo_set_mac_address = eth_mac_addr,
	.ndo_hwtstamp_get = rswitch_hwstamp_get,
	.ndo_hwtstamp_set = rswitch_hwstamp_set,
};

bool is_rdev(const struct net_device *ndev)
{
	return (ndev->netdev_ops == &rswitch_netdev_ops);
}

static int rswitch_get_ts_info(struct net_device *ndev, struct kernel_ethtool_ts_info *info)
{
	struct rswitch_device *rdev = netdev_priv(ndev);

	info->phc_index = rcar_gen4_ptp_clock_index(rdev->priv->ptp_priv);
	info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
				SOF_TIMESTAMPING_TX_HARDWARE |
				SOF_TIMESTAMPING_RX_HARDWARE |
				SOF_TIMESTAMPING_RAW_HARDWARE;
	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);

	return 0;
}

static const struct ethtool_ops rswitch_ethtool_ops = {
	.get_ts_info = rswitch_get_ts_info,
	.get_link_ksettings = phy_ethtool_get_link_ksettings,
	.set_link_ksettings = phy_ethtool_set_link_ksettings,
};

static const struct of_device_id renesas_eth_sw_of_table[] = {
	{ .compatible = "renesas,r8a779f0-ether-switch", },
	{ }
};
MODULE_DEVICE_TABLE(of, renesas_eth_sw_of_table);

static void rswitch_etha_init(struct rswitch_private *priv, unsigned int index)
{
	struct rswitch_etha *etha = &priv->etha[index];

	memset(etha, 0, sizeof(*etha));
	etha->index = index;
	etha->addr = priv->addr + RSWITCH_ETHA_OFFSET + index * RSWITCH_ETHA_SIZE;
	etha->coma_addr = priv->addr;

	/* MPIC.PSMCS = (clk [MHz] / (MDC frequency [MHz] * 2) - 1.
	 * Calculating PSMCS value as MDC frequency = 2.5MHz. So, multiply
	 * both the numerator and the denominator by 10.
	 */
	etha->psmcs = clk_get_rate(priv->clk) / 100000 / (25 * 2) - 1;
}

static int rswitch_device_alloc(struct rswitch_private *priv, unsigned int index)
{
	struct platform_device *pdev = priv->pdev;
	struct rswitch_device *rdev;
	struct net_device *ndev;
	int err;

	if (index >= RSWITCH_NUM_PORTS)
		return -EINVAL;

	ndev = alloc_etherdev_mqs(sizeof(struct rswitch_device), 1, 1);
	if (!ndev)
		return -ENOMEM;

	SET_NETDEV_DEV(ndev, &pdev->dev);
	ether_setup(ndev);

	rdev = netdev_priv(ndev);
	rdev->ndev = ndev;
	rdev->priv = priv;
	priv->rdev[index] = rdev;
	rdev->port = index;
	rdev->etha = &priv->etha[index];
	rdev->addr = priv->addr;

	ndev->base_addr = (unsigned long)rdev->addr;
	snprintf(ndev->name, IFNAMSIZ, "tsn%d", index);
	ndev->netdev_ops = &rswitch_netdev_ops;

Annotation

Implementation Notes