drivers/net/ethernet/realtek/rtase/rtase_main.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/realtek/rtase/rtase_main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/realtek/rtase/rtase_main.c
Extension
.c
Size
59623 bytes
Lines
2407
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 rtase_netdev_ops = {
	.ndo_open = rtase_open,
	.ndo_stop = rtase_close,
	.ndo_start_xmit = rtase_start_xmit,
	.ndo_set_rx_mode = rtase_set_rx_mode,
	.ndo_set_mac_address = rtase_set_mac_address,
	.ndo_change_mtu = rtase_change_mtu,
	.ndo_tx_timeout = rtase_tx_timeout,
	.ndo_get_stats64 = rtase_get_stats64,
	.ndo_setup_tc = rtase_setup_tc,
	.ndo_fix_features = rtase_fix_features,
	.ndo_set_features = rtase_set_features,
};

static void rtase_get_mac_address(struct net_device *dev)
{
	struct rtase_private *tp = netdev_priv(dev);
	u8 mac_addr[ETH_ALEN] __aligned(2) = {};
	u32 i;

	for (i = 0; i < ETH_ALEN; i++)
		mac_addr[i] = rtase_r8(tp, RTASE_MAC0 + i);

	if (!is_valid_ether_addr(mac_addr)) {
		eth_hw_addr_random(dev);
		netdev_warn(dev, "Random ether addr %pM\n", dev->dev_addr);
	} else {
		eth_hw_addr_set(dev, mac_addr);
		ether_addr_copy(dev->perm_addr, dev->dev_addr);
	}

	rtase_rar_set(tp, dev->dev_addr);
}

static int rtase_get_settings(struct net_device *dev,
			      struct ethtool_link_ksettings *cmd)
{
	u32 supported = SUPPORTED_MII | SUPPORTED_Pause | SUPPORTED_Asym_Pause;
	const struct rtase_private *tp = netdev_priv(dev);

	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
						supported);

	switch (tp->hw_ver) {
	case RTASE_HW_VER_906X_7XA:
	case RTASE_HW_VER_906X_7XC:
		cmd->base.speed = SPEED_5000;
		break;
	case RTASE_HW_VER_907XD_V1:
	case RTASE_HW_VER_907XD_VA:
		cmd->base.speed = SPEED_10000;
		break;
	}

	cmd->base.duplex = DUPLEX_FULL;
	cmd->base.port = PORT_MII;
	cmd->base.autoneg = AUTONEG_DISABLE;

	return 0;
}

static void rtase_get_pauseparam(struct net_device *dev,
				 struct ethtool_pauseparam *pause)
{
	const struct rtase_private *tp = netdev_priv(dev);
	u16 value = rtase_r16(tp, RTASE_CPLUS_CMD);

	pause->autoneg = AUTONEG_DISABLE;
	pause->tx_pause = !!(value & RTASE_FORCE_TXFLOW_EN);
	pause->rx_pause = !!(value & RTASE_FORCE_RXFLOW_EN);
}

static int rtase_set_pauseparam(struct net_device *dev,
				struct ethtool_pauseparam *pause)
{
	const struct rtase_private *tp = netdev_priv(dev);
	u16 value = rtase_r16(tp, RTASE_CPLUS_CMD);

	if (pause->autoneg)
		return -EOPNOTSUPP;

	value &= ~(RTASE_FORCE_TXFLOW_EN | RTASE_FORCE_RXFLOW_EN);

	if (pause->tx_pause)
		value |= RTASE_FORCE_TXFLOW_EN;

	if (pause->rx_pause)
		value |= RTASE_FORCE_RXFLOW_EN;

	rtase_w16(tp, RTASE_CPLUS_CMD, value);

Annotation

Implementation Notes