net/dsa/conduit.c

Source file repositories/reference/linux-study-clean/net/dsa/conduit.c

File Facts

System
Linux kernel
Corpus path
net/dsa/conduit.c
Extension
.c
Size
13602 bytes
Lines
536
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

if (dsa_port_supports_hwtstamp(dp)) {
			NL_SET_ERR_MSG(extack,
				       "HW timestamping not allowed on DSA conduit when switch supports the operation");
			return -EBUSY;
		}
	}

	return 0;
}

static int dsa_conduit_ethtool_setup(struct net_device *dev)
{
	struct dsa_port *cpu_dp = dev->dsa_ptr;
	struct dsa_switch *ds = cpu_dp->ds;
	struct ethtool_ops *ops;

	if (netif_is_lag_master(dev))
		return 0;

	ops = devm_kzalloc(ds->dev, sizeof(*ops), GFP_KERNEL);
	if (!ops)
		return -ENOMEM;

	cpu_dp->orig_ethtool_ops = dev->ethtool_ops;
	if (cpu_dp->orig_ethtool_ops)
		memcpy(ops, cpu_dp->orig_ethtool_ops, sizeof(*ops));

	ops->get_regs_len = dsa_conduit_get_regs_len;
	ops->get_regs = dsa_conduit_get_regs;
	ops->get_sset_count = dsa_conduit_get_sset_count;
	ops->get_ethtool_stats = dsa_conduit_get_ethtool_stats;
	ops->get_strings = dsa_conduit_get_strings;
	ops->get_ethtool_phy_stats = dsa_conduit_get_ethtool_phy_stats;

	dev->ethtool_ops = ops;

	return 0;
}

static void dsa_conduit_ethtool_teardown(struct net_device *dev)
{
	struct dsa_port *cpu_dp = dev->dsa_ptr;

	if (netif_is_lag_master(dev))
		return;

	dev->ethtool_ops = cpu_dp->orig_ethtool_ops;
	cpu_dp->orig_ethtool_ops = NULL;
}

/* Keep the conduit always promiscuous if the tagging protocol requires that
 * (garbles MAC DA) or if it doesn't support unicast filtering, case in which
 * it would revert to promiscuous mode as soon as we call dev_uc_add() on it
 * anyway.
 */
static void dsa_conduit_set_promiscuity(struct net_device *dev, int inc)
{
	const struct dsa_device_ops *ops = dev->dsa_ptr->tag_ops;

	if ((dev->priv_flags & IFF_UNICAST_FLT) && !ops->promisc_on_conduit)
		return;

	ASSERT_RTNL();

	dev_set_promiscuity(dev, inc);
}

static ssize_t tagging_show(struct device *d, struct device_attribute *attr,
			    char *buf)
{
	struct net_device *dev = to_net_dev(d);
	struct dsa_port *cpu_dp = dev->dsa_ptr;

	return sysfs_emit(buf, "%s\n",
		       dsa_tag_protocol_to_str(cpu_dp->tag_ops));
}

static ssize_t tagging_store(struct device *d, struct device_attribute *attr,
			     const char *buf, size_t count)
{
	const struct dsa_device_ops *new_tag_ops, *old_tag_ops;
	const char *end = strchrnul(buf, '\n'), *name;
	struct net_device *dev = to_net_dev(d);
	struct dsa_port *cpu_dp = dev->dsa_ptr;
	size_t len = end - buf;
	int err;

	/* Empty string passed */
	if (!len)
		return -ENOPROTOOPT;

Annotation

Implementation Notes